Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Airtable usability improvements #14691

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
5 changes: 5 additions & 0 deletions components/airtable_oauth/actions/common/common.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ export default {
],
withLabel: true,
},
warningAlert: {
type: "alert",
alertType: "warning",
content: "**Note:** if using a custom expression to specify the `Base` (e.g. `{{steps.mydata.$return_value}}`) you should also use a custom expression for the `Table`, and any other props that depend on it.",
},
tableId: {
propDefinition: [
airtable,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import common from "../common/common.mjs";
export default {
key: "airtable_oauth-create-comment",
name: "Create Comment",
description: "Create a new comment on a record. [See the documentation](https://airtable.com/developers/web/api/create-comment)",
version: "0.0.6",
description: "Create a comment on a selected record. [See the documentation](https://airtable.com/developers/web/api/create-comment)",
version: "0.0.7",
type: "action",
props: {
...common.props,
Expand All @@ -23,7 +23,7 @@ export default {
comment: {
type: "string",
label: "Comment",
description: "The text comment",
description: "The text comment to create",
},
},
async run({ $ }) {
Expand Down
45 changes: 34 additions & 11 deletions components/airtable_oauth/actions/create-field/create-field.mjs
Original file line number Diff line number Diff line change
@@ -1,30 +1,53 @@
import constants from "../../sources/common/constants.mjs";
import common from "../common/common.mjs";

export default {
key: "airtable_oauth-create-field",
name: "Create Field",
description: "Create a new field in a table. [See the documentation](https://airtable.com/developers/web/api/create-field)",
version: "0.0.6",
version: "0.0.7",
type: "action",
props: {
...common.props,
field: {
name: {
type: "string",
label: "Field",
description: "A JSON object representing the field. Refer to [field types](https://airtable.com/developers/web/api/model/field-type) for supported field types, the write format for field options, and other specifics for certain field types.",
label: "Field Name",
description: "The name of the field",
},
type: {
type: "string",
label: "Field Type",
description: "The field type. [See the documentation](https://airtable.com/developers/web/api/model/field-type) for more information.",
options: constants.FIELD_TYPES,
},
description: {
type: "string",
label: "Field Description",
description: "The description of the field",
optional: true,
},
options: {
type: "object",
label: "Field Options",
description: "The options for the field as a JSON object, e.g. `{ \"color\": \"greenBright\" }`. Each type has a specific set of options - [see the documentation](https://airtable.com/developers/web/api/field-model) for more information.",
optional: true,
},
},
async run({ $ }) {
const field = typeof this.field === "object"
? this.field
: JSON.parse(this.field);
const data = {
...field,
};
const {
description, name, options, type,
} = this;
const response = await this.airtable.createField({
baseId: this.baseId.value,
tableId: this.tableId.value,
data,
data: {
name,
type,
description,
options: typeof options === "string"
? JSON.parse(options)
: options,
},
Comment on lines +37 to +50
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for options parsing

The current implementation might throw unclear errors if invalid JSON is provided.

Consider adding explicit error handling:

       data: {
         name,
         type,
         description,
-        options: typeof options === "string"
-          ? JSON.parse(options)
-          : options,
+        options: typeof options === "string"
+          ? (() => {
+              try {
+                return JSON.parse(options);
+              } catch (e) {
+                throw new Error(`Invalid JSON in options: ${e.message}`);
+              }
+            })()
+          : options,
       },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const {
description, name, options, type,
} = this;
const response = await this.airtable.createField({
baseId: this.baseId.value,
tableId: this.tableId.value,
data,
data: {
name,
type,
description,
options: typeof options === "string"
? JSON.parse(options)
: options,
},
const {
description, name, options, type,
} = this;
const response = await this.airtable.createField({
baseId: this.baseId.value,
tableId: this.tableId.value,
data: {
name,
type,
description,
options: typeof options === "string"
? (() => {
try {
return JSON.parse(options);
} catch (e) {
throw new Error(`Invalid JSON in options: ${e.message}`);
}
})()
: options,
},

$,
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import chunk from "lodash.chunk";
import airtable from "../../airtable_oauth.app.mjs";
import common from "../common/common.mjs";
import { ConfigurationError } from "@pipedream/platform";

const BATCH_SIZE = 10; // The Airtable API allows us to update up to 10 rows per request.

export default {
key: "airtable_oauth-create-multiple-records",
name: "Create Multiple Records",
description: "Create one or more records in a table by passing an array of objects containing field names and values as key/value pairs. [See the documentation](https://airtable.com/developers/web/api/create-records)",
version: "0.0.6",
description: "Create one or more records in a table in a single operation with an array. [See the documentation](https://airtable.com/developers/web/api/create-records)",
version: "0.0.7",
type: "action",
props: {
...common.props,
Expand All @@ -18,6 +19,15 @@ export default {
"records",
],
},
customExpressionInfo: {
type: "alert",
alertType: "info",
content: `You can use a custom expression that evaluates to an object for each entry in the array, e.g. \`{{ { "foo": "bar", "id": 123 } }}\`.
\\
You can also reference an object exported by a previous step, e.g. \`{{steps.foo.$return_value}}\`.
\\
If desired, you can use a custom expression in the same fashion for the entire array instead of providing individual values.`,
},
typecast: {
propDefinition: [
airtable,
Expand All @@ -39,9 +49,18 @@ export default {
if (!Array.isArray(data)) {
data = JSON.parse(data);
}
data = data.map((fields) => ({
fields,
}));
data = data.map((fields, index) => {
if (typeof fields === "string") {
try {
fields = JSON.parse(fields);
} catch (err) {
throw new ConfigurationError(`Error parsing record (index ${index}) as JSON: ${err.message}`);
}
}
return {
fields,
};
});
if (!data.length) {
throw new Error("No Airtable record data passed to step. Please pass at least one record");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import commonActions from "../../common/actions.mjs";

export default {
key: "airtable_oauth-create-or-update-record",
name: "Create Single Record Or Update",
description: "Updates a record if `recordId` is provided or adds a record to a table.",
version: "0.0.7",
name: "Create or Update Record",
description: "Create a new record or update an existing one. [See the documentation](https://airtable.com/developers/web/api/create-records)",
version: "0.1.0",
type: "action",
props: {
...common.props,
// eslint-disable-next-line pipedream/props-label,pipedream/props-description
tableId: {
...common.props.tableId,
reloadProps: true,
Expand All @@ -27,7 +26,7 @@ export default {
}),
],
optional: true,
description: "Enter a [record ID](https://support.airtable.com/hc/en-us/articles/360051564873-Record-ID) if you want to update an existing record. Leave blank to create a new record.",
description: "To update an existing record, select it from the list or provide its [Record ID](https://support.airtable.com/hc/en-us/articles/360051564873-Record-ID). If left blank, a new record will be created.",
},
typecast: {
propDefinition: [
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default {
key: "airtable_oauth-create-table",
name: "Create Table",
description: "Create a new table. [See the documentation](https://airtable.com/developers/web/api/create-table)",
version: "0.0.6",
version: "0.0.7",
type: "action",
props: {
airtable,
Expand All @@ -17,18 +17,18 @@ export default {
name: {
type: "string",
label: "Name",
description: "The name for the table",
description: "The name of the table",
},
description: {
type: "string",
label: "Description",
description: "The description for the table",
description: "The description of the table",
optional: true,
},
fields: {
type: "string[]",
label: "Fields",
description: "A list of JSON objects representing the fields in the table. Refer to [field types](https://airtable.com/developers/web/api/model/field-type) for supported field types, the write format for field options, and other specifics for certain field types.",
description: "A list of JSON objects representing the fields in the table. [See the documentation](https://airtable.com/developers/web/api/model/field-type) for supported field types, the write format for field options, and other specifics for certain field types.",
},
},
async run({ $ }) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import common from "../common/common.mjs";
export default {
key: "airtable_oauth-delete-record",
name: "Delete Record",
description: "Delete a record from a table by record ID. [See the documentation](https://airtable.com/developers/web/api/delete-record)",
version: "0.0.6",
description: "Delete a selected record from a table. [See the documentation](https://airtable.com/developers/web/api/delete-record)",
version: "0.0.8",
type: "action",
props: {
...common.props,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ import commonActions from "../../common/actions.mjs";
export default {
key: "airtable_oauth-get-record-or-create",
name: "Get Record Or Create",
description: "Get a record from a table by record ID or create a new register.",
version: "0.0.7",
description: "Get a specific record, or create one if it doesn't exist. [See the documentation](https://airtable.com/developers/web/api/create-records)",
version: "0.0.8",
type: "action",
props: {
...common.props,
// eslint-disable-next-line pipedream/props-label,pipedream/props-description
tableId: {
...common.props.tableId,
reloadProps: true,
Expand Down
4 changes: 2 additions & 2 deletions components/airtable_oauth/actions/get-record/get-record.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import commonActions from "../../common/actions.mjs";
export default {
key: "airtable_oauth-get-record",
name: "Get Record",
description: "Get a record from a table by record ID. [See the documentation](https://airtable.com/developers/web/api/get-record)",
version: "0.0.7",
description: "Get data of a selected record from a table. [See the documentation](https://airtable.com/developers/web/api/get-record)",
version: "0.0.8",
type: "action",
props: {
...common.props,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ import commonList from "../common/common-list.mjs";
export default {
key: "airtable_oauth-list-records-in-view",
name: "List Records in View",
description: "Retrieve records in a view with automatic pagination. Optionally sort and filter results. Only available for Enterprise accounts.",
description: "Retrieve records from a view, optionally sorting and filtering results. [See the documentation](https://airtable.com/developers/web/api/list-views)",
type: "action",
version: "0.0.6",
version: "0.0.7",
...commonList,
props: {
accountTierAlert: {
type: "alert",
alertType: "info",
content: "Note: views are only available for Airtable Enterprise accounts. [See the documentation](https://airtable.com/developers/web/api/list-views) for more information.",
},
...common.props,
viewId: {
propDefinition: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import commonList from "../common/common-list.mjs";
export default {
key: "airtable_oauth-list-records",
name: "List Records",
description: "Retrieve records from a table with automatic pagination. Optionally sort and filter results.",
description: "Retrieve records from a table, optionally sorting and filtering results. [See the documentation](https://airtable.com/developers/web/api/list-records)",
type: "action",
version: "0.0.6",
version: "0.0.8",
...commonList,
props: {
...common.props,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { fieldTypeToPropType } from "../../common/utils.mjs";
export default {
key: "airtable_oauth-search-records",
name: "Search Records",
description: "Searches for a record by formula or by field value. [See the documentation](https://airtable.com/developers/web/api/list-records)",
version: "0.0.8",
description: "Search for a record by formula or by field value. [See the documentation](https://airtable.com/developers/web/api/list-records)",
version: "0.0.9",
type: "action",
props: {
...common.props,
Expand All @@ -32,7 +32,7 @@ export default {
props.searchFormula = {
type: "string",
label: "Search Formula",
description: "Use an Airtable search formula to find records. For example, if you want to find records with `Tags` includes `test-1`, use `FIND('test-1', {Tags})`. Learn more on [Airtable's website](https://support.airtable.com/docs/formula-field-reference)",
description: "Use an [Airtable search formula (see info on the documentation)](https://support.airtable.com/docs/formula-field-reference) to find records. For example, if you want to find records with `Tags` including `test-1`, use `FIND('test-1', {Tags})`.",
optional: true,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import common from "../common/common.mjs";
export default {
key: "airtable_oauth-update-comment",
name: "Update Comment",
description: "Updates an existing comment on a record. [See the documentation](https://airtable.com/developers/web/api/update-comment)",
version: "0.0.6",
description: "Update an existing comment on a selected record. [See the documentation](https://airtable.com/developers/web/api/update-comment)",
version: "0.0.7",
type: "action",
props: {
...common.props,
Expand Down Expand Up @@ -36,7 +36,7 @@ export default {
comment: {
type: "string",
label: "Comment",
description: "The text comment",
description: "The new content of the comment",
},
},
async run({ $ }) {
Expand Down
10 changes: 5 additions & 5 deletions components/airtable_oauth/actions/update-field/update-field.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { ConfigurationError } from "@pipedream/platform";
export default {
key: "airtable_oauth-update-field",
name: "Update Field",
description: "Updates an existing field in a table. [See the documentation](https://airtable.com/developers/web/api/update-field)",
version: "0.0.6",
description: "Update an existing field in a table. [See the documentation](https://airtable.com/developers/web/api/update-field)",
version: "0.0.7",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Version inconsistency detected across Airtable OAuth actions

The version numbers are not consistent across the Airtable OAuth action files:

  • Version "0.0.6": create-table.mjs, update-comment.mjs, update-table.mjs
  • Version "0.0.7": create-comment.mjs, create-field.mjs, create-multiple-records.mjs, list-records-in-view.mjs, update-field.mjs
  • Version "0.0.8": delete-record.mjs, get-record.mjs, get-record-or-create.mjs, list-records.mjs, search-records.mjs
  • Version "0.1.0": create-or-update-record.mjs

This inconsistency should be addressed to maintain version alignment across related components.

🔗 Analysis chain

Verify version consistency across related files

The version bump to "0.0.7" should be consistent across related Airtable OAuth action files.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check version numbers in related Airtable OAuth action files
# Expected: All related files should have version: "0.0.7"

echo "Checking version numbers in Airtable OAuth action files:"
rg -U 'version: "([^"]+)"' --type js components/airtable_oauth/actions/

Length of output: 196


Script:

#!/bin/bash
# Let's try a different approach to find all action files and their versions
echo "Searching for action files in airtable_oauth directory:"
fd . components/airtable_oauth/actions/ -t f -e mjs

echo -e "\nChecking version strings in each file:"
for file in $(fd . components/airtable_oauth/actions/ -t f -e mjs); do
  echo "=== $file ==="
  cat "$file" | grep -A 1 "export default {" | grep "version"
done

Length of output: 7022


Script:

#!/bin/bash
# Let's try a simpler approach with just grep to find version strings
echo "Checking version strings in all .mjs files:"
for file in components/airtable_oauth/actions/*/*.mjs; do
  echo "=== $file ==="
  grep -A 2 "export default" "$file"
done

Length of output: 6410


Script:

#!/bin/bash
# Let's try one more time with a more specific grep pattern to find version strings
echo "Checking version strings in all .mjs files:"
for file in components/airtable_oauth/actions/*/*.mjs; do
  if grep -A 5 "export default {" "$file" | grep -q "version:"; then
    echo "=== $file ==="
    grep -A 5 "export default {" "$file" | grep "version:"
  fi
done

Length of output: 7117

type: "action",
props: {
...common.props,
Expand All @@ -27,19 +27,19 @@ export default {
name: {
type: "string",
label: "Name",
description: "The name of the field",
description: "The new name of the field",
optional: true,
},
description: {
type: "string",
label: "Description",
description: "The description for the field",
description: "The new description of the field",
optional: true,
},
},
async run({ $ }) {
if (!this.name && !this.description) {
throw new ConfigurationError("At least one of `name` or `description` must be provided.");
throw new ConfigurationError("At least one of `Name` or `Description` must be provided.");
}

const data = {};
Expand Down
Loading
Loading