diff --git a/components/nocodb/actions/add-record/add-record.mjs b/components/nocodb/actions/add-record/add-record.mjs index 82b347bf0bf13..adbe8a8ab03fc 100644 --- a/components/nocodb/actions/add-record/add-record.mjs +++ b/components/nocodb/actions/add-record/add-record.mjs @@ -5,7 +5,7 @@ export default { key: "nocodb-add-record", name: "Add Record", description: "This action adds a record in a table. [See the documentation](https://data-apis-v2.nocodb.com/#tag/Table-Records/operation/db-data-table-row-create)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/nocodb/actions/delete-record/delete-record.mjs b/components/nocodb/actions/delete-record/delete-record.mjs index 58de395793d2b..d9591b3c96ada 100644 --- a/components/nocodb/actions/delete-record/delete-record.mjs +++ b/components/nocodb/actions/delete-record/delete-record.mjs @@ -5,7 +5,7 @@ export default { key: "nocodb-delete-record", name: "Delete Record", description: "This action deletes a row in a table. [See the documentation](https://data-apis-v2.nocodb.com/#tag/Table-Records/operation/db-data-table-row-delete)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/nocodb/actions/get-record/get-record.mjs b/components/nocodb/actions/get-record/get-record.mjs index 63c4f67494548..5ae8549178421 100644 --- a/components/nocodb/actions/get-record/get-record.mjs +++ b/components/nocodb/actions/get-record/get-record.mjs @@ -5,7 +5,7 @@ export default { key: "nocodb-get-record", name: "Get Record (from row number)", description: "This action gets a row by row Id. [See the documentation](https://data-apis-v2.nocodb.com/#tag/Table-Records/operation/db-data-table-row-read)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/nocodb/actions/list-records-matching-criteria/list-records-matching-criteria.mjs b/components/nocodb/actions/list-records-matching-criteria/list-records-matching-criteria.mjs index b1df484d68558..14aabf15b1afa 100644 --- a/components/nocodb/actions/list-records-matching-criteria/list-records-matching-criteria.mjs +++ b/components/nocodb/actions/list-records-matching-criteria/list-records-matching-criteria.mjs @@ -5,7 +5,7 @@ export default { key: "nocodb-list-records-matching-criteria", name: "List Records in Table Matching Criteria", description: "This action lists all rows in a table. [See the documentation](https://data-apis-v2.nocodb.com/#tag/Table-Records/operation/db-data-table-row-list)", - version: "0.0.5", + version: "0.0.6", type: "action", props: { ...common.props, diff --git a/components/nocodb/actions/update-record/update-record.mjs b/components/nocodb/actions/update-record/update-record.mjs index adab950775c61..8756f4f0c64d7 100644 --- a/components/nocodb/actions/update-record/update-record.mjs +++ b/components/nocodb/actions/update-record/update-record.mjs @@ -5,7 +5,7 @@ export default { key: "nocodb-update-record", name: "Update Record", description: "This action updates a record in a table. [See the documentation](https://data-apis-v2.nocodb.com/#tag/Table-Records/operation/db-data-table-row-update)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/nocodb/nocodb.app.mjs b/components/nocodb/nocodb.app.mjs index 97065fcb0e0ed..bc4326cafbb25 100644 --- a/components/nocodb/nocodb.app.mjs +++ b/components/nocodb/nocodb.app.mjs @@ -69,6 +69,27 @@ export default { return rows?.map(({ Id }) => `${Id}` ) || []; }, }, + viewId: { + type: "string", + label: "View ID", + description: "The ID of a view", + async options({ + tableId, page, + }) { + const { list } = await this.listViews({ + tableId, + params: { + offset: page * DEFAULT_LIMIT, + }, + }); + return list?.map(({ + id: value, title: label, + }) => ({ + label, + value, + })) || []; + }, + }, data: { type: "any", label: "data", @@ -233,5 +254,13 @@ export default { ...opts, }); }, + listViews({ + tableId, ...opts + }) { + return this._makeRequest({ + path: `/meta/tables/${tableId}/views`, + ...opts, + }); + }, }, }; diff --git a/components/nocodb/package.json b/components/nocodb/package.json index c53cdf7a13904..fd91c3e67f090 100644 --- a/components/nocodb/package.json +++ b/components/nocodb/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/nocodb", - "version": "0.0.7", + "version": "0.1.0", "description": "Pipedream Nocodb Components", "main": "nocodb.app.mjs", "keywords": [ @@ -9,11 +9,10 @@ ], "homepage": "https://pipedream.com/apps/nocodb", "author": "Pipedream (https://pipedream.com/)", - "dependencies": { - "@pipedream/platform": "^1.6.0", - "moment": "^2.29.4" - }, "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.3" } } diff --git a/components/nocodb/sources/common/base.mjs b/components/nocodb/sources/common/base.mjs index 67a42071eb0a0..20b3f807d9d29 100644 --- a/components/nocodb/sources/common/base.mjs +++ b/components/nocodb/sources/common/base.mjs @@ -1,4 +1,3 @@ -import moment from "moment"; import nocodb from "../../nocodb.app.mjs"; import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform"; @@ -46,59 +45,53 @@ export default { _setLastTime(lastTime) { this.db.set("lastTime", lastTime); }, - async processEvent({ - params, lastTime, - }) { + getParams(timeField) { + return { + sort: `-${timeField}`, + }; + }, + async getRows(records, timeField, lastTime) { + const rows = []; + for await (const row of records) { + if (!lastTime || Date.parse(row[timeField]) >= Date.parse(lastTime)) { + rows.push(row); + } else { + break; + } + } + return rows.reverse(); + }, + async processEvent(max) { const timeField = this.getTimeField(); + const lastTime = this._getLastTime(); const records = this.nocodb.paginate({ fn: this.nocodb.listTableRow, args: { tableId: this.tableId.value, - params, + params: this.getParams(timeField), }, + max, }); - for await (const record of records) { - if (moment(record[timeField]).isAfter(lastTime)) this._setLastTime(record[timeField]); - this.$emit(record, this.getDataToEmit(record)); + const rows = await this.getRows(records, timeField, lastTime); + + if (!rows.length) { + return; } + + this._setLastTime(rows[rows.length - 1][timeField]); + + rows.forEach((row) => this.$emit(row, this.getDataToEmit(row))); }, }, hooks: { - async activate() { - const timeField = this.getTimeField(); - const lastTime = this._getLastTime(); - const { list } = await this.nocodb.listTableRow({ - tableId: this.tableId.value, - params: { - sort: `-${timeField}`, - }, - }); - - list.reverse(); - - for (const row of list) { - if (!lastTime || moment(lastTime).isAfter(row[timeField])) { - this._setLastTime(row[timeField]); - } - this.$emit(row, this.getDataToEmit(row)); - } + async deploy() { + await this.processEvent(25); }, }, async run() { - const timeField = this.getTimeField(); - const lastTime = this._getLastTime(); - const params = { - sort: timeField, - }; - // moment is necessary because nocodb query doesn't filter equal datetime in 'greater than' - if (lastTime) params.where = `(${timeField},gte,${moment(lastTime).add(1, "ms") - .toISOString()})`; - return this.processEvent({ - params, - lastTime, - }); + await this.processEvent(); }, }; diff --git a/components/nocodb/sources/new-record-in-view/new-record-in-view.mjs b/components/nocodb/sources/new-record-in-view/new-record-in-view.mjs new file mode 100644 index 0000000000000..b3f67c758ed62 --- /dev/null +++ b/components/nocodb/sources/new-record-in-view/new-record-in-view.mjs @@ -0,0 +1,51 @@ +import common from "../common/base.mjs"; + +export default { + ...common, + key: "nocodb-new-record-in-view", + name: "New Record in View", + description: "Emit new event for each new record in a view. [See the documentation](https://data-apis-v2.nocodb.com/#tag/Table-Records/operation/db-data-table-row-list)", + version: "0.0.1", + type: "source", + dedupe: "unique", + props: { + ...common.props, + viewId: { + propDefinition: [ + common.props.nocodb, + "viewId", + (c) => ({ + tableId: c.tableId.value || c.tableId, + }), + ], + }, + }, + methods: { + ...common.methods, + getDataToEmit(record) { + return { + id: record.id, + summary: `New record created (${record.id})`, + ts: Date.parse(record[this.getTimeField()]), + }; + }, + getTimeField() { + return "created_at"; + }, + getParams(timeField) { + return { + viewId: this.viewId, + fields: timeField, + }; + }, + async getRows(records, timeField, lastTime) { + const rows = []; + for await (const row of records) { + if (!lastTime || Date.parse(row[timeField]) >= Date.parse(lastTime)) { + rows.push(row); + } + } + return rows; + }, + }, +}; diff --git a/components/nocodb/sources/new-record/new-record.mjs b/components/nocodb/sources/new-record/new-record.mjs index 238bf43ca4421..64d836fcfe7e1 100644 --- a/components/nocodb/sources/new-record/new-record.mjs +++ b/components/nocodb/sources/new-record/new-record.mjs @@ -6,7 +6,7 @@ export default { name: "New Record in Table", key: "nocodb-new-record", description: "Emit new event for each new record in table. [See the documentation](https://data-apis-v2.nocodb.com/#tag/Table-Records/operation/db-data-table-row-list)", - version: "0.0.5", + version: "0.0.6", dedupe: "unique", props: { ...common.props, diff --git a/components/nocodb/sources/updated-record/updated-record.mjs b/components/nocodb/sources/updated-record/updated-record.mjs index aa6daa498b211..18633ea71ead5 100644 --- a/components/nocodb/sources/updated-record/updated-record.mjs +++ b/components/nocodb/sources/updated-record/updated-record.mjs @@ -6,7 +6,7 @@ export default { name: "New Update in Table", key: "nocodb-updated-record", description: "Emit new event for each update in table. [See the documentation](https://data-apis-v2.nocodb.com/#tag/Table-Records/operation/db-data-table-row-list)", - version: "0.0.5", + version: "0.0.6", dedupe: "unique", props: { ...common.props, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 524e6e8222969..73c655e4abc9c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6655,11 +6655,9 @@ importers: components/nocodb: specifiers: - '@pipedream/platform': ^1.6.0 - moment: ^2.29.4 + '@pipedream/platform': ^3.0.3 dependencies: - '@pipedream/platform': 1.6.0 - moment: 2.29.4 + '@pipedream/platform': 3.0.3 components/nocrm_io: specifiers: @@ -13221,55 +13219,6 @@ packages: - aws-crt dev: false - /@aws-sdk/client-sso-oidc/3.600.0_tdq3komn4zwyd65w7klbptsu34: - resolution: {integrity: sha512-7+I8RWURGfzvChyNQSyj5/tKrqRbzRl7H+BnTOf/4Vsw1nFOi5ROhlhD4X/Y0QCTacxnaoNcIrqnY7uGGvVRzw==} - engines: {node: '>=16.0.0'} - dependencies: - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sts': 3.600.0 - '@aws-sdk/core': 3.598.0 - '@aws-sdk/credential-provider-node': 3.600.0_f7n47caigsrjd2lr2szmwfuee4 - '@aws-sdk/middleware-host-header': 3.598.0 - '@aws-sdk/middleware-logger': 3.598.0 - '@aws-sdk/middleware-recursion-detection': 3.598.0 - '@aws-sdk/middleware-user-agent': 3.598.0 - '@aws-sdk/region-config-resolver': 3.598.0 - '@aws-sdk/types': 3.598.0 - '@aws-sdk/util-endpoints': 3.598.0 - '@aws-sdk/util-user-agent-browser': 3.598.0 - '@aws-sdk/util-user-agent-node': 3.598.0 - '@smithy/config-resolver': 3.0.3 - '@smithy/core': 2.2.3 - '@smithy/fetch-http-handler': 3.2.1 - '@smithy/hash-node': 3.0.2 - '@smithy/invalid-dependency': 3.0.2 - '@smithy/middleware-content-length': 3.0.2 - '@smithy/middleware-endpoint': 3.0.4 - '@smithy/middleware-retry': 3.0.6 - '@smithy/middleware-serde': 3.0.3 - '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.3 - '@smithy/node-http-handler': 3.1.2 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.6 - '@smithy/types': 3.3.0 - '@smithy/url-parser': 3.0.3 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.6 - '@smithy/util-defaults-mode-node': 3.0.6 - '@smithy/util-endpoints': 2.0.3 - '@smithy/util-middleware': 3.0.3 - '@smithy/util-retry': 3.0.2 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.3 - transitivePeerDependencies: - - '@aws-sdk/client-sts' - - aws-crt - dev: false - /@aws-sdk/client-sso/3.423.0: resolution: {integrity: sha512-znIufHkwhCIePgaYciIs3x/+BpzR57CZzbCKHR9+oOvGyufEPPpUT5bFLvbwTgfiVkTjuk6sG/ES3U5Bc+xtrA==} engines: {node: '>=14.0.0'} @@ -13505,7 +13454,7 @@ packages: dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.600.0_tdq3komn4zwyd65w7klbptsu34 + '@aws-sdk/client-sso-oidc': 3.600.0 '@aws-sdk/core': 3.598.0 '@aws-sdk/credential-provider-node': 3.600.0_f7n47caigsrjd2lr2szmwfuee4 '@aws-sdk/middleware-host-header': 3.598.0 @@ -13547,6 +13496,55 @@ packages: - aws-crt dev: false + /@aws-sdk/client-sts/3.600.0_dseaa2p5u2yk67qiepewcq3hkq: + resolution: {integrity: sha512-KQG97B7LvTtTiGmjlrG1LRAY8wUvCQzrmZVV5bjrJ/1oXAU7DITYwVbSJeX9NWg6hDuSk0VE3MFwIXS2SvfLIA==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/client-sso-oidc': 3.600.0 + '@aws-sdk/core': 3.598.0 + '@aws-sdk/credential-provider-node': 3.600.0_f7n47caigsrjd2lr2szmwfuee4 + '@aws-sdk/middleware-host-header': 3.598.0 + '@aws-sdk/middleware-logger': 3.598.0 + '@aws-sdk/middleware-recursion-detection': 3.598.0 + '@aws-sdk/middleware-user-agent': 3.598.0 + '@aws-sdk/region-config-resolver': 3.598.0 + '@aws-sdk/types': 3.598.0 + '@aws-sdk/util-endpoints': 3.598.0 + '@aws-sdk/util-user-agent-browser': 3.598.0 + '@aws-sdk/util-user-agent-node': 3.598.0 + '@smithy/config-resolver': 3.0.3 + '@smithy/core': 2.2.3 + '@smithy/fetch-http-handler': 3.2.1 + '@smithy/hash-node': 3.0.2 + '@smithy/invalid-dependency': 3.0.2 + '@smithy/middleware-content-length': 3.0.2 + '@smithy/middleware-endpoint': 3.0.4 + '@smithy/middleware-retry': 3.0.6 + '@smithy/middleware-serde': 3.0.3 + '@smithy/middleware-stack': 3.0.3 + '@smithy/node-config-provider': 3.1.3 + '@smithy/node-http-handler': 3.1.2 + '@smithy/protocol-http': 4.0.3 + '@smithy/smithy-client': 3.1.6 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + '@smithy/util-base64': 3.0.0 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-body-length-node': 3.0.0 + '@smithy/util-defaults-mode-browser': 3.0.6 + '@smithy/util-defaults-mode-node': 3.0.6 + '@smithy/util-endpoints': 2.0.3 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-retry': 3.0.2 + '@smithy/util-utf8': 3.0.0 + tslib: 2.6.3 + transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' + - aws-crt + dev: false + /@aws-sdk/core/3.556.0: resolution: {integrity: sha512-vJaSaHw2kPQlo11j/Rzuz0gk1tEaKdz+2ser0f0qZ5vwFlANjt08m/frU17ctnVKC1s58bxpctO/1P894fHLrA==} engines: {node: '>=14.0.0'} @@ -14612,7 +14610,7 @@ packages: '@azure/logger': 1.0.4 '@types/node-fetch': 2.6.6 '@types/tunnel': 0.0.3 - form-data: 4.0.0 + form-data: 4.0.1 node-fetch: 2.7.0 process: 0.11.10 tslib: 2.6.3 @@ -14649,7 +14647,7 @@ packages: '@azure/core-tracing': 1.0.1 '@azure/core-util': 1.5.0 '@azure/logger': 1.0.4 - form-data: 4.0.0 + form-data: 4.0.1 http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 tslib: 2.6.3 @@ -17839,7 +17837,7 @@ packages: '@aws-sdk/client-sns': 3.423.0 '@aws-sdk/client-sqs': 3.423.0 '@aws-sdk/client-ssm': 3.423.0 - '@aws-sdk/client-sts': 3.600.0 + '@aws-sdk/client-sts': 3.600.0_dseaa2p5u2yk67qiepewcq3hkq '@aws-sdk/s3-request-presigner': 3.609.0 '@pipedream/helper_functions': 0.3.12 '@pipedream/platform': 1.6.6 @@ -21557,12 +21555,6 @@ packages: dependencies: undici-types: 5.26.5 - /@types/node/22.7.9: - resolution: {integrity: sha512-jrTfRC7FM6nChvU7X2KqcrgquofrWLFDeYC1hKfwNWomVvrn7JIksqf344WN2X/y8xrgqBd2dJATZV4GbatBfg==} - dependencies: - undici-types: 6.19.8 - dev: false - /@types/normalize-package-data/2.4.2: resolution: {integrity: sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A==} dev: true @@ -21696,7 +21688,7 @@ packages: /@types/ws/8.5.12: resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} dependencies: - '@types/node': 22.7.9 + '@types/node': 20.16.1 dev: false /@types/ws/8.5.3: @@ -22557,7 +22549,7 @@ packages: resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==} dependencies: follow-redirects: 1.15.9 - form-data: 4.0.0 + form-data: 4.0.1 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug @@ -22567,7 +22559,7 @@ packages: resolution: {integrity: sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==} dependencies: follow-redirects: 1.15.9 - form-data: 4.0.0 + form-data: 4.0.1 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug @@ -22616,7 +22608,7 @@ packages: resolution: {integrity: sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==} dependencies: follow-redirects: 1.15.9_debug@3.2.7 - form-data: 4.0.0 + form-data: 4.0.1 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug @@ -34409,7 +34401,7 @@ packages: cookiejar: 2.1.4 debug: 4.3.6 fast-safe-stringify: 2.1.1 - form-data: 4.0.0 + form-data: 4.0.1 formidable: 2.1.2 methods: 1.1.2 mime: 2.6.0