n8n-nodes-pb 1.0.0

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 ADDED
@@ -0,0 +1,60 @@
1
+ # n8n-nodes-pocketbase
2
+
3
+ This is an n8n community node for [PocketBase](https://pocketbase.io/) - an open-source backend with realtime database, authentication, and file storage.
4
+
5
+ [n8n](https://n8n.io/) is a [fair-code licensed](https://docs.n8n.io/reference/license/) workflow automation platform.
6
+
7
+ ## Installation
8
+
9
+ Follow the [installation guide](https://docs.n8n.io/integrations/community-nodes/installation/) in the n8n community nodes documentation.
10
+
11
+ ```bash
12
+ npm install n8n-nodes-pocketbase
13
+ ```
14
+
15
+ ## Features
16
+
17
+ This node supports the following PocketBase API operations:
18
+
19
+ ### Records
20
+ - **Get Many** - List records with filter, sort, and pagination
21
+ - **Get** - Get a single record by ID
22
+ - **Create** - Create a new record
23
+ - **Update** - Update an existing record
24
+ - **Delete** - Delete a record
25
+
26
+ ### Collections
27
+ - **Get Many** - List all collections
28
+ - **Get** - Get collection details
29
+
30
+ ### Files
31
+ - **Get URL** - Get file download URL with optional thumbnail
32
+ - **Get Token** - Get protected file access token
33
+
34
+ ### Health
35
+ - **Check** - Check PocketBase server health status
36
+
37
+ ## Credentials
38
+
39
+ To use this node, you need to configure the following credentials:
40
+
41
+ | Field | Description |
42
+ |-------|-------------|
43
+ | **PocketBase URL** | Your PocketBase instance URL (e.g., `https://your-pb.com`) |
44
+ | **Email** | Admin or user email |
45
+ | **Password** | Account password |
46
+ | **Auth Collection** | Authentication collection (default: `_superusers`) |
47
+
48
+ ## Compatibility
49
+
50
+ - **PocketBase**: v0.22.0+
51
+ - **n8n**: v1.0.0+
52
+
53
+ ## Resources
54
+
55
+ - [PocketBase Documentation](https://pocketbase.io/docs)
56
+ - [n8n Community Nodes](https://docs.n8n.io/integrations/community-nodes/)
57
+
58
+ ## License
59
+
60
+ [MIT](LICENSE)
@@ -0,0 +1,9 @@
1
+ import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class PocketBaseApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ authenticate: IAuthenticateGeneric;
8
+ test: ICredentialTestRequest;
9
+ }
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PocketBaseApi = void 0;
4
+ class PocketBaseApi {
5
+ constructor() {
6
+ this.name = 'pocketBaseApi';
7
+ this.displayName = 'PocketBase API';
8
+ this.documentationUrl = 'https://pocketbase.io/docs';
9
+ this.properties = [
10
+ {
11
+ displayName: 'PocketBase URL',
12
+ name: 'url',
13
+ type: 'string',
14
+ default: 'http://127.0.0.1:8090',
15
+ placeholder: 'https://your-pocketbase.com',
16
+ description: 'The URL of your PocketBase instance',
17
+ required: true,
18
+ },
19
+ {
20
+ displayName: 'Email',
21
+ name: 'email',
22
+ type: 'string',
23
+ default: '',
24
+ placeholder: 'admin@example.com',
25
+ description: 'Admin or user email for authentication',
26
+ required: true,
27
+ },
28
+ {
29
+ displayName: 'Password',
30
+ name: 'password',
31
+ type: 'string',
32
+ typeOptions: {
33
+ password: true,
34
+ },
35
+ default: '',
36
+ description: 'Password for authentication',
37
+ required: true,
38
+ },
39
+ {
40
+ displayName: 'Auth Collection',
41
+ name: 'authCollection',
42
+ type: 'string',
43
+ default: '_superusers',
44
+ description: 'The auth collection to authenticate against (e.g., _superusers, users)',
45
+ },
46
+ ];
47
+ this.authenticate = {
48
+ type: 'generic',
49
+ properties: {},
50
+ };
51
+ this.test = {
52
+ request: {
53
+ baseURL: '={{$credentials.url}}',
54
+ url: '/api/health',
55
+ method: 'GET',
56
+ },
57
+ };
58
+ }
59
+ }
60
+ exports.PocketBaseApi = PocketBaseApi;
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" fill="none">
2
+ <rect width="128" height="128" rx="16" fill="#16161a"/>
3
+ <path d="M64 24C41.909 24 24 41.909 24 64s17.909 40 40 40 40-17.909 40-40S86.091 24 64 24zm0 64c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24z" fill="#3C82F6"/>
4
+ <circle cx="64" cy="64" r="12" fill="#3C82F6"/>
5
+ </svg>
@@ -0,0 +1,5 @@
1
+ import PocketBase from 'pocketbase';
2
+ import { IExecuteFunctions, ILoadOptionsFunctions } from 'n8n-workflow';
3
+ export declare function getPocketBaseClient(this: IExecuteFunctions | ILoadOptionsFunctions): Promise<PocketBase>;
4
+ export declare function handlePocketBaseError(context: IExecuteFunctions, error: unknown, itemIndex: number): never;
5
+ export declare function clearTokenCache(): void;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getPocketBaseClient = getPocketBaseClient;
7
+ exports.handlePocketBaseError = handlePocketBaseError;
8
+ exports.clearTokenCache = clearTokenCache;
9
+ const pocketbase_1 = __importDefault(require("pocketbase"));
10
+ const n8n_workflow_1 = require("n8n-workflow");
11
+ const tokenCache = new Map();
12
+ async function getPocketBaseClient() {
13
+ const credentials = await this.getCredentials('pocketBaseApi');
14
+ const url = credentials.url;
15
+ const email = credentials.email;
16
+ const password = credentials.password;
17
+ const authCollection = credentials.authCollection || '_superusers';
18
+ const pb = new pocketbase_1.default(url);
19
+ const cacheKey = `${url}:${email}`;
20
+ const cached = tokenCache.get(cacheKey);
21
+ if (cached && cached.expiresAt > Date.now()) {
22
+ pb.authStore.save(cached.token, null);
23
+ return pb;
24
+ }
25
+ try {
26
+ const authData = await pb.collection(authCollection).authWithPassword(email, password);
27
+ tokenCache.set(cacheKey, {
28
+ token: authData.token,
29
+ expiresAt: Date.now() + 60 * 60 * 1000,
30
+ });
31
+ return pb;
32
+ }
33
+ catch (error) {
34
+ const errorMessage = error instanceof Error ? error.message : String(error);
35
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), { message: errorMessage }, {
36
+ message: 'PocketBase authentication failed',
37
+ description: `Failed to authenticate with ${authCollection}: ${errorMessage}`,
38
+ });
39
+ }
40
+ }
41
+ function handlePocketBaseError(context, error, itemIndex) {
42
+ const errorMessage = error instanceof Error ? error.message : String(error);
43
+ throw new n8n_workflow_1.NodeApiError(context.getNode(), { message: errorMessage }, { itemIndex });
44
+ }
45
+ function clearTokenCache() {
46
+ tokenCache.clear();
47
+ }
@@ -0,0 +1,5 @@
1
+ import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ export declare class PocketBase implements INodeType {
3
+ description: INodeTypeDescription;
4
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
+ }
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PocketBase = void 0;
4
+ const GenericFunctions_1 = require("./GenericFunctions");
5
+ const RecordDescription_1 = require("./descriptions/RecordDescription");
6
+ const CollectionDescription_1 = require("./descriptions/CollectionDescription");
7
+ const FileDescription_1 = require("./descriptions/FileDescription");
8
+ class PocketBase {
9
+ constructor() {
10
+ this.description = {
11
+ displayName: 'PocketBase',
12
+ name: 'pocketBase',
13
+ icon: 'file:pocketbase.svg',
14
+ group: ['transform'],
15
+ version: 1,
16
+ subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
17
+ description: 'Interact with PocketBase API',
18
+ defaults: {
19
+ name: 'PocketBase',
20
+ },
21
+ inputs: ['main'],
22
+ outputs: ['main'],
23
+ credentials: [
24
+ {
25
+ name: 'pocketBaseApi',
26
+ required: true,
27
+ },
28
+ ],
29
+ properties: [
30
+ {
31
+ displayName: 'Resource',
32
+ name: 'resource',
33
+ type: 'options',
34
+ noDataExpression: true,
35
+ options: [
36
+ {
37
+ name: 'Record',
38
+ value: 'record',
39
+ description: 'Work with records in a collection',
40
+ },
41
+ {
42
+ name: 'Collection',
43
+ value: 'collection',
44
+ description: 'Work with collections',
45
+ },
46
+ {
47
+ name: 'File',
48
+ value: 'file',
49
+ description: 'Work with files',
50
+ },
51
+ {
52
+ name: 'Health',
53
+ value: 'health',
54
+ description: 'Check server health',
55
+ },
56
+ ],
57
+ default: 'record',
58
+ },
59
+ {
60
+ displayName: 'Operation',
61
+ name: 'operation',
62
+ type: 'options',
63
+ noDataExpression: true,
64
+ displayOptions: {
65
+ show: {
66
+ resource: ['health'],
67
+ },
68
+ },
69
+ options: [
70
+ {
71
+ name: 'Check',
72
+ value: 'check',
73
+ description: 'Check server health status',
74
+ action: 'Check health',
75
+ },
76
+ ],
77
+ default: 'check',
78
+ },
79
+ ...RecordDescription_1.recordOperations,
80
+ ...RecordDescription_1.recordFields,
81
+ ...CollectionDescription_1.collectionOperations,
82
+ ...CollectionDescription_1.collectionFields,
83
+ ...FileDescription_1.fileOperations,
84
+ ...FileDescription_1.fileFields,
85
+ ],
86
+ };
87
+ }
88
+ async execute() {
89
+ const items = this.getInputData();
90
+ const returnData = [];
91
+ const resource = this.getNodeParameter('resource', 0);
92
+ const operation = this.getNodeParameter('operation', 0);
93
+ const pb = await GenericFunctions_1.getPocketBaseClient.call(this);
94
+ for (let i = 0; i < items.length; i++) {
95
+ try {
96
+ let responseData;
97
+ if (resource === 'record') {
98
+ const collection = this.getNodeParameter('collection', i);
99
+ if (operation === 'getMany') {
100
+ const returnAll = this.getNodeParameter('returnAll', i);
101
+ const options = this.getNodeParameter('options', i, {});
102
+ const queryOptions = {};
103
+ if (options.filter)
104
+ queryOptions.filter = options.filter;
105
+ if (options.sort)
106
+ queryOptions.sort = options.sort;
107
+ if (options.expand)
108
+ queryOptions.expand = options.expand;
109
+ if (options.fields)
110
+ queryOptions.fields = options.fields;
111
+ if (returnAll) {
112
+ const records = await pb.collection(collection).getFullList(queryOptions);
113
+ responseData = records;
114
+ }
115
+ else {
116
+ const limit = this.getNodeParameter('limit', i);
117
+ const result = await pb.collection(collection).getList(1, limit, queryOptions);
118
+ responseData = result.items;
119
+ }
120
+ }
121
+ if (operation === 'get') {
122
+ const recordId = this.getNodeParameter('recordId', i);
123
+ const options = this.getNodeParameter('options', i, {});
124
+ const queryOptions = {};
125
+ if (options.expand)
126
+ queryOptions.expand = options.expand;
127
+ const record = await pb.collection(collection).getOne(recordId, queryOptions);
128
+ responseData = record;
129
+ }
130
+ if (operation === 'create') {
131
+ const fieldsInput = this.getNodeParameter('fields', i, {});
132
+ const options = this.getNodeParameter('options', i, {});
133
+ const data = {};
134
+ if (fieldsInput.field) {
135
+ for (const field of fieldsInput.field) {
136
+ try {
137
+ data[field.name] = JSON.parse(field.value);
138
+ }
139
+ catch {
140
+ data[field.name] = field.value;
141
+ }
142
+ }
143
+ }
144
+ const queryOptions = {};
145
+ if (options.expand)
146
+ queryOptions.expand = options.expand;
147
+ const record = await pb.collection(collection).create(data, queryOptions);
148
+ responseData = record;
149
+ }
150
+ if (operation === 'update') {
151
+ const recordId = this.getNodeParameter('recordId', i);
152
+ const fieldsInput = this.getNodeParameter('fields', i, {});
153
+ const options = this.getNodeParameter('options', i, {});
154
+ const data = {};
155
+ if (fieldsInput.field) {
156
+ for (const field of fieldsInput.field) {
157
+ try {
158
+ data[field.name] = JSON.parse(field.value);
159
+ }
160
+ catch {
161
+ data[field.name] = field.value;
162
+ }
163
+ }
164
+ }
165
+ const queryOptions = {};
166
+ if (options.expand)
167
+ queryOptions.expand = options.expand;
168
+ const record = await pb.collection(collection).update(recordId, data, queryOptions);
169
+ responseData = record;
170
+ }
171
+ if (operation === 'delete') {
172
+ const recordId = this.getNodeParameter('recordId', i);
173
+ await pb.collection(collection).delete(recordId);
174
+ responseData = { success: true, deleted: recordId };
175
+ }
176
+ }
177
+ if (resource === 'collection') {
178
+ if (operation === 'getMany') {
179
+ const collections = await pb.collections.getFullList();
180
+ responseData = collections;
181
+ }
182
+ if (operation === 'get') {
183
+ const collectionId = this.getNodeParameter('collectionId', i);
184
+ const col = await pb.collections.getOne(collectionId);
185
+ responseData = col;
186
+ }
187
+ }
188
+ if (resource === 'file') {
189
+ if (operation === 'getUrl') {
190
+ const collection = this.getNodeParameter('collection', i);
191
+ const recordId = this.getNodeParameter('recordId', i);
192
+ const filename = this.getNodeParameter('filename', i);
193
+ const options = this.getNodeParameter('options', i, {});
194
+ const record = await pb.collection(collection).getOne(recordId);
195
+ const urlOptions = {};
196
+ if (options.thumb)
197
+ urlOptions.thumb = options.thumb;
198
+ const fileUrl = pb.files.getURL(record, filename, urlOptions);
199
+ responseData = { url: fileUrl, filename, recordId, collection };
200
+ }
201
+ if (operation === 'getToken') {
202
+ const token = await pb.files.getToken();
203
+ responseData = { token };
204
+ }
205
+ }
206
+ if (resource === 'health') {
207
+ if (operation === 'check') {
208
+ const health = await pb.health.check();
209
+ responseData = health;
210
+ }
211
+ }
212
+ if (Array.isArray(responseData)) {
213
+ returnData.push(...responseData.map((item) => ({
214
+ json: item,
215
+ pairedItem: { item: i },
216
+ })));
217
+ }
218
+ else if (responseData) {
219
+ returnData.push({
220
+ json: responseData,
221
+ pairedItem: { item: i },
222
+ });
223
+ }
224
+ }
225
+ catch (error) {
226
+ if (this.continueOnFail()) {
227
+ returnData.push({
228
+ json: { error: error.message },
229
+ pairedItem: { item: i },
230
+ });
231
+ continue;
232
+ }
233
+ (0, GenericFunctions_1.handlePocketBaseError)(this, error, i);
234
+ }
235
+ }
236
+ return [returnData];
237
+ }
238
+ }
239
+ exports.PocketBase = PocketBase;
@@ -0,0 +1,3 @@
1
+ import { INodeProperties } from 'n8n-workflow';
2
+ export declare const collectionOperations: INodeProperties[];
3
+ export declare const collectionFields: INodeProperties[];
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.collectionFields = exports.collectionOperations = void 0;
4
+ exports.collectionOperations = [
5
+ {
6
+ displayName: 'Operation',
7
+ name: 'operation',
8
+ type: 'options',
9
+ noDataExpression: true,
10
+ displayOptions: {
11
+ show: {
12
+ resource: ['collection'],
13
+ },
14
+ },
15
+ options: [
16
+ {
17
+ name: 'Get Many',
18
+ value: 'getMany',
19
+ description: 'Get all collections',
20
+ action: 'Get many collections',
21
+ },
22
+ {
23
+ name: 'Get',
24
+ value: 'get',
25
+ description: 'Get a collection by ID or name',
26
+ action: 'Get a collection',
27
+ },
28
+ ],
29
+ default: 'getMany',
30
+ },
31
+ ];
32
+ exports.collectionFields = [
33
+ {
34
+ displayName: 'Collection ID or Name',
35
+ name: 'collectionId',
36
+ type: 'string',
37
+ required: true,
38
+ default: '',
39
+ placeholder: 'notes',
40
+ description: 'ID or name of the collection',
41
+ displayOptions: {
42
+ show: {
43
+ resource: ['collection'],
44
+ operation: ['get'],
45
+ },
46
+ },
47
+ },
48
+ ];
@@ -0,0 +1,3 @@
1
+ import { INodeProperties } from 'n8n-workflow';
2
+ export declare const fileOperations: INodeProperties[];
3
+ export declare const fileFields: INodeProperties[];
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fileFields = exports.fileOperations = void 0;
4
+ exports.fileOperations = [
5
+ {
6
+ displayName: 'Operation',
7
+ name: 'operation',
8
+ type: 'options',
9
+ noDataExpression: true,
10
+ displayOptions: {
11
+ show: {
12
+ resource: ['file'],
13
+ },
14
+ },
15
+ options: [
16
+ {
17
+ name: 'Get URL',
18
+ value: 'getUrl',
19
+ description: 'Get the URL of a file',
20
+ action: 'Get file URL',
21
+ },
22
+ {
23
+ name: 'Get Token',
24
+ value: 'getToken',
25
+ description: 'Get a token for accessing protected files',
26
+ action: 'Get file token',
27
+ },
28
+ ],
29
+ default: 'getUrl',
30
+ },
31
+ ];
32
+ exports.fileFields = [
33
+ {
34
+ displayName: 'Collection Name',
35
+ name: 'collection',
36
+ type: 'string',
37
+ required: true,
38
+ default: '',
39
+ placeholder: 'notes',
40
+ description: 'Name of the collection',
41
+ displayOptions: {
42
+ show: {
43
+ resource: ['file'],
44
+ operation: ['getUrl'],
45
+ },
46
+ },
47
+ },
48
+ {
49
+ displayName: 'Record ID',
50
+ name: 'recordId',
51
+ type: 'string',
52
+ required: true,
53
+ default: '',
54
+ placeholder: 'abc123xyz',
55
+ description: 'ID of the record',
56
+ displayOptions: {
57
+ show: {
58
+ resource: ['file'],
59
+ operation: ['getUrl'],
60
+ },
61
+ },
62
+ },
63
+ {
64
+ displayName: 'Filename',
65
+ name: 'filename',
66
+ type: 'string',
67
+ required: true,
68
+ default: '',
69
+ placeholder: 'image.jpg',
70
+ description: 'Name of the file',
71
+ displayOptions: {
72
+ show: {
73
+ resource: ['file'],
74
+ operation: ['getUrl'],
75
+ },
76
+ },
77
+ },
78
+ {
79
+ displayName: 'Options',
80
+ name: 'options',
81
+ type: 'collection',
82
+ placeholder: 'Add Option',
83
+ default: {},
84
+ displayOptions: {
85
+ show: {
86
+ resource: ['file'],
87
+ operation: ['getUrl'],
88
+ },
89
+ },
90
+ options: [
91
+ {
92
+ displayName: 'Thumb',
93
+ name: 'thumb',
94
+ type: 'string',
95
+ default: '',
96
+ placeholder: '100x100',
97
+ description: 'Thumbnail size (e.g., 100x100, 0x300)',
98
+ },
99
+ ],
100
+ },
101
+ ];
@@ -0,0 +1,3 @@
1
+ import { INodeProperties } from 'n8n-workflow';
2
+ export declare const recordOperations: INodeProperties[];
3
+ export declare const recordFields: INodeProperties[];
@@ -0,0 +1,222 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.recordFields = exports.recordOperations = void 0;
4
+ exports.recordOperations = [
5
+ {
6
+ displayName: 'Operation',
7
+ name: 'operation',
8
+ type: 'options',
9
+ noDataExpression: true,
10
+ displayOptions: {
11
+ show: {
12
+ resource: ['record'],
13
+ },
14
+ },
15
+ options: [
16
+ {
17
+ name: 'Create',
18
+ value: 'create',
19
+ description: 'Create a new record',
20
+ action: 'Create a record',
21
+ },
22
+ {
23
+ name: 'Delete',
24
+ value: 'delete',
25
+ description: 'Delete a record',
26
+ action: 'Delete a record',
27
+ },
28
+ {
29
+ name: 'Get',
30
+ value: 'get',
31
+ description: 'Get a record by ID',
32
+ action: 'Get a record',
33
+ },
34
+ {
35
+ name: 'Get Many',
36
+ value: 'getMany',
37
+ description: 'Get many records',
38
+ action: 'Get many records',
39
+ },
40
+ {
41
+ name: 'Update',
42
+ value: 'update',
43
+ description: 'Update a record',
44
+ action: 'Update a record',
45
+ },
46
+ ],
47
+ default: 'getMany',
48
+ },
49
+ ];
50
+ exports.recordFields = [
51
+ {
52
+ displayName: 'Collection Name',
53
+ name: 'collection',
54
+ type: 'string',
55
+ required: true,
56
+ default: '',
57
+ placeholder: 'notes',
58
+ description: 'Name of the collection to operate on',
59
+ displayOptions: {
60
+ show: {
61
+ resource: ['record'],
62
+ },
63
+ },
64
+ },
65
+ {
66
+ displayName: 'Record ID',
67
+ name: 'recordId',
68
+ type: 'string',
69
+ required: true,
70
+ default: '',
71
+ placeholder: 'abc123xyz',
72
+ description: 'ID of the record',
73
+ displayOptions: {
74
+ show: {
75
+ resource: ['record'],
76
+ operation: ['get', 'update', 'delete'],
77
+ },
78
+ },
79
+ },
80
+ {
81
+ displayName: 'Fields',
82
+ name: 'fields',
83
+ type: 'fixedCollection',
84
+ typeOptions: {
85
+ multipleValues: true,
86
+ },
87
+ default: {},
88
+ placeholder: 'Add Field',
89
+ description: 'Fields to set on the record',
90
+ displayOptions: {
91
+ show: {
92
+ resource: ['record'],
93
+ operation: ['create', 'update'],
94
+ },
95
+ },
96
+ options: [
97
+ {
98
+ name: 'field',
99
+ displayName: 'Field',
100
+ values: [
101
+ {
102
+ displayName: 'Field Name',
103
+ name: 'name',
104
+ type: 'string',
105
+ default: '',
106
+ placeholder: 'title',
107
+ description: 'Name of the field',
108
+ },
109
+ {
110
+ displayName: 'Field Value',
111
+ name: 'value',
112
+ type: 'string',
113
+ default: '',
114
+ placeholder: 'My Title',
115
+ description: 'Value of the field',
116
+ },
117
+ ],
118
+ },
119
+ ],
120
+ },
121
+ {
122
+ displayName: 'Return All',
123
+ name: 'returnAll',
124
+ type: 'boolean',
125
+ default: false,
126
+ description: 'Whether to return all results or only up to a given limit',
127
+ displayOptions: {
128
+ show: {
129
+ resource: ['record'],
130
+ operation: ['getMany'],
131
+ },
132
+ },
133
+ },
134
+ {
135
+ displayName: 'Limit',
136
+ name: 'limit',
137
+ type: 'number',
138
+ default: 50,
139
+ typeOptions: {
140
+ minValue: 1,
141
+ maxValue: 500,
142
+ },
143
+ description: 'Max number of results to return',
144
+ displayOptions: {
145
+ show: {
146
+ resource: ['record'],
147
+ operation: ['getMany'],
148
+ returnAll: [false],
149
+ },
150
+ },
151
+ },
152
+ {
153
+ displayName: 'Options',
154
+ name: 'options',
155
+ type: 'collection',
156
+ placeholder: 'Add Option',
157
+ default: {},
158
+ displayOptions: {
159
+ show: {
160
+ resource: ['record'],
161
+ operation: ['getMany'],
162
+ },
163
+ },
164
+ options: [
165
+ {
166
+ displayName: 'Filter',
167
+ name: 'filter',
168
+ type: 'string',
169
+ default: '',
170
+ placeholder: "status = 'active' && created > '2024-01-01'",
171
+ description: 'Filter expression to apply',
172
+ },
173
+ {
174
+ displayName: 'Sort',
175
+ name: 'sort',
176
+ type: 'string',
177
+ default: '',
178
+ placeholder: '-created,title',
179
+ description: 'Sort order (use - for descending)',
180
+ },
181
+ {
182
+ displayName: 'Expand',
183
+ name: 'expand',
184
+ type: 'string',
185
+ default: '',
186
+ placeholder: 'author,tags',
187
+ description: 'Comma-separated list of relations to expand',
188
+ },
189
+ {
190
+ displayName: 'Fields',
191
+ name: 'fields',
192
+ type: 'string',
193
+ default: '',
194
+ placeholder: 'id,title,created',
195
+ description: 'Comma-separated list of fields to return',
196
+ },
197
+ ],
198
+ },
199
+ {
200
+ displayName: 'Options',
201
+ name: 'options',
202
+ type: 'collection',
203
+ placeholder: 'Add Option',
204
+ default: {},
205
+ displayOptions: {
206
+ show: {
207
+ resource: ['record'],
208
+ operation: ['get', 'create', 'update'],
209
+ },
210
+ },
211
+ options: [
212
+ {
213
+ displayName: 'Expand',
214
+ name: 'expand',
215
+ type: 'string',
216
+ default: '',
217
+ placeholder: 'author,tags',
218
+ description: 'Comma-separated list of relations to expand',
219
+ },
220
+ ],
221
+ },
222
+ ];
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "n8n-nodes-pb",
3
+ "version": "1.0.0",
4
+ "description": "n8n community node for PocketBase - Open Source backend with realtime database, authentication, and file storage",
5
+ "keywords": [
6
+ "n8n-community-node-package",
7
+ "n8n",
8
+ "pocketbase",
9
+ "database",
10
+ "backend",
11
+ "api"
12
+ ],
13
+ "license": "MIT",
14
+ "homepage": "https://github.com/DuanPeng1314/n8n-nodes-pocketbase",
15
+ "author": {
16
+ "name": "DuanPeng1314"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/DuanPeng1314/n8n-nodes-pocketbase.git"
21
+ },
22
+ "main": "dist/index.js",
23
+ "scripts": {
24
+ "build": "tsc && gulp build:icons",
25
+ "dev": "tsc --watch",
26
+ "lint": "eslint . --ext .ts",
27
+ "prepublishOnly": "npm run build"
28
+ },
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "n8n": {
33
+ "n8nNodesApiVersion": 1,
34
+ "credentials": [
35
+ "dist/credentials/PocketBaseApi.credentials.js"
36
+ ],
37
+ "nodes": [
38
+ "dist/nodes/PocketBase/PocketBase.node.js"
39
+ ]
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^20.10.0",
43
+ "gulp": "^4.0.2",
44
+ "n8n-workflow": "^1.0.0",
45
+ "typescript": "^5.3.0"
46
+ },
47
+ "dependencies": {
48
+ "pocketbase": "^0.25.0"
49
+ },
50
+ "peerDependencies": {
51
+ "n8n-workflow": "*"
52
+ }
53
+ }