Skip to content

Commit

Permalink
🪟 🔧 Add ConnectorIds utility (#19826)
Browse files Browse the repository at this point in the history
* Add ConnectorIds utility

* Fix typo

* Update airbyte-webapp/packages/eslint-plugin/no-hardcoded-connector-ids.js

Co-authored-by: Lake Mossman <lake@airbyte.io>

* Change variable name

* Use in tests

* Remove unnecessary comment

* Adjust linting errors

Co-authored-by: Lake Mossman <lake@airbyte.io>
  • Loading branch information
timroes and lmossman authored Dec 2, 2022
1 parent acc7b32 commit bd9eedf
Show file tree
Hide file tree
Showing 21 changed files with 445 additions and 46 deletions.
5 changes: 3 additions & 2 deletions airbyte-webapp/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ module.exports = {
"plugin:prettier/recommended",
"plugin:css-modules/recommended",
"plugin:jsx-a11y/recommended",
"plugin:@airbyte/recommended",
],
plugins: ["react", "@typescript-eslint", "prettier", "unused-imports", "css-modules", "jsx-a11y"],
plugins: ["react", "@typescript-eslint", "prettier", "unused-imports", "css-modules", "jsx-a11y", "@airbyte"],
parserOptions: {
ecmaVersion: 2020,
sourceType: "module",
Expand Down Expand Up @@ -104,7 +105,7 @@ module.exports = {
parser: "@typescript-eslint/parser",
overrides: [
{
files: ["scripts/**/*"],
files: ["scripts/**/*", "packages/**/*"],
rules: {
"@typescript-eslint/no-var-requires": "off",
},
Expand Down
14 changes: 14 additions & 0 deletions airbyte-webapp/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions airbyte-webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"yup": "^0.32.11"
},
"devDependencies": {
"@airbyte/eslint-plugin": "file:./packages/eslint-plugin",
"@craco/craco": "^7.0.0-alpha.7",
"@storybook/addon-essentials": "^6.5.7",
"@storybook/builder-webpack5": "^6.5.7",
Expand Down
2 changes: 2 additions & 0 deletions airbyte-webapp/packages/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This folder should only contain other folders that are treated like local npm packages,
e.g. because we want to provide plugins or configuration for build tools.
12 changes: 12 additions & 0 deletions airbyte-webapp/packages/eslint-plugin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
rules: {
"no-hardcoded-connector-ids": require("./no-hardcoded-connector-ids"),
},
configs: {
recommended: {
rules: {
"@airbyte/no-hardcoded-connector-ids": "error",
},
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const destinations = require("../../src/utils/connectors/destinations.json");
const sources = require("../../src/utils/connectors/sources.json");

// Create a map for connector id to variable name (i.e. flip the direction of the map)
const sourceIdToName = Object.fromEntries(Object.entries(sources).map((entry) => [entry[1], entry[0]]));
const destinationIdToName = Object.fromEntries(Object.entries(destinations).map((entry) => [entry[1], entry[0]]));

const validateStringContent = (context, node, nodeContent) => {
if (nodeContent in destinationIdToName) {
context.report({ node, messageId: "destinationId", data: { id: nodeContent, name: destinationIdToName[nodeContent] } });
} else if (nodeContent in sourceIdToName) {
context.report({ node, messageId: "sourceId", data: { id: nodeContent, name: sourceIdToName[nodeContent] } });
}
};

module.exports = {
meta: {
type: "suggestion",
messages: {
sourceId: "Found hard-coded connector id, use `ConnectorIds.Sources.{{ name }}` from `utils/connectors` instead.",
destinationId:
"Found hard-coded connector id, use `ConnectorIds.Destinations.{{ name }}` from `utils/connectors` instead.",
},
},
create: (context) => ({
Literal: (node) => {
if (typeof node.value === "string") {
validateStringContent(context, node, node.value);
}
},
TemplateLiteral: (node) => {
// Only check template literals which are "static", i.e. don't contain ${} elements
if (!node.expressions.length && node.quasis.length === 1) {
validateStringContent(context, node, node.quasis[0].value.raw);
}
},
}),
};
3 changes: 1 addition & 2 deletions airbyte-webapp/scripts/classname-serializer.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { prettyDOM } from "@testing-library/react";

/**
* Traverse a tree of nodes and replace all class names with
* the count of classnames instead, e.g. "<3 classnames>"
* Traverse a tree of nodes and replace all class names with "<removed-for-snapshot-test>"
*/
const traverseAndRedactClasses = (node) => {
if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useAvailableConnectorDefinitions } from "hooks/domain/connector/useAvai
import { useExperiment } from "hooks/services/Experiment";
import { useConnectorSpecifications } from "services/connector/ConnectorDefinitions";
import { useCurrentWorkspace } from "services/workspaces/WorkspacesService";
import { ConnectorIds } from "utils/connectors";
import { getIcon } from "utils/imageUtils";
import { links } from "utils/links";

Expand All @@ -25,15 +26,15 @@ interface ConnectionOnboardingProps {
}

const DEFAULT_SOURCES = [
"e7778cfc-e97c-4458-9ecb-b4f2bba8946c", // Facebook
"decd338e-5647-4c0b-adf4-da0e75f5a750", // Postgres
"71607ba1-c0ac-4799-8049-7f4b90dd50f7", // Google Sheets
ConnectorIds.Sources.FacebookMarketing,
ConnectorIds.Sources.Postgres,
ConnectorIds.Sources.GoogleSheets,
];

const DEFAULT_DESTINATIONS = [
"22f6c74f-5699-40ff-833c-4a879ea40133", // BigQuery
"424892c4-daac-4491-b35d-c6688ba547ba", // Snowflake
"25c5221d-dce2-4163-ade9-739ef790f503", // Postgres
ConnectorIds.Destinations.BigQuery,
ConnectorIds.Destinations.Snowflake,
ConnectorIds.Destinations.Postgres,
];

interface ConnectorSpecificationMap {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { DestinationDefinitionRead } from "core/request/AirbyteClient";
import { LogsRequestError } from "core/request/LogsRequestError";
import { useExperiment } from "hooks/services/Experiment";
import { useGetDestinationDefinitionSpecificationAsync } from "services/connector/DestinationDefinitionSpecificationService";
import { ConnectorIds } from "utils/connectors";
import { generateMessageFromError, FormError } from "utils/errorStatusMessage";
import { ConnectorCard } from "views/Connector/ConnectorCard";
import { ConnectorCardValues, FrequentlyUsedConnectors, StartWithDestination } from "views/Connector/ConnectorForm";
Expand Down Expand Up @@ -65,8 +66,8 @@ export const DestinationForm: React.FC<DestinationFormProps> = ({
const errorMessage = error ? generateMessageFromError(error) : null;

const frequentlyUsedDestinationIds = useExperiment("connector.frequentlyUsedDestinationIds", [
"22f6c74f-5699-40ff-833c-4a879ea40133",
"424892c4-daac-4491-b35d-c6688ba547ba",
ConnectorIds.Destinations.BigQuery,
ConnectorIds.Destinations.Snowflake,
]);
const frequentlyUsedDestinationsComponent = !isLoading && !destinationDefinitionId && (
<FrequentlyUsedConnectors
Expand Down
29 changes: 15 additions & 14 deletions airbyte-webapp/src/core/domain/connector/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { isCloudApp } from "utils/app";
import { ConnectorIds } from "utils/connectors";

export const DEV_IMAGE_TAG = "dev";

Expand All @@ -15,26 +16,26 @@ export const DEV_IMAGE_TAG = "dev";
* @param {string} workspaceId The workspace Id
* @returns {array} List of connectorIds that should be filtered out
*/
export const getExcludedConnectorIds = (workspaceId?: string) =>
export const getExcludedConnectorIds = (workspaceId?: string): string[] =>
isCloudApp()
? [
"707456df-6f4f-4ced-b5c6-03f73bcad1c5", // hide Cassandra Destination https://github.com/airbytehq/airbyte-cloud/issues/2606
"9f760101-60ae-462f-9ee6-b7a9dafd454d", // hide Kafka Destination https://github.com/airbytehq/airbyte-cloud/issues/2610
"294a4790-429b-40ae-9516-49826b9702e1", // hide MariaDB Destination https://github.com/airbytehq/airbyte-cloud/issues/2611
"f3802bc4-5406-4752-9e8d-01e504ca8194", // hide MQTT Destination https://github.com/airbytehq/airbyte-cloud/issues/2613
"2340cbba-358e-11ec-8d3d-0242ac130203", // hide Pular Destination https://github.com/airbytehq/airbyte-cloud/issues/2614
"2c9d93a7-9a17-4789-9de9-f46f0097eb70", // hide Rockset Destination https://github.com/airbytehq/airbyte-cloud/issues/2615
"2470e835-feaf-4db6-96f3-70fd645acc77", // Salesforce Singer
"3dc6f384-cd6b-4be3-ad16-a41450899bf0", // hide Scylla Destination https://github.com/airbytehq/airbyte-cloud/issues/2617
"af7c921e-5892-4ff2-b6c1-4a5ab258fb7e", // hide MeiliSearch Destination https://github.com/airbytehq/airbyte/issues/16313
"e06ad785-ad6f-4647-b2e8-3027a5c59454", // hide RabbitMQ Destination https://github.com/airbytehq/airbyte/issues/16315
"0eeee7fb-518f-4045-bacc-9619e31c43ea", // hide Amazon SQS Destination https://github.com/airbytehq/airbyte/issues/16316
ConnectorIds.Destinations.Cassandra, // hide Cassandra Destination https://github.com/airbytehq/airbyte-cloud/issues/2606
ConnectorIds.Destinations.Kafka, // hide Kafka Destination https://github.com/airbytehq/airbyte-cloud/issues/2610
ConnectorIds.Destinations.MariaDbColumnStore, // hide MariaDB Destination https://github.com/airbytehq/airbyte-cloud/issues/2611
ConnectorIds.Destinations.Mqtt, // hide MQTT Destination https://github.com/airbytehq/airbyte-cloud/issues/2613
ConnectorIds.Destinations.Pulsar, // hide Pulsar Destination https://github.com/airbytehq/airbyte-cloud/issues/2614
ConnectorIds.Destinations.Rockset, // hide Rockset Destination https://github.com/airbytehq/airbyte-cloud/issues/2615
ConnectorIds.Sources.SalesforceSinger, // Salesforce Singer
ConnectorIds.Destinations.Scylla, // hide Scylla Destination https://github.com/airbytehq/airbyte-cloud/issues/2617
ConnectorIds.Destinations.MeiliSearch, // hide MeiliSearch Destination https://github.com/airbytehq/airbyte/issues/16313
ConnectorIds.Destinations.RabbitMq, // hide RabbitMQ Destination https://github.com/airbytehq/airbyte/issues/16315
ConnectorIds.Destinations.AmazonSqs, // hide Amazon SQS Destination https://github.com/airbytehq/airbyte/issues/16316
...(workspaceId !== "54135667-ce73-4820-a93c-29fe1510d348" // Shopify workspace for review
? ["9da77001-af33-4bcd-be46-6252bf9342b9"] // Shopify
? [ConnectorIds.Sources.Shopify] // Shopify
: []),
// revert me
...(workspaceId !== "d705a766-e9e3-4689-85cb-52143422317d" // `oauth-testing` workspace for review
? ["78752073-6d96-447d-8a93-2b6953f3c787"] // Youtube Analytics Business
? [ConnectorIds.Sources.YouTubeAnalyticsBusiness] // Youtube Analytics Business
: []),
//
]
Expand Down
5 changes: 3 additions & 2 deletions airbyte-webapp/src/test-utils/mock-data/mockConnection.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable no-template-curly-in-string */
import { WebBackendConnectionRead } from "core/request/AirbyteClient";
import { ConnectorIds } from "utils/connectors";

export const mockConnection: WebBackendConnectionRead = {
connectionId: "a9c8e4b5-349d-4a17-bdff-5ad2f6fbd611",
Expand Down Expand Up @@ -305,7 +306,7 @@ export const mockConnection: WebBackendConnectionRead = {
status: "active",
operationIds: ["8af8ef4d-01b1-49c8-b145-23775f34a74b"],
source: {
sourceDefinitionId: "6371b14b-bc68-4236-bfbd-468e8df8e968",
sourceDefinitionId: ConnectorIds.Sources.PokeApi,
sourceId: "a3295ed7-4acf-4c0b-b16b-07a00e624a52",
workspaceId: "47c74b9b-9b89-4af1-8331-4865af6c4e4d",
connectionConfiguration: {
Expand All @@ -315,7 +316,7 @@ export const mockConnection: WebBackendConnectionRead = {
sourceName: "PokeAPI",
},
destination: {
destinationDefinitionId: "25c5221d-dce2-4163-ade9-739ef790f503",
destinationDefinitionId: ConnectorIds.Destinations.Postgres,
destinationId: "083a53bc-8bc2-4dc0-b05a-4273a96f3b93",
workspaceId: "47c74b9b-9b89-4af1-8331-4865af6c4e4d",
connectionConfiguration: {
Expand Down
3 changes: 2 additions & 1 deletion airbyte-webapp/src/test-utils/mock-data/mockDestination.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { DestinationDefinitionSpecificationRead } from "core/request/AirbyteClient";
import { ConnectorIds } from "utils/connectors";

export const mockDestination: DestinationDefinitionSpecificationRead = {
destinationDefinitionId: "25c5221d-dce2-4163-ade9-739ef790f503",
destinationDefinitionId: ConnectorIds.Destinations.Postgres,
documentationUrl: "https://docs.airbyte.io/integrations/destinations/postgres",
connectionSpecification: {
type: "object",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { DestinationDefinitionSpecificationRead } from "core/request/AirbyteClient";
import { ConnectorIds } from "utils/connectors";

export const mockDestinationDefinition: DestinationDefinitionSpecificationRead = {
destinationDefinitionId: "25c5221d-dce2-4163-ade9-739ef790f503",
destinationDefinitionId: ConnectorIds.Destinations.Postgres,
documentationUrl: "https://docs.airbyte.io/integrations/destinations/postgres",
connectionSpecification: {
type: "object",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { SourceDefinitionSpecificationRead } from "core/request/AirbyteClient";
import { ConnectorIds } from "utils/connectors";

export const mockSourceDefinition: SourceDefinitionSpecificationRead = {
sourceDefinitionId: "6371b14b-bc68-4236-bfbd-468e8df8e968",
sourceDefinitionId: ConnectorIds.Sources.PokeApi,
documentationUrl: "https://docs.airbyte.io/integrations/sources/pokeapi",
connectionSpecification: {
type: "object",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { ConnectorIds } from "utils/connectors";

import { ReleaseStage } from "../../core/request/AirbyteClient";

export const mockData = {
destinationDefinitionId: "8b746512-8c2e-6ac1-4adc-b59faafd473c",
destinationDefinitionId: ConnectorIds.Destinations.MongoDb,
name: "MongoDB",
icon: '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="640" height="640"><defs><path d="M454.48 258.27C421.69 113.73 344.25 66.21 335.9 48.07C328.85 36.65 322.83 24.62 317.93 12.13C317.72 11.55 317.48 10.98 317.21 10.43C317.65 22.19 312.69 33.5 303.74 41.15C284.96 55.79 188.75 136.46 180.85 300.76C173.57 453.48 291.52 545.1 307.51 556.78C307.69 556.91 309.13 557.91 309.31 558.04C313.89 547.62 318.29 517.71 321.7 476.65C322.42 509.71 327.18 545.19 343.62 552.65C343.71 552.59 344.43 552.08 344.52 552.02C351.58 547.01 358.3 541.55 364.64 535.67C404.62 498.84 480.08 407.66 454.48 258.27" id="b3m9u0RT9j"></path><path d="M321.43 477.01C318.2 517.98 313.53 547.8 309.04 557.86C309.04 557.86 314.07 593.79 318.02 632.24C319.27 632.24 329.26 632.24 330.51 632.24C333.44 605.49 337.82 578.92 343.62 552.65C327.36 545.1 322.6 509.71 321.88 476.65" id="aevBvhJN5"></path><path d="M454.48 258.27C421.69 113.73 344.25 66.21 335.9 48.07C328.81 36.67 322.79 24.64 317.93 12.13C325.66 42.41 324.4 284.14 325.21 313.07C326.92 367.62 325.75 422.22 321.7 476.65C322.42 509.71 327.18 545.19 343.53 552.74C343.63 552.67 344.42 552.09 344.52 552.02C351.58 547.06 358.31 541.62 364.64 535.76C364.72 535.7 365.29 535.2 365.36 535.13C404.53 499.2 480.08 407.66 454.48 258.27" id="akHagKvoh"></path></defs><g><g><g><use xlink:href="#b3m9u0RT9j" opacity="1" fill="#12a950" fill-opacity="1"></use><g><use xlink:href="#b3m9u0RT9j" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="0"></use></g></g><g><use xlink:href="#aevBvhJN5" opacity="1" fill="#b8c5c2" fill-opacity="1"></use><g><use xlink:href="#aevBvhJN5" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="0"></use></g></g><g><use xlink:href="#akHagKvoh" opacity="1" fill="#13994f" fill-opacity="1"></use><g><use xlink:href="#akHagKvoh" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="0"></use></g></g></g></g></svg>',
releaseStage: ReleaseStage.alpha,
Expand Down
7 changes: 7 additions & 0 deletions airbyte-webapp/src/utils/connectors/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import destinationConnectorIds from "./destinations.json";
import sourceConnectorIds from "./sources.json";

export const ConnectorIds = {
Sources: sourceConnectorIds,
Destinations: destinationConnectorIds,
} as const;
50 changes: 50 additions & 0 deletions airbyte-webapp/src/utils/connectors/destinations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"AzureBlobStorage": "b4c5d105-31fd-4817-96b6-cb923bfc04cb",
"AmazonSqs": "0eeee7fb-518f-4045-bacc-9619e31c43ea",
"ApacheDoris": "05c161bf-ca73-4d48-b524-d392be417002",
"ApacheIceberg": "df65a8f3-9908-451b-aa9b-445462803560",
"AwsDatalake": "99878c90-0fbd-46d3-9d98-ffde879d17fc",
"BigQuery": "22f6c74f-5699-40ff-833c-4a879ea40133",
"BigQueryDenormalizedTypedStruct": "079d5540-f236-4294-ba7c-ade8fd918496",
"Cassandra": "707456df-6f4f-4ced-b5c6-03f73bcad1c5",
"ChargifyKeen": "81740ce8-d764-4ea7-94df-16bb41de36ae",
"Clickhouse": "ce0d828e-1dc4-496c-b122-2da42e637e48",
"CloudflareR2": "0fb07be9-7c3b-4336-850d-5efc006152ee",
"DatabricksLakehouse": "072d5540-f236-4294-ba7c-ade8fd918496",
"DynamoDb": "8ccd8909-4e99-4141-b48d-4984b70b2d89",
"E2ETesting": "2eb65e87-983a-4fd7-b3e3-9d9dc6eb8537",
"ElasticSearch": "68f351a7-2745-4bef-ad7f-996b8e51bb8c",
"Firebolt": "18081484-02a5-4662-8dba-b270b582f321",
"GoogleCloudStorageGcs": "ca8f6566-e555-4b40-943a-545bf123117a",
"GoogleFirestore": "27dc7500-6d1b-40b1-8b07-e2f2aea3c9f4",
"GooglePubSub": "356668e2-7e34-47f3-a3b0-67a8a481b692",
"Kafka": "9f760101-60ae-462f-9ee6-b7a9dafd454d",
"Kinesis": "6d1d66d4-26ab-4602-8d32-f85894b04955",
"LocalCsv": "8be1cf83-fde1-477f-a4ad-318d23c9f3c6",
"LocalJson": "a625d593-bba5-4a1c-a53d-2d246268a816",
"Mqtt": "f3802bc4-5406-4752-9e8d-01e504ca8194",
"MsSqlServer": "d4353156-9217-4cad-8dd7-c108fd4f74cf",
"MeiliSearch": "af7c921e-5892-4ff2-b6c1-4a5ab258fb7e",
"MongoDb": "8b746512-8c2e-6ac1-4adc-b59faafd473c",
"MySql": "ca81ee7c-3163-4246-af40-094cc31e5e42",
"Oracle": "3986776d-2319-4de9-8af8-db14c0996e72",
"Postgres": "25c5221d-dce2-4163-ade9-739ef790f503",
"Pulsar": "2340cbba-358e-11ec-8d3d-0242ac130203",
"RabbitMq": "e06ad785-ad6f-4647-b2e8-3027a5c59454",
"Redis": "d4d3fef9-e319-45c2-881a-bd02ce44cc9f",
"Redshift": "f7a7d195-377f-cf5b-70a5-be6b819019dc",
"Redpanda": "825c5ee3-ed9a-4dd1-a2b6-79ed722f7b13",
"Rockset": "2c9d93a7-9a17-4789-9de9-f46f0097eb70",
"S3": "4816b78f-1489-44c1-9060-4b19d5fa9362",
"S3Glue": "471e5cab-8ed1-49f3-ba11-79c687784737",
"SftpJson": "e9810f61-4bab-46d2-bb22-edfc902e0644",
"Snowflake": "424892c4-daac-4491-b35d-c6688ba547ba",
"MariaDbColumnStore": "294a4790-429b-40ae-9516-49826b9702e1",
"Streamr": "eebd85cf-60b2-4af6-9ba0-edeca01437b0",
"Scylla": "3dc6f384-cd6b-4be3-ad16-a41450899bf0",
"GoogleSheets": "a4cbd2d1-8dbe-4818-b8bc-b90ad782d12a",
"LocalSqLite": "b76be0a6-27dc-4560-95f6-2623da0bd7b6",
"TiDb": "06ec60c7-7468-45c0-91ac-174f6e1a788b",
"Typesense": "36be8dc6-9851-49af-b776-9d4c30e4ab6a",
"YugabyteDb": "2300fdcf-a532-419f-9f24-a014336e7966"
}
1 change: 1 addition & 0 deletions airbyte-webapp/src/utils/connectors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ConnectorIds } from "./constants";
Loading

0 comments on commit bd9eedf

Please sign in to comment.