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

Re-applying Airtable usability changes #15015

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.7",
description: "Create a comment on a selected record. [See the documentation](https://airtable.com/developers/web/api/create-comment)",
version: "0.0.8",
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.7",
version: "0.1.0",
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.

💡 Codebase verification

Add error handling for JSON parsing to match existing patterns

Looking at the codebase, other Airtable components (like create-multiple-records) implement proper JSON parsing error handling with try-catch blocks and specific error messages. The create-field action should follow the same pattern for consistency and robustness.

  • components/airtable_oauth/actions/create-field/create-field.mjs: Add try-catch block for JSON parsing of options
  options: typeof options === "string"
-   ? JSON.parse(options)
+   ? (() => {
+       try {
+         return JSON.parse(options);
+       } catch (err) {
+         throw new ConfigurationError(`Error parsing options as JSON: ${err.message}`);
+       }
+     })()
    : options,
🔗 Analysis chain

Verify options parsing safety

The code safely handles options parsing, but consider adding error handling for malformed JSON input.

Consider adding try-catch for JSON parsing:

  options: typeof options === "string"
-   ? JSON.parse(options)
+   ? (() => {
+       try {
+         return JSON.parse(options);
+       } catch (e) {
+         throw new Error(`Invalid JSON in options: ${e.message}`);
+       }
+     })()
    : options,
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for error handling patterns in similar Airtable actions
rg -A 5 'JSON.parse.*try' components/airtable_oauth/

Length of output: 54


Script:

#!/bin/bash
# Let's search for any JSON.parse usage in Airtable components to understand error handling patterns
rg -A 5 'JSON\.parse' components/airtable_oauth/

# Also search for similar field creation patterns
ast-grep --pattern 'createField({
  $$$
  data: {
    $$$
  }
})'

Length of output: 2411

$,
});

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.7",
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.8",
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.8",
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default {
key: "airtable_oauth-create-single-record",
name: "Create Single Record",
description: "Adds a record to a table.",
version: "0.0.8",
version: "0.0.9",
type: "action",
props: {
...common.props,
Expand Down
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.7",
version: "0.0.8",
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.7",
description: "Delete a selected record from a table. [See the documentation](https://airtable.com/developers/web/api/delete-record)",
version: "0.0.8",
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 components

The version numbers are not consistent across the components:

  • Most action components use version "0.0.8" (including delete-record.mjs)
  • Some action components have higher versions:
    • get-record.mjs and get-record-or-create.mjs: "0.0.9"
    • search-records.mjs: "0.0.10"
    • create-field.mjs and create-or-update-record.mjs: "0.1.0"
  • Source components have varying versions from "0.0.7" to "0.1.0"

Consider aligning the versions or documenting the reason for version differences.

🔗 Analysis chain

Verify version consistency across Airtable OAuth components.

The version bump to "0.0.8" is appropriate for the description change. However, we should ensure version consistency across related Airtable OAuth components.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check version numbers across Airtable OAuth components
# Expected: All components should have the same version number

echo "Checking version numbers in Airtable OAuth components..."
rg -g '*.mjs' '"version":\s*"[0-9]+\.[0-9]+\.[0-9]+"' components/airtable_oauth/

Length of output: 205


Script:

#!/bin/bash
# Let's try a different pattern that matches the version format in the file
echo "Checking version numbers in Airtable OAuth components..."
rg -g '*.mjs' 'version: "[0-9]+\.[0-9]+\.[0-9]+"' components/airtable_oauth/

Length of output: 2498

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.8",
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.9",
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.8",
description: "Get data of a selected record from a table. [See the documentation](https://airtable.com/developers/web/api/get-record)",
version: "0.0.9",
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.7",
version: "0.0.8",
...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.7",
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.9",
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.10",
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.7",
description: "Update an existing comment on a selected record. [See the documentation](https://airtable.com/developers/web/api/update-comment)",
version: "0.0.8",
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.7",
description: "Update an existing field in a table. [See the documentation](https://airtable.com/developers/web/api/update-field)",
version: "0.0.8",
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.");
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

Error message formatting is inconsistent with codebase patterns

Looking at the error messages across the Airtable OAuth components, the standard pattern is to use backticks only for dynamic values or technical identifiers (e.g., true, base IDs, table IDs). Other error messages use plain text for field names when referring to UI elements. For consistency, the error message should not wrap "Name" and "Description" in backticks.

  • components/airtable_oauth/actions/update-field/update-field.mjs: Change to "At least one of Name or Description must be provided."
🔗 Analysis chain

Error message formatting improvement

The updated error message now matches the UI field labels, making it more user-friendly.

Let's check for consistency with other error messages in the codebase:


Let me search for more error messages to get a better understanding of the error message formatting patterns.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for similar error messages in other Airtable OAuth components
rg -g "components/airtable_oauth/**" "must be provided" -B 2 -A 2

Length of output: 555


Script:

#!/bin/bash
# Search for ConfigurationError messages in Airtable OAuth components
rg -g "components/airtable_oauth/**" "ConfigurationError" -B 1 -A 1

# Also search for error messages with backticks
rg -g "components/airtable_oauth/**" '`\w+`' -B 1 -A 1

Length of output: 6457

}

const data = {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default {
key: "airtable_oauth-update-record",
name: "Update Record",
description: "Update a single record in a table by Record ID. [See the documentation](https://airtable.com/developers/web/api/update-record)",
version: "0.0.8",
version: "0.0.9",
type: "action",
props: {
...common.props,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@ import common from "../common/common.mjs";
export default {
key: "airtable_oauth-update-table",
name: "Update Table",
description: "Updates an existing table. [See the documentation](https://airtable.com/developers/web/api/update-table)",
version: "0.0.7",
description: "Update an existing table. [See the documentation](https://airtable.com/developers/web/api/update-table)",
version: "0.0.8",
type: "action",
props: {
...common.props,
name: {
type: "string",
label: "Name",
description: "The name for the table",
description: "The updated name of the table",
optional: true,
},
description: {
type: "string",
label: "Description",
description: "The description for the table",
description: "The updated description of the table",
optional: true,
},
},
Expand Down
Loading
Loading