first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled

This commit is contained in:
2026-03-17 16:22:57 +03:30
commit 3d5eaf9445
15349 changed files with 2847338 additions and 0 deletions
@@ -0,0 +1,18 @@
{
"node": "n8n-nodes-base.timescaleDb",
"nodeVersion": "1.0",
"codexVersion": "1.0",
"categories": ["Data & Storage", "Development"],
"resources": {
"credentialDocumentation": [
{
"url": "https://docs.n8n.io/integrations/builtin/credentials/timescaledb/"
}
],
"primaryDocumentation": [
{
"url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.timescaledb/"
}
]
}
}
@@ -0,0 +1,335 @@
import type {
IExecuteFunctions,
INodeExecutionData,
INodeType,
INodeTypeDescription,
} from 'n8n-workflow';
import { NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';
import pgPromise from 'pg-promise';
import { pgInsert, pgQueryV2, pgUpdate } from '../Postgres/v1/genericFunctions';
export class TimescaleDb implements INodeType {
description: INodeTypeDescription = {
displayName: 'TimescaleDB',
name: 'timescaleDb',
icon: { light: 'file:timescaleDb.svg', dark: 'file:timescaleDb.dark.svg' },
group: ['input'],
version: 1,
description: 'Add and update data in TimescaleDB',
defaults: {
name: 'TimescaleDB',
},
usableAsTool: true,
inputs: [NodeConnectionTypes.Main],
outputs: [NodeConnectionTypes.Main],
parameterPane: 'wide',
credentials: [
{
name: 'timescaleDb',
required: true,
},
],
properties: [
// eslint-disable-next-line n8n-nodes-base/node-param-operation-without-no-data-expression
{
displayName: 'Operation',
name: 'operation',
type: 'options',
options: [
{
name: 'Execute Query',
value: 'executeQuery',
description: 'Execute an SQL query',
action: 'Execute a SQL query',
},
{
name: 'Insert',
value: 'insert',
description: 'Insert rows in database',
action: 'Insert rows in database',
},
{
name: 'Update',
value: 'update',
description: 'Update rows in database',
action: 'Update rows in database',
},
],
default: 'insert',
},
// ----------------------------------
// executeQuery
// ----------------------------------
{
displayName: 'Query',
name: 'query',
type: 'string',
noDataExpression: true,
typeOptions: {
editor: 'sqlEditor',
sqlDialect: 'PostgreSQL',
},
displayOptions: {
show: {
operation: ['executeQuery'],
},
},
default: '',
placeholder: 'SELECT id, name FROM product WHERE quantity > $1 AND price <= $2',
required: true,
description:
'The SQL query to execute. You can use n8n expressions or $1 and $2 in conjunction with query parameters.',
},
// ----------------------------------
// insert
// ----------------------------------
{
displayName: 'Schema',
name: 'schema',
type: 'string',
displayOptions: {
show: {
operation: ['insert'],
},
},
default: 'public',
required: true,
description: 'Name of the schema the table belongs to',
},
{
displayName: 'Table',
name: 'table',
type: 'string',
displayOptions: {
show: {
operation: ['insert'],
},
},
default: '',
required: true,
description: 'Name of the table in which to insert data to',
},
{
displayName: 'Columns',
name: 'columns',
type: 'string',
displayOptions: {
show: {
operation: ['insert'],
},
},
default: '',
placeholder: 'id,name,description',
description:
'Comma-separated list of the properties which should used as columns for the new rows',
},
// ----------------------------------
// update
// ----------------------------------
{
displayName: 'Schema',
name: 'schema',
type: 'string',
displayOptions: {
show: {
operation: ['update'],
},
},
default: 'public',
required: true,
description: 'Name of the schema the table belongs to',
},
{
displayName: 'Table',
name: 'table',
type: 'string',
displayOptions: {
show: {
operation: ['update'],
},
},
default: '',
required: true,
description: 'Name of the table in which to update data in',
},
{
displayName: 'Update Key',
name: 'updateKey',
type: 'string',
displayOptions: {
show: {
operation: ['update'],
},
},
default: 'id',
required: true,
// eslint-disable-next-line n8n-nodes-base/node-param-description-miscased-id
description:
'Name of the property which decides which rows in the database should be updated. Normally that would be "id".',
},
{
displayName: 'Columns',
name: 'columns',
type: 'string',
displayOptions: {
show: {
operation: ['update'],
},
},
default: '',
placeholder: 'name,description',
description:
'Comma-separated list of the properties which should used as columns for rows to update',
},
// ----------------------------------
// insert,update
// ----------------------------------
{
displayName: 'Return Fields',
name: 'returnFields',
type: 'string',
displayOptions: {
show: {
operation: ['insert', 'update'],
},
},
default: '*',
description: 'Comma-separated list of the fields that the operation will return',
},
// ----------------------------------
// additional fields
// ----------------------------------
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
options: [
{
displayName: 'Mode',
name: 'mode',
type: 'options',
options: [
{
name: 'Independently',
value: 'independently',
description: 'Execute each query independently',
},
{
name: 'Multiple Queries',
value: 'multiple',
description: '<b>Default</b>. Sends multiple queries at once to database.',
},
{
name: 'Transaction',
value: 'transaction',
description: 'Executes all queries in a single transaction',
},
],
default: 'multiple',
description:
'The way queries should be sent to database. Can be used in conjunction with <b>Continue on Fail</b>. See <a href="https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.timescaledb/">the docs</a> for more examples',
},
{
displayName: 'Query Parameters',
name: 'queryParams',
type: 'string',
displayOptions: {
show: {
'/operation': ['executeQuery'],
},
},
default: '',
placeholder: 'quantity,price',
description:
'Comma-separated list of properties which should be used as query parameters',
},
],
},
],
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const credentials = await this.getCredentials('timescaleDb');
const pgp = pgPromise();
const config = {
host: credentials.host as string,
port: credentials.port as number,
database: credentials.database as string,
user: credentials.user as string,
password: credentials.password as string,
ssl: !['disable', undefined].includes(credentials.ssl as string | undefined),
sslmode: (credentials.ssl as string) || 'disable',
};
const db = pgp(config);
let returnItems = [];
const items = this.getInputData();
const operation = this.getNodeParameter('operation', 0);
if (operation === 'executeQuery') {
// ----------------------------------
// executeQuery
// ----------------------------------
const queryResult = await pgQueryV2.call(this, pgp, db, items, this.continueOnFail(), {
resolveExpression: true,
});
returnItems = this.helpers.returnJsonArray(queryResult);
} else if (operation === 'insert') {
// ----------------------------------
// insert
// ----------------------------------
const insertData = await pgInsert(
this.getNodeParameter,
pgp,
db,
items,
this.continueOnFail(),
);
// Add the id to the data
for (let i = 0; i < insertData.length; i++) {
returnItems.push({
json: insertData[i],
});
}
} else if (operation === 'update') {
// ----------------------------------
// update
// ----------------------------------
const updateItems = await pgUpdate(
this.getNodeParameter,
pgp,
db,
items,
this.continueOnFail(),
);
returnItems = this.helpers.returnJsonArray(updateItems);
} else {
await db.$pool.end();
throw new NodeOperationError(
this.getNode(),
`The operation "${operation}" is not supported!`,
);
}
// shuts down the connection pool associated with the db object to allow the process to finish
await db.$pool.end();
return [returnItems];
}
}
@@ -0,0 +1,15 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.4046 18.0053L17.4015 14.6971C17.4015 14.5012 17.3238 14.3115 17.1838 14.1716L14.3171 11.3018L12.3179 13.5062L16.988 18.1763C17.1434 18.3287 17.4046 18.2198 17.4046 18.0053Z" fill="url(#paint0_linear_1043_6445)"/>
<path d="M11.0742 25.9834L5.44332 20.365L3.43164 22.5508L10.8814 29.9912C11.0338 30.1436 11.2949 30.0348 11.2949 29.8202V26.5089C11.2918 26.313 11.2141 26.1233 11.0742 25.9834Z" fill="url(#paint1_linear_1043_6445)"/>
<path d="M18.5769 0.0492619C8.47181 0.748843 0.393976 9.11272 0.0146475 19.2364C-0.358462 29.1207 6.43836 37.4815 15.6137 39.5336L3.38196 27.2987C3.20785 27.1246 3.10835 26.8852 3.10835 26.6364L3.11768 22.6846C3.11768 22.5198 3.31667 22.4359 3.43482 22.554L5.44651 20.3682C5.31903 20.2407 5.31903 20.0355 5.44651 19.9111L7.38357 17.9803C7.51105 17.8528 7.71315 17.8559 7.84063 17.9803L14.3794 24.5191C14.6561 24.7958 14.8147 25.1751 14.8147 25.5669V32.3917C14.8147 33.3742 15.2064 34.3163 15.8998 35.0128L20.887 40C22.1525 39.9471 23.3869 39.773 24.5808 39.4932L18.2628 33.1752C17.9519 32.8643 17.7747 32.4383 17.7747 31.9968V25.399C17.7747 24.3169 17.3456 23.2816 16.5807 22.5167L9.94248 15.8784C9.815 15.751 9.815 15.5458 9.94248 15.4214L11.864 13.5061C11.9915 13.3786 12.1936 13.3817 12.3211 13.5061L14.3203 11.3016C14.283 11.2581 14.2488 11.2115 14.2115 11.1648C13.6394 10.3937 13.2942 9.12516 13.6985 7.6918C13.941 6.77457 14.4447 6.08431 15.3712 5.24171C15.4521 5.16709 15.5827 5.16398 15.6635 5.23549L18.0669 7.31558L18.5396 7.726C18.7199 7.88457 18.9375 7.9965 19.1738 8.05247L26.664 9.83096C26.7511 9.85272 26.8319 9.89625 26.8941 9.95844L34.5926 17.6352C34.7263 17.7627 34.804 17.943 34.804 18.1295V19.7619C34.804 20.0137 34.7418 20.2594 34.6206 20.4801L30.8118 27.4169C30.647 27.7216 30.2739 27.8491 29.9567 27.7091L28.2 26.9443H21.7856C21.3721 26.9443 21.0394 27.277 21.0394 27.6905V30.551C21.0394 30.9459 21.1949 31.3221 21.4716 31.6019L28.116 38.2961C35.1118 35.1807 39.9934 28.1631 39.9934 20.0075C39.9934 8.48776 30.2614 -0.759143 18.5769 0.0492619Z" fill="#F5FF80"/>
<defs>
<linearGradient id="paint0_linear_1043_6445" x1="17.4527" y1="14.7987" x2="14.2137" y2="14.7505" gradientUnits="userSpaceOnUse">
<stop stop-color="#F5FF80" stop-opacity="0"/>
<stop offset="1" stop-color="#F5FF80"/>
</linearGradient>
<linearGradient id="paint1_linear_1043_6445" x1="11.2251" y1="25.2152" x2="7.18901" y2="25.2152" gradientUnits="userSpaceOnUse">
<stop stop-color="#F5FF80" stop-opacity="0"/>
<stop offset="0.96" stop-color="#F5FF80"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

@@ -0,0 +1,8 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_1043_6438" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="40" height="40">
<path d="M20 0C31.0448 0 40 8.95522 40 20C40 31.0448 31.0448 40 20 40C8.95522 40 0 31.0448 0 20C0 8.95522 8.95522 0 20 0Z" fill="white"/>
</mask>
<g mask="url(#mask0_1043_6438)">
<path d="M39.9191 19.997C39.9191 28.122 35.059 35.1089 28.0907 38.2122L21.4738 31.5455C21.1971 31.2656 21.0416 30.8894 21.0416 30.4976V27.6494C21.0416 27.2389 21.3743 26.9062 21.7848 26.9062H28.1747L29.9222 27.668C30.2394 27.8048 30.6063 27.6804 30.7742 27.3757L34.5677 20.4665C34.689 20.2489 34.7512 20.0001 34.7512 19.7513V18.1251C34.7512 17.9385 34.6765 17.7613 34.5397 17.6338L26.8749 9.99077C26.8127 9.92858 26.7319 9.88505 26.6448 9.86328L19.1852 8.09089C18.952 8.03492 18.7344 7.92298 18.554 7.76751L18.0814 7.35706L15.6871 5.28306C15.6032 5.21154 15.4757 5.21465 15.3948 5.28928C14.4713 6.12572 13.9707 6.81602 13.7282 7.72709C13.3239 9.15433 13.6691 10.4199 14.2381 11.1848C14.2723 11.2346 14.3096 11.2781 14.3469 11.3216L17.2014 14.1792C17.3413 14.316 17.416 14.5057 17.416 14.7016L17.4191 17.9976C17.4191 18.2122 17.161 18.3179 17.0086 18.1686L12.36 13.5231C12.2356 13.3987 12.0304 13.3987 11.906 13.5231L9.9906 15.4292C9.86311 15.5536 9.86311 15.7588 9.9906 15.8863L16.6013 22.497C17.3631 23.2588 17.7891 24.2911 17.7891 25.367V31.9342C17.7891 32.3757 17.9632 32.7955 18.2742 33.1064L24.5646 39.4C23.3768 39.6798 22.1454 39.8508 20.883 39.9068L15.9172 34.941C15.2238 34.2476 14.8351 33.3086 14.8351 32.3322V25.5349C14.8351 25.1431 14.6797 24.7669 14.4029 24.4901L7.89483 17.979C7.77045 17.8546 7.56523 17.8546 7.44085 17.979L5.51299 19.9037C5.3855 20.0281 5.3855 20.2333 5.51299 20.3577L11.1193 25.964C11.2561 26.104 11.3339 26.2905 11.3339 26.4864V29.7731C11.3339 29.9877 11.0758 30.0934 10.9234 29.9441L3.50739 22.5312C3.39234 22.4161 3.19333 22.497 3.19333 22.6618L3.18401 26.5984C3.18401 26.844 3.2804 27.0834 3.45453 27.2576L15.6374 39.4435C6.49868 37.4006 -0.270596 29.0735 0.0994286 19.229C0.478782 9.14811 8.52294 0.814773 18.5882 0.121365C30.2269 -0.683983 39.9191 8.52311 39.9191 19.997Z" fill="black"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB