n8n-nodes-datatable-variables 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.
Files changed (29) hide show
  1. package/LICENSE.md +19 -0
  2. package/README.md +123 -0
  3. package/dist/credentials/GithubIssuesApi.credentials.d.ts +10 -0
  4. package/dist/credentials/GithubIssuesApi.credentials.js +37 -0
  5. package/dist/credentials/GithubIssuesApi.credentials.js.map +1 -0
  6. package/dist/credentials/GithubIssuesOAuth2Api.credentials.d.ts +9 -0
  7. package/dist/credentials/GithubIssuesOAuth2Api.credentials.js +54 -0
  8. package/dist/credentials/GithubIssuesOAuth2Api.credentials.js.map +1 -0
  9. package/dist/dist/icons/datatable-import-export.svg +5 -0
  10. package/dist/dist/icons/datatable-trigger.svg +5 -0
  11. package/dist/dist/icons/datatable.svg +4 -0
  12. package/dist/icons/datatable-import-export.svg +5 -0
  13. package/dist/icons/datatable-trigger.svg +5 -0
  14. package/dist/icons/datatable.svg +4 -0
  15. package/dist/nodes/DatatableVariables/DatatableVariables.node.d.ts +10 -0
  16. package/dist/nodes/DatatableVariables/DatatableVariables.node.js +476 -0
  17. package/dist/nodes/DatatableVariables/DatatableVariables.node.js.map +1 -0
  18. package/dist/nodes/DatatableVariables/DatatableVariablesImportExport.node.d.ts +10 -0
  19. package/dist/nodes/DatatableVariables/DatatableVariablesImportExport.node.js +296 -0
  20. package/dist/nodes/DatatableVariables/DatatableVariablesImportExport.node.js.map +1 -0
  21. package/dist/nodes/DatatableVariables/DatatableVariablesTrigger.node.d.ts +10 -0
  22. package/dist/nodes/DatatableVariables/DatatableVariablesTrigger.node.js +145 -0
  23. package/dist/nodes/DatatableVariables/DatatableVariablesTrigger.node.js.map +1 -0
  24. package/dist/nodes/DatatableVariables/db.d.ts +46 -0
  25. package/dist/nodes/DatatableVariables/db.js +296 -0
  26. package/dist/nodes/DatatableVariables/db.js.map +1 -0
  27. package/dist/package.json +51 -0
  28. package/dist/tsconfig.tsbuildinfo +1 -0
  29. package/package.json +51 -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,123 @@
1
+ # n8n-nodes-datatable-variables
2
+
3
+ This is an n8n community node package that enables users to create local tables and store variables within them. It runs entirely locally on your host or container, without requiring any external database servers or cloud service setups.
4
+
5
+ With this node, you can easily cache, share, and persist variables between workflow runs, execution iterations, or different paths in a workflow.
6
+
7
+ ---
8
+
9
+ ## Key Features
10
+
11
+ - **Local Storage**: Persists data inside `~/.n8n/n8n-nodes-datatable-variables.json`.
12
+ - **Concurrency & Thread Safety**: Uses a self-healing `.lock` file (with PID tracking and a 5-second automatic expiration timeout) and atomic file writes (via temporary file swap) to ensure data safety when multiple executions modify tables simultaneously.
13
+ - **Rich Data Types Support**: Supports Text, Numbers, Booleans, Dates, parsed JSON objects, and Binary files.
14
+ - **Change Log Polling Trigger**: A trigger node that watches for table updates and fires workflows based on changes (for all variables, a specific key, or multiple keys).
15
+ - **Import/Export**: Easily backup or restore tables as binary JSON files or raw JSON objects.
16
+
17
+ ---
18
+
19
+ ## Directory Structure
20
+
21
+ ```text
22
+ n8n-nodes-datatable-variables/
23
+ ├── icons/
24
+ │ ├── datatable.svg # Icon for the main node
25
+ │ ├── datatable-trigger.svg # Icon for the trigger node
26
+ │ └── datatable-import-export.svg # Icon for the import/export node
27
+ ├── nodes/
28
+ │ └── DatatableVariables/
29
+ │ ├── db.ts # Local database driver (locks, writes, changes)
30
+ │ ├── DatatableVariables.node.ts # Main node logic (CRUD operations)
31
+ │ ├── DatatableVariablesTrigger.node.ts # Polling trigger node
32
+ │ └── DatatableVariablesImportExport.node.ts # Data backup and restore node
33
+ ├── package.json # Package configurations and scripts
34
+ └── tsconfig.json # TypeScript configuration
35
+ ```
36
+
37
+ ---
38
+
39
+ ## Available Nodes & Operations
40
+
41
+ ### 1. Datatable Variables (Main Node)
42
+
43
+ Acts as a local key-value datatable store.
44
+
45
+ #### Resource: Variable
46
+ - **Set**: Save or update a variable.
47
+ - Supports inline table creation if the table doesn't exist yet via `[+ Create New Table...]`.
48
+ - Type-safe inputs: Text, Number, Boolean, JSON, Date, and Binary files (binary files are read from the incoming item and stored inside the database as Base64 strings along with filename and mimeType).
49
+ - **Get**: Load a variable from a table.
50
+ - If it is a binary file, it will reconstruct the file buffer and output it as a binary property on the n8n execution item.
51
+ - **Delete**: Delete a variable key from a table.
52
+ - **Get All**: Retrieve all variables in a table as a key-value object (binary files return file metadata).
53
+
54
+ #### Resource: Table
55
+ - **List**: List all tables in your local database along with their variable count.
56
+ - **Delete**: Delete a table and all variables within it.
57
+
58
+ ---
59
+
60
+ ### 2. Datatable Variables Trigger
61
+
62
+ Polls the local database change-log and triggers workflows when updates occur.
63
+
64
+ - **Table Name**: Choose which table to watch.
65
+ - **Trigger On**:
66
+ - `All Changes in the Table`: Fires on any variable insert, update, or deletion.
67
+ - `Specific Variable`: Fires only when a specific key is updated.
68
+ - `Multiple Variables`: Fires when any key in a defined list is updated.
69
+ - **State Tracking**: Uses n8n workflow static data (`node` scope) to track the processed change IDs. It automatically initializes to the latest change ID when activated, ensuring that workflows only fire on new changes.
70
+
71
+ ---
72
+
73
+ ### 3. Datatable Variables Import/Export
74
+
75
+ Lets you download or restore your datatable variables easily.
76
+
77
+ - **Export**: Export a single table or all tables. Output format can be:
78
+ - `JSON File (Binary)`: Generates a downloadable `.json` file.
79
+ - `JSON Output`: Outputs the raw JSON structure directly on the execution node.
80
+ - **Import**: Reads a backup file or a raw JSON string.
81
+ - **Modes**: Choose `Merge` (insert/overwrite keys) or `Replace` (wipes the database first and loads the new content).
82
+
83
+ ---
84
+
85
+ ## Installation
86
+
87
+ ### Community Node Install (Standard)
88
+
89
+ Refer to the official [n8n Community Nodes Installation Guide](https://docs.n8n.io/integrations/community-nodes/installation/) to install this package in your n8n instance using:
90
+
91
+ ```text
92
+ n8n-nodes-datatable-variables
93
+ ```
94
+
95
+ ### Local Development Setup
96
+
97
+ To link and run this node locally for testing:
98
+
99
+ 1. **Build & Link the Node**:
100
+ ```bash
101
+ cd /path/to/n8n-nodes-datatable-variables
102
+ npm install
103
+ npm run build
104
+ npm link
105
+ ```
106
+
107
+ 2. **Mount in your local n8n installation**:
108
+ Navigate to your local n8n folder (usually `~/.n8n/`):
109
+ ```bash
110
+ cd ~/.n8n
111
+ mkdir nodes
112
+ cd nodes
113
+ npm link n8n-nodes-datatable-variables
114
+ ```
115
+
116
+ 3. **Restart n8n**:
117
+ Restart your n8n server, and the new nodes will appear in your workflow editor.
118
+
119
+ ---
120
+
121
+ ## License
122
+
123
+ [MIT](LICENSE.md)
@@ -0,0 +1,10 @@
1
+ import type { IAuthenticateGeneric, Icon, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class GithubIssuesApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ icon: Icon;
6
+ documentationUrl: string;
7
+ properties: INodeProperties[];
8
+ authenticate: IAuthenticateGeneric;
9
+ test: ICredentialTestRequest;
10
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GithubIssuesApi = void 0;
4
+ class GithubIssuesApi {
5
+ constructor() {
6
+ this.name = 'githubIssuesApi';
7
+ this.displayName = 'GitHub Issues API';
8
+ this.icon = { light: 'file:../icons/github.svg', dark: 'file:../icons/github.dark.svg' };
9
+ this.documentationUrl = 'https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#deleting-a-personal-access-token';
10
+ this.properties = [
11
+ {
12
+ displayName: 'Access Token',
13
+ name: 'accessToken',
14
+ type: 'string',
15
+ typeOptions: { password: true },
16
+ default: '',
17
+ },
18
+ ];
19
+ this.authenticate = {
20
+ type: 'generic',
21
+ properties: {
22
+ headers: {
23
+ Authorization: '=token {{$credentials?.accessToken}}',
24
+ },
25
+ },
26
+ };
27
+ this.test = {
28
+ request: {
29
+ baseURL: 'https://api.github.com',
30
+ url: '/user',
31
+ method: 'GET',
32
+ },
33
+ };
34
+ }
35
+ }
36
+ exports.GithubIssuesApi = GithubIssuesApi;
37
+ //# sourceMappingURL=GithubIssuesApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GithubIssuesApi.credentials.js","sourceRoot":"","sources":["../../credentials/GithubIssuesApi.credentials.ts"],"names":[],"mappings":";;;AAQA,MAAa,eAAe;IAA5B;QACC,SAAI,GAAG,iBAAiB,CAAC;QAEzB,gBAAW,GAAG,mBAAmB,CAAC;QAElC,SAAI,GAAS,EAAE,KAAK,EAAE,0BAA0B,EAAE,IAAI,EAAE,+BAA+B,EAAE,CAAC;QAE1F,qBAAgB,GACf,sJAAsJ,CAAC;QAExJ,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,cAAc;gBAC3B,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;aACX;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,aAAa,EAAE,sCAAsC;iBACrD;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,wBAAwB;gBACjC,GAAG,EAAE,OAAO;gBACZ,MAAM,EAAE,KAAK;aACb;SACD,CAAC;IACH,CAAC;CAAA;AApCD,0CAoCC"}
@@ -0,0 +1,9 @@
1
+ import type { Icon, ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class GithubIssuesOAuth2Api implements ICredentialType {
3
+ name: string;
4
+ extends: string[];
5
+ displayName: string;
6
+ icon: Icon;
7
+ documentationUrl: string;
8
+ properties: INodeProperties[];
9
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GithubIssuesOAuth2Api = void 0;
4
+ class GithubIssuesOAuth2Api {
5
+ constructor() {
6
+ this.name = 'githubIssuesOAuth2Api';
7
+ this.extends = ['oAuth2Api'];
8
+ this.displayName = 'GitHub Issues OAuth2 API';
9
+ this.icon = { light: 'file:../icons/github.svg', dark: 'file:../icons/github.dark.svg' };
10
+ this.documentationUrl = 'https://docs.github.com/en/apps/oauth-apps';
11
+ this.properties = [
12
+ {
13
+ displayName: 'Grant Type',
14
+ name: 'grantType',
15
+ type: 'hidden',
16
+ default: 'authorizationCode',
17
+ },
18
+ {
19
+ displayName: 'Authorization URL',
20
+ name: 'authUrl',
21
+ type: 'hidden',
22
+ default: 'https://github.com/login/oauth/authorize',
23
+ required: true,
24
+ },
25
+ {
26
+ displayName: 'Access Token URL',
27
+ name: 'accessTokenUrl',
28
+ type: 'hidden',
29
+ default: 'https://github.com/login/oauth/access_token',
30
+ required: true,
31
+ },
32
+ {
33
+ displayName: 'Scope',
34
+ name: 'scope',
35
+ type: 'hidden',
36
+ default: 'repo',
37
+ },
38
+ {
39
+ displayName: 'Auth URI Query Parameters',
40
+ name: 'authQueryParameters',
41
+ type: 'hidden',
42
+ default: '',
43
+ },
44
+ {
45
+ displayName: 'Authentication',
46
+ name: 'authentication',
47
+ type: 'hidden',
48
+ default: 'header',
49
+ },
50
+ ];
51
+ }
52
+ }
53
+ exports.GithubIssuesOAuth2Api = GithubIssuesOAuth2Api;
54
+ //# sourceMappingURL=GithubIssuesOAuth2Api.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GithubIssuesOAuth2Api.credentials.js","sourceRoot":"","sources":["../../credentials/GithubIssuesOAuth2Api.credentials.ts"],"names":[],"mappings":";;;AAEA,MAAa,qBAAqB;IAAlC;QACC,SAAI,GAAG,uBAAuB,CAAC;QAE/B,YAAO,GAAG,CAAC,WAAW,CAAC,CAAC;QAExB,gBAAW,GAAG,0BAA0B,CAAC;QAEzC,SAAI,GAAS,EAAE,KAAK,EAAE,0BAA0B,EAAE,IAAI,EAAE,+BAA+B,EAAE,CAAC;QAE1F,qBAAgB,GAAG,4CAA4C,CAAC;QAEhE,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,mBAAmB;aAC5B;YACD;gBACC,WAAW,EAAE,mBAAmB;gBAChC,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,0CAA0C;gBACnD,QAAQ,EAAE,IAAI;aACd;YACD;gBACC,WAAW,EAAE,kBAAkB;gBAC/B,IAAI,EAAE,gBAAgB;gBACtB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,6CAA6C;gBACtD,QAAQ,EAAE,IAAI;aACd;YACD;gBACC,WAAW,EAAE,OAAO;gBACpB,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,MAAM;aACf;YACD;gBACC,WAAW,EAAE,2BAA2B;gBACxC,IAAI,EAAE,qBAAqB;gBAC3B,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;aACX;YACD;gBACC,WAAW,EAAE,gBAAgB;gBAC7B,IAAI,EAAE,gBAAgB;gBACtB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,QAAQ;aACjB;SACD,CAAC;IACH,CAAC;CAAA;AAnDD,sDAmDC"}
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="100%" height="100%">
2
+ <rect width="24" height="24" rx="4" fill="#4B0082" opacity="0.1"/>
3
+ <path d="M4 6c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6zm2 0v2h12V6H6zm0 4v2h3v-2H6zm5 0v2h7v-2h-7zm-5 4v2h3v-2H6zm5 0v2h7v-2h-7zm-5 4v2h3v-2H6zm5 0v2h7v-2h-7z" fill="#4B0082" opacity="0.5"/>
4
+ <path d="M15 10l-3-3v2H8v2h4v2zm-6 4l3 3v-2h4v-2h-4v-2z" fill="#4B0082"/>
5
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="100%" height="100%">
2
+ <rect width="24" height="24" rx="4" fill="#FF3366" opacity="0.1"/>
3
+ <path d="M4 6c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6zm2 0v2h12V6H6zm0 4v2h3v-2H6zm5 0v2h7v-2h-7zm-5 4v2h3v-2H6zm5 0v2h7v-2h-7zm-5 4v2h3v-2H6zm5 0v2h7v-2h-7z" fill="#FF3366" opacity="0.5"/>
4
+ <path d="M12.5 7l-4 6h3v4l4-6h-3z" fill="#FF3366"/>
5
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="100%" height="100%">
2
+ <rect width="24" height="24" rx="4" fill="#FF9900" opacity="0.1"/>
3
+ <path d="M4 6c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6zm2 0v2h12V6H6zm0 4v2h3v-2H6zm5 0v2h7v-2h-7zm-5 4v2h3v-2H6zm5 0v2h7v-2h-7zm-5 4v2h3v-2H6zm5 0v2h7v-2h-7z" fill="#FF9900"/>
4
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="100%" height="100%">
2
+ <rect width="24" height="24" rx="4" fill="#4B0082" opacity="0.1"/>
3
+ <path d="M4 6c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6zm2 0v2h12V6H6zm0 4v2h3v-2H6zm5 0v2h7v-2h-7zm-5 4v2h3v-2H6zm5 0v2h7v-2h-7zm-5 4v2h3v-2H6zm5 0v2h7v-2h-7z" fill="#4B0082" opacity="0.5"/>
4
+ <path d="M15 10l-3-3v2H8v2h4v2zm-6 4l3 3v-2h4v-2h-4v-2z" fill="#4B0082"/>
5
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="100%" height="100%">
2
+ <rect width="24" height="24" rx="4" fill="#FF3366" opacity="0.1"/>
3
+ <path d="M4 6c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6zm2 0v2h12V6H6zm0 4v2h3v-2H6zm5 0v2h7v-2h-7zm-5 4v2h3v-2H6zm5 0v2h7v-2h-7zm-5 4v2h3v-2H6zm5 0v2h7v-2h-7z" fill="#FF3366" opacity="0.5"/>
4
+ <path d="M12.5 7l-4 6h3v4l4-6h-3z" fill="#FF3366"/>
5
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="100%" height="100%">
2
+ <rect width="24" height="24" rx="4" fill="#FF9900" opacity="0.1"/>
3
+ <path d="M4 6c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6zm2 0v2h12V6H6zm0 4v2h3v-2H6zm5 0v2h7v-2h-7zm-5 4v2h3v-2H6zm5 0v2h7v-2h-7zm-5 4v2h3v-2H6zm5 0v2h7v-2h-7z" fill="#FF9900"/>
4
+ </svg>
@@ -0,0 +1,10 @@
1
+ import { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ export declare class DatatableVariables implements INodeType {
3
+ description: INodeTypeDescription;
4
+ methods: {
5
+ loadOptions: {
6
+ getTables(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
7
+ };
8
+ };
9
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
10
+ }