From 3263b561a17c51345bcf662f76f059fd2d2c5f23 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Thu, 13 Jun 2024 13:28:25 -0400 Subject: [PATCH 001/135] Release clickhouse v0.2.9 (#177) --- registry/clickhouse/metadata.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/registry/clickhouse/metadata.json b/registry/clickhouse/metadata.json index 466d9de2..4a15c32d 100644 --- a/registry/clickhouse/metadata.json +++ b/registry/clickhouse/metadata.json @@ -17,6 +17,17 @@ "is_verified": true, "is_hosted_by_hasura": false, "packages": [ + { + "version": "0.2.9", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.9/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "source": { + "hash": "93752f433f4e7c91f0c13d92ea9369deb97d1970" + } + }, { "version": "0.2.8", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.8/connector-definition.tgz", @@ -121,6 +132,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-clickhouse/", "version": [ + { + "tag": "v0.2.9", + "hash": "93752f433f4e7c91f0c13d92ea9369deb97d1970", + "is_verified": true + }, { "tag": "v0.2.8", "hash": "f1629f715770358e587a25f9a0ca015728d422dd", From e05f49c5802dd2ae0c81b2691969af4877e9193a Mon Sep 17 00:00:00 2001 From: Brandon Martin Date: Thu, 13 Jun 2024 19:43:27 -0600 Subject: [PATCH 002/135] Release MongoDB v0.1.0 --- registry/mongodb/metadata.json | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/registry/mongodb/metadata.json b/registry/mongodb/metadata.json index 9c6dcfc4..7992477e 100644 --- a/registry/mongodb/metadata.json +++ b/registry/mongodb/metadata.json @@ -4,7 +4,9 @@ "description": "Connect to a MongoDB database and expose it to Hasura v3 Project", "title": "MongoDB Connector", "logo": "logo.png", - "tags": ["database"], + "tags": [ + "database" + ], "latest_version": "v0.0.6" }, "author": { @@ -15,6 +17,17 @@ "is_verified": true, "is_hosted_by_hasura": false, "packages": [ + { + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "adb5ce24e053117ba33c16ecf54bdc5a678790f3b31801645911fdf7091a58e0" + }, + "source": { + "hash": "175272912b86a11359a9b6b7fd72c7a6e2326bf1" + } + }, { "version": "0.0.6", "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.6/connector-definition.tgz", @@ -86,6 +99,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-mongodb/", "version": [ + { + "tag": "v0.1.0", + "hash": "175272912b86a11359a9b6b7fd72c7a6e2326bf1", + "is_verified": true + }, { "tag": "v0.0.6", "hash": "6e842c308eeee38d3bc393e6b99157961ca3ed03", From 81734689d847732369e7ff2aca929716d851208e Mon Sep 17 00:00:00 2001 From: Darshan Lukhi Date: Mon, 17 Jun 2024 23:23:09 +0530 Subject: [PATCH 003/135] Add Elasticsearch connector to registry (#174) Co-authored-by: Jonathan Weiss --- registry/elasticsearch/README.md | 178 +++++++++++++++++++++++++++ registry/elasticsearch/logo.png | Bin 0 -> 52594 bytes registry/elasticsearch/metadata.json | 59 +++++++++ 3 files changed, 237 insertions(+) create mode 100644 registry/elasticsearch/README.md create mode 100644 registry/elasticsearch/logo.png create mode 100644 registry/elasticsearch/metadata.json diff --git a/registry/elasticsearch/README.md b/registry/elasticsearch/README.md new file mode 100644 index 00000000..4932d168 --- /dev/null +++ b/registry/elasticsearch/README.md @@ -0,0 +1,178 @@ +# Elasticsearch Connector + + + +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/latest/connectors/elasticsearch/) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-elasticsearch-blue.svg?style=flat)](https://hasura.io/connectors/ndc-elasticsearch) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) +[![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) + +With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your documents in Elasticsearch. This connector supports Elasticsearch functionalities listed in the table below, allowing for efficient and scalable data operations. Additionally, you will benefit from all the powerful features of Hasura’s Data Delivery Network (DDN) platform, including query pushdown capabilities that delegate all query operations to the Elasticsearch, thereby enhancing query optimization and performance. + +This connector is built using the [Go Data Connector SDK](https://github.com/hasura/ndc-sdk-go) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). + +- [Connector information in the Hasura Hub](https://hasura.io/connectors/elasticsearch) +- [Hasura V3 Documentation](https://hasura.io/docs/3.0) + +## Features + +Below, you'll find a matrix of all supported features for the Elasticsearch connector: + + + +| Feature | Supported | Notes | +| ------------------------------- | --------- | ----- | +| Native Queries + Logical Models | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Nested Objects | ✅ | | +| Nested Arrays | ✅ | | +| Nested Filtering | ❌ | | +| Nested Sorting | ❌ | | +| Nested Relationships | ❌ | | + + +## Before you get Started + +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Install the [CLI](https://hasura.io/docs/3.0/cli/installation/) +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) + +## Using the connector + +To use the Elasticsearch connector, follow these steps in a Hasura project: +(Note: for more information on the following steps, please refer to the Postgres connector documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) + + +### 1. Init the connector +(Note: here and following we are naming the subgraph "my_subgraph" and the connector "my_elastic") + + ```bash + ddn connector init my_elastic --subgraph my_subgraph --hub-connector hasura/elasticsearch + ``` + +### 2. Add your Elasticsearch credentials: + +```env title="my_subgraph/connector/my_elastic/.env.local" +OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 +OTEL_SERVICE_NAME=my_subgraph_my_elastic +ELASTICSEARCH_URL= +ELASTICSEARCH_USERNAME= +ELASTICSEARCH_PASSWORD= +``` + +To configure the connector, the following environment variables need to be set: + +| Environment Variable | Description | Required | Example Value | +| ----------------------------- | --------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------- | +| `ELASTICSEARCH_URL` | The comma-separated list of Elasticsearch host addresses for connection | Yes | `https://example.es.gcp.cloud.es.io:9200` | +| `ELASTICSEARCH_USERNAME` | The username for authenticating to the Elasticsearch cluster | Yes | `admin` | +| `ELASTICSEARCH_PASSWORD` | The password for the Elasticsearch user account | Yes | `default` | +| `ELASTICSEARCH_API_KEY` | The Elasticsearch API key for authenticating to the Elasticsearch cluster | No | `ABCzYWk0NEI0aDRxxxxxxxxxx1k6LWVQa2gxMUpRTUstbjNwTFIzbGoyUQ==` | +| `ELASTICSEARCH_CA_CERT_PATH` | The path to the Certificate Authority (CA) certificate for verifying the Elasticsearch server's SSL certificate | No | `/etc/connector/cacert.pem` | +| `ELASTICSEARCH_INDEX_PATTERN` | The pattern for matching Elasticsearch indices, potentially including wildcards, used by the connector | No | `hasura*` | + + +### 3. Intropsect your indices + +```bash title="From the root of your project run:" +ddn connector introspect --connector my_subgraph/connector/my_elastic/connector.yaml +``` + +If you look at the `configuration.json` for your connector, you'll see metadata describing your Elasticsearch mappings. + +### 4. Create the Hasura metadata + +```bash title="Run the following from the root of your project:" +ddn connector-link add my_elastic --subgraph my_subgraph +``` + +The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your +subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the +connector. Ensure the port value matches what is published in your connector's docker compose file. + +```env title="my_subgraph/.env.my_subgraph" +MY_SUBGRAPH_MY_ELASTIC_READ_URL=http://local.hasura.dev:8082 +MY_SUBGRAPH_MY_ELASTIC_WRITE_URL=http://local.hasura.dev:8082 +``` + +### 5. Start the connector's docker compose + +Let's start our connector's docker compose file. + +```bash title="Run the following from the connector's subdirectory inside a subgraph:" +docker compose -f docker-compose.my_elastic.yaml up +``` + +This starts our PostgreSQL connector on the specified port. We can navigate to the following address, with the port +modified, to see the schema of our Elasticsearch data source: + +```bash +http://localhost:8081/schema +``` + +### 6. Include the connector in your docker compose + +Kill the connector by pressing `CTRL+C` in the terminal tab in which the connector is running. + +Then, add the following inclusion to the docker compose in your project's root directory, taking care to modify the +subgraph's name. + +```yaml title="docker-compose.hasura.yaml" +include: + - path: my_subgraph/connector/my_elastic/docker-compose.my_elastic.yaml +``` + +Now, whenever running the following, you'll bring up the GraphQL engine, observability tools, and any connectors you've +included: + +```bash title="From the root of your project, run:" +HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yaml watch +``` + +### 7. Update the new DataConnectorLink object + +Finally, now that our `DataConnectorLink` has the correct environment variables configured for the Elasticsearch connector, +we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's +schema in `hml` format. In a new terminal tab, run: + +```bash title="From the root of your project, run:" +ddn connector-link update my_elastic --subgraph my_subgraph +``` + +After this command runs, you can open your `my_subgraph/metadata/my_elastic.hml` file and see your metadata completely +scaffolded out for you 🎉 + +### 8. Import _all_ your indices + +You can do this in one convenience command. + +```bash title="From the root of your project, run:" +ddn connector-link update my_elastic --subgraph my_subgraph --add-all-resources +``` + +### 9. Create a supergraph build + +Pass the `local` subcommand along with specifying the output directory as `./engine` in the root of the project. This +directory is used by the docker-compose file to serve the engine locally: + +```bash title="From the root of your project, run:" +ddn supergraph build local --output-dir ./engine +``` + +You can now navigate to +[`https://console.hasura.io/local/graphql?url=http://localhost:3000`](https://console.hasura.io/local/graphql?url=http://localhost:3000) +and interact with your API using the Hasura Console. + + +## Contributing + +Check out our [contributing guide](./docs/contributing.md) for more details. + +## License + +The Elasticsearch connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/registry/elasticsearch/logo.png b/registry/elasticsearch/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..06b4a258912f0e08619757289b55daa498873e4e GIT binary patch literal 52594 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'QDSl;vG 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 z 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 literal 0 HcmV?d00001 diff --git a/registry/elasticsearch/metadata.json b/registry/elasticsearch/metadata.json new file mode 100644 index 00000000..63c5caa6 --- /dev/null +++ b/registry/elasticsearch/metadata.json @@ -0,0 +1,59 @@ +{ + "overview": { + "namespace": "hasura", + "description": "The Hasura Elasticsearch Connector allows for connecting to a Elasticsearch search engine, giving you an instant GraphQL API on top of your Elasticsearch data.", + "title": "Elasticsearch Native Data Connector", + "logo": "logo.png", + "tags": [ + "search engine" + ], + "latest_version": "v0.1.1" + }, + "author": { + "support_email": "support@hasura.io", + "homepage": "https://hasura.io", + "name": "Hasura" + }, + "is_verified": true, + "is_hosted_by_hasura": false, + "packages": [ + { + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v0.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "a856e10b6b30b516db2bb38af08037ad5db32bfd4ec072270fb8685872e13d5b" + }, + "source": { + "hash": "4c6fabedaf3a28cdd6c55a18a37e1db974a83262" + } + }, + { + "version": "0.1.1", + "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v0.1.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "60629c9b24467fa4ed58c87732410203eedbdee31cdd18e90c635f10d23a8e23" + }, + "source": { + "hash": "413a2a4ddfd1910757c40c38e9a18148bc3b3bdc" + } + } + ], + "source_code": { + "is_open_source": true, + "repository": "https://github.com/hasura/ndc-elasticsearch/", + "version": [ + { + "tag": "v0.1.0", + "hash": "4c6fabedaf3a28cdd6c55a18a37e1db974a83262", + "is_verified": true + }, + { + "tag": "v0.1.1", + "hash": "413a2a4ddfd1910757c40c38e9a18148bc3b3bdc", + "is_verified": true + } + ] + } +} From 59543a1d71e2d7c3972d8e2f1811f9db518e89b7 Mon Sep 17 00:00:00 2001 From: gneeri Date: Tue, 18 Jun 2024 13:14:25 -0400 Subject: [PATCH 004/135] fixed ports in Elasticsearch README (#178) --- registry/elasticsearch/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/registry/elasticsearch/README.md b/registry/elasticsearch/README.md index 4932d168..777ba035 100644 --- a/registry/elasticsearch/README.md +++ b/registry/elasticsearch/README.md @@ -96,8 +96,8 @@ subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, a connector. Ensure the port value matches what is published in your connector's docker compose file. ```env title="my_subgraph/.env.my_subgraph" -MY_SUBGRAPH_MY_ELASTIC_READ_URL=http://local.hasura.dev:8082 -MY_SUBGRAPH_MY_ELASTIC_WRITE_URL=http://local.hasura.dev:8082 +MY_SUBGRAPH_MY_ELASTIC_READ_URL=http://local.hasura.dev:8081 +MY_SUBGRAPH_MY_ELASTIC_WRITE_URL=http://local.hasura.dev:8081 ``` ### 5. Start the connector's docker compose From 1f9479c508349d7497cc966856c2a40f66afbb4f Mon Sep 17 00:00:00 2001 From: pranshi06 <85474619+pranshi06@users.noreply.github.com> Date: Wed, 19 Jun 2024 00:45:45 +0530 Subject: [PATCH 005/135] Release SQL Server v0.1.2 (#179) --- registry/sqlserver/README.md | 172 ++++++++++++++++++++----------- registry/sqlserver/metadata.json | 20 +++- 2 files changed, 132 insertions(+), 60 deletions(-) diff --git a/registry/sqlserver/README.md b/registry/sqlserver/README.md index a9511081..9f74d41b 100644 --- a/registry/sqlserver/README.md +++ b/registry/sqlserver/README.md @@ -21,94 +21,150 @@ the [Data Connector Spec](https://github.com/hasura/ndc-spec). Below, you'll find a matrix of all supported features for the SQL Server connector: -| Feature | Supported | Notes | -| ------------------------------- | --------- | ----- | -| Native Queries + Logical Models | ✅ | | -| Simple Object Query | ✅ | | -| Filter / Search | ✅ | | -| Simple Aggregation | ✅ | | -| Sort | ✅ | | -| Paginate | ✅ | | -| Table Relationships | ✅ | | -| Views | ✅ | | -| Remote Relationships | ✅ | | -| Custom Fields | ❌ | | -| Mutations | ❌ | | -| Distinct | ✅ | | -| Enums | ❌ | | -| Naming Conventions | ❌ | | -| Default Values | ❌ | | -| User-defined Functions | ❌ | | +| Feature | Supported | Notes | +|---------------------------------|-----------|--------------------------------------| +| Native Queries + Logical Models | ✅ | | +| Native Mutations | ✅ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ✅ | | +| Views | ✅ | | +| Remote Relationships | ✅ | | +| Custom Fields | ❌ | | +| Mutations | ✅ | Only native mutations are suppported | +| Distinct | ✅ | | +| Enums | ❌ | | +| Naming Conventions | ❌ | | +| Default Values | ❌ | | +| User-defined Functions | ❌ | | ## Before you get Started 1. Create a [Hasura Cloud account](https://console.hasura.io) 2. Install the [CLI](https://hasura.io/docs/3.0/cli/installation/) 3. Install the [Hasura VS Code extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) -4. [Create a project](https://hasura.io/docs/3.0/getting-started/create-a-project) +4. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +5. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) ## Using the connector To use the SQL Server connector, follow these steps in a Hasura project: +(Note: for more information on the following steps, please refer to the Postgres connector documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) -1. Add the connector: +### 1. Init the connector +(Note: here and following we are naming the subgraph "my_subgraph" and the connector "my_sql") ```bash - ddn add connector-manifest sqlserver_connector --subgraph app --hub-connector hasura/sqlserver --type cloud + ddn connector init my_sql --subgraph my_subgraph --hub-connector hasura/sqlserver ``` - In the snippet above, we've used the subgraph `app` as it's available by default; however, you can change this value - to match any [subgraph](https://hasura.io/docs/3.0/project-configuration/subgraphs) which you've created in your - project. +### 2. Add your SQLServer credentials: -2. Add your connection URI: +Add your credentials to `my_subgraph/connector/my_sql/.env.local` - Open your project in your text editor and open the `/app/sqlserver_connector/connector/sqlserver_connector.build.hml` - file of your project. Then, add the `CONNECTION_URI` environment variable with the connection string: +```env title="my_subgraph/connector/my_sql/.env.local" +OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 +OTEL_SERVICE_NAME=my_subgraph_my_sql +CONNECTION_URI= +``` - ```yaml - # other configuration above - CONNECTION_URI: - value: "" - ``` +### 3. Intropsect your indices -3. Update the connector manifest and the connector link +```bash title="From the root of your project run:" +ddn connector introspect --connector my_subgraph/connector/my_sql/connector.yaml +``` - These two steps will (1) allow Hasura to introspect your data source and complete the configuration and (2) deploy - the connector to Hasura DDN: +If you look at the `configuration.json` for your connector, you'll see metadata describing your SQL Server mappings. - ```bash - ddn update connector-manifest sqlserver_connector - ``` +### 4. Create the Hasura metadata - ```bash - ddn update data-connector-link sqlserver_connector --add-all-resources - ``` +```bash title="Run the following from the root of your project:" +ddn connector-link add my_sql --subgraph my_subgraph +``` - `--add-all-resources` flag adds all the models and commands present in the database to the connector metadata. +The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your +subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the +connector. Ensure the port value matches what is published in your connector's docker compose file. -4. Create a build +```env title="my_subgraph/.env.my_subgraph" +MY_SUBGRAPH_MY_SQL_READ_URL=http://local.hasura.dev:8081 +MY_SUBGRAPH_MY_SQL_WRITE_URL=http://local.hasura.dev:8081 +``` - ```bash - ddn build supergraph-manifest - ``` +### 5. Start the connector's docker compose + +Let's start our connector's docker compose file. + +```bash title="Run the following from the connector's subdirectory inside a subgraph:" +docker compose -f docker-compose.my_sql.yaml up +``` + +This starts our SQL Server connector on the specified port. We can navigate to the following address, with the port +modified, to see the schema of our SQL Server data source: + +```bash +http://localhost:8081/schema +``` + +### 6. Include the connector in your docker compose + +Kill the connector by pressing `CTRL+C` in the terminal tab in which the connector is running. + +Then, add the following inclusion to the docker compose `docker-compose.hasura.yaml` in your project's root directory, taking care to modify the +subgraph's name. + +```yaml title="docker-compose.hasura.yaml" +include: + - path: my_subgraph/connector/my_sql/docker-compose.my_sql.yaml +``` + +Now, whenever running the following, you'll bring up the GraphQL engine, observability tools, and any connectors you've +included: + +```bash title="From the root of your project, run:" +HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yaml watch +``` + +### 7. Update the new DataConnectorLink object + +Finally, now that our `DataConnectorLink` has the correct environment variables configured for the SQL Server connector, +we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's +schema in `hml` format. In a new terminal tab, run: + +```bash title="From the root of your project, run:" +ddn connector-link update my_sql --subgraph my_subgraph +``` + +After this command runs, you can open your `my_subgraph/metadata/my_sql.hml` file and see your metadata completely +scaffolded out for you 🎉 + +### 8. Import _all_ your indices + +You can do this in one convenience command. + +```bash title="From the root of your project, run:" +ddn connector-link update my_sql --subgraph my_subgraph --add-all-resources +``` + +### 9. Create a supergraph build - This will return information about the build: +Pass the `local` subcommand along with specifying the output directory as `./engine` in the root of the project. This +directory is used by the docker-compose file to serve the engine locally: - | | | - | ------------- | ------------------------------------------------------------------------------------------------- | - | Build Version | bd96bb221a | - | API URL | https://-bd96bb221a.ddn.hasura.app/graphql | - | Console URL | https://console.hasura.io/project//environment/default/build/bd96bb221a/graphql | - | Project Name | | - | Description | | +```bash title="From the root of your project, run:" +ddn supergraph build local --output-dir ./engine +``` - Follow the project configuration build [guide](https://hasura.io/docs/3.0/project-configuration/builds/) to apply - other actions on the build. +You can now navigate to +[`https://console.hasura.io/local/graphql?url=http://localhost:3000`](https://console.hasura.io/local/graphql?url=http://localhost:3000) +and interact with your API using the Hasura Console. -5. Test the API +## Documentation - The console URL in the build information cna be used to open the GraphiQL console to test out the API +View the full documentation for the ndc-sqlserver connector [here](https://github.com/hasura/ndc-sqlserver/blob/main/docs/readme.md). ## Contributing diff --git a/registry/sqlserver/metadata.json b/registry/sqlserver/metadata.json index 49688d32..1017adf9 100644 --- a/registry/sqlserver/metadata.json +++ b/registry/sqlserver/metadata.json @@ -5,7 +5,7 @@ "title": "SQL Server Connector", "logo": "logo.png", "tags": ["database"], - "latest_version": "v0.1.1" + "latest_version": "v0.1.2" }, "author": { "support_email": "support@hasura.io", @@ -13,8 +13,19 @@ "name": "Hasura" }, "is_verified": true, - "is_hosted_by_hasura": false, + "is_hosted_by_hasura": true, "packages": [ + { + "version": "0.1.2", + "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.1.2/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "102c642b2e0ddea1eaa471c5189ecd3423a20f91ad83995e09f9d4721dd85732" + }, + "source": { + "hash": "bc0fd3d126f6c142587e014aa900fc6bc90cd59d" + } + }, { "version": "0.1.1", "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.1.1/package.tar.gz", @@ -42,6 +53,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-sqlserver/", "version": [ + { + "tag": "v0.1.2", + "hash": "bc0fd3d126f6c142587e014aa900fc6bc90cd59d", + "is_verified": true + }, { "tag": "v0.1.1", "hash": "638a2b608f7a9c4625de7df35c61c909d2ce16b1", From cb32ceaa770a58fe5a7876cd2a74e89d8c167f73 Mon Sep 17 00:00:00 2001 From: Tristen Harr Date: Wed, 19 Jun 2024 10:34:43 -0500 Subject: [PATCH 006/135] add turso to registry (#120) Merged! :) --- registry/turso/README.md | 173 +++++++++++++++++++++++++++++++++++ registry/turso/logo.svg | 8 ++ registry/turso/metadata.json | 43 +++++++++ 3 files changed, 224 insertions(+) create mode 100644 registry/turso/README.md create mode 100644 registry/turso/logo.svg create mode 100644 registry/turso/metadata.json diff --git a/registry/turso/README.md b/registry/turso/README.md new file mode 100644 index 00000000..389bbe79 --- /dev/null +++ b/registry/turso/README.md @@ -0,0 +1,173 @@ +# Hasura Turso Connector + + +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/connectors/turso) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-turso-blue.svg?style=flat)](https://hasura.io/connectors/turso) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](https://github.com/hasura/ndc-turso/blob/main/LICENSE.txt) +[![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](https://github.com/hasura/ndc-turso/blob/main/README.md) + +The Hasura Turso Connector allows for connecting to a LibSQL/SQLite database or a Turso hosted LibSQL database to give you an instant GraphQL API on top of your Turso data. + +This connector is built using the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). + +* [Connector information in the Hasura Hub](https://hasura.io/connectors/turso) +* [Hasura V3 Documentation](https://hasura.io/docs/3.0/index/) + +## Features + +Below, you'll find a matrix of all supported features for the Turso connector: + +| Feature | Supported | Notes | +| ------------------------------- | --------- | ----- | +| Native Queries + Logical Models | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ❌ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ✅ | | +| Views | ❌ | | +| Distinct | ❌ | | +| Remote Relationships | ✅ | | +| Custom Fields | ❌ | | +| Mutations | ✅ | | + +## Before you get Started + +[Prerequisites or recommended steps before using the connector.] + +1. The [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed +2. A [supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +3. A [subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) +4. Have a [Turso](https://turso.tech/) hosted database, or a persistent Turso SQLite database file — for supplying data to your API. + +The steps below explain how to Initialize and configure a connector for local development. You can learn how to deploy a +connector — after it's been configured — [here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). + +## Using the Turso connector + +### Step 1: Authenticate your CLI session + +```bash +ddn auth login +``` + +### Step 2: Initialize the connector + +```bash +ddn connector init turso --subgraph my_subgraph --hub-connector hasura/turso +``` + +In the snippet above, we've used the subgraph `my_subgraph` as an example; however, you should change this +value to match any subgraph which you've created in your project. + +### Step 3: Modify the connector's port + +When you initialized your connector, the CLI generated a set of configuration files, including a Docker Compose file for +the connector. Typically, connectors default to port `8080`. Each time you add a connector, we recommend incrementing the published port by one to avoid port collisions. + +As an example, if your connector's configuration is in `my_subgraph/connector/turso/docker-compose.turso.yaml`, you can modify the published port to reflect a value that isn't currently being used by any other connectors: + +```yaml +ports: + - mode: ingress + target: 8080 + published: "8082" + protocol: tcp +``` + +### Step 4: Add environment variables + +Now that our connector has been scaffolded out for us, we need to provide a connection string so that the data source can be introspected and the boilerplate configuration can be taken care of by the CLI. + +The CLI has provided an `.env.local` file for our connector in the `my_subgraph/connector/turso` directory. We can add a key-value pair +of `TURSO_URL` along with the connection string itself to this file, and our connector will use this to connect to our database. If you are connecting to a cloud hosted Turso database you can also provide the environment variable for the `TURSO_AUTH_TOKEN` which allows the connector to authenticate. + + +The file, after adding the `TURSO_URL`, should look like this example if connecting to a Turso hosted database instance: + +```env +OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 +OTEL_SERVICE_NAME=my_subgraph_turso +TURSO_URL=libsql://chinook-tristenharr.turso.io +TURSO_AUTH_TOKEN=eyJhb... +``` + +To connect to a local SQLite file, you can add the persistent SQLite database file into the `my_subgraph/connector/turso` directory, and since all files in this directory will get mounted to the container at `/etc/connector/` you can then point the `TURSO_URL` to the local file. Assuming that the Turso file was named `chinook.sqlite` the file should look like this example: + +```env +OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 +OTEL_SERVICE_NAME=my_subgraph_turso +TURSO_URL=file:/etc/connector/chinook.sqlite +``` + +### Step 5: Introspect your data source + +With the connector configured, we can now use the CLI to introspect our database and create a source-specific configuration file for our connector. + +```bash +ddn connector introspect --connector my_subgraph/connector/turso/connector.yaml +``` + +### Step 6. Create the Hasura metadata + +Hasura DDN uses a concept called "connector linking" to take [NDC-compliant](https://github.com/hasura/ndc-spec) +configuration JSON files for a data connector and transform them into an `hml` (Hasura Metadata Language) file as a +[`DataConnectorLink` metadata object](https://hasura.io/docs/3.0/supergraph-modeling/data-connectors#dataconnectorlink-dataconnectorlink). + +Basically, metadata objects in `hml` files define our API. + +First we need to create this `hml` file with the `connector-link add` command and then convert our configuration files +into `hml` syntax and add it to this file with the `connector-link update` command. + +Let's name the `hml` file the same as our connector, `turso`: + +```bash +ddn connector-link add turso --subgraph my_subgraph +``` + +The new file is scaffolded out at `my_subgraph/metadata/turso/turso.hml`. + +### Step 7. Update the environment variables + +The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the connector. Ensure the port value matches what is published in your connector's docker compose file. + +As an example: + +```env +MY_SUBGRAPH_TURSO_READ_URL=http://local.hasura.dev: +MY_SUBGRAPH_TURSO_WRITE_URL=http://local.hasura.dev: +``` + +These values are for the connector itself and utilize `local.hasura.dev` to ensure proper resolution within the docker container. + +### Step 8. Start the connector's Docker Compose + +Let's start our connector's Docker Compose file by running the following from inside the connector's subgraph: + +```bash +docker compose -f docker-compose.turso.yaml up +``` + +### Step 9. Update the new `DataConnectorLink` object + +Finally, now that our `DataConnectorLink` has the correct environment variables configured for the connector, we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's schema in `hml` format. In a new terminal tab, run: + +```bash +ddn connector-link update turso --subgraph my_subgraph +``` + +After this command runs, you can open your `my_subgraph/metadata/turso.hml` file and see your metadata completely +scaffolded out for you 🎉 + +## Documentation + +View the full documentation for the Turso connector [here](https://github.com/hasura/ndc-turso/blob/main/docs/index.md). + +## Contributing + +Check out our [contributing guide](https://github.com/hasura/ndc-turso/blob/main/docs/contributing.md) for more details. + +## License + +The Turso connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file diff --git a/registry/turso/logo.svg b/registry/turso/logo.svg new file mode 100644 index 00000000..273dd7ef --- /dev/null +++ b/registry/turso/logo.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/registry/turso/metadata.json b/registry/turso/metadata.json new file mode 100644 index 00000000..8562d6e7 --- /dev/null +++ b/registry/turso/metadata.json @@ -0,0 +1,43 @@ +{ + "overview": { + "namespace": "hasura", + "description": "Connect to a SQLite database and expose them to Hasura v3 Project", + "title": "(Turso) SQLite Native Data Connector", + "logo": "logo.svg", + "tags": [ + "database" + ], + "latest_version": "v0.0.15" + }, + "author": { + "support_email": "support@hasura.io", + "homepage": "https://hasura.io", + "name": "Hasura" + }, + "is_verified": false, + "is_hosted_by_hasura": true, + "packages": [ + { + "version": "0.0.15", + "uri": "https://github.com/hasura/ndc-turso/releases/download/v0.0.15/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "a2c8426c443bf8c94b0f706d8438bd06eeeef30c0d2b40389c0e37be4be920a6" + }, + "source": { + "hash": "6bae967daf7b9aa718d62103e077a739c41d5a6d" + } + } + ], + "source_code": { + "is_open_source": true, + "repository": "https://github.com/hasura/ndc-turso", + "version": [ + { + "tag": "v0.0.15", + "hash": "6bae967daf7b9aa718d62103e077a739c41d5a6d", + "is_verified": false + } + ] + } +} From dadf4dc4bec601ce93de6443fd25d7c58a376464 Mon Sep 17 00:00:00 2001 From: Tristen Harr Date: Wed, 19 Jun 2024 10:35:24 -0500 Subject: [PATCH 007/135] update qdrant registry metadata (#123) Merged :) --- registry/qdrant/README.md | 212 +++++++++++++++++++--------------- registry/qdrant/metadata.json | 23 +++- 2 files changed, 135 insertions(+), 100 deletions(-) diff --git a/registry/qdrant/README.md b/registry/qdrant/README.md index 4959b280..98138040 100644 --- a/registry/qdrant/README.md +++ b/registry/qdrant/README.md @@ -1,150 +1,172 @@ -## Qdrant Connector Overview +# Hasura Qdrant Connector + -The Qdrant Data Connector allows for connecting to a Qdrant instance giving you an instant GraphQL API that supports querying on top of your data. This uses the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/connectors/qdrant) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-qdrant-blue.svg?style=flat)](https://hasura.io/connectors/qdrant) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](https://github.com/hasura/ndc-qdrant/blob/main/LICENSE.txt) +[![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](https://github.com/hasura/ndc-qdrant/blob/main/README.md) -In order to use this connector you will need a Qdrant database setup. This connector currently only supports querying. +The Hasura Qdrant Connector allows for connecting to a Qdrant database to give you an instant GraphQL API on top of your Qdrant data. -## Before you get started +This connector is built using the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). -It is recommended that you: +* [Connector information in the Hasura Hub](https://hasura.io/connectors/qdrant) +* [Hasura V3 Documentation](https://hasura.io/docs/3.0/index/) -* Setup a [Qdrant Database instance](https://qdrant.tech/) -* Install the [Hasura3 CLI](https://github.com/hasura/v3-cli#hasura-v3-cli) -* Log in via the CLI -* Install the [connector plugin](https://hasura.io/docs/latest/hasura-cli/connector-plugin/) -* Install [VSCode](https://code.visualstudio.com) -* Install the [Hasura VSCode Extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) +## Features -## Deployment For Hasura Users +Below, you'll find a matrix of all supported features for the Qdrant connector: -To deploy a connector and use it in a Hasura V3 project, follow these steps: +| Feature | Supported | Notes | +| ------------------------------- | --------- | ----- | +| Native Queries + Logical Models | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ❌ | | +| Sort | ❌ | | +| Paginate | ✅ | Pagination offset field only works for documents with Integer ID's | +| Nested Objects | ✅ | | +| Nested Arrays | ✅ | | +| Nested Filtering | ❌ | | +| Nested Sorting | ❌ | | +| Nested Relationships | ❌ | | +| Vector Search | ✅ | | -1. Create a Hasura V3 project (or use an existing project) +## Before you get Started -2. Generate a configuration file for your Qdrant Database, there are 2 ways to get the configuration file. +[Prerequisites or recommended steps before using the connector.] - First you'll need to clone [this repo](https://github.com/hasura/ndc-qdrant), and run ```npm install``` - i. The easiest way to generate a configuration file is to run the generate-config script using ts-node. +1. The [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed +2. A [supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +3. A [subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) +4. Have a [Qdrant](https://qdrant.tech/) hosted database, or a locally running Qdrant database — for supplying data to your API. - When running this script specify: +The steps below explain how to Initialize and configure a connector for local development. You can learn how to deploy a +connector — after it's been configured — [here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). - --url The URL where Qdrant is hosted +## Using the Qdrant connector - --key The API key for connecting to the Qdrant Client. +### Step 1: Authenticate your CLI session - --output The name of the file to store the configuration in - - Example Usage: +```bash +ddn auth login +``` - ```ts-node generate-config --url https://qdrant-url --key QdrantApiKey --output config.json``` - - ii. You can also run the connector in configuration mode and generate the config file using CURL. +### Step 2: Initialize the connector - ```ts-node ./src/index.ts configuration serve``` +```bash +ddn connector init qdrant --subgraph my_subgraph --hub-connector hasura/qdrant +``` - You can then send a CURL request specifying the qdrant_url and qdrant_api_key to get the configuration file. +In the snippet above, we've used the subgraph `my_subgraph` as an example; however, you should change this +value to match any subgraph which you've created in your project. - Example: +### Step 3: Modify the connector's port - ```curl -X POST -H "Content-Type: application/json" -d '{"qdrant_url": "https://link-to-qdrant.cloud.qdrant.io", "qdrant_api_key": "QdrantApiKey"}' http://localhost:9100 > config.json``` +When you initialized your connector, the CLI generated a set of configuration files, including a Docker Compose file for +the connector. Typically, connectors default to port `8080`. Each time you add a connector, we recommend incrementing the published port by one to avoid port collisions. -3. Once you have a configuration file, you can deploy the connector onto Hasura Cloud +As an example, if your connector's configuration is in `my_subgraph/connector/qdrant/docker-compose.qdrant.yaml`, you can modify the published port to reflect a value that isn't currently being used by any other connectors: -Ensure you are logged in to Hasura CLI +```yaml +ports: + - mode: ingress + target: 8080 + published: "8082" + protocol: tcp +``` -```hasura3 cloud login --pat 'YOUR-HASURA-TOKEN'``` +### Step 4: Add environment variables -From there, you can deploy the connector: +Now that our connector has been scaffolded out for us, we need to provide a connection string so that the data source can be introspected and the boilerplate configuration can be taken care of by the CLI. -```hasura3 connector create qdrant:v1 --github-repo-url https://github.com/hasura/ndc-qdrant/tree/main --config-file ./config.json``` +The CLI has provided an `.env.local` file for our connector in the `my_subgraph/connector/qdrant` directory. We can add a key-value pair of `QDRANT_URL` along with the connection string itself to this file, and our connector will use this to connect to our database. If the Qdrant database has an API key you can also provide the environment variable for the `QDRANT_API_KEY` which allows the connector to authenticate. -## Usage -Once your connector is deployed, you can get the URL of the connector using: -```hasura3 connector list``` +The file, after adding the `QDRANT_URL`, should look like this example if connecting to a Qdrant hosted database instance: +```env +OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 +OTEL_SERVICE_NAME=my_subgraph_qdrant +QDRANT_URL=https://7312d6c4-3f6c-432c-987c-34d7d96428ef.us-east4-0.gcp.cloud.qdrant.io +QDRANT_API_KEY=Ch8I... ``` -my-cool-connector:v1 https://connector-9XXX7-hyc5v23h6a-ue.a.run.app active + +To connect to a locally running Qdrant instance you can then point the `QDRANT_URL` to the local database. Assuming the Qdrant database is running on port 6333 without any API key, you should be able to use this example: + +```env +OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 +OTEL_SERVICE_NAME=my_subgraph_qdrant +QDRANT_URL=http://local.hasura.dev:6333 ``` -In order to use the connector once deployed you will first want to reference the connector in your project metadata: +### Step 5: Introspect your data source -```yaml -kind: "AuthConfig" -allowRoleEmulationFor: "admin" -webhook: - mode: "POST" - webhookUrl: "https://auth.pro.hasura.io/webhook/ddn?role=admin" ---- -kind: DataConnector -version: v1 -definition: - name: my_connector - url: - singleUrl: 'https://connector-9XXX7-hyc5v23h6a-ue.a.run.app' +With the connector configured, we can now use the CLI to introspect our database and create a source-specific configuration file for our connector. + +```bash +ddn connector introspect --connector my_subgraph/connector/qdrant/connector.yaml ``` -If you have the [Hasura VSCode Extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) installed -you can run the following code actions: +### Step 6. Create the Hasura metadata -* `Hasura: Refresh data source` -* `Hasura: Track all collections / functions ...` +Hasura DDN uses a concept called "connector linking" to take [NDC-compliant](https://github.com/hasura/ndc-spec) +configuration JSON files for a data connector and transform them into an `hml` (Hasura Metadata Language) file as a +[`DataConnectorLink` metadata object](https://hasura.io/docs/3.0/supergraph-modeling/data-connectors#dataconnectorlink-dataconnectorlink). -This will integrate your connector into your Hasura project which can then be deployed or updated using the Hasura3 CLI: +Basically, metadata objects in `hml` files define our API. -``` -hasura3 cloud build create --project-id my-project-id --metadata-file metadata.hml +First we need to create this `hml` file with the `connector-link add` command and then convert our configuration files +into `hml` syntax and add it to this file with the `connector-link update` command. + +Let's name the `hml` file the same as our connector, `qdrant`: + +```bash +ddn connector-link add qdrant --subgraph my_subgraph ``` -## Service Authentication +The new file is scaffolded out at `my_subgraph/metadata/qdrant/qdrant.hml`. -If you don't wish to have your connector publically accessible then you must set a service token by specifying the `SERVICE_TOKEN_SECRET` environment variable when creating your connector: +### Step 7. Update the environment variables -* `--env SERVICE_TOKEN_SECRET=SUPER_SECRET_TOKEN_XXX123` +The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the connector. Ensure the port value matches what is published in your connector's docker compose file. -Your Hasura project metadata must then set a matching bearer token: +As an example: -```yaml -kind: DataConnector -version: v1 -definition: - name: my_connector - url: - singleUrl: 'https://connector-9XXX7-hyc5v23h6a-ue.a.run.app' - headers: - Authorization: - value: "Bearer SUPER_SECRET_TOKEN_XXX123" +```env +MY_SUBGRAPH_QDRANT_READ_URL=http://local.hasura.dev: +MY_SUBGRAPH_QDRANT_WRITE_URL=http://local.hasura.dev: ``` -While you can specify the token inline as above, it is recommended to use the Hasura secrets functionality for this purpose: +These values are for the connector itself and utilize `local.hasura.dev` to ensure proper resolution within the docker container. -```yaml -kind: DataConnector -version: v1 -definition: - name: my_connector - url: - singleUrl: 'https://connector-9XXX7-hyc5v23h6a-ue.a.run.app' - headers: - Authorization: - valueFromSecret: BEARER_TOKEN_SECRET +### Step 8. Start the connector's Docker Compose + +Let's start our connector's Docker Compose file by running the following from inside the connector's subgraph: + +```bash +docker compose -f docker-compose.qdrant.yaml up ``` -NOTE: This secret should contain the `Bearer ` prefix. +### Step 9. Update the new `DataConnectorLink` object +Finally, now that our `DataConnectorLink` has the correct environment variables configured for the connector, we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's schema in `hml` format. In a new terminal tab, run: + +```bash +ddn connector-link update qdrant --subgraph my_subgraph +``` -## Default Collection Parameters: +After this command runs, you can open your `my_subgraph/metadata/qdrant.hml` file and see your metadata completely +scaffolded out for you 🎉 -You'll find that each collection on your graph is parameterized, and that you have the ability to pass in the following parameters as collection arguments: +## Documentation -vector -positive -negative +View the full documentation for the Qdrant connector [here](https://github.com/hasura/ndc-qdrant/blob/main/docs/index.md). -These will allow you to perform vector searches, or to get recommendations. +## Contributing -You can pass in a search vector to the vector parameter, which is a flat list of floats. This will typically be the output from some embedding model, and it will return results ordered by closest match. You'll likely want to ensure that you are passing a limit on all your queries. +Check out our [contributing guide](https://github.com/hasura/ndc-qdrant/blob/main/docs/contributing.md) for more details. -You can also pass in an array of ID's to the positive and negative parameters to provide example data-points. This is an easy way to get recommendations without having to manage or deal with passing around entire vectors. If you know the ID of some positive and negative data-points, you can simply pass the ID's. You must provide at least 1 positive example when using this. You can provide a list of positive examples, a list of positive and a list of negative, but you cannot provide only a list of negative examples. +## License -You can read more about these parameters [here](https://qdrant.tech/documentation/concepts/search/) \ No newline at end of file +The Qdrant connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file diff --git a/registry/qdrant/metadata.json b/registry/qdrant/metadata.json index 74e7cefb..260ca973 100644 --- a/registry/qdrant/metadata.json +++ b/registry/qdrant/metadata.json @@ -5,23 +5,36 @@ "title":"Qdrant Data Connector", "logo":"logo.png", "tags":["database"], - "latest_version":"v0.1" + "latest_version":"v0.2.1" }, "author":{ "support_email":"support@hasura.io", "homepage":"https://hasura.io", "name":"Hasura" }, - "is_verified":true, + "is_verified":false, "is_hosted_by_hasura":false, + "packages": [ + { + "version": "0.2.1", + "uri": "https://github.com/hasura/ndc-qdrant/releases/download/v0.2.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "007cfaa76e45d3df2c2f50e1fdf0d4a3122a48895088958eaa972aee5ce49ac8" + }, + "source": { + "hash": "2effed689bd2f97c9649d1b8f9966533ed1d82a0" + } + } + ], "source_code":{ "is_open_source":true, "repository":"https://github.com/hasura/ndc-qdrant", "version":[ { - "tag":"v0.1", - "hash":"eec3339a83a9cdea6ff9f4a76f2ed38849a1bff4", - "is_verified": true + "tag":"v0.2.1", + "hash":"2effed689bd2f97c9649d1b8f9966533ed1d82a0", + "is_verified": false } ] } From fcddd8625d299605bbda512c149ade3dc21d6f84 Mon Sep 17 00:00:00 2001 From: Tristen Harr Date: Wed, 19 Jun 2024 10:35:43 -0500 Subject: [PATCH 008/135] add duckdb to registry (#132) Add DuckDB to the registry --- registry/duckdb/README.md | 177 ++++++++++++++++++++++++++++++++++ registry/duckdb/logo.svg | 1 + registry/duckdb/metadata.json | 43 +++++++++ 3 files changed, 221 insertions(+) create mode 100644 registry/duckdb/README.md create mode 100644 registry/duckdb/logo.svg create mode 100644 registry/duckdb/metadata.json diff --git a/registry/duckdb/README.md b/registry/duckdb/README.md new file mode 100644 index 00000000..c9c3ddd4 --- /dev/null +++ b/registry/duckdb/README.md @@ -0,0 +1,177 @@ +# Hasura DuckDB Connector + + +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/connectors/duckdb) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-duckdb-blue.svg?style=flat)](https://hasura.io/connectors/duckdb) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](https://github.com/hasura/ndc-duckdb/blob/main/LICENSE.txt) +[![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](https://github.com/hasura/ndc-duckdb/blob/main/README.md) + +The Hasura DuckDB Connector allows for connecting to a DuckDB database or a MotherDuck hosted DuckDB database to give you an instant GraphQL API on top of your DuckDB data. + +This connector is built using the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). + +* [Connector information in the Hasura Hub](https://hasura.io/connectors/duckdb) +* [Hasura V3 Documentation](https://hasura.io/docs/3.0/index/) + +## Features + +Below, you'll find a matrix of all supported features for the DuckDB connector: + +| Feature | Supported | Notes | +| ------------------------------- | --------- | ----- | +| Native Queries + Logical Models | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ❌ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ✅ | | +| Views | ❌ | | +| Distinct | ❌ | | +| Remote Relationships | ✅ | | +| Custom Fields | ❌ | | +| Mutations | ❌ | | + +## Before you get Started + +[Prerequisites or recommended steps before using the connector.] + +1. The [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed +2. A [supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +3. A [subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) +4. Have a [MotherDuck](https://motherduck.com/) hosted DuckDB database, or a persitent DuckDB database file — for supplying data to your API. + +The steps below explain how to Initialize and configure a connector for local development. You can learn how to deploy a +connector — after it's been configured — [here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). + +## Using the DuckDB connector + +### Step 1: Authenticate your CLI session + +```bash +ddn auth login +``` + +### Step 2: Initialize the connector + +```bash +ddn connector init duckdb --subgraph my_subgraph --hub-connector hasura/duckdb +``` + +In the snippet above, we've used the subgraph `my_subgraph` as an example; however, you should change this +value to match any subgraph which you've created in your project. + +### Step 3: Modify the connector's port + +When you initialized your connector, the CLI generated a set of configuration files, including a Docker Compose file for +the connector. Typically, connectors default to port `8080`. Each time you add a connector, we recommend incrementing the published port by one to avoid port collisions. + +As an example, if your connector's configuration is in `my_subgraph/connector/duckdb/docker-compose.duckdb.yaml`, you can modify the published port to +reflect a value that isn't currently being used by any other connectors: + +```yaml +ports: + - mode: ingress + target: 8080 + published: "8082" + protocol: tcp +``` + +### Step 4: Add environment variables + +Now that our connector has been scaffolded out for us, we need to provide a connection string so that the data source can be introspected and the +boilerplate configuration can be taken care of by the CLI. + +The CLI has provided an `.env.local` file for our connector in the `my_subgraph/connector/duckdb` directory. We can add a key-value pair +of `DUCKDB_URL` along with the connection string itself to this file, and our connector will use this to connect to our database. + + +The file, after adding the `DUCKDB_URL`, should look like this example if connecting to a MotherDuck hosted DuckDB instance: + +```env +OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 +OTEL_SERVICE_NAME=my_subgraph_duckdb +DUCKDB_URL=md:?motherduck_token=eyJhbGc... +``` + +To connect to a local DuckDB file, you can add the persistent DuckDB database file into the `my_subgraph/connector/duckdb` directory, and since all files in this directory will get mounted to the container at `/etc/connector/` you can then point the `DUCKDB_URL` to the local file. Assuming that the duckdb file was named `chinook.db` the file should look like this example: + +```env +OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 +OTEL_SERVICE_NAME=my_subgraph_duckdb +DUCKDB_URL=/etc/connector/chinook.db +``` + +### Step 5: Introspect your data source + +With the connector configured, we can now use the CLI to introspect our database and create a source-specific configuration file for our connector. + +```bash +ddn connector introspect --connector my_subgraph/connector/duckdb/connector.yaml +``` + +### Step 6. Create the Hasura metadata + +Hasura DDN uses a concept called "connector linking" to take [NDC-compliant](https://github.com/hasura/ndc-spec) +configuration JSON files for a data connector and transform them into an `hml` (Hasura Metadata Language) file as a +[`DataConnectorLink` metadata object](https://hasura.io/docs/3.0/supergraph-modeling/data-connectors#dataconnectorlink-dataconnectorlink). + +Basically, metadata objects in `hml` files define our API. + +First we need to create this `hml` file with the `connector-link add` command and then convert our configuration files +into `hml` syntax and add it to this file with the `connector-link update` command. + +Let's name the `hml` file the same as our connector, `duckdb`: + +```bash +ddn connector-link add duckdb --subgraph my_subgraph +``` + +The new file is scaffolded out at `my_subgraph/metadata/duckdb/duckdb.hml`. + +### Step 7. Update the environment variables + +The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your subgraph's `.env.my_subgraph` file. +Each key is prefixed by the subgraph name, an underscore, and the name of the connector. Ensure the port value matches what is published in your connector's docker compose file. + +As an example: + +```env +MY_SUBGRAPH_DUCKDB_READ_URL=http://local.hasura.dev: +MY_SUBGRAPH_DUCKDB_WRITE_URL=http://local.hasura.dev: +``` + +These values are for the connector itself and utilize `local.hasura.dev` to ensure proper resolution within the docker container. + +### Step 8. Start the connector's Docker Compose + +Let's start our connector's Docker Compose file by running the following from inside the connector's subgraph: + +```bash +docker compose -f docker-compose.duckdb.yaml up +``` + +### Step 9. Update the new `DataConnectorLink` object + +Finally, now that our `DataConnectorLink` has the correct environment variables configured for the connector, +we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's +schema in `hml` format. In a new terminal tab, run: + +```bash +ddn connector-link update duckdb --subgraph my_subgraph +``` + +After this command runs, you can open your `my_subgraph/metadata/duckdb.hml` file and see your metadata completely +scaffolded out for you 🎉 + +## Documentation + +View the full documentation for the DuckDB connector [here](https://github.com/hasura/ndc-duckdb/blob/main/docs/index.md). + +## Contributing + +Check out our [contributing guide](https://github.com/hasura/ndc-duckdb/blob/main/docs/contributing.md) for more details. + +## License + +The DuckDB connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file diff --git a/registry/duckdb/logo.svg b/registry/duckdb/logo.svg new file mode 100644 index 00000000..c6d5d2f0 --- /dev/null +++ b/registry/duckdb/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/registry/duckdb/metadata.json b/registry/duckdb/metadata.json new file mode 100644 index 00000000..1d1c9044 --- /dev/null +++ b/registry/duckdb/metadata.json @@ -0,0 +1,43 @@ +{ + "overview": { + "namespace": "hasura", + "description": "Connect to a DuckDB database and expose them to Hasura v3 Project", + "title": "(MotherDuck) DuckDB Native Data Connector", + "logo": "logo.svg", + "tags": [ + "database" + ], + "latest_version": "v0.0.17" + }, + "author": { + "support_email": "support@hasura.io", + "homepage": "https://hasura.io", + "name": "Hasura" + }, + "is_verified": false, + "is_hosted_by_hasura": true, + "packages": [ + { + "version": "0.0.17", + "uri": "https://github.com/hasura/ndc-duckdb/releases/download/v0.0.17/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "3449766fff1794f0866f19505355b37d151d91682e1f784aef664b91abd57570" + }, + "source": { + "hash": "875c5fb4539febea0e5dad569fd8b64557870c1c" + } + } + ], + "source_code": { + "is_open_source": true, + "repository": "https://github.com/hasura/ndc-duckdb", + "version": [ + { + "tag": "v0.0.17", + "hash": "875c5fb4539febea0e5dad569fd8b64557870c1c", + "is_verified": false + } + ] + } + } \ No newline at end of file From d83f2467b4df28985d7eaff617eba5fe45122072 Mon Sep 17 00:00:00 2001 From: Philip Lykke Carlsen Date: Thu, 20 Jun 2024 15:28:56 +0200 Subject: [PATCH 009/135] Add ndc-postgres v0.7.1 (#180) --- registry/aurora/metadata.json | 7 ++++++- registry/citus/metadata.json | 7 ++++++- registry/cockroach/metadata.json | 7 ++++++- registry/neon/metadata.json | 7 ++++++- registry/postgres-alloydb/metadata.json | 7 ++++++- registry/postgres-azure/metadata.json | 7 ++++++- registry/postgres-cosmos/metadata.json | 7 ++++++- registry/postgres-gcp/metadata.json | 7 ++++++- registry/postgres-timescaledb/metadata.json | 7 ++++++- registry/postgres/metadata.json | 7 ++++++- 10 files changed, 60 insertions(+), 10 deletions(-) diff --git a/registry/aurora/metadata.json b/registry/aurora/metadata.json index b4199c7c..4dd8a6cd 100644 --- a/registry/aurora/metadata.json +++ b/registry/aurora/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.0" + "latest_version": "v0.7.1" }, "author": { "support_email": "support@hasura.io", @@ -34,6 +34,11 @@ "tag": "v0.7.0", "hash": "0c6fbadcaceb08791fe98f3e68294c739decfbec", "is_verified": true + }, + { + "tag": "v0.7.1", + "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", + "is_verified": true } ] } diff --git a/registry/citus/metadata.json b/registry/citus/metadata.json index 7e1bd28c..30771aed 100644 --- a/registry/citus/metadata.json +++ b/registry/citus/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.0" + "latest_version": "v0.7.1" }, "author": { "support_email": "support@hasura.io", @@ -34,6 +34,11 @@ "tag": "v0.7.0", "hash": "0c6fbadcaceb08791fe98f3e68294c739decfbec", "is_verified": true + }, + { + "tag": "v0.7.1", + "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", + "is_verified": true } ] } diff --git a/registry/cockroach/metadata.json b/registry/cockroach/metadata.json index 5c460c8c..288c3123 100644 --- a/registry/cockroach/metadata.json +++ b/registry/cockroach/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.0" + "latest_version": "v0.7.1" }, "author": { "support_email": "support@hasura.io", @@ -34,6 +34,11 @@ "tag": "v0.7.0", "hash": "0c6fbadcaceb08791fe98f3e68294c739decfbec", "is_verified": true + }, + { + "tag": "v0.7.1", + "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", + "is_verified": true } ] } diff --git a/registry/neon/metadata.json b/registry/neon/metadata.json index 89baf3d9..053fe2a9 100644 --- a/registry/neon/metadata.json +++ b/registry/neon/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.0" + "latest_version": "v0.7.1" }, "author": { "support_email": "support@hasura.io", @@ -34,6 +34,11 @@ "tag": "v0.7.0", "hash": "0c6fbadcaceb08791fe98f3e68294c739decfbec", "is_verified": true + }, + { + "tag": "v0.7.1", + "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", + "is_verified": true } ] } diff --git a/registry/postgres-alloydb/metadata.json b/registry/postgres-alloydb/metadata.json index 404680c6..050f9040 100644 --- a/registry/postgres-alloydb/metadata.json +++ b/registry/postgres-alloydb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.0" + "latest_version": "v0.7.1" }, "author": { "support_email": "support@hasura.io", @@ -34,6 +34,11 @@ "tag": "v0.7.0", "hash": "0c6fbadcaceb08791fe98f3e68294c739decfbec", "is_verified": true + }, + { + "tag": "v0.7.1", + "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", + "is_verified": true } ] } diff --git a/registry/postgres-azure/metadata.json b/registry/postgres-azure/metadata.json index ec0dfb84..a136f9dd 100644 --- a/registry/postgres-azure/metadata.json +++ b/registry/postgres-azure/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.0" + "latest_version": "v0.7.1" }, "author": { "support_email": "support@hasura.io", @@ -34,6 +34,11 @@ "tag": "v0.7.0", "hash": "0c6fbadcaceb08791fe98f3e68294c739decfbec", "is_verified": true + }, + { + "tag": "v0.7.1", + "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", + "is_verified": true } ] } diff --git a/registry/postgres-cosmos/metadata.json b/registry/postgres-cosmos/metadata.json index d348a791..d5cf0c32 100644 --- a/registry/postgres-cosmos/metadata.json +++ b/registry/postgres-cosmos/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.0" + "latest_version": "v0.7.1" }, "author": { "support_email": "support@hasura.io", @@ -34,6 +34,11 @@ "tag": "v0.7.0", "hash": "0c6fbadcaceb08791fe98f3e68294c739decfbec", "is_verified": true + }, + { + "tag": "v0.7.1", + "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", + "is_verified": true } ] } diff --git a/registry/postgres-gcp/metadata.json b/registry/postgres-gcp/metadata.json index b33877af..3ad0d7fe 100644 --- a/registry/postgres-gcp/metadata.json +++ b/registry/postgres-gcp/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.0" + "latest_version": "v0.7.1" }, "author": { "support_email": "support@hasura.io", @@ -34,6 +34,11 @@ "tag": "v0.7.0", "hash": "0c6fbadcaceb08791fe98f3e68294c739decfbec", "is_verified": true + }, + { + "tag": "v0.7.1", + "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", + "is_verified": true } ] } diff --git a/registry/postgres-timescaledb/metadata.json b/registry/postgres-timescaledb/metadata.json index 9e18acf1..d81f8a45 100644 --- a/registry/postgres-timescaledb/metadata.json +++ b/registry/postgres-timescaledb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.0" + "latest_version": "v0.7.1" }, "author": { "support_email": "support@hasura.io", @@ -34,6 +34,11 @@ "tag": "v0.7.0", "hash": "0c6fbadcaceb08791fe98f3e68294c739decfbec", "is_verified": true + }, + { + "tag": "v0.7.1", + "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", + "is_verified": true } ] } diff --git a/registry/postgres/metadata.json b/registry/postgres/metadata.json index 5f5a34fd..49037465 100644 --- a/registry/postgres/metadata.json +++ b/registry/postgres/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.0" + "latest_version": "v0.7.1" }, "author": { "support_email": "support@hasura.io", @@ -34,6 +34,11 @@ "tag": "v0.7.0", "hash": "0c6fbadcaceb08791fe98f3e68294c739decfbec", "is_verified": true + }, + { + "tag": "v0.7.1", + "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", + "is_verified": true } ] } From 9d080cf05a45157f0256c98711ef976690b365c8 Mon Sep 17 00:00:00 2001 From: pranshi06 <85474619+pranshi06@users.noreply.github.com> Date: Thu, 20 Jun 2024 19:04:08 +0530 Subject: [PATCH 010/135] Release Azure Cosmos (#169) Co-authored-by: gneeri --- registry/azure-cosmos/README.md | 171 ++++++++++++++++++++++++++++ registry/azure-cosmos/logo.png | Bin 0 -> 38264 bytes registry/azure-cosmos/metadata.json | 57 ++++++++++ 3 files changed, 228 insertions(+) create mode 100644 registry/azure-cosmos/README.md create mode 100644 registry/azure-cosmos/logo.png create mode 100644 registry/azure-cosmos/metadata.json diff --git a/registry/azure-cosmos/README.md b/registry/azure-cosmos/README.md new file mode 100644 index 00000000..e1961ce5 --- /dev/null +++ b/registry/azure-cosmos/README.md @@ -0,0 +1,171 @@ +# Azure Cosmos Connector + +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/latest/connectors/azure-cosmos/) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-azure--cosmos-blue.svg?style=flat)](https://hasura.io/connectors/azure-cosmos) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) +[![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) + +With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in Azure Cosmos Database containers. This connector supports Azure Cosmos's functionalities listed in the table below, allowing for efficient and scalable data operations. + +This connector is built using the [TypeScript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). + +- [Connector information in the Hasura Hub](https://hasura.io/connectors/azure-cosmos) +- [Hasura V3 Documentation](https://hasura.io/docs/3.0) + +## Features + +Below, you'll find a matrix of all supported features for the Azure Cosmos connector: + +| Feature | Supported | Notes | +| ------------------------------- | --------- | ----- | +| Native Queries + Logical Models | ✅ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Nested Objects | ✅ | | +| Nested Arrays | ✅ | | +| Nested Filtering | ❌ | | +| Nested Sorting | ❌ | | +| Nested Relationships | ❌ | | + + +## Before you get Started + +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Install the [CLI](https://hasura.io/docs/3.0/cli/installation/) +3. Install the [Hasura VS Code extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) +4. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +5. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) + +## Using the connector + +To use the Azure Cosmos connector, follow these steps in a Hasura project: +(Note: for more information on the following steps, please refer to the Postgres connector documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) + + +### 1. Init the connector +(Note: here and following we are naming the subgraph "my_subgraph" and the connector "my_azure_cosmos") + + ```bash + ddn connector init my_azure_cosmos --subgraph my_subgraph --hub-connector hasura/azure-cosmos + ``` + +### 2. Add your Azure Cosmos credentials: + +Add you credentials to `my_subgraph/connector/my_azure_cosmos/.env.local` + +```env title="my_subgraph/connector/my_azure_cosmos/.env.local" +OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 +OTEL_SERVICE_NAME=my_subgraph_my_azure_cosmos +AZURE_COSMOS_DB_NAME= +AZURE_COSMOS_ENDPOINT= +AZURE_COSMOS_KEY= +AZURE_COSMOS_NO_OF_ROWS_TO_FETCH= +``` + +Note: `AZURE_COSMOS_CONNECTOR_NO_OF_ROWS_TO_FETCH` is an optional field, with 100 rows to be fetched by default. + +### 3. Intropsect your indices + +From the root of your project run: + +```bash title="From the root of your project run:" +ddn connector introspect --connector my_subgraph/connector/my_azure_cosmos/connector.yaml +``` + +If you look at the `config.json` for your connector, you'll see metadata describing your Azure Cosmos mappings. + +### 4. Create the Hasura metadata + +Run the following from the root of your project: + +```bash title="Run the following from the root of your project:" +ddn connector-link add my_azure_cosmos --subgraph my_subgraph +``` + +The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your +subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the +connector. Ensure the port value matches what is published in your connector's docker compose file. + +```env title="my_subgraph/.env.my_subgraph" +MY_SUBGRAPH_MY_AZURE_COSMOS_READ_URL=http://local.hasura.dev:8081 +MY_SUBGRAPH_MY_AZURE_COSMOS_WRITE_URL=http://local.hasura.dev:8081 +``` + +### 5. Start the connector's docker compose + +Let's start our connector's docker compose file. Run the following from the connector's subdirectory inside a subgraph: + +```bash title="Run the following from the connector's subdirectory inside a subgraph:" +docker compose -f docker-compose.my_azure_cosmos.yaml up +``` + +This starts our Azure Cosmos connector on the specified port. We can navigate to the following address, with the port +modified, to see the schema of our Azure Cosmos data source: + +```bash +http://localhost:8081/schema +``` + +### 6. Include the connector in your docker compose + +Kill the connector by pressing `CTRL+C` in the terminal tab in which the connector is running. + +Then, add the following inclusion to the docker compose `docker-compose.hasura.yaml` in your project's root directory, taking care to modify the +subgraph's name. + +```yaml title="docker-compose.hasura.yaml" +include: + - path: my_subgraph/connector/my_azure_cosmos/docker-compose.my_azure_cosmos.yaml +``` + +Now, whenever running the following, you'll bring up the GraphQL engine, observability tools, and any connectors you've +included. From the root of your project, run: + +```bash title="From the root of your project, run:" +HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yaml watch +``` + +### 7. Update the new DataConnectorLink object + +Finally, now that our `DataConnectorLink` has the correct environment variables configured for the Azure Cosmos connector, +we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's +schema in `hml` format. In a new terminal tab from the root of your project, run: + +```bash title="From the root of your project, run:" +ddn connector-link update my_azure_cosmos --subgraph my_subgraph +``` + +After this command runs, you can open your `my_subgraph/metadata/my_azure_cosmos.hml` file and see your metadata completely +scaffolded out for you 🎉 + +### 8. Import _all_ your indices + +You can do this in one convenience command. From the root of your project, run: + +```bash title="From the root of your project, run:" +ddn connector-link update my_azure_cosmos --subgraph my_subgraph --add-all-resources +``` + +### 9. Create a supergraph build + +Pass the `local` subcommand along with specifying the output directory as `./engine` in the root of the project. This +directory is used by the docker-compose file to serve the engine locally. From the root of your project, run: + +```bash title="From the root of your project, run:" +ddn supergraph build local --output-dir ./engine +``` + +You can now navigate to +[`https://console.hasura.io/local/graphql?url=http://localhost:3000`](https://console.hasura.io/local/graphql?url=http://localhost:3000) +and interact with your API using the Hasura Console. + +## Contributing + +We're happy to receive any contributions from the community. Please refer to our [development guide](https://github.com/hasura/ndc-azure-cosmos-connector/blob/main/docs/development.md). + +## License + +The Hasura Azure Cosmos connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/registry/azure-cosmos/logo.png b/registry/azure-cosmos/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..001667d864a9bb07f7389f2534dec3a2514e86eb GIT binary patch literal 38264 zcmb?iWmjBHkjCAe;O?Ff+}+*X2@>2TxVw9BcXt?MaDvMK!3pjVB(TG~XaB)|m~+p$ zx2L=Msj4pRC>14XRHRQx5D*ZkvN95C5D-x85D<_?2yoyxIY%_B;0L0UjIJvL1Tyx= z4-z6fmjD8S970w?RKqLxtk=88K-#_*cf> z9Dzsw4Wjwu0g+#vvhZ*s!Z@M{#U`B{#X}n z;;bpsnS(#AXZAnr)HcxuT-_)EVvB;R+9s)#&HN-OAE-XV7X)3q!D4dD&x=LN(Kj>> z{kLR!!UrYZ9yS%IFwsarPe$VZ$R-1?$Tw4MG{zjd_bD^a?Z)w5oAQH1U=%)kete3Y zs{ng>ejLIi9*e1BgxC$3AmxG`*x2%+3J5y!UB(_uE-UNp;rP(~4;=f3z+g+SbwyBw z;>Ro-S15($BC)Oc)IZ;wd`yY`-{&kY0A^k`IvEg{No*&n4vEmMLV6Mk%O$O9FsL&0>A+O7^M>}wm%|1ykay7Wdc-_~U?q>BdE zg==CAr%G5zb-UzLYfPL4ed^=y{!z07Uh6ZEi{h-9%`Ae|0%A_SZgZ94l*(CY@Z$2o4h2MB#oN}TsG z38B8H?YB*XEyP#t)CVi+RC{tiH&9m3Tnxbn>z=Qeu6^_XOc#sxR*7FDue5({Y?kQ< z0sakillf)Z1-e8lxK$Z`h?^TeST+@M6n#IZknAeLyb6-wut7joV+i&6A=Y1K{WqJ> z6(PZF%W9W&g!GY98p37fg_-+;m>0_59DnJ*nqv?U;6U>hS^8p6!Q>(@rlNW`EioBZLYJyAeAsd`v=;3^Lq* z+WzXeLubGk<_P>x)|MBzND|70>8%a7emKE4$hABks-{U!8PW&Vn!kc(zBKiNIR4Y? z)(=>sYr8*x@nL35{eh00y95A1x1i$2BW&o5-R^wf0x0`)kAg9_LIW><0+v@29hBJx zobT8NVkQCY=GiDnjDS6Q@SRWvkTYAZ@B#5W2Wz ziWCpZh7R*hoPghDqjbj#Tkz2_z7nV!`c^y~z!4r}Yh^o7qmo%FX@$woPtRFRj}pU< zOn^xM0jDueQSu{kV&h98c_RF%CNByx6dKeE4jTDc`GEST2IElw{WamFT|%_0npq2< zt~h*lX%@!vbDFQh76_RI!T6O8n%fqsxC18bRQ7ZSu~QU5@IN*O6!#{kgRbse&51i~ zQO(KM57-5zi9la?&RHyuaK~+v>=}n_ASQ9OpsJ}&cqi0CRZY?X7?wf7$;nM3st9FV zgM9*bdJsre`5jFO3plrF`D3-0pI8v1(H-fXosvmg!7B?~u6 zXb(VC^+Ih&DYd{Z2?RuXy&Dr0a9-d|zVwL9&l*<+nNAyMv~5l@j^D6`x(2PK8Xc*~ z_y3wl;w4{*$q;!&V#En@Hc?1L#Jv#_mCMTUM_M_!ecf|s+AqA2IyrXGVD-uj+9hb7 zXTZZ~(l9MW&{tWesKK>NN8%02WjyYCr%;{PAclG<-Y^QiEZR^A@+I@hrF(U%E!Vtz zgdf2+2levhFc)B&5=HlaRmo8?h5GyYR_;Bkm~$Y~4z?~J=&i?WNVJ3l8F)gqV`4Q0 zienr#1yvOJ%l@A#A|V2NNzx$#Pf=6~I6%TN(w*=99t3syswtIU&*!GrDbkayToH0G z^0lWc2B1tDE+r?ZRlUSQjUm6<1?9cabu9h98R9aGuR@=j8)%ETU!wFYEmxo6iV*ic zC|zMq(eEOWk?*wk%+@{T9S{SU2sL0>AOf&bM-I*<2Z$x$RX7oB$)T~JAS==~Qz%tn zSRnT3u@UyjBSZ>By>YyVcT}UFosQWO3P;Mvlm$k_p_Q-GruRq$(NR^sNAhAz;B-h} zYBX2LofrX#P?IWfT_mP#MSxIxPe@~CoDPn_P|$0r$*jf|lvQ}+x#>Ugpac*8_+r?w z7*E!;?{56@4CFnw+UYd6aP*v^q1B=Z(B47-#$T}Xu9#V{C?RDcVo``GnJYXgnG7W| zy8B}=PCs8)BTn`P1P5x#`z4ScIWS3gkAdjd{WF9)22ARrmZ!ZI(oHB405R1z`W^%x zG}EwDPA2HL2=Utr_Mn@Ff$1>H0%Y31$1`69_KwoMvqz9K2}j!^?!=(pYVjTGc=j;S zaBh0`bC~vln`osBZ5MLa!C|+EYoT~wGe#yF>4A{060w&dV+7K!#@M(_t!>jyhxEF3 zVl4Lt7b#*1){bgn<}Kuo;DkJPfK~% zfp&N>SV4jVHFuP1O?YYeb?)H@^`_r`gFWJPNEgrUEmz zhv2f?9o6(3)1R0imdF}RHyn0Orn!WGUN$IOi(h8RoNOl57;)*9Pty627w`c}jep-& zo>&82UpLVbTy_MRQQ%i%CButLIAX|6)K@YM$MxqNAiH(I1qx~h0uQO>@|=gIittZBa~0S!5)@pHlOgBV z?Fu(Yvy_HiXrXYiWtd@J`9T?lyL2HSYmQIvv)xU|^&lib{MJ0+4-;sQSHAkY@Ur@t zqCWO`VF5UY)Xw`V5#WWGwKzh5L}d@7OJ2mFU-OwsV}q?t{+ardGOD|v`#83=rgWiH zzI0kFCG0P{@T0>~EqekIoiaUq{5e$gdH!r;f46_MOj)emc5o8B+0VIUVuN(#~wti;_f=D4<|Shr7Zm7*jDP&hb%JrT=O(r~Ld7e9g<{VIdVhN61y z3zpgvUuD%N#tH2hK>hP!J_}ig16r5~cHt}Sm6{1`6)z&=I(0sctyD{-uk;XGSUft# z8uxTGVQVwTTwd9)BzAhV*pizVt%TV6Rd#;jtQ^Ji`Q4*|yHBOEea1p=k-`@RWTg2X zA09SqeTRB;7Nk<@k9GzF%F-O*J+5BY(*}MttkBC@-o~8zt@g=vnISJ8OV5uVzhMLo zO`L79>i9usF?b6TG+Mdh@^w79?s^3wvRxDOh4e;c&Z^j$?Dw2p;q((IWur%IM2s~X z0_7bhBikbM^ZfvSTD30C!FcDt#ito#|2|L<1UuHBfgY%BhNFlGfee6{XS1}q`TEw= zFS7*(&B5I-yDRH7{9;-TIEqGqC7mpYT*hV!_sAuk_(d0` z3-|s?qEo|1lRv3$;o@ty1iCx!R_7EP$rU7*C$8Oa!#2Yxzju1@w%?CfgBDy~Bj&gm zjIJYDWtjR25iT`#mQ#l0N{wwi@pq^q(5~b9bmVuNHf;~lYM}g~uZYNVrV%@3Z}lk6 zXuF;b{2P;_(&Ekc?@GD@Z zIiNQZ?`$G`$ER8O7wLs}P(K9gFn8{C(k!?wh+j{Y(gm~6@^cc3!r@4Am_exs zKqK4I(ZpQaQPS0?c>CG4&}|-9*1ee}jai+2Nx}3yz4M92&bky% zO6?8n%#jiYC*UWxfzPy@cL!+4i!b8+mv`BSt*^U@YP2w}7u|$Y`>x84t)|fHuOYvl zqm`%*`$uxurvA7webIdU$g*rqRx^6MavNK*2I|?YsPt8_F^4byCx)CPn>B&QZbMA* zu>cDWE?EkyqGDut+T}c+`iA}0q?&>=kRT4u&cc)PR^TS%+RC|?K;9rS!R*~y;Z9rg zlVWOr%DkaBzf|XM9|*70nbMnDr8Ys^EzeU7(W_6?9byv7oDuHHVKMw5tl1WYhlvs| zP+Xmg3r8MXqEv`HYZ8|KN&ZjdX+vj=3%k^`N;(Ui%w`KG`_1uN-5wtv61ZL}3k`ZG z*r1|dIoa~c;Ar;32`&U>=m?njpRr7l2tkaxp_nETsl1FR&{_Gpk8q_5u{XcL(GB{; zYXX6?{6}n!W#n9L#U=jAeU+pXO%V1Hb5&;@IN~no>wQP#%UQD{0kwr_k1SzLgNVPv zuIkcO+Gx`V8^fZN+y{ZxPmp_GcJrmk9ab){$i`bjhZ-R}^eonUDao}zsZAD(^U&fq zdk!P3{#QG{>GaOQn$9dYecI=A+KQtf#4zU|ssTvNd`T}nFQ@|s6EZ+RP>3XtOwiCL zc2+%+$UpX}n;I1$qRSWX# zK1OfKj~#A>U%gN=H?oE0r#dx;M}CUI8)6l08193p@)&RS*8f+!lmDdlO;WQmT&-M5 zAViHxv1@m%#R-*TiO8sm&Z3Db>vbLb=uq1sJ7vNmvQ3!d zcvBm1N125mi5+aW7VOKE^PS(4E*07*;TF1l0w4$B$27!~c0iT^NXMJciI_&5Z=`6-@uJ|k*MDm$73mh|$a$p2yi*i}6T*_JMf<)8;Qw2zd> zP7%CYWy#;zfl2-2_6>Od>uuAwh9kTR-$xc`iwM>qS3{Itjc-n>eiaqEJ6J@HO|Jx! z9D!}KGFj%*H~68x%E|sN%DJg_vJH;x%2F&#T!a)0Hlp29Vzjn8vOznYYmJKKYyu5V zOJknu3{TFaj%dIR|D#W91x^+Iv(*f!X+*ExKrKO@_)x zA8Jag!Riy*4E+~tVjhq0?LZ=5-q&%i>haYKme8Aj>=KzzxrF-Lj(EK$<$V6u2!^E7K>O+i-#SArOW^{w44U6 z7EUpEzNGT=285stJCH#9_-v@Hg1KNZ>QVP_TWkDJ=g34CCe$PF4t9sc@0&QrUCs9~ zstWdg4KMkfJqZS!#wk5qVJ|#-JKZgfpeuyRWPU z6&~T~e<~c?cdMwy@pvC4zuG6<_o1vel-Uyl8{*B|8%gpsPp4)+bEtk*O9v|i3cBXR zZdTg9Pa}#F1Gc)vy-~EmU=n=aG|-6mPzahULHm5kvN91p>Pjj#$fHHIFAo5`@XM~g zSY_Tjw;5U>@q-&(z^r@1X@~l~=q0RPFrQ~7yyAX+1NMF4wEK_|g~(uUumLil@`M*JsGkW9QPEH8og4@JKZ0v8Ge;L5ZwLNe4}SW4$u>OA`W5tJ#w(3 z90>3&aN0!jws{xYDxaX!;F*u-mOz9t>NCsqKEJv={z&5S4K1ljJoOA%0G}_J=#6dV z6{c_MjG4{GgZnAAm7z_A7Wv92TxI@9Oc#dAkwh(5{?_HDGT6xTQ;gLJ5B=nJWfnu) zz8{JB!-dH4sP$ZrnN>9Lm(-a~HsJz~M_vtfGc|3HxpMX)NzJ#VORTbAJOizIe>c$!1Y)!DR>&if<2Ax6&I zZ1#`q6~4`@f{HRYG(z8r`tO$!rR0iAq8M+KUHgp8cRAfAdKcv65_=_pFQx3T3a+4d zWKWvNdoq&;o9*30F2hEHQU0c9Xg}_OF^JMERRP0E>DWwaRsrn!DFatKr5=j?DvwR6 zO;P^tD%zE>R33!a8b3AP@5A-M^)UR~^v1uF-c>rDHoj%eWP#e3nP!C9C3_w{aLbL$*qmuARd?&ddo__*N4`aB z-!j%74qxO%pkNMQE#?dMq1y}0LfMPgz$j%L4Yl|=5VO?sH#aQ>2yXsYX5oGPoIvka zpOl9*LiyU?3-48h?FT3g zBBrbbn|9f)fmzZ)R$hYzRJnC0u4V{becVOzx5HMrBtbvHzs> z(^zL8bdUX*zHD4egh7WB$PrsLnmJ8JIdgA&4L8$=do?612?(eEA#dxa75N5KdFl6w zkLxNke(5L{8}-{Pa?iV;TBbVc_d`K@ks%sAjew}iK^$UpSvqGsOeU%A@Age_o|Zy` zFos0~7gYe{P6kZ=K3yLs5RD4y6{f;BLI*Q{oJsgpLBVn>@R%_4Mi^>m^=A$HiMvke zzwpdRxA?iUCl`)jd>^il`WdQ z9{lnPi60JnfK_03WC)`s%N_ zNmmznqLD=#u~%L(y>Kx0Hl@nSo*yMNXEf47?h4`0C07Hj?}LJQQ8vBm_uD9jXIBrwhU9`C$EcQU-+ z^P5dxV&5*dI%DC3$XW;Q;o44Pg*>IP-@@+Pa)|-~kg5TOD>9vF@}<9moI)Rsec%}0 zI7HHUMq=)fiKMO7eOPDWYcA@Yo5hE}6)UyTCQr*?vEt6{PP9bsnZCresM^t8H=QsD znDxa5idry@ZwXnoXF4Mj%3^TF*C2VsKG+!tz^_tP-F(t80z#-kqLhcNbtXQELn23r z;h|=bf**%yp;HrZ`}1N1tCZn1KgsqcR&sS6JftY2Z$fSuyJ~NdVrG05eYIZi-SRcs zp|6O;3>aZa=Rm4PSr$crS$>SDtDu4cgy$%TwOo3m$e4_d+BrhnwNEb&zBPPH4#asD zEYCKZRS7o#syesn6P{g{nmxXba@(`xHk;MOcd6B~q6tT@jvR&){1lIL)US${QK~G+iNVIvd1}Y zw4@`l_~=jQo4*?W*9+htEN*)7%g<$CQ0wW=4IS)L85Zj7Yf~->QAMjHQhK%uMm}zK z5z6|@r7BKG;xjPCR)}y+C_rvw@GbcdM=+c{6a`FWOZA^s*rjI)6&*}RrAtsy-9IP+ zFip1H*DcGeymf0LmyueY10@AimYBZSQii8<*iTELQm8Yii|0flG=j{LE0D}03*_#T z48}NI#gq(ktxivvfiucn*{EY_BXZ{R5Sps4USi&NB0Efay8~&Neh;molEDK|S`*5Wp!AcE9b*IX_1^JqX%5qdH*(S=;`s|#K z(h_UF6p=b#lEK`H;{*;v*FdxQ<@`DA_5h3XlQ)*PUUfBQ5Va+yx~;vIlGiu~uTiHE zFe+wYiVR8q>vT3{kO(Wyz8WAm=*J#j$y3~3xYvz}=-cghR0 zmGR%o=aHD^x;*!&w9b)uLm-}v6~D7_{ByV}Grzebzl1!O|E0$BQD&Xf8UF3SWY#DB zoMExH;n*y~C@WWDv9j!)N=uJ3(^5TdAOtChqK zF8t_y%oJCGvQXrW zno|Z@pMYxCvSy<)2NI!)G!~RX#6xne4=|XP9<1BJsJupxJ)-ehDU_Q#ntCu6)Y!Ss zuQ!9j{nr`j|HkDL^tsK$rA9dwN=$o}^w{asfky)V;POR&9Xlp_`rQGw6LrBiprLI$ zd}6l&)D{KCsDv!huza()f`&iMR00PI5fVO^v*~KaM2e)mOB?MQW7fY;LpID)A)lnK zhkUuiA!bcbU%FA$Oq?@}t>f@8f&}d>!A`Wfj%@4QA+Mcg{BM5S#06~&%C-8L;=$a( ztHgZIz#$UT^b@Cpe z#LZ9cFg{@eBGn`E1{xjB^mWzQCu=!HLo5a;s>$RA$+Um79flvHikXerE8PiVyUM(x zW?hr2;v*G*)!KIuYo{>ir4gs?RU;7B=GX4;6i#dq6;hjlxhy#ZS-&YTmXj|$P-E~5 zyVvxG)gemw_rQP8ERTI&D|NH^T+k8f$7fm`h^>v2^{RWFT5HYVHBU&=nl zwm3YO>Q=)jo+jg>w}yW@FA8!TQTI;T6-Nv4op|j8&P4TL9sVPD6fHCQy{@)>aD@Z5 zlU#n!OU=CB4cm@}<--)lZqi)U$X@0QmA_wjFfY)c@|NCXI|9`OR=ySFUwmYBn82Rz zDDBN_2%ufV3(gc}har@WL|_WPLr*W|&>x&BDVYbs@|LPuM8{F9V)Yi4$LCENOY}(a zgKU5dGfG^vLNznp`A&$jT}$S;5eZFXFOJg>B*oCqzbU$WGQOQ+^0FXbj&dzKy+J+auIo9ywmIZy?!ygL- zr#6D#o@?;@u?`=+7vaZ{_{F78!A0 z88&^5lJW+bv>LjePL4SEr}y=|*BC-XZQ+n4s z%{tOW1XtUiMD@FkZZpLz-TS?Yga#|6XeK2xt0$X&3!|bEXgp?Oq__QNP`=*QxlUOy zT#dHFlcr3<@0Kz}I|XmPcrZh=fG>_Dlxfe%m_`J+GTtcRy;qMFPIKg8c9|0`hVcUm|{wvp+;%9;#ll;+ophgf!`kHa6wJO3H~XR7k2EC*0*${4a?jmiVqW%%?MVOPD5Osa8rw%zaAFGyyTi+ z))%@ggJj(N@v3Xb0G+r7VP=ZTrjO|70;E2L}xW(;K(vPDRR`znvxL|gquScMgX})R5o~LCs4IT zZMN1hbw0V-=6$9E#Nf@SyUj>Us&tSxE{7F|{LbtCLwAj^$Y^3;ZLl#Wf-~>|edTx7 zxd$`qTAe6{6C?YETsxxx(?oCW-SIK25cFOa@6>po!gedpc0= z-ES_k*t;W^);`T);v;Ndya(@i}ittJNdm-o!i_-u7d|gyhgqKUnWNf zX<6W@v5DZx8`BFi@tZkz$OsNs>&-xX>$>B4?h-a9R4AlD2gl^bVAj91Owul&g;T1DcqC$t zlT&N0`1@nq9!8dpNUVB3C1M#t;na)oST(axP<;i99da_U}V z5ke(rdsU9ohD$W?UxwDmYrrkyvsz^lnv0vNZe_VKG{+g@#jN4+AM!SZs+AVqWAQd~ zCf%}12$%s`#AtDh+PH^oF8=)G16S^vy{LO`UOa`neu5fTne_mlQn~cbwYM9KT%@c2 zfn)rF;nU;q;Sn?NGsu+V={9(!^R8<}LpZc;tCemMs;XG6m0oGt-A#tByOL8KU_Vq0 z_+Zy=8`YSd*S+CK+4x@Er)Xf=>Yr?{(Kp@EZS=}`{4Hx)z-}!`#=*EYcOB7H@j31@ zMlDY^GLN}tHfism8-HSX3-dXmj=stScq|S>P$?c zgwS37;2K4Kw;^SxnEGrNeUd(UyUrYe?&ygPsLmh1&U8Yo2c1huIMl}2IsuwB&Ne$Z zBlJ2@C4o_#B|_S|9pW$Gs{=JIsvxHR7A3T))uzR9?6RVQ*E?QW@CTOz@7S>3@I~Xf z_+Qn$&l7Y=s;U#dL^yqOA7Kb)gnhWprnlAVp^n6CbSS>g8lrq~QdNT|#ixt!q>wEd zq2Pn+?zI&NhB4i1X*a9Q4}lY-JshgYLEC|yOsG1OPqUX>W+6ZeC0Ay)^HP&T#clxutlew*-a=-xvF5c*D#?;bS>92=?V0)2zN&gO%Op~dNV%tWXcCgqyUNi$oIVAbMbGb}z zA$(E2l1La5fKFE#RFr@ApOigdolBd{uLj9_=7+D3tJYrNF}#1daMyTJr$E`S=zgY; z+EH-2h+@-q<-7`s=k75KVF$v}+ktkBc0eluv&KS#>R|h%{OxwSd8@0@3q#`Edx4` z;APyDv=>0;m3XHb-1waS@^A<9ws3k(7Oq{3>s9-+kbe>jmtxdWemC_%v}hoT zKC6PD0*8nafQM05;6-bGvRk_7O^0Hq`KkvrRhp_@ZamQ(5f8Q*ytAbL5y|efIH*e6 zS~+YGgFR_{t~1p&%ApG+j#{damw-u|ka7ixtY3%oeo{pZ=NueyT}JVAG9*YFB(8^2 za_Bso?}~c&JUa6Jxzs1v8v^!D14KoPLz zz7`;OP1$x81(JdZwu_Gu@6dn|G3d}C#0F(ddUBx`$G=#`sfuD_%5VrT8)U88+2%o4 zZ=FH187XjrlYz~ZD-OT=da3>a!X6vIwOC1g;WW`uXvx2P;O6T8NO*_weGWlC)1~|K zC1}jq#7*jf&7oVIYglS~J%I(q-q|b)Q9Fx5VQPkpffWlB4b;BYtW^&%0~&#hnIe&k zqdmK8!n6FF`iZGc&6|uV8<&O`4ILe;oqZv`yi1)hW;IYN9HJsMy8?0{O{w)KT0$Xl zqMfMgi3zk1Q4s2dDPqb;y@I;mZ!2HhnwO_H7cSb2{zdlT|CPyE4(NOWhhZ=0tv6mo ze!f01!ci*=WEJ_!P0A4YC%GuWju%ODRoXp>oF zLv*jXq5@JizEAI2=xJ0{JEx3PHDE@LApN9h@wIs3lN`66YQ2c%95_U_h8*6&j;X zJsR`L?19n4td!Bd>e`OF&N~E&5I3^vyeX{h029!4LgYh~Kl!fN*md2E3fX3f60&)k} zJ9I1PPZbzZNW}bYKCb3xUfEb|;T_c(?#`A521O%yaCK-vA?0auy_{yXc1UxUOamk( zJv^5=XWQi|)Um$@`s?982VYG)Er9vJ_kZ)#$of9;N8m1w?8M0*OSO0UqG{#G4SRIu zV-ozYzCOrcbJja;<3ly}R5v9Z7A`K_h$0OL7&3Ptn`@&a#2<=~@c;bv>*zVqo?o{| zqTZ${ES@FzWRr;@-J$Wb?47s&pqlbzg(;40qu+Ejfk)b3sGvAxF;-rR=|jnBbZqZ3 zpa>t2=bnw10E^+OlI4>cD})i#dK;6;`}w-^%`NxS!yN&*uI7`&&I4~z`D7ll_FDqi6zr!I-<-alP*OaEx-Jv;E>v0i}<_)=~5K?{_gK2W2&+{R?64(3u`zh_Q384eZvIO_d z3;`WKHSj(|iA?aXI~a&b&EG_rhymg%;x;jJrrmtXo*uB@@;tb9sTnDY>h?(d_ny9J z%15j=G?Ua~u`Q*!p!NqX7S%3$M(58D39VT9QMQg;$_3Q4nwwcl`Nn%p19y{tOwLYS zJ+s&z`drV$ekPEc95H@h>n&z+ZZ`~ZOaBUKEiD{WE1qWeqo8f5z5MHksX*sCg(W9q zO7TpAk#7~J8K-50nyLxeDJy(GNng9B1$WkYlHtl~W%*AAoxIVG$jjHsH4Pho)+2r? znl(6@k!Uo7nnIS8kmn%j=h?p3pC{&Gy8@KP?2GYQO>gWp|2WOG!aEFZcYy=wOM-5} zo&busP{277?;_fJ{?@QH7>IGp?ggxHHb|?r?lUxjwq~;hn|=!Fs?stHEbFDrUjvRz zYL1Q_{&ZXE$3$T70Y_7E`1oQ&G2XT#&Y${ZD$nk~Y~e^xQ}P2elskfYkJ zBx9RuqiJrI#EzJzJplm7V_RqX(<(B$NY9(z>EtHSGcU{ZIx>T`Hwdm1r(W-Clg*ok zp#5fP8W?FG_C%+2qA8yUsu!lC=eiov^52w$^{02dO9Sm%+TEXsjavZB0d zL+!JF$s2WR`4l0$9_cdC2vudn@^*D{oZlp1W84)URFT|K&E(&5fT#_YwgW^;3LMGz zyQLXpWx?k3aQZ(Y%GCmA;M#un#Bl%9S)TX1WD~x%bNn6=sQi78i#vm%R*lkgFZm1OGbPQp{(q$>7Y9-LY*6KPfIobzHWGSBj%0CCi*2 zHf>VF&I==Q21(;xqeHd{9I-fgXWjPcSNwG4{)eUTh`*d1l~`$?zKT-nKmKU|z~gea zQM6zI483>MzvfXrwYBaX>wcV?q?gYll-o5EWohVNiHT7bRn8l^X~`?vXYOd6rhBeKS#oCHAEG0^AMAfd4)66k z)(q#|LGHhfiAYy2oB6n;l{b_FYvd^Zu2l%YOieHhMwu17MIE2q5?XTSF<~k zK*YgHP1A}FYP>5rI?Ag(&|pQ=C>3GqkOa(c5KNBZ(WLP>aHLba6nUt=1?@0q>suO6!O6_~!yk=DtSX_%u6|iJa+!`~ws!wGyIS>So z+?j!3<0Bltekb3y1cvYXp>-T#Cb|vqg4(}--!MM=r7~}Tmb-PB*%x3Fd)W%^4!Ya} z8}RmylX7{Hc8JCq0xTE=Eoq|0YBmx3cbz3HhniSP`*!i%j@{N0wcY*SGQP6ABhlqs zG)qgI&4w!+L`5Sw%ysU@P*F;MzwB|G4?)Zb(VEa1PoEbTG>Mw<8s=tnsb99-7v4sJTw4J~~AFwrEepgg=K zE;GIX@?^q+6P~LE-h-{emgkFcj9J#j{H}mg{w8eq>?n`nd!|)gB(C^X z425CEe`gAQW94rf1Sn)*An8VLE8>pnWP38rDrkd=0V6Gy(RjP}o8{~-xvubXL(&1e zj_(|a=|=@!j*j-4TeZG!US2=?@w_x&=|oReyoz-8p??cVk=lXf@9iT`bBUqEENY?H zQv8+An)r7-A|Xzz=kk+Y>xgpe;z4&jzq$goO|6YJ875tuu{?w>a5tL9)=M__JR70W zPo~MKP*0jTcoa*-oiu2GfeA|3xm_6%TK5Z|jD=t(_&O*TU(Q#CS3J4Zw$U(WOrd{g zFv8#UiT?LK@#W7QpI?%7hG{c8QC2L;Ho1f{c=Ybgh*oXIH!_+0<`)@bb$3adGC1jXc}`QY5T!-o z&a^z0TEl~RZESJfl8-7NCOtC$TAM`W;0Roh{`(zUd6pb27fXazPsVTIkHtBf&|Ete zc9MzC<|z(2V%!>_d~Sn){{_5UlQ8QKMxa@Q1}+U+&KRytdLE%Gi##?iD{i1@tC1!j zO|)>c{Tj3B$eB-la(M=#gg7Q|ZA)p>IfWnx!V|wHUVE$QP7>7XQ@hqUm4gFt!Sk<0 zUHR7zd(TgmiV(R9Uo#eMxn0z->Dwy#aAhQZQuDT$J2PZO)`y*bHnuZ1G+zpVc1vHM7i`7C2-m9qZFE{Fc{? ztqml-rERpH>!0f&QlxLAyI5ygD*~__W@EEGY-Cn-a2)|Nouy&a{-G%F{ZNcKF)%tj zMs8w=&(i64Q%~I4E6QD%X~WS7yTspNd;OIJ3&31%7jmFhA!lq#4wV|OQ(|7?OP6tKvA5D<44dWz zpC#qFnk5Y4Ngg_FqrtZ8MsQ8%XD!pKD0PkPc}8&eyOp?zD2wEH_1QOdTh4q z+8;?;^6bD9JzLn>z+i#S=d$t8tzy^lGBOXYdHzJm#HUj*1Ui#q9{u8iouu45bREKb(80m_5R( zg2$XwlAO1?m+ZW@oAT69Q`dptSthbW6id0zB}G~xfNz4l1u^(3k-?m5ssoquwUI6W zzoFvl1eZAn>%B3$}WRK%2cQLUYU+s}KMsQ(4-6XB~Uhaqvy^TT|0a41bmwMd}|vNnQLnE{fjrhq_! zh|9kr+DZHtFQdG+{E4ek#t&=FHD5b*@@}%1^r9Q*yty#&)DO0^_%RbN8-d5B>=&^^?_$~g)FKxQ#N(;&Kjc#Aj`B5wIL zg9pnQ0^uce8gW@I!qvaZH+w$lK^-_frp!8+#z!%CH3;O@nE72TP^C}9Y@)5tyR7}W zQLA0ELw={#Qw1{_xsy8$y#JtyoaXyJx)Xv7qYm-A5081YC#_aFv_1};bvtR4iB&NQcmhZKZgL(|UWqZI-`hi37&F5(%aBnczW(s!G2GiMm z`)}y_BOIlMj`msCm74_lfu}h`P+$aMIM=bKj}=(#>y{{-(*rrdQO zhtcG8j})eh{fE~wrn1Pi4L|ic=rrD!7M*!jX@Nlhw71t0Y<5A>LFa*yw2T3dy?>HX zePCJ_ouLZ5aU&ZfzcYp1a(}Ng`KUkSI7PpmhbHY0Y#4r$4%7qeM0$0QS2R?=i~jhj zvhE(&;O`(ZIaUlmJNkt};4Q!)Ng1k(Z5TqGQ?I&4qKx1sak^~3W&A_H#wN<5Ui@s; zXe*P8mX-!9#qafJ-OwN9Ke1?`wrRyenskZ&s-l9Xr##15ogc+KR{8du=9V`xB#mF- zOdkGBc3;zMcY85#pO8&*E(Eb=e!%TsygT0>ajHrE<=`~MWA0rENK1{~y2YfZ3+9+Rw0Up5SeEfeo!4C-h1>89YU^78Q1A}G_n z-=64fh&IK(rF3*$Cs)~jc$Lg@in9`!DW?|QO%qSV-1u+sqx9RP;(uNmddo0RiE#K= zr28-0pEGfZM?+7$I^eMhnV@;5YMSq5ZXFlOD#Y28iFmO{idpMfP;z)s5d)1OG8*2mOnG z7;zJO9dI=@V?MQVTjU1RCvAG{Y2;d2^zrM7SoP$!f3hvzsd#Z(4%={|*wohYh* zoyMtmu-84gNrNaj|G|G*qAbpPl49Oz1xVJ zjL=j<88tmL2@)7@vAmg?%>yTb3UJ=%ZkaZ6*|EX*Uv%+)e4h%dfhFEi!XX{&?oDx? z%nt9cNW-&>`Tv}EBMHw>NtHVj%{te~y4tT^EI&KGKv?UlnN)Y+Nr0n=Ue=fi=AGtv z3nDy2@4vnN)%fTehXKQmh8#4?9UnN#Z@Mc({J38$++M6lm)n{8vsH!#!;?N`tTz!^ zOn*|!gNyW4Br$ZIu*;NRDU)KlsAPPW+;DWW6YWnQtP`1KhSJ28Urcsw4DLJWaO48T zSKaXbYc-bGuU1Z?iFf|2YbSn+;iR~QwsB%DwK9y;4_e95|H&9W3L79!eauyH$Ei^i zl$fbz2Tk_zxyc6+W89}M7!3VrI?zGb( z8jp7#OeF)^~X!@oAuq^^KE< zt*&CW_FDO}amuKqcQTVkOX5h(!AxEkZ@+Hkdb*ZMBtb>I=WxmJWw+?=1fx~o==#-8 zklv+D=hCns$4`{a_tp0cpL~kV{{LZfRQvDG%e`8zr@O!Y@P4Qz4&#m$MsrZFS1PMK zm&#OCz3=fKN$k{V{nz#IO>`U<8FJm?iLK5^)as>{5F^hzwaMxKe1vRV!0@etc%rjo z_%iIiHW6m6C>PK4%*wh8_f5*Pq}I0I*Uw~gRw>lZyc-C2=f{lEfi5)T|IvUfA2sko zq4Tf@%dRKZ8=T+Df0`BM`crBH?BaVCW3ZG->rcA%)4n%QFyK7L+GYtKu3|$&ja;j z2PZk{GSMT#UI9_(_uoCgTFajUov61HdHMAzy0>rq7>>AZONPb8ji83BRkyl{8SSe>n~$#lcYZ1vQrOWN_w#M~M7}MSNaKUg z>5{Ympw1Uz^9O5YLHa%q@e)?SRdp3zI!sJO>GIc+5U`BPh-BiD^c^ZuXho%O6VJW5UPfJ*5l#su+i`UZeN zT%>%V1HRpg*-8;|A9tv)M+W4Y>;0N3$)S1S)E|5^qrZ?Z5h{(&e zKaYB+tzPB6kmM6_Tpm-3)t>hleR=AQ<3EAw{8zFFdRhbRiJh>#xA6!o-I6eibyA2+ z4M)h@sQTI`lilhr=|)V6Nf(zA`1;Hj|6;J*Oc75Kg5RF&h6302wGSQAkfW&c1(LR# z02M`tqtD)nMjMwzUN6t(wBdJ3WCzBx6e{R28zbKSrddJK`}#xWl}2Kg1QHgUrUg5v zf97_fs4=e-YRZ+PnHak*mdi9PrR&&47KDYU>Jr$q=!Rb;|TVwO$zDS*v zKZ4X-i>|c?ctmv2g)5#1Uvd^YsW+TQ1KS%=S0D{sJ8JEaC|NLWZg(NT4z6+O-5>8 zpFtn>etU7ixK7YHxt%&afmGHz87nC}Jv&;>wKp%rUkMHam5xZ(zMamP7GVjA<0s*8 zQlnkNWapjdgxlM}sr`EWA3xvH{fDF3qBEiI9!EKchmSWkc@b!RB@CZM z=ug$|?Y0O>)!rJomUAr7v797d#)}zktfR3VGl4TB?2&l(30TQ=s--z}p}Hz1Z+5#Z zC7B7VR+Q-)lrw_BC*AN)>|WBEe+TmXE#IO;s=B>gUCze)Gk+}oeLqy{aQkIpvY;&N z!+A1@)H>(2pcc^~qVQhzeUawAXYGnMREX=jG;yF^+kRA%@zfVnkqrY!O#;+KQ=xF%(I_bugFqjdGM{h`RG^kyf-)p~ZAFTjd^&dCrVmqMQGDSa(hpXQ0(ZH( zbS6i0b#z1M^F5aCyv1ZZKWgKkIi+HswHq>avnWX+#;B(*cBPJTt{KMP7*^2GAzdmq zOGOzId6hl9P zj^zHvimf5uwT@A+Tl|WMhxia{vOyL3R)zz#{7_S)Pr>rjWL~(+Y_lB^s@|v7p+rQ- zq(TH$WNFk(kI1UV`;S|ew6VA?rbE>2PJeR`Lk|AN3aRiU)+L}o`2cYd{j6b$01Nca zdqQn~eIJoi=6+BJ20dGxuAJ($v7p}4DyB@BL-h|UXx(^Nv{vKoznMJ!kQxhIvcynI zy~ZmHKT5&g$QLt#I3v3Bgd(&JPAO;soHVNQC<`zSNip-*cnB`PAB13PqwiBpq`KCCcorqLRz2;G zLGk72LMPw3N4{5qU)NsOLT7eb$drNh9}oGi*d;2%IEZxT5K87pA=o?oV%Gmep>M8^ z&?E3f*zOVqkwA=rfccP%g>CP7uqW(xd=Mx;3yKbVZdX05Cl(QB+jGzSNaT$C1NN#` z=FY>O@yQtb0H2KUk_?LE3I`v85@ZJ$=B!E2cg=K@);NR1CIj|19@DWz=^0?{eDbu(6?|!lh}_jW$;(64AKb96keF{ zsd1Ahpb$)YxjzvFRWSsG3T*v5s#5Km5Fe`S@MJR##(}LTB8W@wJW&7HwQkThvP3K*L;M8JSBF51Pr^X^5%gS*BEf0B`XdOQ0^s zb^We;V3h*(FEJI>K0Go~GZNwHmDAP~qisyi+bGOt2{U0%UV3z8L1!|WMDcfx7VVBP z_mWtUkLGFO{kz-h`X8rU@-;p=up@qXf|t?w=U1eFqSbH=_~C}c>-F&A2m{lVUYFCc@))#=Ylb80E3)bB(?sbZ(_Xk`J?0g@O49r zA;wQ14~fYR*+`;;2-2o1Zhav4L^r(}g`nwG2fPm~PzC;3enhhRklxf@T=WwPc0_k!fcwPVK{&I z=cn4c2%-Q|ur{eLjzm8Ed8bp6;F)sgY17{p|3MiHcRIxls?o;gj#+=TZY&Lq0{&+`@D!xo@k}K8*Qyu{jlczb%Ds6aBAaUGSMZR*AC;o z%aGdeN*$prJo!hvUYw#Yj=+Z*qV$?r=S??3*n%h5mn#-wU^Bg%6sl9P_di>NOF6Uo z?&EWXnz2s~IBaeaa3f~YR-5stpN;kB( zi69g?d_{Z$^~reL^`94X?)b@fuWLPL`2Wyku=f{eKqlmd(wl`;azb6tqBvYx`bN7pBjI|$C zr#J1fAT7=vUb+-B`99Bjqu}$@ zKiHmOlUG|A5?V4qA^3vyU~C3g5lEkxYtPd~1T$)BxIwtlpL>ppK31X6&C_l^pQoGl z?4NgcLW@)|r|+&gm)$K8{>we zni;t0ampV&`|;rE|2C_kyXsS|c501CgT$`u0F6uUZ*lk7RcSuDh%B4E^?W>A=8o8$ zzCg}y9gSEtNbnII@ld#NOItM<_bJ!^wP{k$f75DfuZVxw=b>TXao^_cr2Gbz1r^>A zw(3HI^GYKLh4-iKuCZhSgk;$r!avnbQEmLpO0@F8m9eP(4QJWn+NSfxWy72VxToMU za!sCzddBtx{`+#Le_OKKPIz_dXet)^zuHxZic#X$ZZ=Jj(}YQ`JJ?5-(_S|LZ}u5f zC?BqcgP)o|-`S{*0wklS#>3)uRKwrsOkzScbQ{`G?i51Ty^fd*2=ge zfP_;C$+b2nOv#CMn&bnyH%c_k(=UciXta#{ZZkG4VIvx9wQz4g107nNN6N9o!# z!2(fqGi?K3VZeK?i;(1PjmEIJHS^0oK~ib90~^WgAFv07HS3dF3FMkg5|_1Wp`{3| zjjXVt>}C){KVsv@`IITAo0`ji0UEl9U62z^N8}d$oGdS(R)pb0un7CgVnS?;`d~hB5Jqotnt$OKuF!z0N;DM8U^i~C>c zeJ$1&;K?OQoukadZ8wf*xUVB`C_tJ}?oi42<98bqt5!u3Z;iq=HGp9kRPsE~e5YU( zVV5j)Gg>|9r$D*-g5RV*>TYYOwO?3$9l%9KRaz!atx^oH_c z?GM3=@oi@_Ecx9~&oj}x{;#$YQQtX?qz3mq6^l`i+up^oq2DOg?H44+q%US)O^kim z>Ljf8+wB*TaCH6mUP&v(rvT29mUvu!=NWMoNs60dMTO|6a|m~s-ULO7WRnd^$>jx zHYg7I2>s3tI;79PFL3f5E}y&op>cn-c7o1w4%>Tq2jTj_m=`e-311Oyo62JvP<6Rw zZi$~+4kK_|$RJ2tm-o+4UCZ{@fA;)gV!Yx-3+!UFpnS20p0WMxtZS7$3g^C^eJAE@3^0xmayE&%KP`^bUGQuYPiCtF5 z*eSxBd2xq;Cl&De1g@@0=>k|#pP{`&GG#HX^4*p9HCmFOTW*h^0}Sk4s5}Z@6a~!S zwoHjYUYR!*=da*1cs*YWvNG{4g4EvE#{g~e>8b>r_&`z8a~xEr_dh(7&L^AW@+pZ{ zg>%!ldG?%A!q6D#apho`otj6+{uJ3$j-?|CUiLZo)`cB4M;kcfMsDiZMla>i{>%QZe< z#NfM#eWT%dD-58 z{dn`TdxqxB`i+v?B_CViJf9bx$O6D#MXjE>LaXFh|MI>1uMe@Ic*1G63JKu<#zAPbgx;SUw zNuqFyQ!85_kh(~v9X|DNdL`b6$`_d?j~}aSfTd*Zl8~W zLEsRSw@rAxF`X|JZLgc6oqi)}`SV59yF(t?h4v@4;==b)D9+Jv={hLbgu7(b@EhCx zkCxscdo1(Xc)}Jg5Fv`AR-k^8x{ud7Ph`5Q-r56TcT^{A?!lqT_r`Xm+1!~&~ zbI9cY9DpIVqT(rZZc{;e?oTC>k6@(bsB*|Ks&YSsk38A59;NOC%RBg14)a(GXr-)~ zmLUOn)4{vW5#Mq1EJktvJpEICi@bwY6LIwqqaSM%tIO#I`1<5}x^y8Z#84sj)UT@} zX3|#u2I&e_DP*{1QPxn;PD92&fG?tp{T$vEu=m?g7k&0XGo_lrF1Z?EZ>>IKSXo{R z9hEZnr5g>(wK~}RY#7NwBZ;R~34iAib@%hwqeOJuIOnMywtZcG>!Gs3D~6CFHt~a? z1P3y}?TwF?71cLF59d~=OPP|AUS)YKX+i0ZF_+yNB8NFtc!SANPCr3u@B7Ki;e}PU zSDGqRf2SC(D0i_PW|6Iwv;%cx10ij;B&_h$(G z3T}~u0`jn1as~q?;Wrcibe_pr7u!Wy6UIXtlf}cHbFFy+nJHMK{e+f+MtC96Q~Nhl zY{5fduDpbtw09!5;Znj#=sx|VHmTZ;U5${HE%&6C$*V?PI#2l@aMHY%iJ3GrM&!NF z$w<+NJr%0nnV5k2wrnh)p+4qd?xMeAUp-O`t+y0nHUGV-0UQ^1r`_+hTT=tRJ~RTl zNxPya3l`bj%_gQk1y633O%)_T=oPiAjWFj4VhYFHQ`<)htN|&m%Y>}L+o&)LFc$KL}ICX7ql)T%%&cw{;y-9XAk^U2r9;HN;wJ@3x2^V1f$h( zM&UW9pW5&wr#Ew7TJX7-$2MG)Z=Le!90`qq|w?v!_{ueuDTG|{)52`sdo45lOUdj+HVP2wvpqw zsbAm)B>(4=dWTN6c&TGcQ@ZSz!>INf9TCTl(&>F$K2vOgvRO#?Z;cEO^AAsSsbQg# z@;uS@L-lFhIpsaCSh9zfx zruy&nHSVH5Hgy}^Iq;&@fgxV65B2axHV?PrIhFXjt0pa-fBn`!{sD4r6wqsz=>ojr zozQ&95v&GGine;OwWq2pl?OK|w95=e^fru!*VF!it2v=K^|FRb-xf!;5=1x}t^1;r z36XANTy|t$6mPBIFrs8~BJN0joka)QHa26#^K9dOp;%NHYX+JfUo0DB7V@U`LkX*R zgBNM4YP?ElPU=Hz7TY##?KeBuAJjJcy3Fm}KkbX?Bv$Cq@r9xrPOBz<1e*@VjzPi9 z$JMj6N&0Vq{aiU9aGg96R6Py-$n0y>7!^kd3!o8MuM~q^_FmI~H0U zS;QLOTct)ys01RcPc~4u6jo5V5fBvhfW_w(oNXNA-x zRpud>VxEj6wfUc4Pv)xk|G3ffYGZ$C%(h9<wrH$j&*T5sBh2I2j=nL)W>BP?mjBxjT8w;D? zaHaj;Hk5Mk90b%_i}Y;h#6fLKjyb+s!g>LBkK>0{Pe|t{@;Y5OTy$B}VI{H?x7Ep} zG1^12(EHKXQ8JR+%UgfEjm`t`KvWr{dN$;3^BcjE@R}4oT586>j4Bbj1TAW zQ)`uC7Kv1WTj=c^&Go^z6)Z zsa#x|lg~aBRaUufyVhAUe#w_#tw3udg*vYGP@c@cV^p66So`5iA;0gn_db%}GBawH zsx0HX`{t+Xaf)?a)Q@uzO@cb;`vDx6lzSeHB zdw*6WVPqFSXy`zEXm6>P_QA{sxonQ7bz4tAF2)LLxP}6hL+q6(q`DpnrM&al;F17% z1UHQeN4O7iEF|j!yxD?d&Q5BK6pnf^kt%$NX&byL>f!N@y z@1nln4ZKpdQ=|)FvHC}57)7nSDF4yN1?YFDHEVCDoA)K5t7|`M$c!BI>WHD)LeAND z#-)X$f4xMBeyNE!MAO-*y-fu^Z=l6{7{3jPKtktfm##(K{c+7Ydu?v5qK z7!=9M4i3gEmB|mV&48NC3dG?;;_gFboPlFvl}x|`eeY#gAMIA}K<{~5~$WM-4-olOROwt!!I!0;`{`ClV0FuMd1qo5LxY%od*ZHNh3gg^t(%&?8INV z*XJa(pHpj4@F!K(c1hqha_F6r+wTUyjP2yfpWzDZ(mDP3x539D$1uPN=;&9(b-{D9>p#f$b(dhZy z7w4kn3$vjg@Xr6uoj?@`&ZED6=ZfBGky~LuqnaT$NWoUkoF*&FBQky7;Z@#fLotvF ziD3Nbm1X5U%;x>Ur@i;9VJ7Yo2pHIpqv+L-efsl+_Nvud%7zA(Nhr8r0Q&K>^1kv=JGk#pmQcSUeAGhBrL36aJb0nE|j$*eB z6#a7xj=_T+_G1$|Iln6(pQUV-!i=XJ^7PqKAs+if!}!#O3({RoqKcmtkq4Fx7LMA#$KxNn z0dCBQO)IzE4OS)g=f6n$5#)Pg>tzTfgO@NL4+AZWsSHt~(p>}cIibjFX=i~YKNodj zs0112$=)*R`px{em1PrBwCR0&au!m^i~MrCB2E;IhPZOn{yG{7roLUMAMtfwbZA}< z^l(4uJ%t|3yF`B+cbqh(O(x6}bVz3TyQ1N$A|f=$=TEYE)LtT99Rh-m#4R|s+Z}5$ zo&Z&sR)0ic_t$O+l#hoBq)QS0)}zaBBKG!70l#c75i(`~lk7$$#y`I0W~PW~E>bQ39SU((tk{LG*$(AUX#wC{mDpa?oO`yd5t80> z(`J@U9ECB-CRbBO(=jy`Ab~w^&`4@_}M$Hhk|8`#AETaQb zS$dX!Hv?*U3$$^&Ty2A2|epdQ$zCFk~B=?jC25JK6r&LA`Dsr zGhgcZNvo;jplwhWetH0a=m0&f7X`FlkSeWHw&L@irY;a+^?2^Ofm+I50bHpRlX8Km z7d!c&Vg^Y5I@%ZTJhi>Kx(TgY1X#o7b<7BoY(4!5;LV7^!cX-}khn&+cCNKmIG`0- zsKe5M;n*@zXw}tZuZ9mHqCv)bbx!#xn4iWW(Pv@K`y{4!YJ)2*kCIU=6~@FWqLY$z z{_ItxB!R*JpC%2&htdhgw&g271%EY$8+>?2`Ld8GxbZ=?v6I?$9a+ z{6q@k=yJXq(g;U><;Rb9iq)-h@bt@yL;=`&WlhIuM9MSYSeiJ+K?*&C49Z6b4c@n& z$r_}uaGlXDx&{7dU=xQ;-QBX0NBjOk2^!OhE7%_(66B3cc59EG#Lpj7Y7ard>pDR3 zunvaM1C0$XTDtOF>BG!+cHsfn_}e!vx=}MCFxW(ir0bx$`M8B|B9LvRhIH|`+~Ri+ z&aN?hd6;)t@FTSATCzs)e)f)IjN3OjZUr_WJNGvcrPo6|EkuwFZjjb8v5x6a{^?*j z#3!)|vXf6sHCw3>GglY41?D8aB%3q3_8)GTK>AbpS)eq0;pvu9vE_KE@v-G1HFMja zv;aiNE}}g;dyx+tG*Y^X|HbceO6{Bp4jxx6oW8dG{=Wv7sVbYj5;t4W8Y8i&phwwG*KxlT6CnTGalxN zo?^_f)gYR+ONi2c@abTWg`$$USj2e@T8nkXHYqtssz-koApDRE@a637<|$Gn%O7xw z3hwTh#M+?FH73dXy0#oeIPzeL@$Ocb*Tm-;mg{Ah;bPmpt&r*&q5sw=rr_*LDADDM z25b4(E`vdauKd>D$NAbNRbD}?XB+j(C>JM(B5y6LyPZHGV>3_+Qcr&>y?J8mr`fWX z;DIP2(=S{rpBocb5@=RBBh2*QAzTt?gFCikC~~NT^EkZj^SqNF@t0hS$59EHKDp^r zt?&?9SjRiw1~m!`bc;9I9yB*|k_|>>~Ai+O&Z8l!yTSq@3y^=Xi*iIIL!+ztm zr{f2f&U-IL*kK|dI<9I1{F8F#We_D+(ZX(GYIO$b-!Jrz`yOzAe09!34lwWxMA)G& zbI3lzIaLJ^-Ir0JE zZvFH0LRL?Lw?%pj&z(%$uYVm9(V<9ltJXVWUC*_Yaf++?9(_yWj*7GoM;fyt|7tkh zHD4DD9vKnH;i7WQpf4GO9JJQkXHd_u3C#|i<&U^@BdjM(6nSg0bG zO8sM#CdIm_O%llMmVK#oWQ7f>c~u8o35&UW@5^bXv3UuoU)69bbp2ML^Z=CiC5Y{q11f09LV!-Y|iI(`JE$Q^u zU6@}{+zdn>_BcycPE%5jvZB3R2r+Q^ODKD;(yjtY1|MX!U8HROV{j-fytK9auF?_n zmCEpy_Sx0G^UYIhzK0c1%2Od|bGZk3jiOXbiqtvoSX_C|MU9Hm6^B^OSQhg~w1@DJ zKebQpvgVG5$OGJxI0TWYsI43)RJGj7?${i6=Q8%xUs5bCTGSYni)-uqzq|W`N)oi5 z#Uz0#mtm2K>X|ckYZ>0&x#tZ;{gf@nS0f?|Ec^sAFyI@~NPn^bAIRpncZcQZ9o- z+kzdmg$W$gD#|jjzm$?U*k|G9>sc>~Ac9QUh@xwT!-Z#IN zynVApI`aK&&#H-|BqduNG3#%FTt4qYGdz@p%ibcFJuQJ7bCOTRlgDzs&qtmPnyjcE zWev;R<7O#mhm<^DL>6DRj57(GZ`Z!h<^J0sqHv5WUp`E#GUVSqep98f)ph=gU9;U( zLXQ5FTc+ITB*^%Xm|8xx`ZX=Zd2;#Rm2+6Un9%Sv_NrA*#wBH~UkhP;IRuv{)jgt7 z=5S?Bd2oO~i3OrFU2>O5)x^2*xqs?E;$-PUHn^{dm#>Y@9$*6YGLW~h6XXk`F1>_u z7VscLAx_aw2SeIM7+hWn;J zW0S|fJfyeSwwbUs9yVni0x5lbv1mYZ?h+?mS|t zi!KGN#8_-ZAteB1Yy>lSBa6$S)%%_COxrs}wI7l6H%gkB@54I=Xkrs8v{R9^jDa?* z7(Sl+Hw;EKzS%vLhFu;Isi*J_(o+i$nX&e|<gwujzfJH zR_Vry{FIGcz*%$6$!h$3ZCsArKHyux-oP*UCf2QWQ(2onTo#-C*=KU~=;ipR zLJRbV8%xS{pS5(H9Z`Aa^G&?p1kA!2S$LxL2lqeei-$*x_*C}QgrHKS5B)rnP&B!j zRA^7R%IsKLUc5>qJgW@Y$1Ayk!C2_fj$lUAEbI#;?3C$28$#M_Fy*)aBUc`&tSf_vcV<( zp`Io$a_~sXyIPgI8HnurOHY_^ES&>NIe^usF=SbN6HD)>!34PYHdrG3R$y^pG=%xH zM5b>fA;5#+>J(|C93rI~2Ro>#XOIt73_y-s{T_dHBHlT5>{9-=xXO^HWgjc%o#7yPsz=8rs!IR0WC#$ZLFO; z-7$qDZZ&S|qJ|P7DVLgF2A@hSvr=~m=>oLND!dDlv_Bz+cl%&cKJMMArC7+K0s5F7 z9ltPlS#E7c6&6)TfWPShZ#Hg9u~!LLMVdDq9h5r{(+6DvBsyrJVkqbTV#Cb0h$B{2lmHA2iLY_-%|3{330QjYknzHam&pFd(Q zbryTZXs7tXijaQqb?g=@0xL#Pi$~3xarDJTd4TBadZnUW)y2b;N}o<5fHdPY&E)$x zNj!}2ArYu3A8@(-m+vJb+uEB&&o5M$s;IYrBvfAu;WS4yOC1U^O5L?MG{6GiC{s)G z7iz^Cmq0$r(-4?bTclw=;40co$D|{^o^pBh+nO2ng-iDLUZKulbsWMC0NA1(Vo3q% z-<^Sd)#4q^xtYKVVyCkMhLmn;!vJHx`d*2Dk`N<^5FwyGZ?;?^!ep%52=g4gt>CYv zp6Rub|NEtVb09{L&N++e~Vyi z*F)ArF};~y-7ri=U|5vA;dh`lv}~MCKbWTfhDQ;2Plo4YnEn+Nn|9Z%^9u255hgl- z9GL$UGrc^}b{|NrTZ0vpt`R=HTmj=cfZ?xZTDg2N0-$iB?b$nh+W}J7xX``3{D|pf zZ(;1?8de>Haklcqi7_Tq`9|Q8b2?X;>>SMoLBZe8-|imqI!IR{8l@up#*#4lKK2fy z&Gu%xIy;JPYx1YDf^o5{&Cl($TU1SW^ae|^?qTM^DSw-Gzw*`cP(n=~u^;rpX7knd zrPN>?fUZWErem5Yo(R~WwvUy8cYi;}OBrw>&a?98ij}FWo_1KUawE*bf2iJkUx!glld?8uCGoqtVa|MdC|GF5UE zcr6o;qNZ!Px z&3ss?Y>nSNg6G?H~bGfJp9{bGw5feRuy6rq8fJ0)Tkb26&SRUZ$O00iFp^7 zMI2Fm1h?E&-q{2-=B~C^keeIXjz8Jb%jBAe9=|ssp2fq=2xabQmV+?eia+Xk(-u6M ztGI;WmYmG}oKBdZmm@zdn(Kyit%FR;u~yfIv2<42;}@P_+eji7(?sj&nGOcI{SgEM zJ9YPJc`Owv5mJ^Wp%$C$f|qS{%1m=xs%;Hw!ywhi8l0x%abnpTa6^h=gjnoF0V6a8 z)yts*HNT~meb?2ocH6GfPHRSvEFeAqTC8{?x)4EEG{1B-A^UdtND^609Ozvz!OV$z z!hiA5-iwJ5=W2eZRj=74Nb>5sc!NR-8sbYUABs}Ij-g^`GLi$LUU_$31;cq@6wb~`@mWhzpy(@sysxgcM0pPi+53`;S~QIa<7r7KcA#1;w8=~QL=sX%rtJ9l|xi@D(Z?KZi7dE1S2gQskbmL z1m(Z@k>?m+-;V{gqy{%8f%3lNRG_ATuAHaU15RC))_f}db{-FFup9Yjl(%YZtWvVbT=OvUoL5%nels0?t zMWNyJooB71KbnDZ$VaUdH<@tmRR$#Pz`148bNk~s+-NoqD|)=3Ywx(}PB|n@W$xwt zJPj`vKEu$`F{&T(G*l-Ui(KW!nz-ztuqiyF2j}L}5#HlM@A4m|31aX7_|^98c>6E? zIQymkGpVxwd{;Q1H%Z4;>sN~!C`Mmsy>*?BsRi>9yx?l=(<0u>*Qb>tD8q$g=i!IT z^qVw0@DTmFK4i+I6q8R|bv~j**I!dT@ElX>lCuA#P*wCRLx8Rd!DaiOsA;V(y53I( z^c>_W+yg`*?85Q(z-YMl!siJT<6Pd(!HH(c=7X*Rw#^`=L z@0T9}zf#FIXC13+T-=9ej984}(d2h?Q5wOVKF3IvU1PCd2f7)80=8<-Ua{jFx-I{W z(3tuJ5^>Nv3NmO*(LM{e)ZVwedx!TZC;3eiL_hAR@J_-o1h<k3i(iE`k>-$SrD)1g&^@{Uw_s4G3a@~$ zmju2th!5^K=3iPUg{7Y9PU%$)S+?o@5FV|6vaDP~hIshN8)tczmXtGaR1=r8G;CBo zfLwq*s2wb<7B0Zv&&Y#xx3J`DY*{uy1`q46wL|Ku(;Iex(1Z#J?<;_Oe3H>+iXLD{O|RJ4P7TMwT!sj!d1&|5=oO~n70>E4=Mw)QvF7DQ zt6bE?ua?FJ6HQ^O7}~k2fEJy;usaM~P#Y`NuNJdXzu^bj(SUlA=Z`&7nH>~%J`w4kNT+Y_86xUGvXf?F|=}Wsz6`qkMm#L-K zgf7K3T6{$foz8w$c!bFAuWGs9W6P8BBSAhygFa%EuLBbQ*2QQRa3Ts6sEz_v1VB-x zys|dBFtLz?rz8KNU0#Clq(OKrSfbxp%OaC1j`K^J*&nAQ*l)$;WerSxe^mDxq&>sa zu5kh+^%vC5iwmaT&(HyYa&YC1J7{C_4M3bqwDjMaP#=d3WhRHr5kEO(j5EUo^!p=IoEy8xzGE2CwXz;U=iuwYb-j)XDWW>jGNfvf=n;XqwO$W zMt3tO4H-x(EB!uZsZz^M!w!9!wnt`{MhnOE0So$JP*ey102V58Zq@zA?~_r%V=2pQ z&To2RkT^Si(G~s8tdE;MTtaUx-$sN9I$FaaO+ArCH&U-0geUA*>Y&`VL99y}!jj}Y zw&GSz&U=OmJqKd3zGiO-lC08Kgn;I=2XG$p>GNW%IwFylv$6a%auyauZF0J zGXJug!RCr3FJ$lFd8XQsv>t4%J4L;!@r1m9aBFssiEV36g>RlgEYv~^!akV~j(b<= zwj;cl3Ml}+E#T?yD2r{CJJpDp5q+OM{o2uvYrPcAAid@Iiyf@a+X>lVVVW* z7?GilbS7MyS^5YMF8(NL6RUe~L^iTB4QCW(YqdotR#;7OC}jP9-l8z~qnQbE`@+Sk zIB;(KyS3l>Y4xTjA2-!x;NoJ_nxgP5&;4$$fBGbOH_S8gNK4a;N%G1z%(Jf-57fB8^4@(cM%cS(~?r#{L$C4tKU;lG9C^VdW2pc z=X&Zn7MIH-8`uT)-}0VKm!m5`cP--Ir=Ls+j9XYX-as3YNi~5F!lQj{$osoc)z?O@ zAgdQ6x+tqKzhRnrn!~OA(X9BJDC7pv<&7rHT?%U#i_3ah)3VCcya!m9AJ)F&m55es z=_$f0Q{oHV_`zzBuqu_A=X=TRK?ZH5QmG(Q7I!E@xd+gEd0*gi15%>AXCY6J3#!7* zE_<9=>-_Lh=-V z&M~}IYz>Y2^&z(~dHNYQhBVUn0h;Z4R_cvlB zs&q;XX@{W@h)?AR;P80s@=&p0jE z063v}1qv}#m`kGYaI2(T)az#V4AkJ~6&{9#Mc}cn8Kz)v4|2Y2oz%C_!`AnMt4QaW z50~~@&cjz~)UD&w^;u&33qB@fe1n2CnlrxD`{%B_CN;SX@%+q$t zc{ikl4ncHoM9*`CrN1xqxWLsjK!bzRon{k)cbV7o9Ji*IN>d#{TG?>{r?I;yw=yjXgd+v&hm8b?At=U(SuZR9$Jha05Q zu!;@mIyX2fOXSgPBX+~=}b+2k8bZQ?J zPHjA|Q)S=jT{>#Ejc|T>#u-n!-T~*xys`?e) zLwnPiP#jiAd=nDJ^2oT}B2+c_&bs!N`Dokc6_Ivqzy+KcJW*TG6Q|Med@Ret)wfX+;xU4|K*}+*F6jSx-558S2iuRs*%I|f-KQ2iS)7UfQ^Lc*6x}jS*iVpQo+Bn8!iHA0yWB(s_Z;rH^rF2 zIQR1i<}~@*CA0Z4osqZJ3B^o&U_iQ>ElE*c3#%r6&hQdn5;R(4IayQz_p0O7Ehwi8 zVi6{z)>zoV&aeGQ0+RM{F!jN&Z;oTL9-ER*i(NY#PH6#ihHL1aM)Y@da=2>O3iN|3 z+m^b=(%!Wg`SH_+A!N%)+(Wq+1jjQYqQkcXNSwCKo|=T3v=%@6ds|qX$m-9&utaW3 zRR~#bD1a0i*3wIq4!X#YTp|xS4xVD>Xr;O3$m}5(pot67tHFk8&Lb+!M>2hO6-~c> z9`7j?fW-!IxbBK=%P%7Eg^~F7me2rX#Wjz_TzhjWv+F)bS6oQV91J~k^rcDIWv%{b z>Q$*Rk8_dEEa;ZaONQ% z&|jwahS7_RhOKGtfTk!%BpT%b_)YbMu8tR}?PKBAh=Cc4@n;ZbdLzUI|&7%y`} z3?r6y;d}sJ`jUuLK!Lc%u0=WLeOW7>qLY$Gh>W@|)leMcwa;``N^pPvFn&M3w_Ex( zz$%qCQDrV>oe4D{l){m+9DSlj-Kh^R^{{yx+tQAi8GPytj=8+Z*0+!1R}Po2*KmWW zq!JC39o<2$lIf;J-Wf!(zE_0|ff1BXW9k8dEH^n$!UDHgU7F+WjxW4t#+j6p6RDM^ zspg-#e9HJ_ow*DxGHLwRGm@%7O-Yog{Q9m&QSmMo_T%LurP{QwMuqACxe01$!Bs{& zd)m$HF1`sJcGzk&{Q^$+i&3XIUTLnSsI9Ew6?V+)1fdf7+kTLZ-ub6eyp$*?@wW_h z+wgTwo+v#+f~9!SJ$&INEqw7)aeYOtm(!a?_eIP5}f4gAkG|dkIAN zXL;j#9#?JkjQ1|(E7%jcGkMSekJ?D7T>JBbSC~bPvcZ@j1)_&CrYAr-?ySuezf5)D z+fo@!>m5dy8t5+V2&HyjO+eiaR|v9`GT9~FGAe4FT+Sz>%I*QNC6}Q$1F*mB-$^-! zlwauS8z=`&N&Q**sgZxXOv_u9mrw03P>);GbN$s@>`WqUi~Mh%h_KYFW0#H(Yyv4c zHO7=N(#25pbOw{QX54U($U-Zdd3$Q>cmR(@QFNWjg1f9^m$GwmKzd@`>yN$`U;e%BL~087d!GE^ohOQ3W_YpcICHF)%2Ckr>=CQ!lOTcB)O~O)+uE4{s?ve$xt& zmK%`vXM3NjO=cAq`S`4@_ksX+f^nF0y7n1QWfcTh4XS|s5G_z1bwc&r9>dCjb!T+D z(?agQn>=w`X_Ga2_PXIyf*rDhE`{!4>9(`Z3xUoPC628xnSo&fKq@@` zxv;U8*dL^#1nxyAr*28K>>P60Y>-peKfzwa|51heNi(o-d+wP!k(y+`N+paBMqFQX$ke>|=kpN<)cdDakFWu$+ z82+~Z1mv9)r@@!dQ1j`>$VJPLx-elXop_Q*NuM9P&Q1Qd$gMl@(am1zBzoYiD3Qkh z_Y9k7I0kFf*!c`5xPbQW+V8hALweHw7`ns>$>wWoY>pA-7xd*n35wJGXB$Df^v9uY zN_$_frgPx_EGv^$7t9FagA?l!2lD~tAb4zAH}mDLXTN5b3;_Q%K@;qlB6_r_=RCm@jUK-?SZ zmTP_{!Vnx{hd_c;JEE3VFxS7AkQjip46sGb@3^P+bNKJ!vG&8|LbRRK+ziUlyw1G9 z^XrG1D_E@)j0Oq_YY60OoNnLfZ5wW0WWvzzPf7RDD^P zF4WO~8|2glvw%PCA`YY~menHO%vCYaXng6X_)n_@24b}S4=||H-J8XlYb)D3IsCN(2I+tiju3?$n&rWs6n3cPRadX-%SML@)35 yhBw=ymNf*nZilV+@u&ESJ_Zc)|Myk#IgaXV_igN6&8emVK9>!V1~2uUWBv!%GJyvG literal 0 HcmV?d00001 diff --git a/registry/azure-cosmos/metadata.json b/registry/azure-cosmos/metadata.json new file mode 100644 index 00000000..de688778 --- /dev/null +++ b/registry/azure-cosmos/metadata.json @@ -0,0 +1,57 @@ +{ + "overview": { + "namespace": "hasura", + "description": "Connect to a Azure Cosmos database and expose it to Hasura v3 Project", + "title": "Azure Cosmos Connector", + "logo": "logo.png", + "tags": [], + "latest_version": "v0.1.3" + }, + "author": { + "support_email": "support@hasura.io", + "homepage": "https://hasura.io", + "name": "Hasura" + }, + "is_verified": true, + "is_hosted_by_hasura": true, + "packages": [ + { + "version": "0.1.3", + "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.1.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "34655ff615be0d5738ffe1811972776808e9880a6fa3ec673123844c648154d7" + }, + "source": { + "hash": "97032d1a41fd932d637b5ba24ca6611d9e1f4905" + } + }, + { + "version": "0.1.2", + "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.1.2/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "09ce246a9039d2aaf799a7e0402b243fb3763ba802535348a9fee243de1bf1b7" + }, + "source": { + "hash": "f67b2f80d64175a055a9489d4e59f30d5d3870a0" + } + } + ], + "source_code": { + "is_open_source": true, + "repository": "https://github.com/hasura/ndc-azure-cosmos-connector/", + "version": [ + { + "tag": "v0.1.3", + "hash": "97032d1a41fd932d637b5ba24ca6611d9e1f4905", + "is_verified": true + }, + { + "tag": "v0.1.2", + "hash": "f67b2f80d64175a055a9489d4e59f30d5d3870a0", + "is_verified": true + } + ] + } + } \ No newline at end of file From 9b1ddfe46043624d8f8f40bb90fd7cc54ea1a47e Mon Sep 17 00:00:00 2001 From: Brandon Martin Date: Thu, 20 Jun 2024 11:14:35 -0600 Subject: [PATCH 011/135] Update metadata.json (#181) Fix latest release. --- registry/mongodb/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/mongodb/metadata.json b/registry/mongodb/metadata.json index 7992477e..334b069e 100644 --- a/registry/mongodb/metadata.json +++ b/registry/mongodb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.0.6" + "latest_version": "v0.1.0" }, "author": { "support_email": "support@hasura.io", From 4babbb19833e1e4f105c4c990b346e53cecd41b1 Mon Sep 17 00:00:00 2001 From: Vishnu Bharathi Date: Mon, 24 Jun 2024 21:36:35 +0530 Subject: [PATCH 012/135] registry: fix elastic search to have an allowed tag --- registry/elasticsearch/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/elasticsearch/metadata.json b/registry/elasticsearch/metadata.json index 63c5caa6..0cc4ccda 100644 --- a/registry/elasticsearch/metadata.json +++ b/registry/elasticsearch/metadata.json @@ -5,7 +5,7 @@ "title": "Elasticsearch Native Data Connector", "logo": "logo.png", "tags": [ - "search engine" + "search" ], "latest_version": "v0.1.1" }, From f037ba2480c5764230717726042b6eb2fe2156d1 Mon Sep 17 00:00:00 2001 From: Brandon Martin Date: Tue, 25 Jun 2024 10:47:29 -0600 Subject: [PATCH 013/135] Update README.md (#183) Update path for logo. --- registry/elasticsearch/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/elasticsearch/README.md b/registry/elasticsearch/README.md index 777ba035..509141ac 100644 --- a/registry/elasticsearch/README.md +++ b/registry/elasticsearch/README.md @@ -1,6 +1,6 @@ # Elasticsearch Connector - + [![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/latest/connectors/elasticsearch/) [![ndc-hub](https://img.shields.io/badge/ndc--hub-elasticsearch-blue.svg?style=flat)](https://hasura.io/connectors/ndc-elasticsearch) From 226cf27aeccab403ed513b2c124392d9fe988022 Mon Sep 17 00:00:00 2001 From: Toan Nguyen Date: Wed, 26 Jun 2024 15:57:53 +0700 Subject: [PATCH 014/135] Add ndc-go v1.2.3 (#173) Adds the v1.2.3 and v0.6.3 of the Go connector to the hub registry. --- registry/go/metadata.json | 44 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/registry/go/metadata.json b/registry/go/metadata.json index bb5bd470..7ec5ece4 100644 --- a/registry/go/metadata.json +++ b/registry/go/metadata.json @@ -5,7 +5,7 @@ "title": "Go Connector", "logo": "logo.svg", "tags": [], - "latest_version": "v1.1.0" + "latest_version": "v1.2.3" }, "author": { "support_email": "support@hasura.io", @@ -15,6 +15,17 @@ "is_verified": true, "is_hosted_by_hasura": false, "packages": [ + { + "version": "v1.2.3", + "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.2.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "9573485be49d633ab3a7b39e8777da2d3524702fafac1739e42217caf5b3ad9a" + }, + "source": { + "hash": "1fdc72d31dccae129d6d626dea6e31b5cd3b0b18" + } + }, { "version": "v1.1.2", "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.1.2/connector-definition.tgz", @@ -37,6 +48,17 @@ "hash": "42259e9a9c719131721f0058c552e9b8a4a36973" } }, + { + "version": "v0.6.3", + "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v0.6.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "e6ebd14bc1a75ab384da80eae7a823dd6883af6a574b42d720358d873491f96e" + }, + "source": { + "hash": "726b3fbb442fae62d18840905545f1d663baf87b" + } + }, { "version": "v0.5.2", "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v0.5.2/connector-definition.tgz", @@ -64,11 +86,31 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-sdk-go", "version": [ + { + "tag": "v1.2.3", + "hash": "1fdc72d31dccae129d6d626dea6e31b5cd3b0b18", + "is_verified": true + }, + { + "tag": "v1.1.2", + "hash": "32e28e549f11b790c320b6a79ad33ad8e6df5bd7", + "is_verified": true + }, { "tag": "v1.0.0", "hash": "42259e9a9c719131721f0058c552e9b8a4a36973", "is_verified": true }, + { + "tag": "v0.6.3", + "hash": "726b3fbb442fae62d18840905545f1d663baf87b", + "is_verified": true + }, + { + "tag": "v0.5.2", + "hash": "79788195359a5e3cf0fc8896b61eb8f4d9196427", + "is_verified": true + }, { "tag": "v0.4.0", "hash": "ac27498b6dbd5e803ca97e0fc702f52e2d9b429d", From 269ba3f103488109d0d320818ac61abeb577b35c Mon Sep 17 00:00:00 2001 From: Brandon Martin Date: Wed, 26 Jun 2024 07:33:57 -0600 Subject: [PATCH 015/135] Update README.md (#184) Remove logo in README --- registry/elasticsearch/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/registry/elasticsearch/README.md b/registry/elasticsearch/README.md index 509141ac..7ada8e8a 100644 --- a/registry/elasticsearch/README.md +++ b/registry/elasticsearch/README.md @@ -1,7 +1,5 @@ # Elasticsearch Connector - - [![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/latest/connectors/elasticsearch/) [![ndc-hub](https://img.shields.io/badge/ndc--hub-elasticsearch-blue.svg?style=flat)](https://hasura.io/connectors/ndc-elasticsearch) [![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) From f391f1c22f56ae1c926027d770dd4d682f6f6fcc Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Thu, 27 Jun 2024 20:27:36 +0530 Subject: [PATCH 016/135] Change Azure cosmos to Azure Cosmos NoSQL DB (#185) Same as title --------- Co-authored-by: Pranshi --- registry/azure-cosmos/README.md | 16 ++++++++-------- registry/azure-cosmos/metadata.json | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/registry/azure-cosmos/README.md b/registry/azure-cosmos/README.md index e1961ce5..ee512416 100644 --- a/registry/azure-cosmos/README.md +++ b/registry/azure-cosmos/README.md @@ -1,11 +1,11 @@ -# Azure Cosmos Connector +# Azure Cosmos NoSQL DB Connector [![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/latest/connectors/azure-cosmos/) [![ndc-hub](https://img.shields.io/badge/ndc--hub-azure--cosmos-blue.svg?style=flat)](https://hasura.io/connectors/azure-cosmos) [![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) [![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) -With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in Azure Cosmos Database containers. This connector supports Azure Cosmos's functionalities listed in the table below, allowing for efficient and scalable data operations. +With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in Azure Cosmos NoSQL Database containers. This connector supports Azure Cosmos's functionalities listed in the table below, allowing for efficient and scalable data operations. This connector is built using the [TypeScript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). @@ -14,7 +14,7 @@ This connector is built using the [TypeScript Data Connector SDK](https://github ## Features -Below, you'll find a matrix of all supported features for the Azure Cosmos connector: +Below, you'll find a matrix of all supported features for the Azure Cosmos NoSQL DB connector: | Feature | Supported | Notes | | ------------------------------- | --------- | ----- | @@ -41,7 +41,7 @@ Below, you'll find a matrix of all supported features for the Azure Cosmos conne ## Using the connector -To use the Azure Cosmos connector, follow these steps in a Hasura project: +To use the Azure Cosmos NoSQL DB connector, follow these steps in a Hasura project: (Note: for more information on the following steps, please refer to the Postgres connector documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) @@ -52,7 +52,7 @@ To use the Azure Cosmos connector, follow these steps in a Hasura project: ddn connector init my_azure_cosmos --subgraph my_subgraph --hub-connector hasura/azure-cosmos ``` -### 2. Add your Azure Cosmos credentials: +### 2. Add your Azure Cosmos NoSQL DB credentials Add you credentials to `my_subgraph/connector/my_azure_cosmos/.env.local` @@ -67,7 +67,7 @@ AZURE_COSMOS_NO_OF_ROWS_TO_FETCH= Note: `AZURE_COSMOS_CONNECTOR_NO_OF_ROWS_TO_FETCH` is an optional field, with 100 rows to be fetched by default. -### 3. Intropsect your indices +### 3. Introspect your indices From the root of your project run: @@ -102,8 +102,8 @@ Let's start our connector's docker compose file. Run the following from the conn docker compose -f docker-compose.my_azure_cosmos.yaml up ``` -This starts our Azure Cosmos connector on the specified port. We can navigate to the following address, with the port -modified, to see the schema of our Azure Cosmos data source: +This starts our Azure Cosmos NoSQL DB connector on the specified port. We can navigate to the following address, with the port +modified, to see the schema of our Azure Cosmos NoSQL DB source: ```bash http://localhost:8081/schema diff --git a/registry/azure-cosmos/metadata.json b/registry/azure-cosmos/metadata.json index de688778..dc3f735c 100644 --- a/registry/azure-cosmos/metadata.json +++ b/registry/azure-cosmos/metadata.json @@ -1,8 +1,8 @@ { "overview": { "namespace": "hasura", - "description": "Connect to a Azure Cosmos database and expose it to Hasura v3 Project", - "title": "Azure Cosmos Connector", + "description": "Connect to a Azure Cosmos NoSQL DB and expose it to Hasura v3 Project", + "title": "Azure Cosmos NoSQL DB Connector", "logo": "logo.png", "tags": [], "latest_version": "v0.1.3" @@ -54,4 +54,4 @@ } ] } - } \ No newline at end of file + } From 353656b189e88247bb3265eb3531f9d213136aa8 Mon Sep 17 00:00:00 2001 From: pranshi06 <85474619+pranshi06@users.noreply.github.com> Date: Thu, 27 Jun 2024 22:17:56 +0530 Subject: [PATCH 017/135] Update SQL Server and Elastic Search README docs (#186) 1. SQL Server + Elastic Search - Fix typo: Intropsect -> Introspect 2. SQL Server: Add extra instructions --- registry/elasticsearch/README.md | 2 +- registry/sqlserver/README.md | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/registry/elasticsearch/README.md b/registry/elasticsearch/README.md index 7ada8e8a..52c529ed 100644 --- a/registry/elasticsearch/README.md +++ b/registry/elasticsearch/README.md @@ -75,7 +75,7 @@ To configure the connector, the following environment variables need to be set: | `ELASTICSEARCH_INDEX_PATTERN` | The pattern for matching Elasticsearch indices, potentially including wildcards, used by the connector | No | `hasura*` | -### 3. Intropsect your indices +### 3. Introspect your indices ```bash title="From the root of your project run:" ddn connector introspect --connector my_subgraph/connector/my_elastic/connector.yaml diff --git a/registry/sqlserver/README.md b/registry/sqlserver/README.md index 9f74d41b..c53704d3 100644 --- a/registry/sqlserver/README.md +++ b/registry/sqlserver/README.md @@ -61,7 +61,7 @@ To use the SQL Server connector, follow these steps in a Hasura project: ddn connector init my_sql --subgraph my_subgraph --hub-connector hasura/sqlserver ``` -### 2. Add your SQLServer credentials: +### 2. Add your SQLServer credentials Add your credentials to `my_subgraph/connector/my_sql/.env.local` @@ -71,7 +71,9 @@ OTEL_SERVICE_NAME=my_subgraph_my_sql CONNECTION_URI= ``` -### 3. Intropsect your indices +### 3. Introspect your indices + +From the root of your project run: ```bash title="From the root of your project run:" ddn connector introspect --connector my_subgraph/connector/my_sql/connector.yaml @@ -81,6 +83,8 @@ If you look at the `configuration.json` for your connector, you'll see metadata ### 4. Create the Hasura metadata +Run the following from the root of your project: + ```bash title="Run the following from the root of your project:" ddn connector-link add my_sql --subgraph my_subgraph ``` @@ -96,7 +100,7 @@ MY_SUBGRAPH_MY_SQL_WRITE_URL=http://local.hasura.dev:8081 ### 5. Start the connector's docker compose -Let's start our connector's docker compose file. +Let's start our connector's docker compose file. Run the following from the connector's subdirectory inside a subgraph: ```bash title="Run the following from the connector's subdirectory inside a subgraph:" docker compose -f docker-compose.my_sql.yaml up @@ -122,7 +126,7 @@ include: ``` Now, whenever running the following, you'll bring up the GraphQL engine, observability tools, and any connectors you've -included: +included. From your project's root directory, run: ```bash title="From the root of your project, run:" HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yaml watch @@ -132,7 +136,7 @@ HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yam Finally, now that our `DataConnectorLink` has the correct environment variables configured for the SQL Server connector, we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's -schema in `hml` format. In a new terminal tab, run: +schema in `hml` format. In a new terminal tab from your project's root directory run: ```bash title="From the root of your project, run:" ddn connector-link update my_sql --subgraph my_subgraph @@ -143,7 +147,7 @@ scaffolded out for you 🎉 ### 8. Import _all_ your indices -You can do this in one convenience command. +You can do this with just one command. From your project's root directory, run: ```bash title="From the root of your project, run:" ddn connector-link update my_sql --subgraph my_subgraph --add-all-resources @@ -152,7 +156,7 @@ ddn connector-link update my_sql --subgraph my_subgraph --add-all-resources ### 9. Create a supergraph build Pass the `local` subcommand along with specifying the output directory as `./engine` in the root of the project. This -directory is used by the docker-compose file to serve the engine locally: +directory is used by the docker-compose file to serve the engine locally. From your project's root directory, run: ```bash title="From the root of your project, run:" ddn supergraph build local --output-dir ./engine From cfdf7ef34b77d5af3e29541264adaca263869d21 Mon Sep 17 00:00:00 2001 From: gneeri Date: Fri, 28 Jun 2024 16:03:31 -0400 Subject: [PATCH 018/135] renamed azure cosmos for nosql per MS instructions (#187) --- registry/azure-cosmos/README.md | 12 ++++++------ registry/azure-cosmos/metadata.json | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/registry/azure-cosmos/README.md b/registry/azure-cosmos/README.md index ee512416..a5600cf1 100644 --- a/registry/azure-cosmos/README.md +++ b/registry/azure-cosmos/README.md @@ -1,4 +1,4 @@ -# Azure Cosmos NoSQL DB Connector +# Azure Cosmos DB for NoSQL Connector [![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/latest/connectors/azure-cosmos/) [![ndc-hub](https://img.shields.io/badge/ndc--hub-azure--cosmos-blue.svg?style=flat)](https://hasura.io/connectors/azure-cosmos) @@ -14,7 +14,7 @@ This connector is built using the [TypeScript Data Connector SDK](https://github ## Features -Below, you'll find a matrix of all supported features for the Azure Cosmos NoSQL DB connector: +Below, you'll find a matrix of all supported features for the Azure Cosmos DB for NoSQL connector: | Feature | Supported | Notes | | ------------------------------- | --------- | ----- | @@ -41,7 +41,7 @@ Below, you'll find a matrix of all supported features for the Azure Cosmos NoSQL ## Using the connector -To use the Azure Cosmos NoSQL DB connector, follow these steps in a Hasura project: +To use the Azure Cosmos DB for NoSQL connector, follow these steps in a Hasura project: (Note: for more information on the following steps, please refer to the Postgres connector documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) @@ -52,7 +52,7 @@ To use the Azure Cosmos NoSQL DB connector, follow these steps in a Hasura proje ddn connector init my_azure_cosmos --subgraph my_subgraph --hub-connector hasura/azure-cosmos ``` -### 2. Add your Azure Cosmos NoSQL DB credentials +### 2. Add your Azure Cosmos DB for NoSQL credentials Add you credentials to `my_subgraph/connector/my_azure_cosmos/.env.local` @@ -102,8 +102,8 @@ Let's start our connector's docker compose file. Run the following from the conn docker compose -f docker-compose.my_azure_cosmos.yaml up ``` -This starts our Azure Cosmos NoSQL DB connector on the specified port. We can navigate to the following address, with the port -modified, to see the schema of our Azure Cosmos NoSQL DB source: +This starts our Azure Cosmos DB for NoSQL connector on the specified port. We can navigate to the following address, with the port +modified, to see the schema of our Azure Cosmos DB for NoSQL source: ```bash http://localhost:8081/schema diff --git a/registry/azure-cosmos/metadata.json b/registry/azure-cosmos/metadata.json index dc3f735c..46b72c45 100644 --- a/registry/azure-cosmos/metadata.json +++ b/registry/azure-cosmos/metadata.json @@ -1,8 +1,8 @@ { "overview": { "namespace": "hasura", - "description": "Connect to a Azure Cosmos NoSQL DB and expose it to Hasura v3 Project", - "title": "Azure Cosmos NoSQL DB Connector", + "description": "Connect to a Azure Cosmos DB for NoSQL and expose it to Hasura v3 Project", + "title": "Azure Cosmos DB for NoSQL Connector", "logo": "logo.png", "tags": [], "latest_version": "v0.1.3" From 8bdb38ed743c40a3f7da3d4651e6028757a2596a Mon Sep 17 00:00:00 2001 From: pranshi06 <85474619+pranshi06@users.noreply.github.com> Date: Mon, 1 Jul 2024 20:07:03 +0530 Subject: [PATCH 019/135] rename azure cosmos per notes from MS (#188) --- registry/azure-cosmos/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/registry/azure-cosmos/README.md b/registry/azure-cosmos/README.md index a5600cf1..70df2d45 100644 --- a/registry/azure-cosmos/README.md +++ b/registry/azure-cosmos/README.md @@ -5,7 +5,7 @@ [![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) [![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) -With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in Azure Cosmos NoSQL Database containers. This connector supports Azure Cosmos's functionalities listed in the table below, allowing for efficient and scalable data operations. +With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in Azure Cosmos DB for NoSQL Database containers. This connector supports Azure Cosmos DB for NoSQL's functionalities listed in the table below, allowing for efficient and scalable data operations. This connector is built using the [TypeScript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). @@ -75,7 +75,7 @@ From the root of your project run: ddn connector introspect --connector my_subgraph/connector/my_azure_cosmos/connector.yaml ``` -If you look at the `config.json` for your connector, you'll see metadata describing your Azure Cosmos mappings. +If you look at the `config.json` for your connector, you'll see metadata describing your Azure Cosmos DB for NoSQL mappings. ### 4. Create the Hasura metadata @@ -130,7 +130,7 @@ HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yam ### 7. Update the new DataConnectorLink object -Finally, now that our `DataConnectorLink` has the correct environment variables configured for the Azure Cosmos connector, +Finally, now that our `DataConnectorLink` has the correct environment variables configured for the Azure Cosmos DB for NoSQL connector, we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's schema in `hml` format. In a new terminal tab from the root of your project, run: @@ -168,4 +168,4 @@ We're happy to receive any contributions from the community. Please refer to our ## License -The Hasura Azure Cosmos connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). +The Hasura Azure Cosmos DB for NoSQL connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). From eeb70ad01294ea952841b04eb39f39eef93bd41e Mon Sep 17 00:00:00 2001 From: gneeri Date: Tue, 2 Jul 2024 14:28:34 -0400 Subject: [PATCH 020/135] Update metadata.json (#191) --- registry/postgres-cosmos/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/postgres-cosmos/metadata.json b/registry/postgres-cosmos/metadata.json index d5cf0c32..e674ccdb 100644 --- a/registry/postgres-cosmos/metadata.json +++ b/registry/postgres-cosmos/metadata.json @@ -2,7 +2,7 @@ "overview": { "namespace": "hasura", "description": "Connect Hasura DDN to a Azure Cosmos DB for PostgreSQL database", - "title": "Azure CosmosDB PostgreSQL", + "title": "Azure Cosmos DB for PostgreSQL", "logo": "logo.png", "tags": [ "database" From 09dcd61153cb789eceb95dc51d17077b4cdd1e3c Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Tue, 2 Jul 2024 18:10:21 -0400 Subject: [PATCH 021/135] Release ndc-graphql 0.1.0 (#190) --- registry/graphql/README.md | 15 ++++++++ registry/graphql/logo.svg | 64 ++++++++++++++++++++++++++++++++++ registry/graphql/metadata.json | 43 +++++++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 registry/graphql/README.md create mode 100644 registry/graphql/logo.svg create mode 100644 registry/graphql/metadata.json diff --git a/registry/graphql/README.md b/registry/graphql/README.md new file mode 100644 index 00000000..8fd0b13d --- /dev/null +++ b/registry/graphql/README.md @@ -0,0 +1,15 @@ +## Overview + +The GraphQL Native Data Connector allows for connecting to a GraphQL endpoint. +This uses the [Rust Data Connector SDK](https://github.com/hasura/ndc-hub#rusk-sdk) from the [Data connector Hub](https://github.com/hasura/ndc-hub) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). + +Please refer to the [Getting Started - Create an API](https://hasura.io/docs/3.0/getting-started/overview/) documentation if you get stuck during any of the steps outlined below. + +### Prerequisites +1. Install the [new Hasura CLI](https://hasura.io/docs/3.0/cli/installation) — to quickly and easily create and manage your Hasura projects and builds. +2. (recommended) Install the [Hasura VS Code extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) — with support for other editors coming soon! + +### Usage + +Please refer to the [connector readme](https://github.com/hasura/ndc-graphql/blob/main/README.md) + diff --git a/registry/graphql/logo.svg b/registry/graphql/logo.svg new file mode 100644 index 00000000..14082a52 --- /dev/null +++ b/registry/graphql/logo.svg @@ -0,0 +1,64 @@ + + + + \ No newline at end of file diff --git a/registry/graphql/metadata.json b/registry/graphql/metadata.json new file mode 100644 index 00000000..e6b1b2c0 --- /dev/null +++ b/registry/graphql/metadata.json @@ -0,0 +1,43 @@ +{ + "overview": { + "namespace": "hasura", + "description": "The GraphQL Native Data Connector allows for connecting to any GraphQL endpoint", + "title": "GraphQL Native Data Connector", + "logo": "logo.svg", + "tags": [ + "database" + ], + "latest_version": "v0.1.0" + }, + "author": { + "support_email": "support@hasura.io", + "homepage": "https://hasura.io", + "name": "Hasura" + }, + "is_verified": true, + "is_hosted_by_hasura": false, + "packages": [ + { + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "0a23dd958f197243334dc07fcdb8c1a223c93bdbcccb3db01f814bd109e5d299" + }, + "source": { + "hash": "2eb35de97cb29056bc194260064f8f242010dde5" + } + } + ], + "source_code": { + "is_open_source": true, + "repository": "https://github.com/hasura/ndc-graphql/", + "version": [ + { + "tag": "v0.1.0", + "hash": "2eb35de97cb29056bc194260064f8f242010dde5", + "is_verified": true + } + ] + } +} \ No newline at end of file From acc1bf026fff165aaa82e9c8054cbcc4baa83fb0 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 3 Jul 2024 14:52:50 -0400 Subject: [PATCH 022/135] Ndc-graphql/release-0.1.0 (#193) fix some CI issues --- registry/graphql/metadata.json | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/registry/graphql/metadata.json b/registry/graphql/metadata.json index e6b1b2c0..99676717 100644 --- a/registry/graphql/metadata.json +++ b/registry/graphql/metadata.json @@ -4,9 +4,7 @@ "description": "The GraphQL Native Data Connector allows for connecting to any GraphQL endpoint", "title": "GraphQL Native Data Connector", "logo": "logo.svg", - "tags": [ - "database" - ], + "tags": [], "latest_version": "v0.1.0" }, "author": { @@ -22,10 +20,10 @@ "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.0/connector-definition.tgz", "checksum": { "type": "sha256", - "value": "0a23dd958f197243334dc07fcdb8c1a223c93bdbcccb3db01f814bd109e5d299" + "value": "30d6883c57b146812fb141feb3b4680a9ffe214cb13e04b0618a8da069d1286c" }, "source": { - "hash": "2eb35de97cb29056bc194260064f8f242010dde5" + "hash": "8fb41a151b3852fadcfadbe17695605f77aaa240" } } ], @@ -35,7 +33,7 @@ "version": [ { "tag": "v0.1.0", - "hash": "2eb35de97cb29056bc194260064f8f242010dde5", + "hash": "8fb41a151b3852fadcfadbe17695605f77aaa240", "is_verified": true } ] From 37e92e19014d1b1e81bf3147554634d170c92e71 Mon Sep 17 00:00:00 2001 From: Mohd Bilal Date: Thu, 4 Jul 2024 18:40:18 +0530 Subject: [PATCH 023/135] add Open API Lambda Connector to NDC Hub (#150) --- registry/open-api-lambda/README.md | 148 +++++++++++++++++++++++++ registry/open-api-lambda/logo.png | Bin 0 -> 240045 bytes registry/open-api-lambda/metadata.json | 89 +++++++++++++++ 3 files changed, 237 insertions(+) create mode 100644 registry/open-api-lambda/README.md create mode 100644 registry/open-api-lambda/logo.png create mode 100644 registry/open-api-lambda/metadata.json diff --git a/registry/open-api-lambda/README.md b/registry/open-api-lambda/README.md new file mode 100644 index 00000000..4b52a93e --- /dev/null +++ b/registry/open-api-lambda/README.md @@ -0,0 +1,148 @@ +# OpenAPI Lambda Connector + +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/getting-started/overview/) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-postgres-blue.svg?style=flat)](https://hasura.io/connectors) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) + +The OpenAPI Lambda Connector allows you to import APIs that are documented in the OpenAPI/Swagger format into the Hasura Supergraph. The connector exposes REST API endpoints as Typescript functions, which can be exposed as GraphQL queries or mutations via the [NodeJS Lambda Connector](https://github.com/hasura/ndc-nodejs-lambda). + +Functions that wrap GET requests are marked with a `@readonly` annotation, and are exposed as GraphQL Queries by the [NodeJS Lambda Connector](https://github.com/hasura/ndc-nodejs-lambda). All other request types are exposed as GraphQL Mutations. + +This Connector implements the [Data Connector Spec](https://github.com/hasura/ndc-spec) + +- [Hasura V3 Documentation](https://hasura.io/docs/3.0) +- [NodeJS Lambda Connector](https://github.com/hasura/ndc-nodejs-lambda) + +## Features + +- Convert Open API/swagger documentation into Typescript functions compatible with NodeJS Lambda Connector +- Supported request types + +| Request Type | Query | Path | Body | Headers | +| ------------ | ----- | ---- | ---- | ------- | +| GET | ✅ | ✅ | NA | ✅ | +| POST | ✅ | ✅ | ✅ | ✅ | +| DELETE | ✅ | ✅ | ✅ | ✅ | +| PUT | ✅ | ✅ | ✅ | ✅ | +| PATCH | ✅ | ✅ | ✅ | ✅ | + +## Before you get Started + +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Install the [DDN CLI](https://hasura.io/docs/3.0/cli/installation/) +3. Please ensure that you have Docker installed and the Docker daemon is running. +4. If you want to make changes to the generated Typescript files, please ensure you have Node.js v20+ installed + +## Quickstart using the DDN CLI + +> [!TIP] +> The following instructions are intended to get you quickly started with using the OpenAPI Lambda connector. +> For further information on DDN, please check out the [Hasura DDN Getting Started Guide](https://hasura.io/docs/3.0/getting-started/overview/). + +> [!NOTE] +> This section assumes that you have already setup a Supergraph and added a Subgraph. + +1. Initialize the connector + +``` +ddn connector init my_openapi --subgraph my_subgraph --hub-connector hasura/openapi +``` + +This will generate the necessary files into `my_subgraph/connector/my_openapi` directory. Supporting Typescript files for API calls will be created in this directory. + +2. Add the correct environment variables to `/my_subgraph/connector/my_openapi/.env.local`. Supported environment variables and their description are listed under [Supported Environment Variables](#supported-environment-variables) section. + +3. Modify the Docker container port in `my_subgraph/connector/my_openapi/docker-compose.my_openapi.yaml`. Typically, connectors default to port 8080. Each time you add a connector, please increment the published port by one to avoid port collisions. For example: + +``` +ports: + - mode: ingress + target: 8080 + published: '8082' + protocol: tcp +``` + +4. Introspect the OpenAPI document using the connector + +``` +ddn connector introspect --connector my_subgraph/connector/my_openapi/connector.yaml +``` + +This will introspect your OpenAPI document and create an `api.ts` file, a `functions.ts` file and other supporting files required to run the Typescript project. + +- The `api.ts` file contains the Data Types and API calls from the OpenAPI document +- The `functions.ts` file contains functions that wrap API calls. You can modify this `functions.ts` file to introduce business logic if you want to. See [Saving User Changes](#saving-user-changes) if you want to preserve your changes in this file when you introspect the OpenAPI document again. + +5. Add a [Data Connector Link](https://hasura.io/docs/3.0/supergraph-modeling/data-connector-links) + +``` +ddn connector-link add my_openapi --subgraph my_subgraph +``` + +This will create a file `my_subgraph/metadata/my_openapi.hml` that links your OpenAPI Connector to your Hasura Supergraph. + +6. Update the evironment variables listed in `my_subgraph/metadata/my_openapi.hml` (here, `MY_SUBGRAPH_MY_OPENAPI_READ_URL` and `MY_SUBGRAPH_MY_OPENAPI_WRITE_URL`) in `my_subgraph/.env.my_subgraph`. + +7. Add the connector's Docker Compose file to your project's Docker Compose file (your project's Docker Compose file is the one that's located in the root directory your project): + +``` +include: + - path: my_subpgraph/connector/my_openapi/docker-compose.my_openapi.yaml +``` + +Start the GraphQL engine, observability tools, and the connector: + +``` +HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yaml watch +``` + +The `http://localhost:${your-docker-container-port}/schema/` should return the schema of your OpenAPI Connector. All functions that wrap `GET` requests will be listed in the `functions` array, while all other functions will be listed in the `procedures` array. + +8. Add the connector schema to [Data Connector Link](<(https://hasura.io/docs/3.0/supergraph-modeling/data-connector-links)>) + +``` +ddn connector-link update my_openapi --subgraph my_subgraph +``` + +This command will modify `my_subgraph/metadata/my_openapi.hml`, and the schema of the connector will be added to the `definition.schema` key. + +9. Add all resources in your connector schema to your GraphQL API + +``` +ddn connector-link update my_openapi --subgraph my_subgraph --add-all-resources +``` + +This will create HML files that represent resources in your connector schema at `my_subgraph/metadata`. These HML files specify your GraphQL API. + +You have now added the OpenAPI Connector and imported all of your APIs in your supergraph. You can now: + +- Deploy the supergraph to Hasura DDN (Please follow the steps [here](https://hasura.io/docs/3.0/getting-started/deployment/)) +- Run the supergraph locally for debugging (Please follow the steps [here](https://hasura.io/docs/3.0/getting-started/build-your-api)) + +## Documentation + +This connector is published as a Docker Image. The image name is `ghcr.io/hasura/ndc-open-api-lambda`. The Docker Image accepts the following environment variables that can be used to alter its functionality. + +### Supported Environment Variables + +1. `NDC_OAS_DOCUMENT_URI` (optional): The URI to your Open API Document. If you're using a file instead of a HTTP link, please ensure that it is named `swagger.json` and is present in the root directory of the volume being mounted to `/etc/connector` (for this tutorial, the `swagger.json` file should be present at `my_subgraph/connector/my_openapi/`). +2. `NDC_OAS_BASE_URL` (optional): The base URL of your API. +3. `NDC_OAS_FILE_OVERWRITE` (optional): A Boolean flag to allow previously generated files to be over-written. Defaults to `false`. +4. `HASURA_PLUGIN_LOG_LEVEL` (optional): The log level. Possible values: `trace`, `debug`, `info`, `warn`, `error`, `fatal`, `panic`. Defaults to `info` +5. `NDC_OAS_LAMBDA_PRETTY_LOGS` (optional): A Boolean flag to print human readable logs instead of JSON. Defaults to `false` + +### Saving User Changes + +When re-introspecting the connector, user changes in `functions.ts` can be preserved by adding an `@save` JS Doc Tag to the documentation comment of a function. This will ensure that that function is not overwritten and the saved function will be added if missing in the newly generated `functions.ts` + +Example + +``` +/** + * Dummy function that mutates an API response + * @save + */ +function mutateResponse(response: ApiResponseObject) { + response.description = "This API does some work. I hope that's helpful"; +} +``` diff --git a/registry/open-api-lambda/logo.png b/registry/open-api-lambda/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b8fdac6902414686495f9f0b0257d32e5323af9f GIT binary patch literal 240045 zcma&Oby!s07dA|n2uL|}iU^1d-5`j7q~gHPF@(}E(%s$NV1Ud3Lx*%DNXY|8H%NEa zd*FF~@B97v9WSmqj5Fu#z4lu7y4SteAxvFW{viQ10U8?GLq&yG@6gb&O3~0TzT)8k z?~qh?xdJcv_6pi?G_(g~cR%Q8>6swlO;6^e$&h^F}J<$Kr6t(o-%mT|YW%UzMDe14N2hP4soW*PA-WoDcu0z`B6>}`DD z=+x9Sydb)T=J^}LaXVY#Pd3^tN|g$Vf~Y46hl4y8t=zYW?O=THkd_P<8T!9tOXEaw*Y|(F^#riDkUskNi1SiGPyXM3 zY*`VMzWVPlHPrBZ!u;QHnU2Br-xnTDjFTIM{r8QYrhGJ||9#^`02}(hFO;L6{r|az zQuYxMaH$@<7!r&z9T~i1r_s}~$-(LB!bxvb_vGdc@ef2XQ`NwJC}%) zHL4l1L{Z#!t-ac=_BZ@CQ6f|_w_EY!NAJc4$JEpm7Z=yi=JB6De~hfGBDS|}e#~$; z8pMb*kjP9s&AV&&n<bxdL_q_eOL%a4s;C zy1LHZUV_6z7j0;&1q>FkvSQ}mXd@^jG%-E>d1`xT(`IDz;onn_Ww&T>GKn}?u)RzH zIhsGpfmsBM>*$DlWP}eG7mtWY=kS;A)QpUktqHzNNw459@-aLT60*oq=04tdRwk7Z z_djCl#DOjYqbW!pD-=P|Dk4~?RUH`T^8VYqP;$iEs*X2;S2gWJu#k)e)ZUT?-`-Em z&aN(YM(8zrXCbvv4oh7&wsTFL7Z;-7ouZ=}jdRm7N*P~}#L5mHB-22qC(AK>kru6+?*zc&QG}9u)az_6W-W6 zq}ay&s>#3~w*Sr++vlwC2Wu z%~}LRL?9t5it&+^t1m@9cr}Dui5E@w8B9U=>VEToV-JsGEV`O~M=s(v+kScAt)Vf} zaCM+`wa?%akz(MUhVr?lh-Q$AhL;evWb(bo)*7gb8#k+YxkrGyceCgJx><|u^FWnZ z4;efb$h&}-1Dz3%>+BcEB(IN14-X@(ZJnXIx+}Adkc(^ju0(V-xNRalnpKgfOP##a zD_|}I5yMoEExU9%H(mV>q5$!UXD#IH3;&$U9=?#ATwYa5xXJePsfhCy2=F&rG3P+Q zV26tlFAk#YJhOm77J6T8+>8!Fx0P02q6&dX4;2@Wv6Zj_U}qx5nMT<*l1Y&iC&0hB zSVdD)v(EdPZMX51Xt(K-JLQF8-pGWBi3!FU?Zj^Qv1ATFE#9h)6LFG5 zI>8(Fh&upo|3YwwiClxCT$n^U30DDg z$HNA&c;U|Y-%<=#Gv=;v=B`$S+%^geHr9R~Hk7=ZLXxW9g-Mg}eVE|B;^QjR97JLi zAr>vYys~J7Z1?PLPf%A|7E((GD{5t9U?CT*(2fuClMgui)3k^Q0ua}rW}BMW&4@rT zkNyjHb?h+%B$glpa>776$k&X96@=*~X#|HqSmQ!995~(d`J5}=9H}+8m%;Avn5MAH zKkE%Q)7~=}BHw+2A`WW=2MVpkps_c``-o-MW0&^u@Bx5ei(agXTp!ah#P~|m zPZ<~{y<^)_XLMd<*!YePrmvYXf?#zsX?z84J9UrGR)q`~d~ODBJAeIBrX$y}dKQkc zHtj{BeU||bIzNQg11paHn@|~%Tst}n8OV_u)U|8ueBr%s2Ov6~@A~>jHZ~pC-QA27 z$n~Wr-2U?Ar4VX{qtxh=lWeX*kb|Qmsnzq%%}u>V_b9+WDjFI>tD>c@+NG9*9vc{0 zS`x5Nks^(E{{^BZ@%u?`@#P3adZNzXLXOobveAGHyEkct+6R6dR(dHKh`)Xm?YGY;mp9~6iIPYMfVUK#fY_H z`pd(uxtIHH7)7f_SLXBYZ49fdG~wks#grNv8Vv`%T7tKoXtb{n2nQ-B? z*P2}a#JT{tjvJJxxMR_m?*)9;Z*srsnDP9xkaU{;?VB86aU1Ww0EWHwf}Hp@5$)vB zn9=tVwujX-=62hH&Fi^=&xr|&5K|e3-R=1tfp11Cvn9p=?lnFAb!xl3si~_B1_y4> z39y;y_r?(PMT5g%cY$k~$Z^N|Pr`5^SOTcc<7&kbEUSbc;TtF0Q-CL4#roW=-Kx|~ zeVf|m1%uxXw);DNcZKJVy4pMa;V9)GzBp$f-_W+ABE)f00Kqy$CdCM8jr zL{{oNj|7v;`N2zUeWr@THx7fJ;tH6$4GmUJ*?9D0B7>KnD$2YiKf3e+!hB%R`ve}( zx-xjPHRyV=Ua&E4xE*kJvz(lJs_L~^!BLuinA*F?;ds2^ig8Ae2+UPVf(oVf}C`8d3fwuL5{&H!|guq9rAsd+vNj;e~yh&l97=eSNBu4 z&1ixWU!W{;iwvw_$}`ldYa#$ICc!{8U2tR#2+m#3-Y)(r`$CA5&BZC(Iis0r?Tzxi z19~E{dziiKFp%v)0y*A^VzisVr(+X!>z{LbwKm=0mY`9f$~S5`vVP1S-jLm%Xhs## zil**+%pQrW%7oQ$dhC$`loRIw>nuW{;ENsLo5dG5{;=-o_oqKlHkIeD|Dp|lhd$sN zh97Y#`(MsMTq$777soW7x0iEk$KyU-8yl8hx{L4P`CIE86>3kjHIa}IZN>QM@pyJa zJveqxBVq<&gWxFQ>J#?9681UP^650ZJvQVM5O|5_0M*9r`i^lo8&jeCls)k@ec>I2 zH`FQ&JjOJ-Jymo5Q_W!IjyVA5X{o73?(RQk$1eRz2*-3X;eywVra#aRh+B>)hq3uP^UdW{)J~ zAs#VPZ2mJ&PUO{wR`YU*)Ya3~wa2NMnWg|J?|QK$^41gi+Zkwv9dO+d1O)WbTGjdzGDl7-~Y;;cBntMGnOAIrGs^1z>(TAA*@7 zqwllVpjPXrmsdvxw`~Bt-}YTyVRS(ONB}5$R}$QI8H_+Py>dK6dOFlMHjSQ+dZ-7* zN;h(tB1b<1)MK`>&kEJp1uSwV38Nw{WEfI~$h#wfiT|RsTBOzv2*%Sj-?%p8GPlw# zbpw9Ptp`{QV4$0^EQ+L=aB{g;BOb;+UIQ;+nsoM8&U< zDy{~08{QB8qV~Bf_T$=Bb3*TMAj^WbODg=9c$t|U&n>@uZTGBbC|e!eZML- z@iRnt)*UUn%U`P*c8i%XOUobGG2}AeLqZ?R`BhaLIH^O#)Kn{icvLhF#8J90k*B~y zXRom;%Am%VMzsu|sF11VNCKsq{I16>f4B18EyTPwfbqNi>RNjrHCTi&XL!!dz1Plg z6MH)628v$Y@d-xB>5=5IjU<+ZF9oj|%J5ygN`?)e+ zdjGq!n)cIuc+-C&k)e}(@27Fd>kBrcnGbr9;<{ZmUgv%+TCAC&iHxcu3JoOLpwfnf zzO5>F_Q$mxaO)}zV+v`=g6XkAl}@qy>#^-Am-Cy`=0RKrPd%w*aDLOA5zoJ31+C7- zKP&*RNae>2G5<@xq{;}HO+LK2WHzHuKQ-BR93Ky`rzIBhB4 zW0i%kcXoMwfyH`1Vota-Mj>4nD4cn%EhwVl_U3ZB4vy;!B<6V5V;Db!-PPs3&GOHQ zO|S3Km}|6MpaXFRqQ5yN&d$kJ<0bnqZVx!LPzJc)b>;jnQr~{dy1TgGf94QC=7)c7 z0n)fhRn)n9ojQ#ZFX=X(8`l%)2lC9+w#TPh&RcreH?4#G_$KZ(-q%<9iC#Yh#& z{t_SD6dc*`M*IK-nz;5?_puM-mBd6^G8Oq3l3=V2c(u^jHM9cA3}okHl0C~755A6f zuKQDkBF!9KPzFp0`${GN-}?zU4ZRt5O^T6m{3`O%bdWopsmJ(>niP;>)D$RQfBX36 zExG5}LWo|iz2E4lz=3!{`h-5Y+>Gs5rpJ@!tgfkBM0JZMQZAkqNNWu*TyL*W&qq-= zSwMwtWFgnaarKV_BXF&dFv(+J_Tp?F#j3dWmnSyf`w=STE+CL)LRl64!NIJG z3nwXQ$uadWSqw0Bm?kzQWY7L^RYmgVj73vRYyG%dzIqC2sf5|!;}I32HR>UD zlWnfub#TDT;JJsM!mW?h>pTMbf^z{BNqnCWY%KIeO=R%>71r1f>WRAp1<$@eTg| z&CApwTKkS7iXT$^jihYM;dn!UTdx+1f>OaI9Ci9T5R|xRL0Z5S983QuL;)j`_ubqH7Nsk8j#B>s^agadL@YEI7DKvsQwvCFCf zWZ^@F|9w@PJ5*o__;1K}DrpG%D+rYaq#MAM5Ms$Q-~N7;axSD6Ly-(OHVK9qBZTg; zc5<8rqP_2qy>k=te@*;(|6B`_JCqqv)zI+kPM84F_{a3I z)6pwVzbx4I^e`MTBvJL0je8?KgU=PdknQw$S#F@_xxCaY{bwIQJ7(OVe=UT;6zDG3 zioh;H^yuj8FC47&0nqcCzgRZJoHNhdNYP2W0|XR|yAlBBv$nH??@W6D^sI5#+4Cj| zaRy|n<=o+?FkpJ}x!PWkD!(8SsJ_0Lx3`}GO3E<FX z-lV&=P>U4no^(A+GS_j*xS3Q1W|bN{xBlFHHFp|@*V%5 ziV}p#M=L8UpaA9p9ql)Pw8Kg#4IrL(>lOP~<9@yV$po~Rq4yLJxwrN=S8kM)ls)B% z0JE#1)U*li7vzcC0C9wWrau9IR*_aoiF3NvA;RDVD&VeYiVJvi53aIDxrh`4RCj-d zkhZ>lF|rsT)t@GpZphlAz$iekN(BSnUAs8m{8T@4xl;fGIMOR3>U&BXqaM%dlsmfZ zT<3Yt`{2Q$)02MNfSS>pCoLs>#fVX^1Xg1>JnL|6u%fIC?3iJ0eDC#N)w+Nw5WnT~ zL|`Bg1m+$d8B;ZOfD35i0+MEiUs4;g-RcTNjrz>n1<<{j9YFwyK95Xb^a{3vmK11^ z(Ja8|Mc9uDUjqxmWEuPrpk&n)Er0}@k&!_z=P>t+xyoJf819J@Zz5~Vlq40L!PSki*VKVo4&12q-9;|_J}Mq5U@2iMqi^H zsJk>b413=d6SD87IUsVMs*0)r=@6}_e7T8IhEDfxHPnIKnYa+!20F_IY9mwvUtB=0 zXf|>K!Ql$k(ODeG5`$VP#t&=0ye8@i*b+>f(TOL{ApvzL2%+%KakWMg*TV8bi)kV$wLF8bo z<;{!^IW`j(AYlT_y97vOuDhG1N}P`X^3?P43#H5>w+|PZ-mp!eM#Z^Z@#otTI$w zaA^Tj@%%NP?{e;+?NmXW>gwvh&h;!0XhS`zAksgosya6|2*4b73SwM_Ca0`>=FCn;-zdlNz3E`=awFKO*IrFFHJy;7}nQaISSjkCLeN5l&}ppsU#|H2CW~%`Q#+2-*f3oV=dsw|H`OvU+ zftaq#`|RRkb?VsTELp*q~N0@(n0M zMMSi3vp)<~d%hjrhehU1ZI{;7slE-os1Co$zK>%W^yD5GiGSzhWdQL9EY0dk%2LSL zqYac8@$0PUKvA4>mYOJBNHSEicQ3OmGDHF$qsbxanVs#YFCCyhg`er}G)f{<7H7=| zk~k)S&KKrTOPcXa?ek|$n&%xu3K594m}C1>%h776#Jv5W`xU&Og?fd>(EJypZ$7nHx1;fh(D~9P}VMBimjnY#lH17&bNLW!~ zJPPU12{>H=WIq3@74ObkjWjdm^P8v~!5ydG?*v8d#tl!L0jab#w?!uc*la|-YT|+s zHX2YFjV7T)tMA+i?VazF15jio{%f(KN7N0Xze-;YQ?)z_c^==@Va#dbCKn0$3vHS; zgJ@Afw5@`tsAWPsjI(G0jcq2clSm--G3JbPo=fl0T)z0Mbg#P*0dFd%#0GTH8N)76^FMf>0OeiU;KI2oGD5P(jA8l~g|%Ok~|b zB_Ekb7^z_2HKZhtAMB5z%ow}mrTwT%6lz>t-4q7vcqqFmY?s~ zbVp2!1-DPIii_mNdQ-E-dpkPF`S=o)m6d;IrNvHoY&P#iSoD23!>UtG9A)+05%vH|&De@~n z4IV7A1LVZ)rT|p3OGWGi2h%CrmF~AIOb7%7HvoNVs?mMechw;ucBiHg-P^e5EZpN8 zBFMf#fx}fJU-D6A6!bB;%eYk9A1>CM-;b}}7+W!`ZvyuSD)tQU+jX?N6l^jqt!h-Y zD3z1i9eN>p6hV*e<(NQrA>vh`!mn>~L?{!&ygO2b%|z`9W-M2sulH@Qh>m*p%qA3@ zJ0B}0A;|HzSOANmtd+#(O{7S0q|v2mdv*7;?E+ixc#E*S7#fyI54iRR^+ViZXVx^l zTFscRbU$rm=m{02zNDZ`>TxV|=LyF|-|;EN3;$-tv~U=R{ek~m^EK(iG3f6~mGmcH z*I6|ZMt=3v<;~bSn5=S8kI|j3YV{0!BPC*al@K_VkP2BW5 zsATOab^Gxm9>J`ayvroHmyN8Ny1}m-P6=_Y~ZtLIC$;-V3cE$I+kN#)` z<=k;oR)Cw*$E}9RdM#3i=vzN(NwWEX#+KM#tlSceCin6MIr%c7a<1X>5iI(-I3~`~ z!Ncl{Qz+f9irF*^7+_YDgyY%gz`pj_kHb$jyTivWR9Jg*R9TQUp5$_q-VEc%S$@w3 zFz`F17sR`ijY?UEjg(C%7azP-_G4MJX}QomKLjZ~!W@8pet5Jkp#vt>p|`{7 z@az5)>Of+`YUB{OU|mwlWy?!7lJGQD^niST!qoP2gD6fo2|oHkEDRSd*!C|`NK;68 zaXDVQAoYW4S)M6ZhCO;xvDW2($mOGHE!^FM6Zi)2chXs&re%l?Z2fv0O)Jqgz4dlA zKZb{Iv@Jf4)#hDFT&-a782QKaWIL_OSG@}-#=_sZjCzgwup-M?Y$PFy#u5{Q@gXWa1M>f9}!VqzWoj@6ED}rdUwRv=o2 zW{?!OcGH91!{`6tmFRiBU~6xAhRJvl8U^vlYS%(nv0n!NF79&0<|!fEVvY?_pk@*c zWx`D{QFulmn=SiGBixTE%i0+K6`5kN>=H8N7pU~7J)u;41J!htwiuiBkPz7Xf zGMkCXR4gM5GP2Bw)Q(3otbvkpZ|8AEx+pq^3e-ZxT}>WsQ1ODX%K2f=u>D zZ0T9Q(r~t@&$@&xKv*K_f|1p|jYZEn&p+{Ac0>``#IQizm@y)!Php?Cy*_jPf!>yhO3q)=70F z4H??4#H&=tz7K-vF|crEB2T27AuRku6|obMgWhGOGo zE1-{!%6`EJjwLtZ;wF?OmUZ(G86x;wHmz;)t+~U}C+yn}a|De`?YMT{rX7jwS1s!@ z0qD0WU1N{ZU(OE17R-u0JY9>*!Bmp@;AFol*1Ui+N-~ULok$_yCzFXrxsO}0lq#?F zFM32%ja{{3-&Ugy5Y`ZXZ6cV&VL5d~C!l$jN@u`V*2gL4hffK6VA8{m42@RraJwKU zoECgWV#04aOJ>7rg8a-C8DRuxj_sh7tPJVYPPP>MAw;hcBxyEBFG()8?cC18 z^=hxA$lVc4GwYIiPFMq%T-++1v9oCMo^i)(Pk2>+An?>gnNc8k9iJyZcdEXd(Y74I zRa)tub&67sH+$AyaKoS%?`XY4_*5-(rDLBjQ`9>c_EgRB;_Lxy`@+@IS~8eg=E#?& z!*S(@sqns3uzIy+GL;rpPWr+{h_SFt2aRlGET;motf^a{DCb**4y$*Oh^2E* zywql*u=yVFR7*9n4JV-Nku|~BRC^yW#mYF6ck#vw6gJwOrv7=QD~7mirX9vFbdG5i zd8BVzw8miUG}jnnZ+ine^=m8*Mn059wDS-MO@A#KEAJY8sRpbYl5heut=aFH4{AB7I7NyXs&OPm=oGkYvEils3CzVqNm1zvo0uex@d5pb~-}ezs~R9hnd4ejg;*wlb|dgsDGh zKVUj5>&>d1J`Mihl2ZY*nWz=|VZ(Az8s$^RV8G3=$#?SukMb{ZvqNNbkB@NrOGw?u zf`v67Etg?4fB*LLS_J{G#*K!;b|i_H7oEdZ-O|9Dc%1l-c@r7s2jL`&UJ-@sSPWcU zHWg!a{i~x-N~X_J!wLlnF~XcOMUM&9a=fAoa@@n#axSS2-A=4Bg}u|i?!OB$_N93#)Ml5H~RocLM#)`Nq&I0HHnqsSjB%R&N@S973%`xddN=7Mwz zZ@_$j_KLwJl4$Y^Y>qa(5D@Y~p@yDbb@i_`f5JimF%@gTX*IoW->6@?oJlpnxlmB(f@QsJ|cey7L{9XD#uv z->4aumHi(Ce_*OA=6wVjplI`rDl4iiM^}zHF6~H)dZ3rq+}ocNb7p!NawNnu)yQ3& zsNf$H%_Y+Nev=b)0p<0dVD6%&*&%7eU?L~qPb;?!wh6_F=;mWg_pSISQYnE`Duw1ZiwI|Uj zb0Bo!h`?-9-EzcnJe`xO7p4Vi0KxWVmomT1*e+#0pQ|u7Q;vMQt$*+>h@_`HlHW#R zT_0dnkKDeJ8~tp0pY@M`F2n0)h7wkgGxcb&RmDRM1TO+{GdEUnL>W5&{FUy&18`&@ zSpZt!CPT$2pdW8ix(Mx*ibGAlz(ZEHA=L+F$&2D{J{fJ&V$XMN8w0l3(xjC3G@y?a zQ#)zwX_?X;gA<*K7mARHjz;d$`1oDUp{=B^%~hTixlcRWFqu{c4W&X$szWIC@ zbWGTtS5sG#KfF^GDCd;<#eyCq@T}|WS%W-JHi@jrT<_YMdTFV9nztUTxT58o)nnJq zexH?|;gL*Hr{sjE*^A4Ce3`<|nS9-Y7$2#sH3#3`7@pUw-(LK&yqHoAe{gJ>zO8fIDY!PVhd>L;lOmV@<;H z@Gd43wDcHyV*IMp{@18|j}1!$$F9cgPE@yW0600DVO}<;?b9FXqVlS$0o=aZ-tAFc zz0}*#O)G}q&yrJr83}%joA^@MHc~kvIdBZ_T3SzB>N_O2(sC%lWliN#sZ91$3d<8O zEA4!knfA3bn3eTa2H~1^7V9K>piO$%q$_7$l_~_PCjDW6If77)yw7g~{2HiXgLxam z&EQM}qJ%h0m_ZSL6hw9-(T>2!~AFc=Hu2iNp+ntv6HOEDe6nWMkRo4f6# zrJOa+oewtbT^)K}yWIFLb*sir3WoJ7#FMA6n)y;>Jh#ppD16OP(Z(}GjT}Rir>u@| zXsIoXTF?-q(8`PClE1ZYX7||sL?0G!LiCZ5+2rTvZ=m%7-1&7g>dtbx>@D$L>xU2{ z3KAA3C|9&muoEjJND&Kfr6G47JXX$kTz@6q%v;;n?~zhh&t}{<5^o;y(R5 z{B21~AwMNGI`;LRT+Z~1k#fKJmcT%9EDZTpWh48JA@mF*nFw@|v1Q?l`COhjepaIk zVN&r&5ln%Bpa{oNF)>Y2=Q*n{dmC>pt4SmkLg{Jr8{3$C;nlRCY0(+NhRI;;x)0%) zl%y#n_#Ge~{z-DL+)z1@(iv?TLMSa++7okpNgSE-{>5IEWS?``toMth(Lxs5ERojr z0)zP^)U~9c+k#xS$Ayc1mjDNt@uIwH7%Cfy4UM2u9S$$EmMa=?=sT%i*a&tirGWSy z(|owmhcq?=yJf73Kg-AVj>kA04ptyZn!pa=`ucht1fNs1=}wT#Rrh^zX;2kDz9(kF zzarxcmO%?(A}!0;p|XWS7DE`81D@C8U=kh>1=O~g&l;C`#GEH7O+%#y`>PK1w66so z%!nNkX1-y9rFT?++~*%KeMPgc==N@sr5npoQ+eVONXQ0F9gR(y)TSlw(bYhh>>JjC z3CZ{Um6IQ7xU^WTs~<&c>OX66uY9e8N7EJX+-ka%ZYXNH#!@Wuc&?;GZ#&lU2qNBPj)$5?>|!+LrR(SiSKyn(a$x&D>a zj0Kgs0w`wJYg$a1UtlPnVw&*;hBZziRcoV(-=UJ7qs@YT372=_#&hO?{(V;7u$m$I)2>_alxFML zHN2K|t&~iovK*fW9i}0unS6fSOLKLx?ekQTG@4H2=i#7Fl->>{^{a z_W3)699lf9vAcVET3T8h457m%{cqa_uo)EZRWRW_(xB(PpJ>&f-Ah!6hZPP|u!oLt zkg-3=YGp%ajMr7Tg?*c)ORfg;^b&!KmTkpQeT%!pgNzinwn%J?hhbu>y@Xk{*m>f{ zE^M3@Vf;9VZgYe*?=MD-QTimzNhZMoD(8qC1U!7Wl%w%QLwq-q>ecq>n_AuP0zY0l zwQlQKYw~PUDok$J)=QaFq>ESuztqz9`MaL5Hg$CAm+E@q5anIg+B>N)S$Bo5mgAny zXOX>n1R%Y{xqxbpsNxvM?Zv4i(G=D5G05{E^fj(86@Pl4h-L)LtO&u6{yvJP6=?$w zua}KIkKYDCD=J24rMzWir-7ECWoe)%^m5?ric^f1ce}Bm2oH?);NvhRZ7bBs|AP_D zU@o*k=+ENsRWsXZuaKCM>(tHDS)=;DBs%zt7lexOj^YwZam!zYi_)-i=3)L|s$d(Q zb}GTK4?BtCZh2c=tT-k;p-kw#qYttwzG`?OmEKc3F+BWd*d122l9k)q4JvqSGF!Z%P1c9-WY!(R zcc?bbAm{-rw#Gm=!7O2juUM~<5H2B>Y^5J-S{t?O5%!o|{!`l7(}};+tG}xr?o8Kq z?vp(gb~<>L?X`;ZJhbxZc`$fO4-^c4&eddSZ+5hSezqQkl_ZW*`l5;IDn8sk`>j83 zfhQ%1rsp`GAINn;Z%PIR1{@BS!$eKTI0FBdh~>XH)8Gn2mFuJY#NurWhp@PNqr?w8%=z)cu z2?6_GW9t@lY+WOXFsdB|@z;3xv78O@UY|45D6+cMV_9(&@LDk*DXT7Ee*E3l6==}p z$CM|r&I82>kj&WJ`&7*6@I2dN$1FM7?$Cp?#%*=taVo%$vy^%G;DKBjtb}W> zR2sqBE2tw?CA-5*jz82|AtDeTQ@BIBY==mDp#~tKtr8B@8OyDIh!vO>EuLSnx1z_a z$IiY}c7eXD{iSXZuL~~4#U13%NZG#~0vKFwto~JhNbuU1IS3!)aNWL8e*!TEnV?7Q zAsk4%_Y6}X{#meJ@A%4!DO|HJ$S{3I@fdXz-#IJdej+OOH$G#jlC8N{nI3-~XO=sz z0_TQ2?iufG{VOp>3+crWc%-mgaO*4CTzMXm;S)s}%@X_XdvCH!KTw%NA7$8*$>#1& zbr_YhwLigGBXnz)jjsYW@;|e)6X3Rzwv!7g{>-mY{L&4A&iv?9^KnQSzuoTsMW42` zV$s}M<8wQB9$@DkQILJpYd@g(lbACs{pmkup%5=(``a)_{jgUpI3Db6Nb_R|gb8NT zwzWkIv|@k#sH0^LDK=O#?mXj?7SW^sMEHKZ69hB`S5Dag&v2z?T0iu8(XQ|yFPZ@$ zw<7ESxn+49q$QZlS*neRoy?3yx~0luy%0? zR9ChSKIBZPD?L}*v6(ilgJ<>ckaGJuKj76uqccf1=_%dkr=qv^Eq!>zB&;Kd8@@1f zjG@MLdR&?u+S9aZQYDku87L@8Z9h+o<+xb7GMY~{A2z&@`Q(-Cr$=iTY_Ik3SQYC; zEhIrh+tx;e*4ErZ6L%c;*Hf3-OxL4^$A)_D_8tF{gf9 zoFPpfySrj;+?=H#O(VLdn|6*4QLhWELCH&gU0oVisTPpzTXH8JXrnWtC4Lob6xr&b z7WoJUxYfnMvT4T8pMr4sNXtO)eZw+t+@1R%@Yu0>&CZKDCw!lfhJk4M@cN+k^bsts zN^hn6{K_b;BaB)#N|Wan7k`ULHXJKSYP&~>%^bQCM5eW*``4|rfMDRR#cN-X5YJC6 zHYj7~L$#eRbZBO<&-lU6ZCq?Q*c^I%?At%+wzZ#gdlJY$w^I|(J`CX6SejhGFS7<$ z=Icn0kl9pqmg+}k^+s(xVq;?~8(Y+CbGD0s@806>dL6N8Opp&s9W(nJ;m$4Go-N%b zq%>a;Xp72?j%BQ&TlJN8>L^8Ke`ep<>=n^57Dn~$y#GK~ZeL5q2DHFM(~0$VyoxA( zE|wW3KrQ@!971kNr`k_YwBb^u?FIq*2@~?m; ze&s@LAX~h1qTq%Mb+sdOw(;Oae15U}oTmXv<5Qa&_Hcji<`_8T8ljo%YAf5H`QA4@ zvXmwQYmZe_RUHqOsRV^;HaODFJJT^ZKO)+GAxM#k)d(=DjH#_{`eOsvJfc#B&3!v9 zu+ed#@IDWcM*22cpwk$h?PSz4DIMHt#OVK`C1K>4lgnmqzPItz?RJ1hul9snNN8|@ zjVS|72;JsTJX#X0dCRO{1;vUt#kjn!IL&|Qn0cDEw(B+bs|ZmdY5!@7*&&A&odk_3 z98F=5*jJstk}-v0i%{(LpyX$W4i2!2q#_X!^shB5zmg$ zZ71yWcYB{eL(g5Czv~=0BGa}PkY}P$D{$A4wV-x|xj=jSI2D5(1(CoUMcFG)5+h!j z50Q1xWI!EUQSXvlTjh%M>yud(f7BpPP(Sxs@%$O_+KL15pl$Lp>&&H}!pSPB2axs$ z>5u)`Aeq)Q(y~u~bY-j=tVF?I*gKvvj_Y>Y-#llF%$p!C+~~|#G2wU8|FU8?-zfVm zYV6_X??k>;BC(&V+Ur0P`jw=CQ?VtSNRpD?K5pV+Sr|EeKt(vU6D@sELBXu_DJb!` zUc-f`8iQ*@^X0x_ndgMg&Qw##%+zU_^9<$U_c4m_!}ocWEa9?=L+89Ze{K7M>)r*T zDZ~dlZH@s?g}DKN81!zwamTXfI+$$fhPGo1>D-il?fP#tIq}nw-}IjH{ttiu2io z47QG!g3_Pw?Vy^ak?J2lL>-(Yjl23RQXJ6Y@c-kXHJovjpc~<|l==ZwFx!46IyTlS zFKiJJ_K~_6@@OK=k1&>-WWo7q=zG3}EcuT#7fX&IRYon0o@Pm@@1v8h!=zR|#Xr>>!&Q&|ha{QN!P6r4Z0Q?l969^Bc6ar#ZD?~`A>|2$Jb z*c(waYJRhlNlKwmO_}A2I+ZI(bTX#X$oBo#;Ic$F>%GgEQj)p$rvsVEAlchFz*)&W zgkvc!Y0zGnSY$z-VDPeV(RRIk0^1din{~uY9r3R5LvfpAEq;*``$_~}-s^#DEGG5s z4vrUUUHIsBOoP670R;MvZ}MneZNd)d_XrX@FEW3r4ymG+CaF?TBH6bg42}!G>$&vH z(*>+{7H4h5J_=HrD6cnj8OpQKK?#W6H+I)Q;cC`dH{pqlU&37pLw50S@Wl`C47ZEXv2=mja`938$+Yy**^kBS^dwr)FE=b<>z<#{(qm z*DGe81s8Fx+)TN;&wPEB2Oms&Z7i#BqO#d$bzZZH>eYIO=Fnf@%PIxe`kcx}I+Zw{ z=4Wwfdp-?QM2k5U{V?3=iEH&>%~Z&gFn3R~w)zctO*51`ppC~T)HZqsQc$kkB*K?-44x@Ul>kqcXQa`Dm$3s z|LYnYcdqe z^{iN!lNpu2kfRW`TKQqO!UC#w9a(gvg={{t0OV9@3Rs zDsGq8uCkWM5S-~R(Z8JVKDF)bEqIp+X8SazO`NOV`#8FIZ|zxa;%W*@A@vf6M+Cw@ z@Lf3e14?_~5e&z(J!9b6$iS-VdV1w#hX_2T_c0G)gl^dysBvJou^5OV&o}G0M|gR( zQvWYTuJrs}%?S1hdTqIe*thrJ(k#);GYR6q!XH|=*rQN&QiZ!Olh`$1!c+~;>9s~4 ziK|CYe*Qm9y<=Qv?fX4EHQ7xzX0mN-CfhbA+jdQEGNzhr+qP}nuK#ZC@9+6My}4dh z*FN`g9$af3YEZ0V7XI?cLu$C_r3PUffpO1SWQen8ik)TjN|88HJQNt0;z&P@n_SQm zL5xa}nh+!u{scv`u|*=D^dUkME7ODxT(PQUFfrJsPsX61>$oKivqdo_M%lSOP+FX6 z4sQ91+}zRj{B>JsuoDifQbLfkA44l6ku{f>%|uk(o}UGEPDafK-fbs97vyj}0&pAp z5r<7y;*+r75S*Ij9dVU&^VZz^`uo+I9I&{YEKNpJY88HxT`B-^L;&fhk#NTsFWPJm z4)*f=Ha4dXp%JK4SSZr&oOqU|J< zk~F;u_q;gWBlF_(8xoY!83PWhrS4!X$&5KmNo|j91OtSHmC8UYRI+T-l{kY%Zy1{8 zN<&Or8?O%qp6c{=vE9r6!Wa=~B7NZRJ{y^+`b-ZY%XASv+qG@Q5tn_=f*{1pqeBAQ zixUvqx{LyN<`Kfk9a`%BA2Z-JnS}Q|{3r`>nsn0Q1u#lVo#H)I0?EUw9UBR~%@O2f zxh;8ddo>l`Y$HXhe?$oAVP!US%IG}0YkS_Jv6i%^z9M=iCaw+#DHTtW3Z!DwB94ud zryM$aPeB)js|DHE-;a~IUhz(Q%3xqdFw7i715dZHP-&3H=bgbU6`ErzZjvb6^;0IF zKxobVin|}P8}QHzjrL@_6aG`#N_WKx$Kl~JAI27-0gqe}Kr!Mmg&~cMhp?;E>uF>| z@pAL}-ZOX|?0Wnp!;#t6YvTk_nw12Oxhf+OjkFk_at?`Ys6J^o|HDz54nBVPGDMaH z>Ka*xJvRargNu>R*OsC7Tjw*Jg;ug@axeKTe`;DAFQN;rHqRL1+ZlE_!K3?G(>2K1 zvMXQn*>ZU3FfVnmeD-J9q4|Oz7|JfCMcNr2t54t3$&@Y&9meA&G0^IMt`0TY?_=WQ z?;Xt+-vES`=ZYSluN{B7DTf(r<}4Sh0s&EjxNo&T9VR}&-vD{7{x^j@`M;M)pNR}2 zk=!Mf`9uXS?eA=giYc;e9N|DqztYyzXc6qXcf!`-_6Tzxi7Oy7VJbWmyE{?1?SUhL zlZUf2BR8fS-;X6RLO#(Eo3+0f&me#V+J~dL*)=t!SK57uD-OIRZsY#@6Zu6pwEx-MP#_ZykvzQl!±Vs=!nCx4HAGMyrv;u^ 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�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∈DEU5bKK+vO+H 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⩔*^+i3U3p(w6O4&~NL4x}_<_OevDzn+97G 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 literal 0 HcmV?d00001 diff --git a/registry/open-api-lambda/metadata.json b/registry/open-api-lambda/metadata.json new file mode 100644 index 00000000..1a5a25eb --- /dev/null +++ b/registry/open-api-lambda/metadata.json @@ -0,0 +1,89 @@ +{ + "overview": { + "namespace": "hasura", + "description": "The Open API Lambda Connector allows you to import already existing APIs specified by the Open API Spec into you Hasura DDN subgraphs", + "title": "Open API Lambda Connector", + "logo": "logo.png", + "tags": [], + "latest_version": "v0.1.1" + }, + "author": { + "support_email": "support@hasura.io", + "homepage": "https://hasura.io", + "name": "Hasura" + }, + "is_verified": true, + "is_hosted_by_hasura": false, + "packages": [ + { + "version": "v0.0.1-alpha", + "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.0.1-alpha/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "0fd96c602f79f50a11b0cc94980559af1a4fc5f26e356bfba9859d53ab92ddcc" + }, + "source": { + "hash": "3cc70a7c4715c72e8dcb56c78c66967c5f687148" + } + }, + { + "version": "v0.0.2-alpha", + "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.0.2-alpha/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "25ec7152d795871e1d2944665ef48012520181afaf6f7c66a030c3a443edbeb3" + }, + "source": { + "hash": "35ba5da05dba1602fea40a3a8fba3652fd1c3e12" + } + }, + { + "version": "v0.1.0", + "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "f371014bc0f8a873644bd0127531aa6354b9fca1e5680b12c567c3a3fc4204a5" + }, + "source": { + "hash": "d0c628e9206d397373f42faaf3733f6ada94b56c" + } + }, + { + "version": "v0.1.1", + "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.1.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "a7365a6f7780dcfae85cc787e2de83ea22d416a1d4a9fc597b68227bf978e264" + }, + "source": { + "hash": "4b70712933de7a7ed475407ccd0be7bed1611ae8" + } + } + ], + "source_code": { + "is_open_source": true, + "repository": "https://github.com/hasura/ndc-open-api-lambda/", + "version": [ + { + "tag": "v0.0.1-alpha", + "hash": "3cc70a7c4715c72e8dcb56c78c66967c5f687148", + "is_verified": true + }, + { + "tag": "v0.0.2-alpha", + "hash": "35ba5da05dba1602fea40a3a8fba3652fd1c3e12", + "is_verified": true + }, + { + "tag": "v0.1.0", + "hash": "d0c628e9206d397373f42faaf3733f6ada94b56c", + "is_verified": true + }, + { + "tag": "v0.1.1", + "hash": "4b70712933de7a7ed475407ccd0be7bed1611ae8", + "is_verified": true + } + ] + } +} From fe880778feb5d5d719a50f7b60c7db75fb12bda2 Mon Sep 17 00:00:00 2001 From: Gil Mizrahi Date: Thu, 4 Jul 2024 16:40:13 +0300 Subject: [PATCH 024/135] ndc-postgres v0.8.0 (#194) https://github.com/hasura/ndc-postgres/releases/tag/v0.8.0 --- registry/aurora/metadata.json | 7 ++++++- registry/citus/metadata.json | 7 ++++++- registry/cockroach/metadata.json | 7 ++++++- registry/neon/metadata.json | 7 ++++++- registry/postgres-alloydb/metadata.json | 7 ++++++- registry/postgres-azure/metadata.json | 7 ++++++- registry/postgres-cosmos/metadata.json | 7 ++++++- registry/postgres-gcp/metadata.json | 7 ++++++- registry/postgres-timescaledb/metadata.json | 7 ++++++- registry/postgres/metadata.json | 7 ++++++- 10 files changed, 60 insertions(+), 10 deletions(-) diff --git a/registry/aurora/metadata.json b/registry/aurora/metadata.json index 4dd8a6cd..715df6ae 100644 --- a/registry/aurora/metadata.json +++ b/registry/aurora/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.1" + "latest_version": "v0.8.0" }, "author": { "support_email": "support@hasura.io", @@ -39,6 +39,11 @@ "tag": "v0.7.1", "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", "is_verified": true + }, + { + "tag": "v0.8.0", + "hash": "4513112", + "is_verified": true } ] } diff --git a/registry/citus/metadata.json b/registry/citus/metadata.json index 30771aed..693a6ef3 100644 --- a/registry/citus/metadata.json +++ b/registry/citus/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.1" + "latest_version": "v0.8.0" }, "author": { "support_email": "support@hasura.io", @@ -39,6 +39,11 @@ "tag": "v0.7.1", "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", "is_verified": true + }, + { + "tag": "v0.8.0", + "hash": "4513112", + "is_verified": true } ] } diff --git a/registry/cockroach/metadata.json b/registry/cockroach/metadata.json index 288c3123..41bec5cf 100644 --- a/registry/cockroach/metadata.json +++ b/registry/cockroach/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.1" + "latest_version": "v0.8.0" }, "author": { "support_email": "support@hasura.io", @@ -39,6 +39,11 @@ "tag": "v0.7.1", "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", "is_verified": true + }, + { + "tag": "v0.8.0", + "hash": "4513112", + "is_verified": true } ] } diff --git a/registry/neon/metadata.json b/registry/neon/metadata.json index 053fe2a9..81cf70aa 100644 --- a/registry/neon/metadata.json +++ b/registry/neon/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.1" + "latest_version": "v0.8.0" }, "author": { "support_email": "support@hasura.io", @@ -39,6 +39,11 @@ "tag": "v0.7.1", "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", "is_verified": true + }, + { + "tag": "v0.8.0", + "hash": "4513112", + "is_verified": true } ] } diff --git a/registry/postgres-alloydb/metadata.json b/registry/postgres-alloydb/metadata.json index 050f9040..4f7b088b 100644 --- a/registry/postgres-alloydb/metadata.json +++ b/registry/postgres-alloydb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.1" + "latest_version": "v0.8.0" }, "author": { "support_email": "support@hasura.io", @@ -39,6 +39,11 @@ "tag": "v0.7.1", "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", "is_verified": true + }, + { + "tag": "v0.8.0", + "hash": "4513112", + "is_verified": true } ] } diff --git a/registry/postgres-azure/metadata.json b/registry/postgres-azure/metadata.json index a136f9dd..7c3ab8a8 100644 --- a/registry/postgres-azure/metadata.json +++ b/registry/postgres-azure/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.1" + "latest_version": "v0.8.0" }, "author": { "support_email": "support@hasura.io", @@ -39,6 +39,11 @@ "tag": "v0.7.1", "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", "is_verified": true + }, + { + "tag": "v0.8.0", + "hash": "4513112", + "is_verified": true } ] } diff --git a/registry/postgres-cosmos/metadata.json b/registry/postgres-cosmos/metadata.json index e674ccdb..cf48fc27 100644 --- a/registry/postgres-cosmos/metadata.json +++ b/registry/postgres-cosmos/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.1" + "latest_version": "v0.8.0" }, "author": { "support_email": "support@hasura.io", @@ -39,6 +39,11 @@ "tag": "v0.7.1", "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", "is_verified": true + }, + { + "tag": "v0.8.0", + "hash": "4513112", + "is_verified": true } ] } diff --git a/registry/postgres-gcp/metadata.json b/registry/postgres-gcp/metadata.json index 3ad0d7fe..73f6f28f 100644 --- a/registry/postgres-gcp/metadata.json +++ b/registry/postgres-gcp/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.1" + "latest_version": "v0.8.0" }, "author": { "support_email": "support@hasura.io", @@ -39,6 +39,11 @@ "tag": "v0.7.1", "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", "is_verified": true + }, + { + "tag": "v0.8.0", + "hash": "4513112", + "is_verified": true } ] } diff --git a/registry/postgres-timescaledb/metadata.json b/registry/postgres-timescaledb/metadata.json index d81f8a45..c2b28416 100644 --- a/registry/postgres-timescaledb/metadata.json +++ b/registry/postgres-timescaledb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.1" + "latest_version": "v0.8.0" }, "author": { "support_email": "support@hasura.io", @@ -39,6 +39,11 @@ "tag": "v0.7.1", "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", "is_verified": true + }, + { + "tag": "v0.8.0", + "hash": "4513112", + "is_verified": true } ] } diff --git a/registry/postgres/metadata.json b/registry/postgres/metadata.json index 49037465..dfa400af 100644 --- a/registry/postgres/metadata.json +++ b/registry/postgres/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.7.1" + "latest_version": "v0.8.0" }, "author": { "support_email": "support@hasura.io", @@ -39,6 +39,11 @@ "tag": "v0.7.1", "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13", "is_verified": true + }, + { + "tag": "v0.8.0", + "hash": "4513112", + "is_verified": true } ] } From 0834444ffd73c179d759111057c32f968bee7d1f Mon Sep 17 00:00:00 2001 From: Brandon Martin Date: Wed, 10 Jul 2024 07:07:45 -0600 Subject: [PATCH 025/135] MongoDB v1.0.0 (#196) https://github.com/hasura/ndc-mongodb/releases/tag/v1.0.0 --- registry/mongodb/metadata.json | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/registry/mongodb/metadata.json b/registry/mongodb/metadata.json index 334b069e..53e9e124 100644 --- a/registry/mongodb/metadata.json +++ b/registry/mongodb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.1.0" + "latest_version": "v1.0.0" }, "author": { "support_email": "support@hasura.io", @@ -17,6 +17,17 @@ "is_verified": true, "is_hosted_by_hasura": false, "packages": [ + { + "version": "1.0.0", + "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v1.0.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "0dc038620f40911a2c5662b61d8e2ac9605876c80b3eb3cbae5cc1ebcd5b611f" + }, + "source": { + "hash": "4beb7ddabddc3035ca5cc7bd85493a71a2e34147" + } + }, { "version": "0.1.0", "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.1.0/connector-definition.tgz", @@ -99,6 +110,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-mongodb/", "version": [ + { + "tag": "v1.0.0", + "hash": "4beb7ddabddc3035ca5cc7bd85493a71a2e34147", + "is_verified": true + }, { "tag": "v0.1.0", "hash": "175272912b86a11359a9b6b7fd72c7a6e2326bf1", From cdca87df24e624d98a9d2616d3e78f6618ed1008 Mon Sep 17 00:00:00 2001 From: Gavin Ray Date: Wed, 10 Jul 2024 09:37:12 -0700 Subject: [PATCH 026/135] Initial commit for JVM connectors (#192) Co-authored-by: gneeri --- registry/mysql/README.md | 169 ++++++++++++++++++++++++++++++ registry/mysql/metadata.json | 43 ++++++++ registry/oracle/README.md | 169 ++++++++++++++++++++++++++++++ registry/oracle/metadata.json | 43 ++++++++ registry/snowflake/README.md | 170 +++++++++++++++++++++++++++++++ registry/snowflake/metadata.json | 43 ++++++++ 6 files changed, 637 insertions(+) create mode 100644 registry/mysql/README.md create mode 100644 registry/mysql/metadata.json create mode 100644 registry/oracle/README.md create mode 100644 registry/oracle/metadata.json create mode 100644 registry/snowflake/README.md create mode 100644 registry/snowflake/metadata.json diff --git a/registry/mysql/README.md b/registry/mysql/README.md new file mode 100644 index 00000000..e5617968 --- /dev/null +++ b/registry/mysql/README.md @@ -0,0 +1,169 @@ +# MySQL Connector + +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/getting-started/overview/) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-sqlserver-blue.svg?style=flat)](https://hasura.io/connectors/sqlserver) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) +[![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) + +With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in +MySQL. This connector supports MySQL's functionalities listed in the table below, allowing for +efficient and scalable data operations. Additionally, users benefit from all the powerful features of Hasura’s Data +Delivery Network (DDN) platform, including query pushdown capabilities that delegate query operations to the database, +thereby enhancing query optimization and performance. + +This connector implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). + +- [Connector information in the Hasura Hub](https://hasura.io/connectors/mysql) +- [Hasura V3 Documentation](https://hasura.io/docs/3.0) + +## Features + +Below, you'll find a matrix of all supported features for the MySQL connector: + +| Feature | Supported | Notes | +| ------------------------------- | --------- | ----- | +| Native Queries + Logical Models | ✅ | | +| Native Mutations | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ✅ | | +| Views | ✅ | | +| Remote Relationships | ✅ | | +| Custom Fields | ❌ | | +| Mutations | ❌ | | +| Distinct | ❌ | | +| Enums | ❌ | | +| Naming Conventions | ❌ | | +| Default Values | ❌ | | +| User-defined Functions | ❌ | | + +## Before you get Started + +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Install the [CLI](https://hasura.io/docs/3.0/cli/installation/) +3. Install the [Hasura VS Code extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) +4. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +5. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) + +## Using the connector + +To use the MySQL connector, follow these steps in a Hasura project: +(Note: for more information on the following steps, please refer to the Postgres connector +documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) + +### 1. Init the connector + +(Note: here and following we are naming the subgraph "my_subgraph" and the connector "my_mysql") + + ```bash + ddn connector init my_mysql --subgraph my_subgraph --hub-connector hasura/MySQL + ``` + +### 2. Add your MySQL credentials: + +Add your credentials to `my_subgraph/connector/my_sql/.env.local` + +```env title="my_subgraph/connector/my_mysql/.env.local" +JDBC_URL="jdbc:MySQL:thin:@//host.docker.internal:1521/XE?user=&password=" +``` + +### 3. Introspect your indices + +```bash title="From the root of your project run:" +ddn connector introspect --connector my_subgraph/connector/my_mysql/connector.yaml +``` + +If you look at the `configuration.json` for your connector, you'll see metadata describing your MySQL mappings. + +### 4. Create the Hasura metadata + +```bash title="Run the following from the root of your project:" +ddn connector-link add my_mysql --subgraph my_subgraph +``` + +The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your +subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the +connector. Ensure the port value matches what is published in your connector's docker compose file. + +```env title="my_subgraph/.env.my_subgraph" +MY_SUBGRAPH_my_mysql_READ_URL=http://local.hasura.dev:8081 +MY_SUBGRAPH_my_mysql_WRITE_URL=http://local.hasura.dev:8081 +``` + +### 5. Start the connector's docker compose + +Let's start our connector's docker compose file. + +```bash title="Run the following from the connector's subdirectory inside a subgraph:" +docker compose -f docker-compose.my_mysql.yaml up +``` + +This starts our MySQL connector on the specified port. We can navigate to the following address, with the port +modified, to see the schema of our MySQL data source: + +```bash +http://localhost:8081/schema +``` + +### 6. Include the connector in your docker compose + +Kill the connector by pressing `CTRL+C` in the terminal tab in which the connector is running. + +Then, add the following inclusion to the docker compose `docker-compose.hasura.yaml` in your project's root directory, +taking care to modify the +subgraph's name. + +```yaml title="docker-compose.hasura.yaml" +include: + - path: my_subgraph/connector/my_mysql/docker-compose.my_mysql.yaml +``` + +Now, whenever running the following, you'll bring up the GraphQL engine, observability tools, and any connectors you've +included: + +```bash title="From the root of your project, run:" +HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yaml watch +``` + +### 7. Update the new DataConnectorLink object + +Finally, now that our `DataConnectorLink` has the correct environment variables configured for the MySQL connector, +we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's +schema in `hml` format. In a new terminal tab, run: + +```bash title="From the root of your project, run:" +ddn connector-link update my_mysql --subgraph my_subgraph +``` + +After this command runs, you can open your `my_subgraph/metadata/my_mysql.hml` file and see your metadata completely +scaffolded out for you 🎉 + +### 8. Import _all_ your indices + +You can do this in one convenience command. + +```bash title="From the root of your project, run:" +ddn connector-link update my_mysql --subgraph my_subgraph --add-all-resources +``` + +### 9. Create a supergraph build + +Pass the `local` subcommand along with specifying the output directory as `./engine` in the root of the project. This +directory is used by the docker-compose file to serve the engine locally: + +```bash title="From the root of your project, run:" +ddn supergraph build local --output-dir ./engine +``` + +You can now navigate to +[`https://console.hasura.io/local/graphql?url=http://localhost:3000`](https://console.hasura.io/local/graphql?url=http://localhost:3000) +and interact with your API using the Hasura Console. + + +## License + +The Hasura MySQL connector is available under the [Apache License +2.0](https://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file diff --git a/registry/mysql/metadata.json b/registry/mysql/metadata.json new file mode 100644 index 00000000..4d991b39 --- /dev/null +++ b/registry/mysql/metadata.json @@ -0,0 +1,43 @@ +{ + "overview": { + "namespace": "hasura", + "description": "Connect to a MySQL database and expose it to Hasura v3 Project", + "title": "MySQL Connector", + "logo": "logo.png", + "tags": [ + "database" + ], + "latest_version": "v0.1.0" + }, + "author": { + "support_email": "support@hasura.io", + "homepage": "https://hasura.io", + "name": "Hasura" + }, + "is_verified": true, + "is_hosted_by_hasura": true, + "packages": [ + { + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/mysql%2Fv0.1.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "09b51f9be725099345159880d21efb712776bfd09291a0daa81d7e7b1418ca2c" + }, + "source": { + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" + } + } + ], + "source_code": { + "is_open_source": true, + "repository": "https://github.com/hasura/ndc-jvm-mono", + "version": [ + { + "tag": "mysql/v0.1.0", + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e", + "is_verified": true + } + ] + } +} \ No newline at end of file diff --git a/registry/oracle/README.md b/registry/oracle/README.md new file mode 100644 index 00000000..604f318c --- /dev/null +++ b/registry/oracle/README.md @@ -0,0 +1,169 @@ +# Oracle Connector + +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/getting-started/overview/) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-sqlserver-blue.svg?style=flat)](https://hasura.io/connectors/sqlserver) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) +[![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) + +With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in +Oracle. This connector supports Oracle's functionalities listed in the table below, allowing for +efficient and scalable data operations. Additionally, users benefit from all the powerful features of Hasura’s Data +Delivery Network (DDN) platform, including query pushdown capabilities that delegate query operations to the database, +thereby enhancing query optimization and performance. + +This connector implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). + +- [Connector information in the Hasura Hub](https://hasura.io/connectors/oracle) +- [Hasura V3 Documentation](https://hasura.io/docs/3.0) + +## Features + +Below, you'll find a matrix of all supported features for the Oracle connector: + +| Feature | Supported | Notes | +|---------------------------------|-----------|-------| +| Native Queries + Logical Models | ✅ | | +| Native Mutations | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ✅ | | +| Views | ✅ | | +| Remote Relationships | ✅ | | +| Custom Fields | ❌ | | +| Mutations | ❌ | | +| Distinct | ❌ | | +| Enums | ❌ | | +| Naming Conventions | ❌ | | +| Default Values | ❌ | | +| User-defined Functions | ❌ | | + +## Before you get Started + +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Install the [CLI](https://hasura.io/docs/3.0/cli/installation/) +3. Install the [Hasura VS Code extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) +4. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +5. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) + +## Using the connector + +To use the Oracle connector, follow these steps in a Hasura project: +(Note: for more information on the following steps, please refer to the Postgres connector +documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) + +### 1. Init the connector + +(Note: here and following we are naming the subgraph "my_subgraph" and the connector "my_oracle") + + ```bash + ddn connector init my_oracle --subgraph my_subgraph --hub-connector hasura/Oracle + ``` + +### 2. Add your Oracle credentials: + +Add your credentials to `my_subgraph/connector/my_sql/.env.local` + +```env title="my_subgraph/connector/my_oracle/.env.local" +JDBC_URL="jdbc:oracle:thin:@//host.docker.internal:1521/XE?user=&password=" +``` + +### 3. Introspect your indices + +```bash title="From the root of your project run:" +ddn connector introspect --connector my_subgraph/connector/my_oracle/connector.yaml +``` + +If you look at the `configuration.json` for your connector, you'll see metadata describing your Oracle mappings. + +### 4. Create the Hasura metadata + +```bash title="Run the following from the root of your project:" +ddn connector-link add my_oracle --subgraph my_subgraph +``` + +The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your +subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the +connector. Ensure the port value matches what is published in your connector's docker compose file. + +```env title="my_subgraph/.env.my_subgraph" +MY_SUBGRAPH_my_oracle_READ_URL=http://local.hasura.dev:8081 +MY_SUBGRAPH_my_oracle_WRITE_URL=http://local.hasura.dev:8081 +``` + +### 5. Start the connector's docker compose + +Let's start our connector's docker compose file. + +```bash title="Run the following from the connector's subdirectory inside a subgraph:" +docker compose -f docker-compose.my_oracle.yaml up +``` + +This starts our Oracle connector on the specified port. We can navigate to the following address, with the port +modified, to see the schema of our Oracle data source: + +```bash +http://localhost:8081/schema +``` + +### 6. Include the connector in your docker compose + +Kill the connector by pressing `CTRL+C` in the terminal tab in which the connector is running. + +Then, add the following inclusion to the docker compose `docker-compose.hasura.yaml` in your project's root directory, +taking care to modify the +subgraph's name. + +```yaml title="docker-compose.hasura.yaml" +include: + - path: my_subgraph/connector/my_oracle/docker-compose.my_oracle.yaml +``` + +Now, whenever running the following, you'll bring up the GraphQL engine, observability tools, and any connectors you've +included: + +```bash title="From the root of your project, run:" +HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yaml watch +``` + +### 7. Update the new DataConnectorLink object + +Finally, now that our `DataConnectorLink` has the correct environment variables configured for the Oracle connector, +we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's +schema in `hml` format. In a new terminal tab, run: + +```bash title="From the root of your project, run:" +ddn connector-link update my_oracle --subgraph my_subgraph +``` + +After this command runs, you can open your `my_subgraph/metadata/my_oracle.hml` file and see your metadata completely +scaffolded out for you 🎉 + +### 8. Import _all_ your indices + +You can do this in one convenience command. + +```bash title="From the root of your project, run:" +ddn connector-link update my_oracle --subgraph my_subgraph --add-all-resources +``` + +### 9. Create a supergraph build + +Pass the `local` subcommand along with specifying the output directory as `./engine` in the root of the project. This +directory is used by the docker-compose file to serve the engine locally: + +```bash title="From the root of your project, run:" +ddn supergraph build local --output-dir ./engine +``` + +You can now navigate to +[`https://console.hasura.io/local/graphql?url=http://localhost:3000`](https://console.hasura.io/local/graphql?url=http://localhost:3000) +and interact with your API using the Hasura Console. + + +## License + +The Hasura Oracle connector is available under the [Apache License +2.0](https://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file diff --git a/registry/oracle/metadata.json b/registry/oracle/metadata.json new file mode 100644 index 00000000..f91d7b3b --- /dev/null +++ b/registry/oracle/metadata.json @@ -0,0 +1,43 @@ +{ + "overview": { + "namespace": "hasura", + "description": "Connect to an Oracle database and expose it to Hasura v3 Project", + "title": "Oracle Connector", + "logo": "logo.png", + "tags": [ + "database" + ], + "latest_version": "v0.1.0" + }, + "author": { + "support_email": "support@hasura.io", + "homepage": "https://hasura.io", + "name": "Hasura" + }, + "is_verified": true, + "is_hosted_by_hasura": true, + "packages": [ + { + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/oracle%2Fv0.1.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "0d837408a213f55df34062b96a2ac7fabcf8c61891918b6b2754d90fc61dd24c" + }, + "source": { + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" + } + } + ], + "source_code": { + "is_open_source": true, + "repository": "https://github.com/hasura/ndc-jvm-mono", + "version": [ + { + "tag": "oracle/v0.1.0", + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e", + "is_verified": true + } + ] + } +} \ No newline at end of file diff --git a/registry/snowflake/README.md b/registry/snowflake/README.md new file mode 100644 index 00000000..b967a94d --- /dev/null +++ b/registry/snowflake/README.md @@ -0,0 +1,170 @@ +# Snowflake Connector + +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/getting-started/overview/) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-sqlserver-blue.svg?style=flat)](https://hasura.io/connectors/sqlserver) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) +[![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) + +With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in +Snowflake. This connector supports Snowflake's functionalities listed in the table below, allowing for +efficient and scalable data operations. Additionally, users benefit from all the powerful features of Hasura’s Data +Delivery Network (DDN) platform, including query pushdown capabilities that delegate query operations to the database, +thereby enhancing query optimization and performance. + +This connector implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). + +- [Connector information in the Hasura Hub](https://hasura.io/connectors/snowflake) +- [Hasura V3 Documentation](https://hasura.io/docs/3.0) + +## Features + +Below, you'll find a matrix of all supported features for the Snowflake connector: + +| Feature | Supported | Notes | +| ------------------------------- | --------- | ----- | +| Native Queries + Logical Models | ✅ | | +| Native Mutations | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ✅ | | +| Views | ✅ | | +| Remote Relationships | ✅ | | +| Custom Fields | ❌ | | +| Mutations | ❌ | | +| Distinct | ❌ | | +| Enums | ❌ | | +| Naming Conventions | ❌ | | +| Default Values | ❌ | | +| User-defined Functions | ❌ | | + +## Before you get Started + +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Install the [CLI](https://hasura.io/docs/3.0/cli/installation/) +3. Install the [Hasura VS Code extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) +4. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +5. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) + +## Using the connector + +To use the Snowflake connector, follow these steps in a Hasura project: +(Note: for more information on the following steps, please refer to the Postgres connector +documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) + +### 1. Init the connector + +(Note: here and following we are naming the subgraph "my_subgraph" and the connector "my_snowflake") + + ```bash + ddn connector init my_snowflake --subgraph my_subgraph --hub-connector hasura/snowflake + ``` + +### 2. Add your Snowflake credentials: + +Add your credentials to `my_subgraph/connector/my_sql/.env.local` + +```env title="my_subgraph/connector/my_snowflake/.env.local" +JDBC_URL="jdbc:snowflake://ak1234.us-east-2.aws.snowflakecomputing.com/?user=&password=&db=CHINOOK&schema=PUBLIC&warehouse=COMPUTE_WH&role=ACCOUNTADMIN" +JDBC_SCHEMAS=PUBLIC +``` + +### 3. Introspect your indices + +```bash title="From the root of your project run:" +ddn connector introspect --connector my_subgraph/connector/my_snowflake/connector.yaml +``` + +If you look at the `configuration.json` for your connector, you'll see metadata describing your Snowflake mappings. + +### 4. Create the Hasura metadata + +```bash title="Run the following from the root of your project:" +ddn connector-link add my_snowflake --subgraph my_subgraph +``` + +The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your +subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the +connector. Ensure the port value matches what is published in your connector's docker compose file. + +```env title="my_subgraph/.env.my_subgraph" +MY_SUBGRAPH_MY_SNOWFLAKE_READ_URL=http://local.hasura.dev:8081 +MY_SUBGRAPH_MY_SNOWFLAKE_WRITE_URL=http://local.hasura.dev:8081 +``` + +### 5. Start the connector's docker compose + +Let's start our connector's docker compose file. + +```bash title="Run the following from the connector's subdirectory inside a subgraph:" +docker compose -f docker-compose.my_snowflake.yaml up +``` + +This starts our Snowflake connector on the specified port. We can navigate to the following address, with the port +modified, to see the schema of our Snowflake data source: + +```bash +http://localhost:8081/schema +``` + +### 6. Include the connector in your docker compose + +Kill the connector by pressing `CTRL+C` in the terminal tab in which the connector is running. + +Then, add the following inclusion to the docker compose `docker-compose.hasura.yaml` in your project's root directory, +taking care to modify the +subgraph's name. + +```yaml title="docker-compose.hasura.yaml" +include: + - path: my_subgraph/connector/my_snowflake/docker-compose.my_snowflake.yaml +``` + +Now, whenever running the following, you'll bring up the GraphQL engine, observability tools, and any connectors you've +included: + +```bash title="From the root of your project, run:" +HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yaml watch +``` + +### 7. Update the new DataConnectorLink object + +Finally, now that our `DataConnectorLink` has the correct environment variables configured for the Snowflake connector, +we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's +schema in `hml` format. In a new terminal tab, run: + +```bash title="From the root of your project, run:" +ddn connector-link update my_snowflake --subgraph my_subgraph +``` + +After this command runs, you can open your `my_subgraph/metadata/my_snowflake.hml` file and see your metadata completely +scaffolded out for you 🎉 + +### 8. Import _all_ your indices + +You can do this in one convenience command. + +```bash title="From the root of your project, run:" +ddn connector-link update my_snowflake --subgraph my_subgraph --add-all-resources +``` + +### 9. Create a supergraph build + +Pass the `local` subcommand along with specifying the output directory as `./engine` in the root of the project. This +directory is used by the docker-compose file to serve the engine locally: + +```bash title="From the root of your project, run:" +ddn supergraph build local --output-dir ./engine +``` + +You can now navigate to +[`https://console.hasura.io/local/graphql?url=http://localhost:3000`](https://console.hasura.io/local/graphql?url=http://localhost:3000) +and interact with your API using the Hasura Console. + + +## License + +The Hasura Snowflake connector is available under the [Apache License +2.0](https://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file diff --git a/registry/snowflake/metadata.json b/registry/snowflake/metadata.json new file mode 100644 index 00000000..d6c317ed --- /dev/null +++ b/registry/snowflake/metadata.json @@ -0,0 +1,43 @@ +{ + "overview": { + "namespace": "hasura", + "description": "Connect to a Snowflake database and expose it to Hasura v3 Project", + "title": "Snowflake Connector", + "logo": "logo.png", + "tags": [ + "database" + ], + "latest_version": "v0.1.0" + }, + "author": { + "support_email": "support@hasura.io", + "homepage": "https://hasura.io", + "name": "Hasura" + }, + "is_verified": true, + "is_hosted_by_hasura": true, + "packages": [ + { + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/snowflake%2Fv0.1.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "564757bc44bebe56560fe21a1306507d160caf084d69556bded4a7ed392e1b41" + }, + "source": { + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" + } + } + ], + "source_code": { + "is_open_source": true, + "repository": "https://github.com/hasura/ndc-jvm-mono", + "version": [ + { + "tag": "snowflake/v0.1.0", + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e", + "is_verified": true + } + ] + } +} \ No newline at end of file From 684959de86a0e1eb146b76580b08c99b313d9d1e Mon Sep 17 00:00:00 2001 From: gneeri Date: Thu, 11 Jul 2024 10:03:36 -0400 Subject: [PATCH 027/135] added missing logos for mysql, oracle and snowflake (#198) --- registry/mysql/logo.svg | 2 ++ registry/oracle/logo.svg | 4 ++++ registry/snowflake/logo.svg | 9 +++++++++ 3 files changed, 15 insertions(+) create mode 100644 registry/mysql/logo.svg create mode 100644 registry/oracle/logo.svg create mode 100644 registry/snowflake/logo.svg diff --git a/registry/mysql/logo.svg b/registry/mysql/logo.svg new file mode 100644 index 00000000..53371d09 --- /dev/null +++ b/registry/mysql/logo.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/registry/oracle/logo.svg b/registry/oracle/logo.svg new file mode 100644 index 00000000..3f4e051f --- /dev/null +++ b/registry/oracle/logo.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/registry/snowflake/logo.svg b/registry/snowflake/logo.svg new file mode 100644 index 00000000..e88dcad6 --- /dev/null +++ b/registry/snowflake/logo.svg @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file From a501e378d6e4e22b1debc03bddf921c0044b39dc Mon Sep 17 00:00:00 2001 From: gneeri Date: Thu, 11 Jul 2024 10:19:50 -0400 Subject: [PATCH 028/135] updated metadata for svg logos (#199) --- registry/mysql/metadata.json | 4 ++-- registry/oracle/metadata.json | 4 ++-- registry/snowflake/metadata.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/registry/mysql/metadata.json b/registry/mysql/metadata.json index 4d991b39..38652674 100644 --- a/registry/mysql/metadata.json +++ b/registry/mysql/metadata.json @@ -3,7 +3,7 @@ "namespace": "hasura", "description": "Connect to a MySQL database and expose it to Hasura v3 Project", "title": "MySQL Connector", - "logo": "logo.png", + "logo": "logo.svg", "tags": [ "database" ], @@ -40,4 +40,4 @@ } ] } -} \ No newline at end of file +} diff --git a/registry/oracle/metadata.json b/registry/oracle/metadata.json index f91d7b3b..94604b66 100644 --- a/registry/oracle/metadata.json +++ b/registry/oracle/metadata.json @@ -3,7 +3,7 @@ "namespace": "hasura", "description": "Connect to an Oracle database and expose it to Hasura v3 Project", "title": "Oracle Connector", - "logo": "logo.png", + "logo": "logo.svg", "tags": [ "database" ], @@ -40,4 +40,4 @@ } ] } -} \ No newline at end of file +} diff --git a/registry/snowflake/metadata.json b/registry/snowflake/metadata.json index d6c317ed..93084ae9 100644 --- a/registry/snowflake/metadata.json +++ b/registry/snowflake/metadata.json @@ -3,7 +3,7 @@ "namespace": "hasura", "description": "Connect to a Snowflake database and expose it to Hasura v3 Project", "title": "Snowflake Connector", - "logo": "logo.png", + "logo": "logo.svg", "tags": [ "database" ], @@ -40,4 +40,4 @@ } ] } -} \ No newline at end of file +} From a0d342c51fc263f308c41412c1679a3668bc6f1f Mon Sep 17 00:00:00 2001 From: pranshi06 <85474619+pranshi06@users.noreply.github.com> Date: Wed, 17 Jul 2024 19:19:00 +0530 Subject: [PATCH 029/135] update Azure Cosmos README according to CLI v1.0.0 (#201) --- registry/azure-cosmos/README.md | 78 ++++++++++++--------------------- 1 file changed, 28 insertions(+), 50 deletions(-) diff --git a/registry/azure-cosmos/README.md b/registry/azure-cosmos/README.md index 70df2d45..ede56fad 100644 --- a/registry/azure-cosmos/README.md +++ b/registry/azure-cosmos/README.md @@ -49,7 +49,7 @@ To use the Azure Cosmos DB for NoSQL connector, follow these steps in a Hasura p (Note: here and following we are naming the subgraph "my_subgraph" and the connector "my_azure_cosmos") ```bash - ddn connector init my_azure_cosmos --subgraph my_subgraph --hub-connector hasura/azure-cosmos + ddn connector init my_azure_cosmos --subgraph my_subgraph/subgraph.yaml --hub-connector hasura/azure-cosmos --configure-port 8081 --add-to-compose-file compose.yaml ``` ### 2. Add your Azure Cosmos DB for NoSQL credentials @@ -67,95 +67,73 @@ AZURE_COSMOS_NO_OF_ROWS_TO_FETCH= Note: `AZURE_COSMOS_CONNECTOR_NO_OF_ROWS_TO_FETCH` is an optional field, with 100 rows to be fetched by default. -### 3. Introspect your indices +### 3. Introspect your Database From the root of your project run: ```bash title="From the root of your project run:" -ddn connector introspect --connector my_subgraph/connector/my_azure_cosmos/connector.yaml +ddn connector introspect --connector my_subgraph/connector/my_azure_cosmos/connector.local.yaml ``` If you look at the `config.json` for your connector, you'll see metadata describing your Azure Cosmos DB for NoSQL mappings. -### 4. Create the Hasura metadata +### 4. Restart the services -Run the following from the root of your project: +Let's restart the docker compose services. Run the folowing from the root of your project: -```bash title="Run the following from the root of your project:" -ddn connector-link add my_azure_cosmos --subgraph my_subgraph -``` - -The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your -subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the -connector. Ensure the port value matches what is published in your connector's docker compose file. - -```env title="my_subgraph/.env.my_subgraph" -MY_SUBGRAPH_MY_AZURE_COSMOS_READ_URL=http://local.hasura.dev:8081 -MY_SUBGRAPH_MY_AZURE_COSMOS_WRITE_URL=http://local.hasura.dev:8081 +```bash title="From the root of your project run:" +HASURA_DDN_PAT=$(ddn auth print-pat) docker compose up --build --watch ``` -### 5. Start the connector's docker compose +The schema of the database can be viewed at http://localhost:8081/schema. -Let's start our connector's docker compose file. Run the following from the connector's subdirectory inside a subgraph: - -```bash title="Run the following from the connector's subdirectory inside a subgraph:" -docker compose -f docker-compose.my_azure_cosmos.yaml up -``` +### 5. Create the Hasura metadata -This starts our Azure Cosmos DB for NoSQL connector on the specified port. We can navigate to the following address, with the port -modified, to see the schema of our Azure Cosmos DB for NoSQL source: +In a new terminal tab from your project's root directory run: -```bash -http://localhost:8081/schema +```bash title="Run the following from the root of your project:" +ddn connector-link add my_azure_cosmos --subgraph my_subgraph/subgraph.yaml --configure-host http://local.hasura.dev:8081 --target-env-file my_subgraph/.env.my_subgraph.local ``` -### 6. Include the connector in your docker compose - -Kill the connector by pressing `CTRL+C` in the terminal tab in which the connector is running. +The above step will add the following env vars to the `.env.my_subgraph.local` file. -Then, add the following inclusion to the docker compose `docker-compose.hasura.yaml` in your project's root directory, taking care to modify the -subgraph's name. - -```yaml title="docker-compose.hasura.yaml" -include: - - path: my_subgraph/connector/my_azure_cosmos/docker-compose.my_azure_cosmos.yaml +```env title="my_subgraph/.env.my_subgraph.local" +MY_SUBGRAPH_MY_AZURE_COSMOS_READ_URL=http://local.hasura.dev:8081 +MY_SUBGRAPH_MY_AZURE_COSMOS_WRITE_URL=http://local.hasura.dev:8081 ``` -Now, whenever running the following, you'll bring up the GraphQL engine, observability tools, and any connectors you've -included. From the root of your project, run: - -```bash title="From the root of your project, run:" -HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yaml watch -``` +The generated file has two environment variables — one for reads and one for writes. +Each key is prefixed by the subgraph name, an underscore, and the name of the +connector. -### 7. Update the new DataConnectorLink object +### 6. Update the new DataConnectorLink object Finally, now that our `DataConnectorLink` has the correct environment variables configured for the Azure Cosmos DB for NoSQL connector, we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's -schema in `hml` format. In a new terminal tab from the root of your project, run: +schema in `hml` format. From your project's root directory, run: ```bash title="From the root of your project, run:" -ddn connector-link update my_azure_cosmos --subgraph my_subgraph +ddn connector-link update my_azure_cosmos --subgraph my_subgraph/subgraph.yaml --env-file my_subgraph/.env.my_subgraph.local ``` After this command runs, you can open your `my_subgraph/metadata/my_azure_cosmos.hml` file and see your metadata completely scaffolded out for you 🎉 -### 8. Import _all_ your indices +### 7. Import _all_ your indices -You can do this in one convenience command. From the root of your project, run: +You can do this with just one command. From your project's root directory, run: ```bash title="From the root of your project, run:" -ddn connector-link update my_azure_cosmos --subgraph my_subgraph --add-all-resources +ddn connector-link update my_azure_cosmos --subgraph my_subgraph/subgraph.yaml --env-file my_subgraph/.env.my_subgraph.local --add-all-resources ``` -### 9. Create a supergraph build +### 8. Create a supergraph build Pass the `local` subcommand along with specifying the output directory as `./engine` in the root of the project. This -directory is used by the docker-compose file to serve the engine locally. From the root of your project, run: +directory is used by the docker-compose file to serve the engine locally. From your project's root directory, run: ```bash title="From the root of your project, run:" -ddn supergraph build local --output-dir ./engine +ddn supergraph build local --output-dir engine --subgraph-env-file my_subgraph:my_subgraph/.env.my_subgraph.local ``` You can now navigate to From 89ee5cada5aeb0cc2a41e4544f183006e2921c19 Mon Sep 17 00:00:00 2001 From: Gil Mizrahi Date: Wed, 17 Jul 2024 17:53:04 +0300 Subject: [PATCH 030/135] ndc-postgres v1.0.0 (#202) https://github.com/hasura/ndc-postgres/releases/tag/v1.0.0 --- registry/aurora/metadata.json | 7 ++++++- registry/citus/metadata.json | 7 ++++++- registry/cockroach/metadata.json | 7 ++++++- registry/neon/metadata.json | 7 ++++++- registry/postgres-alloydb/metadata.json | 7 ++++++- registry/postgres-azure/metadata.json | 7 ++++++- registry/postgres-cosmos/metadata.json | 7 ++++++- registry/postgres-gcp/metadata.json | 7 ++++++- registry/postgres-timescaledb/metadata.json | 7 ++++++- registry/postgres/metadata.json | 7 ++++++- 10 files changed, 60 insertions(+), 10 deletions(-) diff --git a/registry/aurora/metadata.json b/registry/aurora/metadata.json index 715df6ae..7f6a0fc1 100644 --- a/registry/aurora/metadata.json +++ b/registry/aurora/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.8.0" + "latest_version": "v1.0.0" }, "author": { "support_email": "support@hasura.io", @@ -44,6 +44,11 @@ "tag": "v0.8.0", "hash": "4513112", "is_verified": true + }, + { + "tag": "v1.0.0", + "hash": "4af168d", + "is_verified": true } ] } diff --git a/registry/citus/metadata.json b/registry/citus/metadata.json index 693a6ef3..82cd60c7 100644 --- a/registry/citus/metadata.json +++ b/registry/citus/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.8.0" + "latest_version": "v1.0.0" }, "author": { "support_email": "support@hasura.io", @@ -44,6 +44,11 @@ "tag": "v0.8.0", "hash": "4513112", "is_verified": true + }, + { + "tag": "v1.0.0", + "hash": "4af168d", + "is_verified": true } ] } diff --git a/registry/cockroach/metadata.json b/registry/cockroach/metadata.json index 41bec5cf..5d7fbaff 100644 --- a/registry/cockroach/metadata.json +++ b/registry/cockroach/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.8.0" + "latest_version": "v1.0.0" }, "author": { "support_email": "support@hasura.io", @@ -44,6 +44,11 @@ "tag": "v0.8.0", "hash": "4513112", "is_verified": true + }, + { + "tag": "v1.0.0", + "hash": "4af168d", + "is_verified": true } ] } diff --git a/registry/neon/metadata.json b/registry/neon/metadata.json index 81cf70aa..87d58b4c 100644 --- a/registry/neon/metadata.json +++ b/registry/neon/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.8.0" + "latest_version": "v1.0.0" }, "author": { "support_email": "support@hasura.io", @@ -44,6 +44,11 @@ "tag": "v0.8.0", "hash": "4513112", "is_verified": true + }, + { + "tag": "v1.0.0", + "hash": "4af168d", + "is_verified": true } ] } diff --git a/registry/postgres-alloydb/metadata.json b/registry/postgres-alloydb/metadata.json index 4f7b088b..89ef6b2d 100644 --- a/registry/postgres-alloydb/metadata.json +++ b/registry/postgres-alloydb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.8.0" + "latest_version": "v1.0.0" }, "author": { "support_email": "support@hasura.io", @@ -44,6 +44,11 @@ "tag": "v0.8.0", "hash": "4513112", "is_verified": true + }, + { + "tag": "v1.0.0", + "hash": "4af168d", + "is_verified": true } ] } diff --git a/registry/postgres-azure/metadata.json b/registry/postgres-azure/metadata.json index 7c3ab8a8..7fc9f971 100644 --- a/registry/postgres-azure/metadata.json +++ b/registry/postgres-azure/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.8.0" + "latest_version": "v1.0.0" }, "author": { "support_email": "support@hasura.io", @@ -44,6 +44,11 @@ "tag": "v0.8.0", "hash": "4513112", "is_verified": true + }, + { + "tag": "v1.0.0", + "hash": "4af168d", + "is_verified": true } ] } diff --git a/registry/postgres-cosmos/metadata.json b/registry/postgres-cosmos/metadata.json index cf48fc27..38e975f0 100644 --- a/registry/postgres-cosmos/metadata.json +++ b/registry/postgres-cosmos/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.8.0" + "latest_version": "v1.0.0" }, "author": { "support_email": "support@hasura.io", @@ -44,6 +44,11 @@ "tag": "v0.8.0", "hash": "4513112", "is_verified": true + }, + { + "tag": "v1.0.0", + "hash": "4af168d", + "is_verified": true } ] } diff --git a/registry/postgres-gcp/metadata.json b/registry/postgres-gcp/metadata.json index 73f6f28f..db0da760 100644 --- a/registry/postgres-gcp/metadata.json +++ b/registry/postgres-gcp/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.8.0" + "latest_version": "v1.0.0" }, "author": { "support_email": "support@hasura.io", @@ -44,6 +44,11 @@ "tag": "v0.8.0", "hash": "4513112", "is_verified": true + }, + { + "tag": "v1.0.0", + "hash": "4af168d", + "is_verified": true } ] } diff --git a/registry/postgres-timescaledb/metadata.json b/registry/postgres-timescaledb/metadata.json index c2b28416..11dafbb7 100644 --- a/registry/postgres-timescaledb/metadata.json +++ b/registry/postgres-timescaledb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.8.0" + "latest_version": "v1.0.0" }, "author": { "support_email": "support@hasura.io", @@ -44,6 +44,11 @@ "tag": "v0.8.0", "hash": "4513112", "is_verified": true + }, + { + "tag": "v1.0.0", + "hash": "4af168d", + "is_verified": true } ] } diff --git a/registry/postgres/metadata.json b/registry/postgres/metadata.json index dfa400af..2152c623 100644 --- a/registry/postgres/metadata.json +++ b/registry/postgres/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.8.0" + "latest_version": "v1.0.0" }, "author": { "support_email": "support@hasura.io", @@ -44,6 +44,11 @@ "tag": "v0.8.0", "hash": "4513112", "is_verified": true + }, + { + "tag": "v1.0.0", + "hash": "4af168d", + "is_verified": true } ] } From 528beb448670e659daa7c4cc1626653aea2e60ba Mon Sep 17 00:00:00 2001 From: Sean Park-Ross <94021366+seanparkross@users.noreply.github.com> Date: Thu, 18 Jul 2024 16:01:05 +0100 Subject: [PATCH 031/135] Fix hub connector name (#206) Name needs to be lowercase to work. --- registry/mysql/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/mysql/README.md b/registry/mysql/README.md index e5617968..092627fb 100644 --- a/registry/mysql/README.md +++ b/registry/mysql/README.md @@ -59,7 +59,7 @@ documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/ (Note: here and following we are naming the subgraph "my_subgraph" and the connector "my_mysql") ```bash - ddn connector init my_mysql --subgraph my_subgraph --hub-connector hasura/MySQL + ddn connector init my_mysql --subgraph my_subgraph --hub-connector hasura/mysql ``` ### 2. Add your MySQL credentials: From ee57123629c8db85e0ff78f5ec603b4c6c052400 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Fri, 19 Jul 2024 12:01:57 -0400 Subject: [PATCH 032/135] Release ndc-graphql v0.1.1 (#207) --- registry/graphql/metadata.json | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/registry/graphql/metadata.json b/registry/graphql/metadata.json index 99676717..e795a9f3 100644 --- a/registry/graphql/metadata.json +++ b/registry/graphql/metadata.json @@ -5,7 +5,7 @@ "title": "GraphQL Native Data Connector", "logo": "logo.svg", "tags": [], - "latest_version": "v0.1.0" + "latest_version": "v0.1.1" }, "author": { "support_email": "support@hasura.io", @@ -15,6 +15,17 @@ "is_verified": true, "is_hosted_by_hasura": false, "packages": [ + { + "version": "0.1.1", + "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "8a5acec98e28953b22932d7a3734f7e7e535ac9478058b4d06ad9da5dc21ce1d" + }, + "source": { + "hash": "85b80185e28eb7f6721fc50ecd2552f96633e5db" + } + }, { "version": "0.1.0", "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.0/connector-definition.tgz", @@ -31,6 +42,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-graphql/", "version": [ + { + "tag": "v0.1.1", + "hash": "85b80185e28eb7f6721fc50ecd2552f96633e5db", + "is_verified": true + }, { "tag": "v0.1.0", "hash": "8fb41a151b3852fadcfadbe17695605f77aaa240", From 8e2813b7f9dee20b86a7001535abebc794ca082e Mon Sep 17 00:00:00 2001 From: pranshi06 <85474619+pranshi06@users.noreply.github.com> Date: Mon, 22 Jul 2024 11:33:56 +0530 Subject: [PATCH 033/135] update SQL Server README according to CLI v1.0.0 (#203) --- registry/sqlserver/README.md | 86 ++++++++++++++---------------------- 1 file changed, 32 insertions(+), 54 deletions(-) diff --git a/registry/sqlserver/README.md b/registry/sqlserver/README.md index c53704d3..314e32d3 100644 --- a/registry/sqlserver/README.md +++ b/registry/sqlserver/README.md @@ -55,111 +55,89 @@ To use the SQL Server connector, follow these steps in a Hasura project: (Note: for more information on the following steps, please refer to the Postgres connector documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) ### 1. Init the connector -(Note: here and following we are naming the subgraph "my_subgraph" and the connector "my_sql") +(Note: here and following we are naming the subgraph "my_subgraph" and the connector "ms_sql") ```bash - ddn connector init my_sql --subgraph my_subgraph --hub-connector hasura/sqlserver + ddn connector init ms_sql --subgraph my_subgraph/subgraph.yaml --hub-connector hasura/sqlserver --configure-port 8081 --add-to-compose-file compose.yaml ``` ### 2. Add your SQLServer credentials -Add your credentials to `my_subgraph/connector/my_sql/.env.local` +Add your credentials to `my_subgraph/connector/ms_sql/.env.local` -```env title="my_subgraph/connector/my_sql/.env.local" +```env title="my_subgraph/connector/ms_sql/.env.local" OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 -OTEL_SERVICE_NAME=my_subgraph_my_sql +OTEL_SERVICE_NAME=my_subgraph_ms_sql CONNECTION_URI= ``` -### 3. Introspect your indices +### 3. Introspect your Database From the root of your project run: ```bash title="From the root of your project run:" -ddn connector introspect --connector my_subgraph/connector/my_sql/connector.yaml +ddn connector introspect --connector my_subgraph/connector/ms_sql/connector.local.yaml ``` If you look at the `configuration.json` for your connector, you'll see metadata describing your SQL Server mappings. -### 4. Create the Hasura metadata +### 4. Restart the services -Run the following from the root of your project: +Let's restart the docker compose services. Run the folowing from the root of your project: -```bash title="Run the following from the root of your project:" -ddn connector-link add my_sql --subgraph my_subgraph -``` - -The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your -subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the -connector. Ensure the port value matches what is published in your connector's docker compose file. - -```env title="my_subgraph/.env.my_subgraph" -MY_SUBGRAPH_MY_SQL_READ_URL=http://local.hasura.dev:8081 -MY_SUBGRAPH_MY_SQL_WRITE_URL=http://local.hasura.dev:8081 +```bash title="From the root of your project run:" +HASURA_DDN_PAT=$(ddn auth print-pat) docker compose up --build --watch ``` -### 5. Start the connector's docker compose - -Let's start our connector's docker compose file. Run the following from the connector's subdirectory inside a subgraph: - -```bash title="Run the following from the connector's subdirectory inside a subgraph:" -docker compose -f docker-compose.my_sql.yaml up -``` +### 5. Create the Hasura metadata -This starts our SQL Server connector on the specified port. We can navigate to the following address, with the port -modified, to see the schema of our SQL Server data source: +In a new terminal tab from your project's root directory run: -```bash -http://localhost:8081/schema +```bash title="Run the following from the root of your project:" +ddn connector-link add ms_sql --subgraph my_subgraph/subgraph.yaml --configure-host http://local.hasura.dev:8081 --target-env-file my_subgraph/.env.my_subgraph.local ``` -### 6. Include the connector in your docker compose - -Kill the connector by pressing `CTRL+C` in the terminal tab in which the connector is running. +The above step will add the following env vars to the `.env.my_subgraph.local` file. -Then, add the following inclusion to the docker compose `docker-compose.hasura.yaml` in your project's root directory, taking care to modify the -subgraph's name. - -```yaml title="docker-compose.hasura.yaml" -include: - - path: my_subgraph/connector/my_sql/docker-compose.my_sql.yaml +```env title="my_subgraph/.env.my_subgraph.local" +MY_SUBGRAPH_MS_SQL_READ_URL=http://local.hasura.dev:8081 +MY_SUBGRAPH_MS_SQL_WRITE_URL=http://local.hasura.dev:8081 ``` -Now, whenever running the following, you'll bring up the GraphQL engine, observability tools, and any connectors you've -included. From your project's root directory, run: +The generated file has two environment variables — one for reads and one for writes. +Each key is prefixed by the subgraph name, an underscore, and the name of the +connector. -```bash title="From the root of your project, run:" -HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yaml watch -``` - -### 7. Update the new DataConnectorLink object +### 6. Update the new DataConnectorLink object Finally, now that our `DataConnectorLink` has the correct environment variables configured for the SQL Server connector, we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's -schema in `hml` format. In a new terminal tab from your project's root directory run: +schema in `hml` format. From your project's root directory, run: ```bash title="From the root of your project, run:" -ddn connector-link update my_sql --subgraph my_subgraph +ddn connector-link update ms_sql --subgraph my_subgraph/subgraph.yaml --env-file my_subgraph/.env.my_subgraph.local ``` -After this command runs, you can open your `my_subgraph/metadata/my_sql.hml` file and see your metadata completely +After this command runs, you can open your `my_subgraph/metadata/ms_sql.hml` file and see your metadata completely scaffolded out for you 🎉 -### 8. Import _all_ your indices +The schema of the database can be viewed at http://localhost:8081/schema. + +### 7. Import _all_ your indices You can do this with just one command. From your project's root directory, run: ```bash title="From the root of your project, run:" -ddn connector-link update my_sql --subgraph my_subgraph --add-all-resources +ddn connector-link update ms_sql --subgraph my_subgraph/subgraph.yaml --env-file my_subgraph/.env.my_subgraph.local --add-all-resources ``` -### 9. Create a supergraph build +### 8. Create a supergraph build Pass the `local` subcommand along with specifying the output directory as `./engine` in the root of the project. This directory is used by the docker-compose file to serve the engine locally. From your project's root directory, run: ```bash title="From the root of your project, run:" -ddn supergraph build local --output-dir ./engine +ddn supergraph build local --output-dir ./engine --subgraph-env-file my_subgraph:my_subgraph/.env.my_subgraph.local ``` You can now navigate to From af7493934eb87f72f270ef831bca64c9eb2613a2 Mon Sep 17 00:00:00 2001 From: Rahul Agarwal <111393043+rahulagarwal13@users.noreply.github.com> Date: Tue, 23 Jul 2024 16:23:05 -0700 Subject: [PATCH 034/135] update graphQL connector readme (#209) Updated it to follow the standard template (reference postgres and mongodb) --- registry/graphql/README.md | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/registry/graphql/README.md b/registry/graphql/README.md index 8fd0b13d..42e9cdb7 100644 --- a/registry/graphql/README.md +++ b/registry/graphql/README.md @@ -1,15 +1,24 @@ ## Overview -The GraphQL Native Data Connector allows for connecting to a GraphQL endpoint. -This uses the [Rust Data Connector SDK](https://github.com/hasura/ndc-hub#rusk-sdk) from the [Data connector Hub](https://github.com/hasura/ndc-hub) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). +The Hasura GraphQL Connector allows for connecting to a GraphQL API and bringing it into Hasura DDN supergraph as a single unified API. It can also be used to bring in your current Hasura v2 graphQL API into Hasura DDN and our recommended approach is to create a new subgraph for the v2 API. -Please refer to the [Getting Started - Create an API](https://hasura.io/docs/3.0/getting-started/overview/) documentation if you get stuck during any of the steps outlined below. +For Hasura v2 users, this functionality is the replacement of [remote schemas](https://hasura.io/docs/latest/remote-schemas/overview/) functionality in v3 (DDN). -### Prerequisites -1. Install the [new Hasura CLI](https://hasura.io/docs/3.0/cli/installation) — to quickly and easily create and manage your Hasura projects and builds. -2. (recommended) Install the [Hasura VS Code extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) — with support for other editors coming soon! +The `ndc-graphql` data connector is open source and can be found in the [ndc-graphql GitHub repository](https://github.com/hasura/ndc-graphql). -### Usage +Visit the [Hasura v3 Documentation](https://hasura.io/docs/3.0/native-data-connectors) for more information. + +## Deployment + +The connector is hosted by Hasura and can be used from the [Hasura v3 CLI](https://hasura.io/docs/3.0/cli/overview/) and [Console](https://console.hasura.io). Please follow either the [Quick Start Guide](https://hasura.io/docs/3.0/getting-started/overview/) or [deploying the connector](https://hasura.io/docs/3.0/connectors/deployment). + +## Usage Please refer to the [connector readme](https://github.com/hasura/ndc-graphql/blob/main/README.md) +## Troubleshooting + +Please [submit a Github issue](https://github.com/hasura/graphql-engine/issues/new)if you encounter any problems! + + + From 909fa52c7dcf287b94cdff98ebb285449c3214d9 Mon Sep 17 00:00:00 2001 From: Rakesh Emmadi <12475069+rakeshkky@users.noreply.github.com> Date: Wed, 24 Jul 2024 19:50:08 +0530 Subject: [PATCH 035/135] ndc-postgres v1.0.1 (#210) https://github.com/hasura/ndc-postgres/releases/tag/v1.0.1 --- registry/aurora/metadata.json | 7 ++++++- registry/citus/metadata.json | 7 ++++++- registry/cockroach/metadata.json | 7 ++++++- registry/neon/metadata.json | 7 ++++++- registry/postgres-alloydb/metadata.json | 7 ++++++- registry/postgres-azure/metadata.json | 7 ++++++- registry/postgres-cosmos/metadata.json | 7 ++++++- registry/postgres-gcp/metadata.json | 7 ++++++- registry/postgres-timescaledb/metadata.json | 7 ++++++- registry/postgres/metadata.json | 7 ++++++- 10 files changed, 60 insertions(+), 10 deletions(-) diff --git a/registry/aurora/metadata.json b/registry/aurora/metadata.json index 7f6a0fc1..c00ff339 100644 --- a/registry/aurora/metadata.json +++ b/registry/aurora/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.0" + "latest_version": "v1.0.1" }, "author": { "support_email": "support@hasura.io", @@ -49,6 +49,11 @@ "tag": "v1.0.0", "hash": "4af168d", "is_verified": true + }, + { + "tag": "v1.0.1", + "hash": "e2fd651", + "is_verified": true } ] } diff --git a/registry/citus/metadata.json b/registry/citus/metadata.json index 82cd60c7..1f4af8a0 100644 --- a/registry/citus/metadata.json +++ b/registry/citus/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.0" + "latest_version": "v1.0.1" }, "author": { "support_email": "support@hasura.io", @@ -49,6 +49,11 @@ "tag": "v1.0.0", "hash": "4af168d", "is_verified": true + }, + { + "tag": "v1.0.1", + "hash": "e2fd651", + "is_verified": true } ] } diff --git a/registry/cockroach/metadata.json b/registry/cockroach/metadata.json index 5d7fbaff..88569e24 100644 --- a/registry/cockroach/metadata.json +++ b/registry/cockroach/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.0" + "latest_version": "v1.0.1" }, "author": { "support_email": "support@hasura.io", @@ -49,6 +49,11 @@ "tag": "v1.0.0", "hash": "4af168d", "is_verified": true + }, + { + "tag": "v1.0.1", + "hash": "e2fd651", + "is_verified": true } ] } diff --git a/registry/neon/metadata.json b/registry/neon/metadata.json index 87d58b4c..2abe04b7 100644 --- a/registry/neon/metadata.json +++ b/registry/neon/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.0" + "latest_version": "v1.0.1" }, "author": { "support_email": "support@hasura.io", @@ -49,6 +49,11 @@ "tag": "v1.0.0", "hash": "4af168d", "is_verified": true + }, + { + "tag": "v1.0.1", + "hash": "e2fd651", + "is_verified": true } ] } diff --git a/registry/postgres-alloydb/metadata.json b/registry/postgres-alloydb/metadata.json index 89ef6b2d..28e968ca 100644 --- a/registry/postgres-alloydb/metadata.json +++ b/registry/postgres-alloydb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.0" + "latest_version": "v1.0.1" }, "author": { "support_email": "support@hasura.io", @@ -49,6 +49,11 @@ "tag": "v1.0.0", "hash": "4af168d", "is_verified": true + }, + { + "tag": "v1.0.1", + "hash": "e2fd651", + "is_verified": true } ] } diff --git a/registry/postgres-azure/metadata.json b/registry/postgres-azure/metadata.json index 7fc9f971..4e85da7d 100644 --- a/registry/postgres-azure/metadata.json +++ b/registry/postgres-azure/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.0" + "latest_version": "v1.0.1" }, "author": { "support_email": "support@hasura.io", @@ -49,6 +49,11 @@ "tag": "v1.0.0", "hash": "4af168d", "is_verified": true + }, + { + "tag": "v1.0.1", + "hash": "e2fd651", + "is_verified": true } ] } diff --git a/registry/postgres-cosmos/metadata.json b/registry/postgres-cosmos/metadata.json index 38e975f0..66d97b3e 100644 --- a/registry/postgres-cosmos/metadata.json +++ b/registry/postgres-cosmos/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.0" + "latest_version": "v1.0.1" }, "author": { "support_email": "support@hasura.io", @@ -49,6 +49,11 @@ "tag": "v1.0.0", "hash": "4af168d", "is_verified": true + }, + { + "tag": "v1.0.1", + "hash": "e2fd651", + "is_verified": true } ] } diff --git a/registry/postgres-gcp/metadata.json b/registry/postgres-gcp/metadata.json index db0da760..691bdfda 100644 --- a/registry/postgres-gcp/metadata.json +++ b/registry/postgres-gcp/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.0" + "latest_version": "v1.0.1" }, "author": { "support_email": "support@hasura.io", @@ -49,6 +49,11 @@ "tag": "v1.0.0", "hash": "4af168d", "is_verified": true + }, + { + "tag": "v1.0.1", + "hash": "e2fd651", + "is_verified": true } ] } diff --git a/registry/postgres-timescaledb/metadata.json b/registry/postgres-timescaledb/metadata.json index 11dafbb7..d014e1fe 100644 --- a/registry/postgres-timescaledb/metadata.json +++ b/registry/postgres-timescaledb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.0" + "latest_version": "v1.0.1" }, "author": { "support_email": "support@hasura.io", @@ -49,6 +49,11 @@ "tag": "v1.0.0", "hash": "4af168d", "is_verified": true + }, + { + "tag": "v1.0.1", + "hash": "e2fd651", + "is_verified": true } ] } diff --git a/registry/postgres/metadata.json b/registry/postgres/metadata.json index 2152c623..af1333d7 100644 --- a/registry/postgres/metadata.json +++ b/registry/postgres/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.0" + "latest_version": "v1.0.1" }, "author": { "support_email": "support@hasura.io", @@ -49,6 +49,11 @@ "tag": "v1.0.0", "hash": "4af168d", "is_verified": true + }, + { + "tag": "v1.0.1", + "hash": "e2fd651", + "is_verified": true } ] } From 1c86a30e82c9319c311238cadec0156f91c208bd Mon Sep 17 00:00:00 2001 From: Daniel Chambers Date: Tue, 30 Jul 2024 14:49:45 +1000 Subject: [PATCH 036/135] Add NodeJS Lambda v1.5.0 (#213) --- registry/nodejs-lambda/metadata.json | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/registry/nodejs-lambda/metadata.json b/registry/nodejs-lambda/metadata.json index 9b5eda37..02b0367d 100644 --- a/registry/nodejs-lambda/metadata.json +++ b/registry/nodejs-lambda/metadata.json @@ -5,7 +5,7 @@ "title": "NodeJS Lambda Connector", "logo": "logo.png", "tags": [], - "latest_version": "v1.4.1" + "latest_version": "v1.5.0" }, "author": { "support_email": "support@hasura.io", @@ -15,6 +15,17 @@ "is_verified": true, "is_hosted_by_hasura": false, "packages": [ + { + "version": "1.5.0", + "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.5.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "d89466e19ad8aeb94bff9e34623f075fee1cb955d5e8ae5ed316df38f1b400c6" + }, + "source": { + "hash": "2a9a04d0a1c8116d9b864a83d81817ccddae355d" + } + }, { "version": "1.4.1", "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.4.1/connector-definition.tgz", @@ -86,6 +97,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-nodejs-lambda/", "version": [ + { + "tag": "v1.5.0", + "hash": "2a9a04d0a1c8116d9b864a83d81817ccddae355d", + "is_verified": true + }, { "tag": "v1.4.1", "hash": "9b5f795aca98854205ba5646162d1df7f060d642", From 8774438a911d3efe81bfe0094e8f5f1dceacf82f Mon Sep 17 00:00:00 2001 From: gneeri Date: Wed, 31 Jul 2024 03:52:32 -0400 Subject: [PATCH 037/135] Release elasticsearch `v1.0.0` (#211) --- registry/elasticsearch/metadata.json | 36 ++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/registry/elasticsearch/metadata.json b/registry/elasticsearch/metadata.json index 0cc4ccda..1bc665e1 100644 --- a/registry/elasticsearch/metadata.json +++ b/registry/elasticsearch/metadata.json @@ -7,7 +7,7 @@ "tags": [ "search" ], - "latest_version": "v0.1.1" + "latest_version": "v1.0.0" }, "author": { "support_email": "support@hasura.io", @@ -15,7 +15,7 @@ "name": "Hasura" }, "is_verified": true, - "is_hosted_by_hasura": false, + "is_hosted_by_hasura": true, "packages": [ { "version": "0.1.0", @@ -38,6 +38,28 @@ "source": { "hash": "413a2a4ddfd1910757c40c38e9a18148bc3b3bdc" } + }, + { + "version": "0.2.0", + "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v0.2.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "7ba4762ae3863a2ea149a5ecf4a93f19a7889f9d36dde27b1cb60b6758ad0e3a" + }, + "source": { + "hash": "f5938f8c76829de7f16cf291c95a06f590b16d9a" + } + }, + { + "version": "1.0.0", + "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v1.0.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "6ca06b00361a272b0afd7ce5ac314a12460b9c99336e43a4a317de00f00ae6ae" + }, + "source": { + "hash": "9f1f508f551b4a9dec02c49e3312f38c24bb16c4" + } } ], "source_code": { @@ -53,6 +75,16 @@ "tag": "v0.1.1", "hash": "413a2a4ddfd1910757c40c38e9a18148bc3b3bdc", "is_verified": true + }, + { + "tag": "v0.2.0", + "hash": "f5938f8c76829de7f16cf291c95a06f590b16d9a", + "is_verified": true + }, + { + "tag": "v1.0.0", + "hash": "9f1f508f551b4a9dec02c49e3312f38c24bb16c4", + "is_verified": true } ] } From e732a4964b467946b0f5459cc40f8bdc2cb0e74f Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 31 Jul 2024 19:49:43 -0400 Subject: [PATCH 038/135] Release v0.1.2 (#214) --- registry/graphql/metadata.json | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/registry/graphql/metadata.json b/registry/graphql/metadata.json index e795a9f3..138690fd 100644 --- a/registry/graphql/metadata.json +++ b/registry/graphql/metadata.json @@ -5,7 +5,7 @@ "title": "GraphQL Native Data Connector", "logo": "logo.svg", "tags": [], - "latest_version": "v0.1.1" + "latest_version": "v0.1.2" }, "author": { "support_email": "support@hasura.io", @@ -15,6 +15,17 @@ "is_verified": true, "is_hosted_by_hasura": false, "packages": [ + { + "version": "0.1.2", + "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.2/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "85aa0294a4a13da85c2932254878814f60f8e9b61621232675b5dfa551248a77" + }, + "source": { + "hash": "1cfb5d3e52d914acf4e5e96edd54d7fc744ec304" + } + }, { "version": "0.1.1", "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.1/connector-definition.tgz", @@ -42,6 +53,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-graphql/", "version": [ + { + "tag": "v0.1.2", + "hash": "1cfb5d3e52d914acf4e5e96edd54d7fc744ec304", + "is_verified": true + }, { "tag": "v0.1.1", "hash": "85b80185e28eb7f6721fc50ecd2552f96633e5db", From 71be31f3d6c22bdd31070350ce6ddc586efce0dc Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Mon, 5 Aug 2024 19:01:58 -0400 Subject: [PATCH 039/135] Release v0.2.10 (#217) --- registry/clickhouse/metadata.json | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/registry/clickhouse/metadata.json b/registry/clickhouse/metadata.json index 4a15c32d..7a20886e 100644 --- a/registry/clickhouse/metadata.json +++ b/registry/clickhouse/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.2.8" + "latest_version": "v0.2.10" }, "author": { "support_email": "support@hasura.io", @@ -17,6 +17,17 @@ "is_verified": true, "is_hosted_by_hasura": false, "packages": [ + { + "version": "0.2.10", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.10/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "4eb32262e528d0261afd0f6a4b283a6fe3fd0edf395b732fe6abcacfdf4ff999" + }, + "source": { + "hash": "dbe5b7765b1c9276e5734c8fbc5005e7b71d0500" + } + }, { "version": "0.2.9", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.9/connector-definition.tgz", @@ -132,6 +143,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-clickhouse/", "version": [ + { + "tag": "v0.2.10", + "hash": "dbe5b7765b1c9276e5734c8fbc5005e7b71d0500", + "is_verified": true + }, { "tag": "v0.2.9", "hash": "93752f433f4e7c91f0c13d92ea9369deb97d1970", From 645d4e4daeb93fe096827cf7f2c6ba137674f8e5 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Mon, 5 Aug 2024 19:02:35 -0400 Subject: [PATCH 040/135] Release v0.1.3 (#216) --- registry/graphql/metadata.json | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/registry/graphql/metadata.json b/registry/graphql/metadata.json index 138690fd..aa468a3b 100644 --- a/registry/graphql/metadata.json +++ b/registry/graphql/metadata.json @@ -5,7 +5,7 @@ "title": "GraphQL Native Data Connector", "logo": "logo.svg", "tags": [], - "latest_version": "v0.1.2" + "latest_version": "v0.1.3" }, "author": { "support_email": "support@hasura.io", @@ -15,6 +15,17 @@ "is_verified": true, "is_hosted_by_hasura": false, "packages": [ + { + "version": "0.1.3", + "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "4045cfd23f6ed4bf747241f967a7717dd391b5fe8285ec486584427698cf9881" + }, + "source": { + "hash": "4262e34d57255c622a47daa408eba8c25fb279f7" + } + }, { "version": "0.1.2", "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.2/connector-definition.tgz", @@ -53,6 +64,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-graphql/", "version": [ + { + "tag": "v0.1.3", + "hash": "4262e34d57255c622a47daa408eba8c25fb279f7", + "is_verified": true + }, { "tag": "v0.1.2", "hash": "1cfb5d3e52d914acf4e5e96edd54d7fc744ec304", From 926c4d46d04f8b2d0ef5a109ddd833ea86740e84 Mon Sep 17 00:00:00 2001 From: Daniel Chambers Date: Thu, 8 Aug 2024 23:48:09 +1000 Subject: [PATCH 041/135] Add NodeJS Lambda v1.6.0 (#223) --- registry/nodejs-lambda/metadata.json | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/registry/nodejs-lambda/metadata.json b/registry/nodejs-lambda/metadata.json index 02b0367d..d5bb15a6 100644 --- a/registry/nodejs-lambda/metadata.json +++ b/registry/nodejs-lambda/metadata.json @@ -5,7 +5,7 @@ "title": "NodeJS Lambda Connector", "logo": "logo.png", "tags": [], - "latest_version": "v1.5.0" + "latest_version": "v1.6.0" }, "author": { "support_email": "support@hasura.io", @@ -15,6 +15,17 @@ "is_verified": true, "is_hosted_by_hasura": false, "packages": [ + { + "version": "1.6.0", + "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.6.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "f69645af8190a93484a8c374830c788035ebf91135e53f57e214b04fe69475e7" + }, + "source": { + "hash": "2fb76722db449b5525d1dcce33cf48ee0cf44ad8" + } + }, { "version": "1.5.0", "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.5.0/connector-definition.tgz", @@ -97,6 +108,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-nodejs-lambda/", "version": [ + { + "tag": "v1.6.0", + "hash": "2fb76722db449b5525d1dcce33cf48ee0cf44ad8", + "is_verified": true + }, { "tag": "v1.5.0", "hash": "2a9a04d0a1c8116d9b864a83d81817ccddae355d", From a4e16c451a776208d798bc7ce3f4536a7b80c306 Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Mon, 12 Aug 2024 15:08:24 +0530 Subject: [PATCH 042/135] Add all the connectors under their namespace folder (#222) This is a no-op PR that just adds all the connectors present in the `registry` folder to `registry/hasura` where hasura is the namespace. --- registry/{ => hasura}/aurora/README.md | 0 registry/{ => hasura}/aurora/logo.svg | 0 registry/{ => hasura}/aurora/metadata.json | 0 registry/{ => hasura}/azure-cosmos/README.md | 0 registry/{ => hasura}/azure-cosmos/logo.png | Bin registry/{ => hasura}/azure-cosmos/metadata.json | 0 registry/{ => hasura}/citus/README.md | 0 registry/{ => hasura}/citus/logo.svg | 0 registry/{ => hasura}/citus/metadata.json | 0 registry/{ => hasura}/clickhouse/README.md | 0 registry/{ => hasura}/clickhouse/logo.png | Bin registry/{ => hasura}/clickhouse/metadata.json | 0 registry/{ => hasura}/cockroach/README.md | 0 registry/{ => hasura}/cockroach/logo.png | Bin registry/{ => hasura}/cockroach/metadata.json | 0 registry/{ => hasura}/duckdb/README.md | 0 registry/{ => hasura}/duckdb/logo.svg | 0 registry/{ => hasura}/duckdb/metadata.json | 0 registry/{ => hasura}/elasticsearch/README.md | 0 registry/{ => hasura}/elasticsearch/logo.png | Bin registry/{ => hasura}/elasticsearch/metadata.json | 0 registry/{ => hasura}/go/README.md | 0 registry/{ => hasura}/go/logo.svg | 0 registry/{ => hasura}/go/metadata.json | 0 registry/{ => hasura}/graphql/README.md | 0 registry/{ => hasura}/graphql/logo.svg | 0 registry/{ => hasura}/graphql/metadata.json | 0 registry/{ => hasura}/mongodb/README.md | 0 registry/{ => hasura}/mongodb/logo.png | Bin registry/{ => hasura}/mongodb/metadata.json | 0 registry/{ => hasura}/mysql/README.md | 0 registry/{ => hasura}/mysql/logo.svg | 0 registry/{ => hasura}/mysql/metadata.json | 0 registry/{ => hasura}/neon/README.md | 0 registry/{ => hasura}/neon/logo.svg | 0 registry/{ => hasura}/neon/metadata.json | 0 registry/{ => hasura}/nodejs-lambda/README.md | 0 registry/{ => hasura}/nodejs-lambda/logo.png | Bin registry/{ => hasura}/nodejs-lambda/metadata.json | 0 registry/{ => hasura}/open-api-lambda/README.md | 0 registry/{ => hasura}/open-api-lambda/logo.png | Bin registry/{ => hasura}/open-api-lambda/metadata.json | 0 registry/{ => hasura}/oracle/README.md | 0 registry/{ => hasura}/oracle/logo.svg | 0 registry/{ => hasura}/oracle/metadata.json | 0 registry/{ => hasura}/postgres-alloydb/README.md | 0 registry/{ => hasura}/postgres-alloydb/logo.png | Bin .../{ => hasura}/postgres-alloydb/metadata.json | 0 registry/{ => hasura}/postgres-azure/README.md | 0 registry/{ => hasura}/postgres-azure/logo.png | Bin registry/{ => hasura}/postgres-azure/metadata.json | 0 registry/{ => hasura}/postgres-cosmos/README.md | 0 registry/{ => hasura}/postgres-cosmos/logo.png | Bin registry/{ => hasura}/postgres-cosmos/metadata.json | 0 registry/{ => hasura}/postgres-gcp/README.md | 0 registry/{ => hasura}/postgres-gcp/logo.png | Bin registry/{ => hasura}/postgres-gcp/metadata.json | 0 .../{ => hasura}/postgres-timescaledb/README.md | 0 registry/{ => hasura}/postgres-timescaledb/logo.png | Bin .../{ => hasura}/postgres-timescaledb/metadata.json | 0 registry/{ => hasura}/postgres/README.md | 0 registry/{ => hasura}/postgres/logo.png | Bin registry/{ => hasura}/postgres/metadata.json | 0 registry/{ => hasura}/qdrant/README.md | 0 registry/{ => hasura}/qdrant/logo.png | Bin registry/{ => hasura}/qdrant/metadata.json | 0 registry/{ => hasura}/sendgrid/README.md | 0 registry/{ => hasura}/sendgrid/logo.png | Bin registry/{ => hasura}/sendgrid/metadata.json | 0 registry/{ => hasura}/snowflake/README.md | 0 registry/{ => hasura}/snowflake/logo.svg | 0 registry/{ => hasura}/snowflake/metadata.json | 0 registry/{ => hasura}/sqlserver/README.md | 0 registry/{ => hasura}/sqlserver/logo.png | Bin registry/{ => hasura}/sqlserver/metadata.json | 0 registry/{ => hasura}/turso/README.md | 0 registry/{ => hasura}/turso/logo.svg | 0 registry/{ => hasura}/turso/metadata.json | 0 registry/{ => hasura}/typescript-deno/README.md | 0 registry/{ => hasura}/typescript-deno/logo.png | Bin registry/{ => hasura}/typescript-deno/metadata.json | 0 registry/{ => hasura}/yugabyte/README.md | 0 registry/{ => hasura}/yugabyte/logo.svg | 0 registry/{ => hasura}/yugabyte/metadata.json | 0 84 files changed, 0 insertions(+), 0 deletions(-) rename registry/{ => hasura}/aurora/README.md (100%) rename registry/{ => hasura}/aurora/logo.svg (100%) rename registry/{ => hasura}/aurora/metadata.json (100%) rename registry/{ => hasura}/azure-cosmos/README.md (100%) rename registry/{ => hasura}/azure-cosmos/logo.png (100%) rename registry/{ => hasura}/azure-cosmos/metadata.json (100%) rename registry/{ => hasura}/citus/README.md (100%) rename registry/{ => hasura}/citus/logo.svg (100%) rename registry/{ => hasura}/citus/metadata.json (100%) rename registry/{ => hasura}/clickhouse/README.md (100%) rename registry/{ => hasura}/clickhouse/logo.png (100%) rename registry/{ => hasura}/clickhouse/metadata.json (100%) rename registry/{ => hasura}/cockroach/README.md (100%) rename registry/{ => hasura}/cockroach/logo.png (100%) rename registry/{ => hasura}/cockroach/metadata.json (100%) rename registry/{ => hasura}/duckdb/README.md (100%) rename registry/{ => hasura}/duckdb/logo.svg (100%) rename registry/{ => hasura}/duckdb/metadata.json (100%) rename registry/{ => hasura}/elasticsearch/README.md (100%) rename registry/{ => hasura}/elasticsearch/logo.png (100%) rename registry/{ => hasura}/elasticsearch/metadata.json (100%) rename registry/{ => hasura}/go/README.md (100%) rename registry/{ => hasura}/go/logo.svg (100%) rename registry/{ => hasura}/go/metadata.json (100%) rename registry/{ => hasura}/graphql/README.md (100%) rename registry/{ => hasura}/graphql/logo.svg (100%) rename registry/{ => hasura}/graphql/metadata.json (100%) rename registry/{ => hasura}/mongodb/README.md (100%) rename registry/{ => hasura}/mongodb/logo.png (100%) rename registry/{ => hasura}/mongodb/metadata.json (100%) rename registry/{ => hasura}/mysql/README.md (100%) rename registry/{ => hasura}/mysql/logo.svg (100%) rename registry/{ => hasura}/mysql/metadata.json (100%) rename registry/{ => hasura}/neon/README.md (100%) rename registry/{ => hasura}/neon/logo.svg (100%) rename registry/{ => hasura}/neon/metadata.json (100%) rename registry/{ => hasura}/nodejs-lambda/README.md (100%) rename registry/{ => hasura}/nodejs-lambda/logo.png (100%) rename registry/{ => hasura}/nodejs-lambda/metadata.json (100%) rename registry/{ => hasura}/open-api-lambda/README.md (100%) rename registry/{ => hasura}/open-api-lambda/logo.png (100%) rename registry/{ => hasura}/open-api-lambda/metadata.json (100%) rename registry/{ => hasura}/oracle/README.md (100%) rename registry/{ => hasura}/oracle/logo.svg (100%) rename registry/{ => hasura}/oracle/metadata.json (100%) rename registry/{ => hasura}/postgres-alloydb/README.md (100%) rename registry/{ => hasura}/postgres-alloydb/logo.png (100%) rename registry/{ => hasura}/postgres-alloydb/metadata.json (100%) rename registry/{ => hasura}/postgres-azure/README.md (100%) rename registry/{ => hasura}/postgres-azure/logo.png (100%) rename registry/{ => hasura}/postgres-azure/metadata.json (100%) rename registry/{ => hasura}/postgres-cosmos/README.md (100%) rename registry/{ => hasura}/postgres-cosmos/logo.png (100%) rename registry/{ => hasura}/postgres-cosmos/metadata.json (100%) rename registry/{ => hasura}/postgres-gcp/README.md (100%) rename registry/{ => hasura}/postgres-gcp/logo.png (100%) rename registry/{ => hasura}/postgres-gcp/metadata.json (100%) rename registry/{ => hasura}/postgres-timescaledb/README.md (100%) rename registry/{ => hasura}/postgres-timescaledb/logo.png (100%) rename registry/{ => hasura}/postgres-timescaledb/metadata.json (100%) rename registry/{ => hasura}/postgres/README.md (100%) rename registry/{ => hasura}/postgres/logo.png (100%) rename registry/{ => hasura}/postgres/metadata.json (100%) rename registry/{ => hasura}/qdrant/README.md (100%) rename registry/{ => hasura}/qdrant/logo.png (100%) rename registry/{ => hasura}/qdrant/metadata.json (100%) rename registry/{ => hasura}/sendgrid/README.md (100%) rename registry/{ => hasura}/sendgrid/logo.png (100%) rename registry/{ => hasura}/sendgrid/metadata.json (100%) rename registry/{ => hasura}/snowflake/README.md (100%) rename registry/{ => hasura}/snowflake/logo.svg (100%) rename registry/{ => hasura}/snowflake/metadata.json (100%) rename registry/{ => hasura}/sqlserver/README.md (100%) rename registry/{ => hasura}/sqlserver/logo.png (100%) rename registry/{ => hasura}/sqlserver/metadata.json (100%) rename registry/{ => hasura}/turso/README.md (100%) rename registry/{ => hasura}/turso/logo.svg (100%) rename registry/{ => hasura}/turso/metadata.json (100%) rename registry/{ => hasura}/typescript-deno/README.md (100%) rename registry/{ => hasura}/typescript-deno/logo.png (100%) rename registry/{ => hasura}/typescript-deno/metadata.json (100%) rename registry/{ => hasura}/yugabyte/README.md (100%) rename registry/{ => hasura}/yugabyte/logo.svg (100%) rename registry/{ => hasura}/yugabyte/metadata.json (100%) diff --git a/registry/aurora/README.md b/registry/hasura/aurora/README.md similarity index 100% rename from registry/aurora/README.md rename to registry/hasura/aurora/README.md diff --git a/registry/aurora/logo.svg b/registry/hasura/aurora/logo.svg similarity index 100% rename from registry/aurora/logo.svg rename to registry/hasura/aurora/logo.svg diff --git a/registry/aurora/metadata.json b/registry/hasura/aurora/metadata.json similarity index 100% rename from registry/aurora/metadata.json rename to registry/hasura/aurora/metadata.json diff --git a/registry/azure-cosmos/README.md b/registry/hasura/azure-cosmos/README.md similarity index 100% rename from registry/azure-cosmos/README.md rename to registry/hasura/azure-cosmos/README.md diff --git a/registry/azure-cosmos/logo.png b/registry/hasura/azure-cosmos/logo.png similarity index 100% rename from registry/azure-cosmos/logo.png rename to registry/hasura/azure-cosmos/logo.png diff --git a/registry/azure-cosmos/metadata.json b/registry/hasura/azure-cosmos/metadata.json similarity index 100% rename from registry/azure-cosmos/metadata.json rename to registry/hasura/azure-cosmos/metadata.json diff --git a/registry/citus/README.md b/registry/hasura/citus/README.md similarity index 100% rename from registry/citus/README.md rename to registry/hasura/citus/README.md diff --git a/registry/citus/logo.svg b/registry/hasura/citus/logo.svg similarity index 100% rename from registry/citus/logo.svg rename to registry/hasura/citus/logo.svg diff --git a/registry/citus/metadata.json b/registry/hasura/citus/metadata.json similarity index 100% rename from registry/citus/metadata.json rename to registry/hasura/citus/metadata.json diff --git a/registry/clickhouse/README.md b/registry/hasura/clickhouse/README.md similarity index 100% rename from registry/clickhouse/README.md rename to registry/hasura/clickhouse/README.md diff --git a/registry/clickhouse/logo.png b/registry/hasura/clickhouse/logo.png similarity index 100% rename from registry/clickhouse/logo.png rename to registry/hasura/clickhouse/logo.png diff --git a/registry/clickhouse/metadata.json b/registry/hasura/clickhouse/metadata.json similarity index 100% rename from registry/clickhouse/metadata.json rename to registry/hasura/clickhouse/metadata.json diff --git a/registry/cockroach/README.md b/registry/hasura/cockroach/README.md similarity index 100% rename from registry/cockroach/README.md rename to registry/hasura/cockroach/README.md diff --git a/registry/cockroach/logo.png b/registry/hasura/cockroach/logo.png similarity index 100% rename from registry/cockroach/logo.png rename to registry/hasura/cockroach/logo.png diff --git a/registry/cockroach/metadata.json b/registry/hasura/cockroach/metadata.json similarity index 100% rename from registry/cockroach/metadata.json rename to registry/hasura/cockroach/metadata.json diff --git a/registry/duckdb/README.md b/registry/hasura/duckdb/README.md similarity index 100% rename from registry/duckdb/README.md rename to registry/hasura/duckdb/README.md diff --git a/registry/duckdb/logo.svg b/registry/hasura/duckdb/logo.svg similarity index 100% rename from registry/duckdb/logo.svg rename to registry/hasura/duckdb/logo.svg diff --git a/registry/duckdb/metadata.json b/registry/hasura/duckdb/metadata.json similarity index 100% rename from registry/duckdb/metadata.json rename to registry/hasura/duckdb/metadata.json diff --git a/registry/elasticsearch/README.md b/registry/hasura/elasticsearch/README.md similarity index 100% rename from registry/elasticsearch/README.md rename to registry/hasura/elasticsearch/README.md diff --git a/registry/elasticsearch/logo.png b/registry/hasura/elasticsearch/logo.png similarity index 100% rename from registry/elasticsearch/logo.png rename to registry/hasura/elasticsearch/logo.png diff --git a/registry/elasticsearch/metadata.json b/registry/hasura/elasticsearch/metadata.json similarity index 100% rename from registry/elasticsearch/metadata.json rename to registry/hasura/elasticsearch/metadata.json diff --git a/registry/go/README.md b/registry/hasura/go/README.md similarity index 100% rename from registry/go/README.md rename to registry/hasura/go/README.md diff --git a/registry/go/logo.svg b/registry/hasura/go/logo.svg similarity index 100% rename from registry/go/logo.svg rename to registry/hasura/go/logo.svg diff --git a/registry/go/metadata.json b/registry/hasura/go/metadata.json similarity index 100% rename from registry/go/metadata.json rename to registry/hasura/go/metadata.json diff --git a/registry/graphql/README.md b/registry/hasura/graphql/README.md similarity index 100% rename from registry/graphql/README.md rename to registry/hasura/graphql/README.md diff --git a/registry/graphql/logo.svg b/registry/hasura/graphql/logo.svg similarity index 100% rename from registry/graphql/logo.svg rename to registry/hasura/graphql/logo.svg diff --git a/registry/graphql/metadata.json b/registry/hasura/graphql/metadata.json similarity index 100% rename from registry/graphql/metadata.json rename to registry/hasura/graphql/metadata.json diff --git a/registry/mongodb/README.md b/registry/hasura/mongodb/README.md similarity index 100% rename from registry/mongodb/README.md rename to registry/hasura/mongodb/README.md diff --git a/registry/mongodb/logo.png b/registry/hasura/mongodb/logo.png similarity index 100% rename from registry/mongodb/logo.png rename to registry/hasura/mongodb/logo.png diff --git a/registry/mongodb/metadata.json b/registry/hasura/mongodb/metadata.json similarity index 100% rename from registry/mongodb/metadata.json rename to registry/hasura/mongodb/metadata.json diff --git a/registry/mysql/README.md b/registry/hasura/mysql/README.md similarity index 100% rename from registry/mysql/README.md rename to registry/hasura/mysql/README.md diff --git a/registry/mysql/logo.svg b/registry/hasura/mysql/logo.svg similarity index 100% rename from registry/mysql/logo.svg rename to registry/hasura/mysql/logo.svg diff --git a/registry/mysql/metadata.json b/registry/hasura/mysql/metadata.json similarity index 100% rename from registry/mysql/metadata.json rename to registry/hasura/mysql/metadata.json diff --git a/registry/neon/README.md b/registry/hasura/neon/README.md similarity index 100% rename from registry/neon/README.md rename to registry/hasura/neon/README.md diff --git a/registry/neon/logo.svg b/registry/hasura/neon/logo.svg similarity index 100% rename from registry/neon/logo.svg rename to registry/hasura/neon/logo.svg diff --git a/registry/neon/metadata.json b/registry/hasura/neon/metadata.json similarity index 100% rename from registry/neon/metadata.json rename to registry/hasura/neon/metadata.json diff --git a/registry/nodejs-lambda/README.md b/registry/hasura/nodejs-lambda/README.md similarity index 100% rename from registry/nodejs-lambda/README.md rename to registry/hasura/nodejs-lambda/README.md diff --git a/registry/nodejs-lambda/logo.png b/registry/hasura/nodejs-lambda/logo.png similarity index 100% rename from registry/nodejs-lambda/logo.png rename to registry/hasura/nodejs-lambda/logo.png diff --git a/registry/nodejs-lambda/metadata.json b/registry/hasura/nodejs-lambda/metadata.json similarity index 100% rename from registry/nodejs-lambda/metadata.json rename to registry/hasura/nodejs-lambda/metadata.json diff --git a/registry/open-api-lambda/README.md b/registry/hasura/open-api-lambda/README.md similarity index 100% rename from registry/open-api-lambda/README.md rename to registry/hasura/open-api-lambda/README.md diff --git a/registry/open-api-lambda/logo.png b/registry/hasura/open-api-lambda/logo.png similarity index 100% rename from registry/open-api-lambda/logo.png rename to registry/hasura/open-api-lambda/logo.png diff --git a/registry/open-api-lambda/metadata.json b/registry/hasura/open-api-lambda/metadata.json similarity index 100% rename from registry/open-api-lambda/metadata.json rename to registry/hasura/open-api-lambda/metadata.json diff --git a/registry/oracle/README.md b/registry/hasura/oracle/README.md similarity index 100% rename from registry/oracle/README.md rename to registry/hasura/oracle/README.md diff --git a/registry/oracle/logo.svg b/registry/hasura/oracle/logo.svg similarity index 100% rename from registry/oracle/logo.svg rename to registry/hasura/oracle/logo.svg diff --git a/registry/oracle/metadata.json b/registry/hasura/oracle/metadata.json similarity index 100% rename from registry/oracle/metadata.json rename to registry/hasura/oracle/metadata.json diff --git a/registry/postgres-alloydb/README.md b/registry/hasura/postgres-alloydb/README.md similarity index 100% rename from registry/postgres-alloydb/README.md rename to registry/hasura/postgres-alloydb/README.md diff --git a/registry/postgres-alloydb/logo.png b/registry/hasura/postgres-alloydb/logo.png similarity index 100% rename from registry/postgres-alloydb/logo.png rename to registry/hasura/postgres-alloydb/logo.png diff --git a/registry/postgres-alloydb/metadata.json b/registry/hasura/postgres-alloydb/metadata.json similarity index 100% rename from registry/postgres-alloydb/metadata.json rename to registry/hasura/postgres-alloydb/metadata.json diff --git a/registry/postgres-azure/README.md b/registry/hasura/postgres-azure/README.md similarity index 100% rename from registry/postgres-azure/README.md rename to registry/hasura/postgres-azure/README.md diff --git a/registry/postgres-azure/logo.png b/registry/hasura/postgres-azure/logo.png similarity index 100% rename from registry/postgres-azure/logo.png rename to registry/hasura/postgres-azure/logo.png diff --git a/registry/postgres-azure/metadata.json b/registry/hasura/postgres-azure/metadata.json similarity index 100% rename from registry/postgres-azure/metadata.json rename to registry/hasura/postgres-azure/metadata.json diff --git a/registry/postgres-cosmos/README.md b/registry/hasura/postgres-cosmos/README.md similarity index 100% rename from registry/postgres-cosmos/README.md rename to registry/hasura/postgres-cosmos/README.md diff --git a/registry/postgres-cosmos/logo.png b/registry/hasura/postgres-cosmos/logo.png similarity index 100% rename from registry/postgres-cosmos/logo.png rename to registry/hasura/postgres-cosmos/logo.png diff --git a/registry/postgres-cosmos/metadata.json b/registry/hasura/postgres-cosmos/metadata.json similarity index 100% rename from registry/postgres-cosmos/metadata.json rename to registry/hasura/postgres-cosmos/metadata.json diff --git a/registry/postgres-gcp/README.md b/registry/hasura/postgres-gcp/README.md similarity index 100% rename from registry/postgres-gcp/README.md rename to registry/hasura/postgres-gcp/README.md diff --git a/registry/postgres-gcp/logo.png b/registry/hasura/postgres-gcp/logo.png similarity index 100% rename from registry/postgres-gcp/logo.png rename to registry/hasura/postgres-gcp/logo.png diff --git a/registry/postgres-gcp/metadata.json b/registry/hasura/postgres-gcp/metadata.json similarity index 100% rename from registry/postgres-gcp/metadata.json rename to registry/hasura/postgres-gcp/metadata.json diff --git a/registry/postgres-timescaledb/README.md b/registry/hasura/postgres-timescaledb/README.md similarity index 100% rename from registry/postgres-timescaledb/README.md rename to registry/hasura/postgres-timescaledb/README.md diff --git a/registry/postgres-timescaledb/logo.png b/registry/hasura/postgres-timescaledb/logo.png similarity index 100% rename from registry/postgres-timescaledb/logo.png rename to registry/hasura/postgres-timescaledb/logo.png diff --git a/registry/postgres-timescaledb/metadata.json b/registry/hasura/postgres-timescaledb/metadata.json similarity index 100% rename from registry/postgres-timescaledb/metadata.json rename to registry/hasura/postgres-timescaledb/metadata.json diff --git a/registry/postgres/README.md b/registry/hasura/postgres/README.md similarity index 100% rename from registry/postgres/README.md rename to registry/hasura/postgres/README.md diff --git a/registry/postgres/logo.png b/registry/hasura/postgres/logo.png similarity index 100% rename from registry/postgres/logo.png rename to registry/hasura/postgres/logo.png diff --git a/registry/postgres/metadata.json b/registry/hasura/postgres/metadata.json similarity index 100% rename from registry/postgres/metadata.json rename to registry/hasura/postgres/metadata.json diff --git a/registry/qdrant/README.md b/registry/hasura/qdrant/README.md similarity index 100% rename from registry/qdrant/README.md rename to registry/hasura/qdrant/README.md diff --git a/registry/qdrant/logo.png b/registry/hasura/qdrant/logo.png similarity index 100% rename from registry/qdrant/logo.png rename to registry/hasura/qdrant/logo.png diff --git a/registry/qdrant/metadata.json b/registry/hasura/qdrant/metadata.json similarity index 100% rename from registry/qdrant/metadata.json rename to registry/hasura/qdrant/metadata.json diff --git a/registry/sendgrid/README.md b/registry/hasura/sendgrid/README.md similarity index 100% rename from registry/sendgrid/README.md rename to registry/hasura/sendgrid/README.md diff --git a/registry/sendgrid/logo.png b/registry/hasura/sendgrid/logo.png similarity index 100% rename from registry/sendgrid/logo.png rename to registry/hasura/sendgrid/logo.png diff --git a/registry/sendgrid/metadata.json b/registry/hasura/sendgrid/metadata.json similarity index 100% rename from registry/sendgrid/metadata.json rename to registry/hasura/sendgrid/metadata.json diff --git a/registry/snowflake/README.md b/registry/hasura/snowflake/README.md similarity index 100% rename from registry/snowflake/README.md rename to registry/hasura/snowflake/README.md diff --git a/registry/snowflake/logo.svg b/registry/hasura/snowflake/logo.svg similarity index 100% rename from registry/snowflake/logo.svg rename to registry/hasura/snowflake/logo.svg diff --git a/registry/snowflake/metadata.json b/registry/hasura/snowflake/metadata.json similarity index 100% rename from registry/snowflake/metadata.json rename to registry/hasura/snowflake/metadata.json diff --git a/registry/sqlserver/README.md b/registry/hasura/sqlserver/README.md similarity index 100% rename from registry/sqlserver/README.md rename to registry/hasura/sqlserver/README.md diff --git a/registry/sqlserver/logo.png b/registry/hasura/sqlserver/logo.png similarity index 100% rename from registry/sqlserver/logo.png rename to registry/hasura/sqlserver/logo.png diff --git a/registry/sqlserver/metadata.json b/registry/hasura/sqlserver/metadata.json similarity index 100% rename from registry/sqlserver/metadata.json rename to registry/hasura/sqlserver/metadata.json diff --git a/registry/turso/README.md b/registry/hasura/turso/README.md similarity index 100% rename from registry/turso/README.md rename to registry/hasura/turso/README.md diff --git a/registry/turso/logo.svg b/registry/hasura/turso/logo.svg similarity index 100% rename from registry/turso/logo.svg rename to registry/hasura/turso/logo.svg diff --git a/registry/turso/metadata.json b/registry/hasura/turso/metadata.json similarity index 100% rename from registry/turso/metadata.json rename to registry/hasura/turso/metadata.json diff --git a/registry/typescript-deno/README.md b/registry/hasura/typescript-deno/README.md similarity index 100% rename from registry/typescript-deno/README.md rename to registry/hasura/typescript-deno/README.md diff --git a/registry/typescript-deno/logo.png b/registry/hasura/typescript-deno/logo.png similarity index 100% rename from registry/typescript-deno/logo.png rename to registry/hasura/typescript-deno/logo.png diff --git a/registry/typescript-deno/metadata.json b/registry/hasura/typescript-deno/metadata.json similarity index 100% rename from registry/typescript-deno/metadata.json rename to registry/hasura/typescript-deno/metadata.json diff --git a/registry/yugabyte/README.md b/registry/hasura/yugabyte/README.md similarity index 100% rename from registry/yugabyte/README.md rename to registry/hasura/yugabyte/README.md diff --git a/registry/yugabyte/logo.svg b/registry/hasura/yugabyte/logo.svg similarity index 100% rename from registry/yugabyte/logo.svg rename to registry/hasura/yugabyte/logo.svg diff --git a/registry/yugabyte/metadata.json b/registry/hasura/yugabyte/metadata.json similarity index 100% rename from registry/yugabyte/metadata.json rename to registry/hasura/yugabyte/metadata.json From bbaada311a9a8e448ca644a7d3c3f2125107707e Mon Sep 17 00:00:00 2001 From: Gil Mizrahi Date: Mon, 12 Aug 2024 16:15:03 +0300 Subject: [PATCH 043/135] Update update-ndc-postgres.sh registry -> registry/hasura (#230) https://hasurahq.slack.com/archives/C04NS5JCD8A/p1723455972067679 --- scripts/update-ndc-postgres.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/update-ndc-postgres.sh b/scripts/update-ndc-postgres.sh index 2042d55b..df8a3ea0 100755 --- a/scripts/update-ndc-postgres.sh +++ b/scripts/update-ndc-postgres.sh @@ -33,18 +33,18 @@ jq \ --arg tag "${TAG}" \ --arg hash "${HASH}" \ '.source_code.version += [{"tag": $tag, "hash": $hash, "is_verified": true}]' \ - registry/"${variant}"/metadata.json \ - > registry/"${variant}"/metadata.json2 + registry/hasura/"${variant}"/metadata.json \ + > registry/hasura/"${variant}"/metadata.json2 -mv registry/"${variant}"/metadata.json2 registry/"${variant}"/metadata.json +mv registry/hasura/"${variant}"/metadata.json2 registry/hasura/"${variant}"/metadata.json # set latest version jq \ --arg tag "${TAG}" \ '.overview.latest_version |= $tag' \ - registry/"${variant}"/metadata.json \ - > registry/"${variant}"/metadata.json2 + registry/hasura/"${variant}"/metadata.json \ + > registry/hasura/"${variant}"/metadata.json2 -mv registry/"${variant}"/metadata.json2 registry/"${variant}"/metadata.json +mv registry/hasura/"${variant}"/metadata.json2 registry/hasura/"${variant}"/metadata.json done From 46ef81f02721cc68e8193d4c045f8b90614c47ec Mon Sep 17 00:00:00 2001 From: gneeri Date: Mon, 12 Aug 2024 13:09:15 -0400 Subject: [PATCH 044/135] added new v1.0.1 release for elasticsearch (#231) --- registry/hasura/elasticsearch/metadata.json | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/registry/hasura/elasticsearch/metadata.json b/registry/hasura/elasticsearch/metadata.json index 1bc665e1..75b74dcb 100644 --- a/registry/hasura/elasticsearch/metadata.json +++ b/registry/hasura/elasticsearch/metadata.json @@ -7,7 +7,7 @@ "tags": [ "search" ], - "latest_version": "v1.0.0" + "latest_version": "v1.0.1" }, "author": { "support_email": "support@hasura.io", @@ -60,6 +60,17 @@ "source": { "hash": "9f1f508f551b4a9dec02c49e3312f38c24bb16c4" } + }, + { + "version": "1.0.1", + "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v1.0.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "83b0b4f5b1f60a50e303f6354c4d48d397fc7d0a361eb8a14d8fe11b63fe6abd" + }, + "source": { + "hash": "72fad205f57e88781da6acafe1e03a7d220467c7" + } } ], "source_code": { @@ -85,6 +96,11 @@ "tag": "v1.0.0", "hash": "9f1f508f551b4a9dec02c49e3312f38c24bb16c4", "is_verified": true + }, + { + "tag": "v1.0.1", + "hash": "72fad205f57e88781da6acafe1e03a7d220467c7", + "is_verified": true } ] } From cf57dc6ed0875463e8f44ccf27671af0d1912521 Mon Sep 17 00:00:00 2001 From: Samir Talwar Date: Tue, 13 Aug 2024 08:10:12 +0200 Subject: [PATCH 045/135] Release ndc-postgres v1.0.2. (#232) --- registry/hasura/aurora/metadata.json | 7 ++++++- registry/hasura/citus/metadata.json | 7 ++++++- registry/hasura/cockroach/metadata.json | 7 ++++++- registry/hasura/neon/metadata.json | 7 ++++++- registry/hasura/postgres-alloydb/metadata.json | 7 ++++++- registry/hasura/postgres-azure/metadata.json | 7 ++++++- registry/hasura/postgres-cosmos/metadata.json | 7 ++++++- registry/hasura/postgres-gcp/metadata.json | 7 ++++++- registry/hasura/postgres-timescaledb/metadata.json | 7 ++++++- registry/hasura/postgres/metadata.json | 7 ++++++- 10 files changed, 60 insertions(+), 10 deletions(-) diff --git a/registry/hasura/aurora/metadata.json b/registry/hasura/aurora/metadata.json index c00ff339..fd1f453b 100644 --- a/registry/hasura/aurora/metadata.json +++ b/registry/hasura/aurora/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.1" + "latest_version": "v1.0.2" }, "author": { "support_email": "support@hasura.io", @@ -54,6 +54,11 @@ "tag": "v1.0.1", "hash": "e2fd651", "is_verified": true + }, + { + "tag": "v1.0.2", + "hash": "1378805", + "is_verified": true } ] } diff --git a/registry/hasura/citus/metadata.json b/registry/hasura/citus/metadata.json index 1f4af8a0..76480564 100644 --- a/registry/hasura/citus/metadata.json +++ b/registry/hasura/citus/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.1" + "latest_version": "v1.0.2" }, "author": { "support_email": "support@hasura.io", @@ -54,6 +54,11 @@ "tag": "v1.0.1", "hash": "e2fd651", "is_verified": true + }, + { + "tag": "v1.0.2", + "hash": "1378805", + "is_verified": true } ] } diff --git a/registry/hasura/cockroach/metadata.json b/registry/hasura/cockroach/metadata.json index 88569e24..f4115c5d 100644 --- a/registry/hasura/cockroach/metadata.json +++ b/registry/hasura/cockroach/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.1" + "latest_version": "v1.0.2" }, "author": { "support_email": "support@hasura.io", @@ -54,6 +54,11 @@ "tag": "v1.0.1", "hash": "e2fd651", "is_verified": true + }, + { + "tag": "v1.0.2", + "hash": "1378805", + "is_verified": true } ] } diff --git a/registry/hasura/neon/metadata.json b/registry/hasura/neon/metadata.json index 2abe04b7..ca88bf34 100644 --- a/registry/hasura/neon/metadata.json +++ b/registry/hasura/neon/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.1" + "latest_version": "v1.0.2" }, "author": { "support_email": "support@hasura.io", @@ -54,6 +54,11 @@ "tag": "v1.0.1", "hash": "e2fd651", "is_verified": true + }, + { + "tag": "v1.0.2", + "hash": "1378805", + "is_verified": true } ] } diff --git a/registry/hasura/postgres-alloydb/metadata.json b/registry/hasura/postgres-alloydb/metadata.json index 28e968ca..7c9faa60 100644 --- a/registry/hasura/postgres-alloydb/metadata.json +++ b/registry/hasura/postgres-alloydb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.1" + "latest_version": "v1.0.2" }, "author": { "support_email": "support@hasura.io", @@ -54,6 +54,11 @@ "tag": "v1.0.1", "hash": "e2fd651", "is_verified": true + }, + { + "tag": "v1.0.2", + "hash": "1378805", + "is_verified": true } ] } diff --git a/registry/hasura/postgres-azure/metadata.json b/registry/hasura/postgres-azure/metadata.json index 4e85da7d..4abff6a4 100644 --- a/registry/hasura/postgres-azure/metadata.json +++ b/registry/hasura/postgres-azure/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.1" + "latest_version": "v1.0.2" }, "author": { "support_email": "support@hasura.io", @@ -54,6 +54,11 @@ "tag": "v1.0.1", "hash": "e2fd651", "is_verified": true + }, + { + "tag": "v1.0.2", + "hash": "1378805", + "is_verified": true } ] } diff --git a/registry/hasura/postgres-cosmos/metadata.json b/registry/hasura/postgres-cosmos/metadata.json index 66d97b3e..8c2bb20e 100644 --- a/registry/hasura/postgres-cosmos/metadata.json +++ b/registry/hasura/postgres-cosmos/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.1" + "latest_version": "v1.0.2" }, "author": { "support_email": "support@hasura.io", @@ -54,6 +54,11 @@ "tag": "v1.0.1", "hash": "e2fd651", "is_verified": true + }, + { + "tag": "v1.0.2", + "hash": "1378805", + "is_verified": true } ] } diff --git a/registry/hasura/postgres-gcp/metadata.json b/registry/hasura/postgres-gcp/metadata.json index 691bdfda..33c4a3db 100644 --- a/registry/hasura/postgres-gcp/metadata.json +++ b/registry/hasura/postgres-gcp/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.1" + "latest_version": "v1.0.2" }, "author": { "support_email": "support@hasura.io", @@ -54,6 +54,11 @@ "tag": "v1.0.1", "hash": "e2fd651", "is_verified": true + }, + { + "tag": "v1.0.2", + "hash": "1378805", + "is_verified": true } ] } diff --git a/registry/hasura/postgres-timescaledb/metadata.json b/registry/hasura/postgres-timescaledb/metadata.json index d014e1fe..201e71b3 100644 --- a/registry/hasura/postgres-timescaledb/metadata.json +++ b/registry/hasura/postgres-timescaledb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.1" + "latest_version": "v1.0.2" }, "author": { "support_email": "support@hasura.io", @@ -54,6 +54,11 @@ "tag": "v1.0.1", "hash": "e2fd651", "is_verified": true + }, + { + "tag": "v1.0.2", + "hash": "1378805", + "is_verified": true } ] } diff --git a/registry/hasura/postgres/metadata.json b/registry/hasura/postgres/metadata.json index af1333d7..501c2b73 100644 --- a/registry/hasura/postgres/metadata.json +++ b/registry/hasura/postgres/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.1" + "latest_version": "v1.0.2" }, "author": { "support_email": "support@hasura.io", @@ -54,6 +54,11 @@ "tag": "v1.0.1", "hash": "e2fd651", "is_verified": true + }, + { + "tag": "v1.0.2", + "hash": "1378805", + "is_verified": true } ] } From 8b022824031d4811f6acfa994f8cdfa8158f709d Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Tue, 13 Aug 2024 12:51:09 +0530 Subject: [PATCH 046/135] Connector publishing automation (#197) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # What This PR is the first PR towards adding automating the publishing of a new connector version. The scope of this PR is limited to the following and further changes will be made in future PRs. More on the automation process [here](https://docs.google.com/document/d/1QL37EkCQI-Ze1spNhUllher4AYcaibqq8T3Na1cOKvs/edit#heading=h.bwydohmrjusx) The scope of the PR is limited to the following: 1. On opening a new PR, any new connector versions added to the `registry` folder according to the format specified in the doc will **only** be deployed to staging. This is basically to test the whole worklow. After that, we will enable the publishing process to prod after a PR is merged to the `main` branch. 2. Only new connector versions added are published automatically (creating a new folder under the `registry//releases`), changes to an existing version are not covered (I'm not sure if this is useful to do anyways, since a release that has already been made never changes). 3. The `README.md` and `logo.png` changes will be made in a separate PR. # How does the automation work? 1. Whenever any PR is opened against the `main` branch, we get the list of files that have been added, modified and deleted. In this PR, we only use the list of added files. 2. We get the name of the connector and the version from the file path. For example: if the `ndc-postgres` releases `v2.0.0`, then one of the added files would be `registry/postgres/releases/v2.0.0/connector-packaging.json` , the name and version of the connector are parsed from the file path. 3. Parse the `connector-packaging.json` file to get the URI of the connector metadata. 4. Download the file from the URL obtained in step 3. 5. Upload the file to GCP registry and also parse the file. 6. Once all uploads are done, then insert rows into the connector versions table in the connector registry DB. 7. Connector published! 🎉 . You should be able to access the added connector version using the staging CLI. # Future work 1. Create an RFC about the file structure for connector version releases and ask the connector authors to make these changes. Once the connector authors make the changes, the connector versions will be deployed to the staging, this will be a good opportunity to test out the automation workflow. 2. Once all the connectors are updated in the `registry` folder according to the proposed structure in the RFC, we can enable the workflow in prod after a PR is merged to the `main` branch. 3. Handle changes made in the `README.md` and the `logo.png`. --------- Co-authored-by: Lyndon Maydwell --- .github/workflows/registry-updates.yaml | 61 +++ .gitignore | 1 + LICENSE | 201 ------- README.md | 1 + registry-automation/cmd/ci.go | 525 +++++++++++++++++++ registry-automation/cmd/gcp.go | 46 ++ registry-automation/cmd/root.go | 29 + registry-automation/cmd/utils.go | 108 ++++ registry-automation/go.mod | 53 ++ registry-automation/go.sum | 204 +++++++ registry-automation/main.go | 7 + rfcs/0002-distribution-gh.md | 6 +- rfcs/0006-connector-publishing-automation.md | 105 ++++ 13 files changed, 1145 insertions(+), 202 deletions(-) create mode 100644 .github/workflows/registry-updates.yaml delete mode 100644 LICENSE create mode 100644 registry-automation/cmd/ci.go create mode 100644 registry-automation/cmd/gcp.go create mode 100644 registry-automation/cmd/root.go create mode 100644 registry-automation/cmd/utils.go create mode 100644 registry-automation/go.mod create mode 100644 registry-automation/go.sum create mode 100644 registry-automation/main.go create mode 100644 rfcs/0006-connector-publishing-automation.md diff --git a/.github/workflows/registry-updates.yaml b/.github/workflows/registry-updates.yaml new file mode 100644 index 00000000..56a6af14 --- /dev/null +++ b/.github/workflows/registry-updates.yaml @@ -0,0 +1,61 @@ +name: Update Hub DB from GH Registry + +on: + pull_request: + branches: + - main + types: [opened, synchronize, reopened] + paths: + - registry/** + +jobs: + update_registry_db: + runs-on: ubuntu-latest + environment: staging + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + fetch_depth: 1 + + - name: Get all connector version package changes + id: connector-version-changed-files + uses: tj-actions/changed-files@v44 + with: + json: true + escape_json: false + files: | + registry/** + + + - name: Print out all the changed filse + env: + ADDED_FILES: ${{ steps.connector-version-changed-files.outputs.added_files }} + MODIFIED_FILES: ${{ steps.connector-version-changed-files.outputs.modified_files }} + DELETED_FILES: ${{ steps.connector-version-changed-files.outputs.deleted_files }} + run: | + echo "{\"added_files\": $ADDED_FILES, \"modified_files\": $MODIFIED_FILES, \"deleted_files\": $DELETED_FILES}" > changed_files.json + + - name: List changed files + id: list_files + run: | + cat changed_files.json + + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: 1.21.x + + - name: Run registry automation program + env: + CHANGED_FILES_PATH: "changed_files.json" + PUBLICATION_ENV: "staging" + CONNECTOR_REGISTRY_GQL_URL: ${{ secrets.CONNECTOR_REGISTRY_GQL_URL }} + GCP_BUCKET_NAME: dev-connector-platform-registry + GCP_SERVICE_ACCOUNT_DETAILS: ${{ secrets.GCP_SERVICE_ACCOUNT_DETAILS }} + CONNECTOR_PUBLICATION_KEY: ${{ secrets.CONNECTOR_PUBLICATION_KEY }} + run: | + mv changed_files.json registry-automation/changed_files.json + cd registry-automation + go run main.go ci diff --git a/.gitignore b/.gitignore index e15b2a27..0d856277 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ # testing /tmp/empty +registry-automation/extracted_tgz diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 261eeb9e..00000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/README.md b/README.md index 8e798367..c617d1ef 100644 --- a/README.md +++ b/README.md @@ -40,3 +40,4 @@ implementation][NDC reference]. [NDC specification]: http://hasura.github.io/ndc-spec/ [NDC reference]: https://github.com/hasura/ndc-spec/tree/main/ndc-reference + diff --git a/registry-automation/cmd/ci.go b/registry-automation/cmd/ci.go new file mode 100644 index 00000000..5f701888 --- /dev/null +++ b/registry-automation/cmd/ci.go @@ -0,0 +1,525 @@ +package cmd + +import ( + "context" + "encoding/json" + "fmt" + "io" + "log" + "os" + "regexp" + + "cloud.google.com/go/storage" + "github.com/machinebox/graphql" + "github.com/spf13/cobra" + "google.golang.org/api/option" + "gopkg.in/yaml.v2" +) + +// ciCmd represents the ci command +var ciCmd = &cobra.Command{ + Use: "ci", + Short: "Run the CI workflow for hub registry publication", + Run: runCI, +} + +type ChangedFiles struct { + Added []string `json:"added_files"` + Modified []string `json:"modified_files"` + Deleted []string `json:"deleted_files"` +} + +// ConnectorVersion represents a version of a connector, this type is +// used to insert a new version of a connector in the registry. +type ConnectorVersion struct { + // Namespace of the connector, e.g. "hasura" + Namespace string `json:"namespace"` + // Name of the connector, e.g. "mongodb" + Name string `json:"name"` + // Semantic version of the connector version, e.g. "v1.0.0" + Version string `json:"version"` + // Docker image of the connector version (optional) + // This field is only required if the connector version is of type `PrebuiltDockerImage` + Image *string `json:"image,omitempty"` + // URL to the connector's metadata + PackageDefinitionURL string `json:"package_definition_url"` + // Is the connector version multitenant? + IsMultitenant bool `json:"is_multitenant"` + // Type of the connector packaging `PrebuiltDockerImage`/`ManagedDockerBuild` + Type string `json:"type"` +} + +// Create a struct with the following fields: +// type string +// image *string (optional) +type ConnectionVersionMetadata struct { + Type string `yaml:"type"` + Image *string `yaml:"image,omitempty"` +} + +const ( + ManagedDockerBuild = "ManagedDockerBuild" + PrebuiltDockerImage = "PrebuiltDockerImage" +) + +// Make a struct with the fields expected in the command line arguments +type ConnectorRegistryArgs struct { + ChangedFilesPath string + PublicationEnv string + ConnectorRegistryGQLUrl string + ConnectorPublicationKey string + GCPServiceAccountDetails string + GCPBucketName string +} + +var ciCmdArgs ConnectorRegistryArgs + +func init() { + rootCmd.AddCommand(ciCmd) + + // Path for the changed files in the PR + var changedFilesPathEnv = os.Getenv("CHANGED_FILES_PATH") + ciCmd.PersistentFlags().StringVar(&ciCmdArgs.ChangedFilesPath, "changed-files-path", changedFilesPathEnv, "path to a line-separated list of changed files in the PR") + if changedFilesPathEnv == "" { + ciCmd.MarkPersistentFlagRequired("changed-files-path") + } + + // Publication environment + var publicationEnv = os.Getenv("PUBLICATION_ENV") + ciCmd.PersistentFlags().StringVar(&ciCmdArgs.PublicationEnv, "publication-env", publicationEnv, "publication environment (staging/prod). Default: staging") + // default publicationEnv to "staging" + if publicationEnv == "" { + ciCmd.PersistentFlags().Set("publication-env", "staging") + } + +} + +func buildContext() { + // Connector registry Hasura GraphQL URL + registryGQLURL := os.Getenv("CONNECTOR_REGISTRY_GQL_URL") + if registryGQLURL == "" { + log.Fatalf("CONNECTOR_REGISTRY_GQL_URL is not set") + } else { + ciCmdArgs.ConnectorRegistryGQLUrl = registryGQLURL + } + + // Connector publication key + connectorPublicationKey := os.Getenv("CONNECTOR_PUBLICATION_KEY") + if connectorPublicationKey == "" { + log.Fatalf("CONNECTOR_PUBLICATION_KEY is not set") + } else { + ciCmdArgs.ConnectorPublicationKey = connectorPublicationKey + } + + // GCP service account details + gcpServiceAccountDetails := os.Getenv("GCP_SERVICE_ACCOUNT_DETAILS") + if gcpServiceAccountDetails == "" { + log.Fatalf("GCP_SERVICE_ACCOUNT_DETAILS is not set") + } else { + ciCmdArgs.GCPServiceAccountDetails = gcpServiceAccountDetails + } + + // GCP bucket name + gcpBucketName := os.Getenv("GCP_BUCKET_NAME") + if gcpBucketName == "" { + log.Fatalf("GCP_BUCKET_NAME is not set") + } else { + ciCmdArgs.GCPBucketName = gcpBucketName + } +} + +// processChangedFiles processes the files in the PR and extracts the connector name and version +// This function checks for the following things: +// 1. If a new connector version is added, it adds the connector version to the `newlyAddedConnectorVersions` map. +// 2. If the logo file is modified, it adds the connector name and the path to the modified logo to the `modifiedLogos` map. +// 3. If the README file is modified, it adds the connector name and the path to the modified README to the `modifiedReadmes` map. +func processChangedFiles(changedFiles ChangedFiles) NewConnectorVersions { + + newlyAddedConnectorVersions := make(map[Connector]map[string]string) + + var connectorVersionPackageRegex = regexp.MustCompile(`^registry/([^/]+)/([^/]+)/releases/([^/]+)/connector-packaging\.json$`) + + files := append(changedFiles.Added, changedFiles.Modified...) + + for _, file := range files { + // Extract the connector name and version from the file path + if connectorVersionPackageRegex.MatchString(file) { + + matches := connectorVersionPackageRegex.FindStringSubmatch(file) + if len(matches) == 4 { + connectorNamespace := matches[1] + connectorName := matches[2] + connectorVersion := matches[3] + + connector := Connector{ + Name: connectorName, + Namespace: connectorNamespace, + } + + if _, exists := newlyAddedConnectorVersions[connector]; !exists { + newlyAddedConnectorVersions[connector] = make(map[string]string) + } + + newlyAddedConnectorVersions[connector][connectorVersion] = file + } + + } else { + fmt.Println("Skipping file: ", file) + } + } + + return newlyAddedConnectorVersions +} + +// runCI is the main function that runs the CI workflow +func runCI(cmd *cobra.Command, args []string) { + buildContext() + changedFilesContent, err := os.Open(ciCmdArgs.ChangedFilesPath) + if err != nil { + log.Fatalf("Failed to open the file: %v, err: %v", ciCmdArgs.ChangedFilesPath, err) + } + defer changedFilesContent.Close() + + client, err := storage.NewClient(context.Background(), option.WithCredentialsJSON([]byte(ciCmdArgs.GCPServiceAccountDetails))) + if err != nil { + log.Fatalf("Failed to create Google bucket client: %v", err) + } + defer client.Close() + + // Read the changed file's contents. This file contains all the changed files in the PR + changedFilesByteValue, err := io.ReadAll(changedFilesContent) + if err != nil { + log.Fatalf("Failed to read the changed files JSON file: %v", err) + } + + var changedFiles ChangedFiles + err = json.Unmarshal(changedFilesByteValue, &changedFiles) + if err != nil { + log.Fatalf("Failed to unmarshal the changed files content: %v", err) + + } + + // Collect the added or modified connectors + addedOrModifiedConnectorVersions := processChangedFiles(changedFiles) + // check if the map is empty + if len(addedOrModifiedConnectorVersions) == 0 { + fmt.Println("No connector versions found in the changed files.") + return + } else { + processNewlyAddedConnectorVersions(client, addedOrModifiedConnectorVersions) + } +} + +func processNewlyAddedConnectorVersions(client *storage.Client, newlyAddedConnectorVersions NewConnectorVersions) { + // Iterate over the added or modified connectors and upload the connector versions + var connectorVersions []ConnectorVersion + var uploadConnectorVersionErr error + encounteredError := false + + for connectorName, versions := range newlyAddedConnectorVersions { + for version, connectorVersionPath := range versions { + var connectorVersion ConnectorVersion + connectorVersion, uploadConnectorVersionErr = uploadConnectorVersionPackage(client, connectorName, version, connectorVersionPath) + + if uploadConnectorVersionErr != nil { + encounteredError = true + break + + } else { + connectorVersions = append(connectorVersions, connectorVersion) + } + + } + + if encounteredError { + // attempt to cleanup the uploaded connector versions + _ = cleanupUploadedConnectorVersions(client, connectorVersions) // ignore errors while cleaning up + // delete the uploaded connector versions from the registry + log.Fatalf("Failed to upload the connector version: %v", uploadConnectorVersionErr) + + } else { + fmt.Printf("Connector versions to be added to the registry: %+v\n", connectorVersions) + err := updateRegistryGQL(connectorVersions) + if err != nil { + // attempt to cleanup the uploaded connector versions + _ = cleanupUploadedConnectorVersions(client, connectorVersions) // ignore errors while cleaning up + log.Fatalf("Failed to update the registry: %v", err) + } + } + + fmt.Println("Successfully added connector versions to the registry.") + } +} + +func cleanupUploadedConnectorVersions(client *storage.Client, connectorVersions []ConnectorVersion) error { + // Iterate over the connector versions and delete the uploaded files + // from the google bucket + fmt.Println("Cleaning up the uploaded connector versions") + + for _, connectorVersion := range connectorVersions { + objectName := generateGCPObjectName(connectorVersion.Namespace, connectorVersion.Name, connectorVersion.Version) + err := deleteFile(client, ciCmdArgs.GCPBucketName, objectName) + if err != nil { + return err + } + } + return nil +} + +// Type that uniquely identifies a connector +type Connector struct { + Name string `json:"name"` + Namespace string `json:"namespace"` +} + +type NewConnectorVersions map[Connector]map[string]string + +// uploadConnectorVersionPackage uploads the connector version package to the registry +func uploadConnectorVersionPackage(client *storage.Client, connector Connector, version string, changedConnectorVersionPath string) (ConnectorVersion, error) { + + var connectorVersion ConnectorVersion + + // connector version's metadata, `registry/mongodb/releases/v1.0.0/connector-packaging.json` + connectorVersionPackagingInfo, err := readJSONFile[map[string]interface{}](changedConnectorVersionPath) // Read metadata file + if err != nil { + return connectorVersion, fmt.Errorf("failed to read the connector packaging file: %v", err) + } + // Fetch, parse, and reupload the TGZ + tgzUrl, ok := connectorVersionPackagingInfo["uri"].(string) + + // Check if the TGZ URL is valid + if !ok || tgzUrl == "" { + return connectorVersion, fmt.Errorf("invalid or undefined TGZ URL: %v", tgzUrl) + } + + connectorVersionMetadata, connectorMetadataTgzPath, err := getConnectorVersionMetadata(tgzUrl, connector, version) + if err != nil { + return connectorVersion, err + } + + uploadedTgzUrl, err := uploadConnectorVersionDefinition(client, connector.Name, connector.Namespace, version, connectorMetadataTgzPath) + if err != nil { + return connectorVersion, fmt.Errorf("failed to upload the connector version definition - connector: %v version:%v - err: %v", connector.Name, version, err) + } else { + // print success message with the name of the connector and the version + fmt.Printf("Successfully uploaded the connector version definition in google cloud registry for the connector: %v version: %v\n", connector.Name, version) + } + + // Build payload for registry upsert + return buildRegistryPayload(connector.Namespace, connector.Name, version, connectorVersionMetadata, uploadedTgzUrl) +} + +func uploadConnectorVersionDefinition(client *storage.Client, connectorNamespace, connectorName string, connectorVersion string, connectorMetadataTgzPath string) (string, error) { + bucketName := ciCmdArgs.GCPBucketName + objectName := generateGCPObjectName(connectorNamespace, connectorName, connectorVersion) + uploadedTgzUrl, err := uploadFile(client, bucketName, objectName, connectorMetadataTgzPath) + + if err != nil { + return "", err + } + return uploadedTgzUrl, nil +} + +// Downloads the TGZ File from the URL specified by `tgzUrl`, extracts the TGZ file and returns the content of the +// connector-definition.yaml present in the .hasura-connector folder. +func getConnectorVersionMetadata(tgzUrl string, connector Connector, connectorVersion string) (map[string]interface{}, string, error) { + var connectorVersionMetadata map[string]interface{} + tgzPath, err := getTempFilePath("extracted_tgz") + if err != nil { + return connectorVersionMetadata, "", fmt.Errorf("failed to get the temp file path: %v", err) + } + err = downloadFile(tgzUrl, tgzPath, map[string]string{}) + if err != nil { + return connectorVersionMetadata, "", fmt.Errorf("failed to download the connector version metadata file from the URL: %v - err: %v", tgzUrl, err) + } + + extractedTgzFolderPath := "extracted_tgz" + + if _, err := os.Stat(extractedTgzFolderPath); os.IsNotExist(err) { + err := os.Mkdir(extractedTgzFolderPath, 0755) + if err != nil { + return connectorVersionMetadata, "", fmt.Errorf("failed to read the connector version metadata file: %v", err) + } + } + + connectorVersionMetadataYamlFilePath, err := extractTarGz(tgzPath, extractedTgzFolderPath+"/"+connector.Namespace+"/"+connector.Name+"/"+connectorVersion) + if err != nil { + return connectorVersionMetadata, "", fmt.Errorf("failed to read the connector version metadata file: %v", err) + } else { + fmt.Println("Extracted metadata file at :", connectorVersionMetadataYamlFilePath) + } + + connectorVersionMetadata, err = readYAMLFile(connectorVersionMetadataYamlFilePath) + if err != nil { + return connectorVersionMetadata, "", fmt.Errorf("failed to read the connector version metadata file: %v", err) + } + return connectorVersionMetadata, tgzPath, nil +} + +// Write a function that accepts a file path to a YAML file and returns +// the contents of the file as a map[string]interface{}. +// readYAMLFile accepts a file path to a YAML file and returns the contents of the file as a map[string]interface{}. +func readYAMLFile(filePath string) (map[string]interface{}, error) { + // Open the file + file, err := os.Open(filePath) + if err != nil { + return nil, fmt.Errorf("failed to open file: %w", err) + } + defer file.Close() + + // Read the file contents + data, err := io.ReadAll(file) + if err != nil { + return nil, fmt.Errorf("failed to read file: %w", err) + } + + // Unmarshal the YAML contents into a map + var result map[string]interface{} + err = yaml.Unmarshal(data, &result) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal YAML: %w", err) + } + + return result, nil +} + +func getConnectorNamespace(connectorMetadata map[string]interface{}) (string, error) { + connectorOverview, ok := connectorMetadata["overview"].(map[string]interface{}) + if !ok { + return "", fmt.Errorf("could not find connector overview in the connector's metadata") + } + connectorNamespace, ok := connectorOverview["namespace"].(string) + if !ok { + return "", fmt.Errorf("could not find the 'namespace' of the connector in the connector's overview in the connector's metadata.json") + } + return connectorNamespace, nil +} + +// struct to store the response of teh GetConnectorInfo query +type GetConnectorInfoResponse struct { + HubRegistryConnector []struct { + Name string `json:"name"` + MultitenantConnector *struct { + ID string `json:"id"` + } `json:"multitenant_connector"` + } `json:"hub_registry_connector"` +} + +func getConnectorInfoFromRegistry(connectorNamespace string, connectorName string) (GetConnectorInfoResponse, error) { + var respData GetConnectorInfoResponse + client := graphql.NewClient(ciCmdArgs.ConnectorRegistryGQLUrl) + ctx := context.Background() + + req := graphql.NewRequest(` +query GetConnectorInfo ($name: String!, $namespace: String!) { + hub_registry_connector(where: {_and: [{name: {_eq: $name}}, {namespace: {_eq: $namespace}}]}) { + name + multitenant_connector { + id + } + } +}`) + req.Var("name", connectorName) + req.Var("namespace", connectorNamespace) + + req.Header.Set("x-hasura-role", "connector_publishing_automation") + req.Header.Set("x-connector-publication-key", ciCmdArgs.ConnectorPublicationKey) + + // Execute the GraphQL query and check the response. + if err := client.Run(ctx, req, &respData); err != nil { + return respData, err + } else { + if len(respData.HubRegistryConnector) == 0 { + return respData, nil + } + } + + return respData, nil +} + +// buildRegistryPayload builds the payload for the registry upsert API +func buildRegistryPayload( + connectorNamespace string, + connectorName string, + version string, + connectorVersionMetadata map[string]interface{}, + uploadedConnectorDefinitionTgzUrl string, +) (ConnectorVersion, error) { + var connectorVersion ConnectorVersion + var connectorVersionDockerImage string + connectorVersionPackagingDefinition, ok := connectorVersionMetadata["packagingDefinition"].(map[interface{}]interface{}) + if !ok { + return connectorVersion, fmt.Errorf("could not find the 'packagingDefinition' of the connector %s version %s in the connector's metadata", connectorName, version) + } + connectorVersionPackagingType, ok := connectorVersionPackagingDefinition["type"].(string) + + if !ok && (connectorVersionPackagingType == ManagedDockerBuild || connectorVersionPackagingType == PrebuiltDockerImage) { + return connectorVersion, fmt.Errorf("invalid or undefined connector type: %v", connectorVersionPackagingDefinition) + } else if connectorVersionPackagingType == PrebuiltDockerImage { + connectorVersionDockerImage, ok = connectorVersionPackagingDefinition["dockerImage"].(string) + if !ok { + return connectorVersion, fmt.Errorf("could not find the 'dockerImage' of the PrebuiltDockerImage connector %s version %s in the connector's metadata", connectorName, version) + } + + } + + connectorInfo, err := getConnectorInfoFromRegistry(connectorNamespace, connectorName) + + if err != nil { + return connectorVersion, err + } + + // Check if the connector exists in the registry first + if len(connectorInfo.HubRegistryConnector) == 0 { + return connectorVersion, fmt.Errorf("Inserting a new connector is not supported yet") + } + + var connectorVersionType string + + if connectorVersionPackagingType == PrebuiltDockerImage { + // Note: The connector version type is set to `PreBuiltDockerImage` if the connector version is of type `PrebuiltDockerImage`, this is a HACK because this value might be removed in the future and we might not even need to insert new connector versions in the `hub_registry_connector_version` table. + connectorVersionType = "PreBuiltDockerImage" + } else { + connectorVersionType = ManagedDockerBuild + } + + connectorVersion = ConnectorVersion{ + Namespace: connectorNamespace, + Name: connectorName, + Version: version, + Image: &connectorVersionDockerImage, + PackageDefinitionURL: uploadedConnectorDefinitionTgzUrl, + IsMultitenant: connectorInfo.HubRegistryConnector[0].MultitenantConnector != nil, + Type: connectorVersionType, + } + + return connectorVersion, nil +} + +func updateRegistryGQL(payload []ConnectorVersion) error { + var respData map[string]interface{} + client := graphql.NewClient(ciCmdArgs.ConnectorRegistryGQLUrl) + ctx := context.Background() + + req := graphql.NewRequest(` +mutation InsertConnectorVersion($connectorVersion: [hub_registry_connector_version_insert_input!]!) { + insert_hub_registry_connector_version(objects: $connectorVersion, on_conflict: {constraint: connector_version_namespace_name_version_key, update_columns: [image, package_definition_url]}) { + affected_rows + returning { + id + } + } +}`) + // add the payload to the request + req.Var("connectorVersion", payload) + + req.Header.Set("x-hasura-role", "connector_publishing_automation") + req.Header.Set("x-connector-publication-key", ciCmdArgs.ConnectorPublicationKey) + + // Execute the GraphQL query and check the response. + if err := client.Run(ctx, req, &respData); err != nil { + return err + } + + return nil +} diff --git a/registry-automation/cmd/gcp.go b/registry-automation/cmd/gcp.go new file mode 100644 index 00000000..40d41d62 --- /dev/null +++ b/registry-automation/cmd/gcp.go @@ -0,0 +1,46 @@ +// Description: This file contains the functions to interact with Google Cloud Storage. +package cmd + +import ( + "cloud.google.com/go/storage" + "context" + "fmt" + "io" + "os" +) + +// deleteFile deletes a file from Google Cloud Storage +func deleteFile(client *storage.Client, bucketName, objectName string) error { + bucket := client.Bucket(bucketName) + object := bucket.Object(objectName) + + return object.Delete(context.Background()) +} + +// uploadFile uploads a file to Google Cloud Storage +// document this function with comments +func uploadFile(client *storage.Client, bucketName, objectName, filePath string) (string, error) { + bucket := client.Bucket(bucketName) + object := bucket.Object(objectName) + newCtx := context.Background() + wc := object.NewWriter(newCtx) + + file, err := os.Open(filePath) + if err != nil { + return "", fmt.Errorf("failed to open file: %v", err) + } + defer file.Close() + + if _, err := io.Copy(wc, file); err != nil { + return "", fmt.Errorf("failed to upload file: %w", err) + } + if err := wc.Close(); err != nil { + return "", fmt.Errorf("failed to close writer: %w", err) + } + + // Return the public URL of the uploaded object. + publicURL := fmt.Sprintf("https://storage.googleapis.com/%s/%s", bucketName, objectName) + + fmt.Printf("File %s uploaded to bucket %s as %s and is available at %s.\n", filePath, bucketName, objectName, publicURL) + return publicURL, nil +} diff --git a/registry-automation/cmd/root.go b/registry-automation/cmd/root.go new file mode 100644 index 00000000..9cf49a5d --- /dev/null +++ b/registry-automation/cmd/root.go @@ -0,0 +1,29 @@ +package cmd + +import ( + "os" + + "github.com/spf13/cobra" +) + +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ + Use: "registry-automation", + Short: "Commands associated with automation for the hub registry", +} + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + err := rootCmd.Execute() + if err != nil { + os.Exit(1) + } +} + +func init() { + // Here you will define your flags and configuration settings. + // Cobra supports persistent flags, which, if defined here, + // will be global for your application. + +} diff --git a/registry-automation/cmd/utils.go b/registry-automation/cmd/utils.go new file mode 100644 index 00000000..15357b07 --- /dev/null +++ b/registry-automation/cmd/utils.go @@ -0,0 +1,108 @@ +package cmd + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "os" + "os/exec" +) + +func generateGCPObjectName(namespace, connectorName, version string) string { + return fmt.Sprintf("packages/%s/%s/%s/package.tgz", namespace, connectorName, version) +} + +func downloadFile(sourceURL, destination string, headers map[string]string) error { + // Create a new HTTP client + client := &http.Client{} + + // Create a new GET request + req, err := http.NewRequest("GET", sourceURL, nil) + if err != nil { + return fmt.Errorf("error creating request: %v", err) + } + + // Add headers + for key, value := range headers { + req.Header.Set(key, value) + } + + // Send the request + resp, err := client.Do(req) + if err != nil { + return fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + // Create the destination file + outFile, err := os.Create(destination) + if err != nil { + return fmt.Errorf("error creating destination file: %v", err) + } + defer outFile.Close() + + // Write the response body to the file + _, err = io.Copy(outFile, resp.Body) + if err != nil { + return fmt.Errorf("error writing to file: %v", err) + } + return nil +} + +// Reads a JSON file and attempts to parse the content of the file +// into the type T. +// Note: The location is relative to the root of the repository +func readJSONFile[T any](location string) (T, error) { + // Read the file + var result T + fileBytes, err := os.ReadFile("../" + location) + if err != nil { + return result, fmt.Errorf("error reading file at location: %s %v", location, err) + } + + if err := json.Unmarshal(fileBytes, &result); err != nil { + return result, fmt.Errorf("error parsing JSON: %v", err) + } + + return result, nil +} + +// getTempFilePath generates a random file name in the specified directory. +func getTempFilePath(directory string) (string, error) { + // Ensure the directory exists + err := os.MkdirAll(directory, os.ModePerm) + if err != nil { + panic(fmt.Errorf("error creating directory: %v", err)) + } + + // Generate a random file name + tempFile, err := os.CreateTemp(directory, "connector-*.tar.gz") + if err != nil { + return "", fmt.Errorf("error creating temp file: %v", err) + } + defer tempFile.Close() + + return tempFile.Name(), nil + +} + +func extractTarGz(src, dest string) (string, error) { + // Create the destination directory + // Get the present working directory + pwd := os.Getenv("PWD") + filepath := pwd + "/" + dest + + if err := os.MkdirAll(filepath, 0755); err != nil { + return "", fmt.Errorf("error creating destination directory: %v", err) + } + // Run the tar command with the -xvzf options + cmd := exec.Command("tar", "-xvzf", src, "-C", dest) + + // Execute the command + if err := cmd.Run(); err != nil { + return "", fmt.Errorf("error extracting tar.gz file: %v", err) + } + + return fmt.Sprintf("%s/.hasura-connector/connector-metadata.yaml", filepath), nil +} diff --git a/registry-automation/go.mod b/registry-automation/go.mod new file mode 100644 index 00000000..59b7ef16 --- /dev/null +++ b/registry-automation/go.mod @@ -0,0 +1,53 @@ +module github.com/hasura/ndc-hub/registry-automation + +go 1.21.4 + +require github.com/spf13/cobra v1.8.0 + +require ( + cloud.google.com/go v0.115.0 // indirect + cloud.google.com/go/auth v0.7.1 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.3 // indirect + cloud.google.com/go/compute/metadata v0.5.0 // indirect + cloud.google.com/go/iam v1.1.11 // indirect + cloud.google.com/go/storage v1.43.0 // indirect + github.com/andybalholm/brotli v1.0.1 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/s2a-go v0.1.7 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect + github.com/googleapis/gax-go/v2 v2.12.5 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/klauspost/pgzip v1.2.5 // indirect + github.com/machinebox/graphql v0.2.2 // indirect + github.com/nwaples/rardecode v1.1.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/ulikunitz/xz v0.5.9 // indirect + github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/time v0.5.0 // indirect + google.golang.org/api v0.188.0 // indirect + google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/grpc v1.65.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/yaml.v2 v2.4.0 +) diff --git a/registry-automation/go.sum b/registry-automation/go.sum new file mode 100644 index 00000000..5d0aac40 --- /dev/null +++ b/registry-automation/go.sum @@ -0,0 +1,204 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= +cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= +cloud.google.com/go/auth v0.7.1 h1:Iv1bbpzJ2OIg16m94XI9/tlzZZl3cdeR3nGVGj78N7s= +cloud.google.com/go/auth v0.7.1/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs= +cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= +cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= +cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= +cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= +cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw= +cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ= +cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= +cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= +github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY= +github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= +github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw= +github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA= +github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.11.4 h1:kz40R/YWls3iqT9zX9AHN3WoVsrAWVyui5sxuLqiXqU= +github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= +github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/machinebox/graphql v0.2.2 h1:dWKpJligYKhYKO5A2gvNhkJdQMNZeChZYyBbrZkBZfo= +github.com/machinebox/graphql v0.2.2/go.mod h1:F+kbVMHuwrQ5tYgU9JXlnskM8nOaFxCAEolaQybkjWA= +github.com/mholt/archiver v3.1.1+incompatible h1:1dCVxuqs0dJseYEhi5pl7MYPH9zDa1wBi7mF09cbNkU= +github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU= +github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= +github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= +github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ= +github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= +github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= +github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4/v4 v4.1.2 h1:qvY3YFXRQE/XB8MlLzJH7mSzBs74eA2gg52YTk6jUPM= +github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I= +github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= +google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= +google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/registry-automation/main.go b/registry-automation/main.go new file mode 100644 index 00000000..4f168b4b --- /dev/null +++ b/registry-automation/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/hasura/ndc-hub/registry-automation/cmd" + +func main() { + cmd.Execute() +} diff --git a/rfcs/0002-distribution-gh.md b/rfcs/0002-distribution-gh.md index e1b39817..2933022a 100644 --- a/rfcs/0002-distribution-gh.md +++ b/rfcs/0002-distribution-gh.md @@ -1,8 +1,13 @@ # Connector Package Distribution RFC - Milestone 1 +> [!NOTE] +> This RFC has since been extended by the [Connector publishing automation](./0006-connectors-publishing-automation.md) + This is a Work-In-Progress document. Please provide any feedback you wish to contribute via Github comments and suggestions. + + ## Purpose Connector API, definition and packaging are specified respectively by: @@ -271,4 +276,3 @@ Any publicly accessible APIs with publication capabilities have the potential to * Recycling of content * Unintentional mistakes * Spam / Reflection - diff --git a/rfcs/0006-connector-publishing-automation.md b/rfcs/0006-connector-publishing-automation.md new file mode 100644 index 00000000..ef4081ea --- /dev/null +++ b/rfcs/0006-connector-publishing-automation.md @@ -0,0 +1,105 @@ +# Connector registry Github packaging + +> [!NOTE] +> This RFC is an update on the [Connector Package Distribution RFC](0002-distribution-gh.md). + +## Introduction + +This RFC proposes how a new connector version should be added to the `registry` folder to automatically be published. Publishing in this context means that the connector version will be available for public use in Hasura's DDN. + +## File structure of the connectors `registry` + +The packages field in the `metadata.json` file will be removed and replaced by a releases folder within the connector directory. + +The releases folder will house a separate folder for each version of the connector, with each version folder containing a `connector-packaging.json` file. + +This `connector-packaging.json` file will include all the necessary information to access the package definition. + +The following directory structure for connector versions is proposed: + +``` +registry// +├── logo.png +├── metadata.json +├── README.md +└── releases + ├── v0.0.1 + │ └── connector-packaging.json + ├── v0.0.2 + │ └── connector-packaging.json + ├── v0.0.3 + │ └── connector-packaging.json + ├── v0.0.4 + │ └── connector-packaging.json + ├── v0.0.5 + │ └── connector-packaging.json + ├── v0.0.6 + │ └── connector-packaging.json + ├── v0.1.0 + │ └── connector-packaging.json + └── v1.0.0 + └── connector-packaging.json +``` + +The `registry` folder will contain a folder for each connector. Each connector folder will contain the following files: + +- `logo.png`: The logo of the connector. The logo should be in PNG format. +- `metadata.json`: The metadata of the connector. Metadata format is described in the [Github Distribution RFC](./0002-distribution-gh.md). +- `README.md`: The README file of the connector. The README file should contain information about the connector, how to use it, and any other relevant information. The contents of the README file would be displayed in the landing page of the connector in the Hasura. +- `releases`: The releases folder will contain a folder for each version of the connector. Each version folder will contain a `connector-packaging.json` file. More details about the `connector-packaging.json` file are provided below. + +NOTE: The `releases` folder should only be added for Hub connectors. +For example, `postgres-azure` connector should not have a `releases` folder as it is not a Hub connector. + +### `connector-packaging.json` + +Every connector version should have a package definition. The `connector-packaging.json` +file should contain the relevant information to access the package definition. + +```json +{ + "version": "0.0.1", + "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "2cd3584557be7e2870f3488a30cac6219924b3f7accd9f5f473285323843a0f4" + }, + "source": { + "hash": "c32adbde478147518f65ff465c40a0703239288a" + } +} +``` + +The following fields are required: + +- `version`: The version of the connector. +- `uri`: The URI to download the connector package. The package should be a tarball containing the connector package definition and the URL should be accessible without any authentication. +- `checksum`: The checksum of the connector package. The checksum should be calculated using the `sha256` algorithm. +- `source`: The source of the connector package. The `hash` field should contain the commit hash of the source code that was used to build the connector package. + + +## Publishing a new connector version + +To publish a new connector version, follow these steps: + +1. Create a new folder with the version number in the `releases` folder of the connector. +2. Create a `connector-packaging.json` file in the new folder with the relevant information. +3. Open a PR against the `main` branch of the repository. +4. You should see the `registry-update` workflow run on the PR. This workflow will validate the connector-packaging.json file and publish the new version to the registry if the validation is successful. +5. Once the workflow is successful, the new version of the connector will be available in the **Staging** Hasura DDN. Every new commit will overwrite the previous version of that connector in the staging DDN. So, feel free to push new commits to the PR to update the connector version in the staging DDN. +6. Once the PR is merged, the new version of the connector will be available in the **Production** Hasura DDN. + +> [!NOTE] +> The `registry-update` workflow will only run on the PRs against the `main` branch of the repository. + +> [!NOTE] +> Multiple connector versions can be published in the same PR. The `registry-update` workflow will publish all the versions in the PR to the registry. + + +## Updates to logo and README + +If you want to update the logo or README of the connector, you can do so by opening a PR against the `main` branch of the repository. + +The `registry-update` workflow will run on the PR and update the logo and README in the staging DDN. + +Once the PR is merged, the logo and README will be updated in the production DDN. From 023a1a3d967ce6ae14404d44eafd40cb42499046 Mon Sep 17 00:00:00 2001 From: Vishnu Bharathi Date: Tue, 13 Aug 2024 15:57:20 +0530 Subject: [PATCH 047/135] postgres: add v1.0.2 version (#234) Co-authored-by: Karthikeyan C --- .github/workflows/registry-updates.yaml | 3 +-- registry-automation/cmd/ci.go | 4 ++-- .../postgres/releases/v1.0.2/connector-packaging.json | 11 +++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 registry/hasura/postgres/releases/v1.0.2/connector-packaging.json diff --git a/.github/workflows/registry-updates.yaml b/.github/workflows/registry-updates.yaml index 56a6af14..6c95b010 100644 --- a/.github/workflows/registry-updates.yaml +++ b/.github/workflows/registry-updates.yaml @@ -28,7 +28,6 @@ jobs: files: | registry/** - - name: Print out all the changed filse env: ADDED_FILES: ${{ steps.connector-version-changed-files.outputs.added_files }} @@ -52,7 +51,7 @@ jobs: CHANGED_FILES_PATH: "changed_files.json" PUBLICATION_ENV: "staging" CONNECTOR_REGISTRY_GQL_URL: ${{ secrets.CONNECTOR_REGISTRY_GQL_URL }} - GCP_BUCKET_NAME: dev-connector-platform-registry + GCP_BUCKET_NAME: ${{ secrets.GCP_BUCKET_NAME }} GCP_SERVICE_ACCOUNT_DETAILS: ${{ secrets.GCP_SERVICE_ACCOUNT_DETAILS }} CONNECTOR_PUBLICATION_KEY: ${{ secrets.CONNECTOR_PUBLICATION_KEY }} run: | diff --git a/registry-automation/cmd/ci.go b/registry-automation/cmd/ci.go index 5f701888..d80dd6e6 100644 --- a/registry-automation/cmd/ci.go +++ b/registry-automation/cmd/ci.go @@ -297,7 +297,7 @@ func uploadConnectorVersionPackage(client *storage.Client, connector Connector, return connectorVersion, err } - uploadedTgzUrl, err := uploadConnectorVersionDefinition(client, connector.Name, connector.Namespace, version, connectorMetadataTgzPath) + uploadedTgzUrl, err := uploadConnectorVersionDefinition(client, connector.Namespace, connector.Name, version, connectorMetadataTgzPath) if err != nil { return connectorVersion, fmt.Errorf("failed to upload the connector version definition - connector: %v version:%v - err: %v", connector.Name, version, err) } else { @@ -503,7 +503,7 @@ func updateRegistryGQL(payload []ConnectorVersion) error { req := graphql.NewRequest(` mutation InsertConnectorVersion($connectorVersion: [hub_registry_connector_version_insert_input!]!) { - insert_hub_registry_connector_version(objects: $connectorVersion, on_conflict: {constraint: connector_version_namespace_name_version_key, update_columns: [image, package_definition_url]}) { + insert_hub_registry_connector_version(objects: $connectorVersion, on_conflict: {constraint: connector_version_namespace_name_version_key, update_columns: [image, package_definition_url, is_multitenant]}) { affected_rows returning { id diff --git a/registry/hasura/postgres/releases/v1.0.2/connector-packaging.json b/registry/hasura/postgres/releases/v1.0.2/connector-packaging.json new file mode 100644 index 00000000..6ecbb324 --- /dev/null +++ b/registry/hasura/postgres/releases/v1.0.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.2", + "uri": "https://github.com/hasura/ndc-postgres/releases/download/v1.0.2/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "38d4f4a843b3cc7c1b798c21594c8ffcbcd7595c5d456927ea61fe02a7f9d80f" + }, + "source": { + "hash": "1378805c72a16934788d3ab6a5bc767f8f0b9741" + } +} From fea5f1df82622572d44b9c3e346de64331997042 Mon Sep 17 00:00:00 2001 From: pranshi06 <85474619+pranshi06@users.noreply.github.com> Date: Tue, 13 Aug 2024 19:21:39 +0530 Subject: [PATCH 048/135] Add SQL Server and Snowflake registration automation releases folder (#235) --- .../releases/v0.1.0/connector-packaging.json | 11 +++++++++++ .../releases/v0.1.0/connector-packaging.json | 11 +++++++++++ .../releases/v0.1.1/connector-packaging.json | 11 +++++++++++ .../releases/v0.1.2/connector-packaging.json | 11 +++++++++++ 4 files changed, 44 insertions(+) create mode 100644 registry/hasura/snowflake/releases/v0.1.0/connector-packaging.json create mode 100644 registry/hasura/sqlserver/releases/v0.1.0/connector-packaging.json create mode 100644 registry/hasura/sqlserver/releases/v0.1.1/connector-packaging.json create mode 100644 registry/hasura/sqlserver/releases/v0.1.2/connector-packaging.json diff --git a/registry/hasura/snowflake/releases/v0.1.0/connector-packaging.json b/registry/hasura/snowflake/releases/v0.1.0/connector-packaging.json new file mode 100644 index 00000000..55a37c1c --- /dev/null +++ b/registry/hasura/snowflake/releases/v0.1.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/snowflake%2Fv0.1.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "564757bc44bebe56560fe21a1306507d160caf084d69556bded4a7ed392e1b41" + }, + "source": { + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" + } +} diff --git a/registry/hasura/sqlserver/releases/v0.1.0/connector-packaging.json b/registry/hasura/sqlserver/releases/v0.1.0/connector-packaging.json new file mode 100644 index 00000000..f0200516 --- /dev/null +++ b/registry/hasura/sqlserver/releases/v0.1.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.1.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "5f47a1df3055b694ffaf13058e201ac0fa83db53ce2044cd15eeaaa841565cb4" + }, + "source": { + "hash": "e26d6bd1a22540dcf5c5b29460260c2d23ff2657" + } +} diff --git a/registry/hasura/sqlserver/releases/v0.1.1/connector-packaging.json b/registry/hasura/sqlserver/releases/v0.1.1/connector-packaging.json new file mode 100644 index 00000000..d1836ef5 --- /dev/null +++ b/registry/hasura/sqlserver/releases/v0.1.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.1", + "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.1.1/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "340f11a2dbc180af838327c09949ac0dc14c94eb87b0d6b5a28c765ec928b1a9" + }, + "source": { + "hash": "638a2b608f7a9c4625de7df35c61c909d2ce16b1" + } +} diff --git a/registry/hasura/sqlserver/releases/v0.1.2/connector-packaging.json b/registry/hasura/sqlserver/releases/v0.1.2/connector-packaging.json new file mode 100644 index 00000000..7757b0bd --- /dev/null +++ b/registry/hasura/sqlserver/releases/v0.1.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.2", + "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.1.2/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "102c642b2e0ddea1eaa471c5189ecd3423a20f91ad83995e09f9d4721dd85732" + }, + "source": { + "hash": "bc0fd3d126f6c142587e014aa900fc6bc90cd59d" + } +} From e67621a20fe1ba2ba086a9484068bdf38913bbf4 Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Wed, 14 Aug 2024 02:09:52 +0530 Subject: [PATCH 049/135] Add releases folder for `azure-cosmos` and `mysql` (#233) --- registry-automation/cmd/ci.go | 12 ++++++++-- registry/hasura/azure-cosmos/metadata.json | 23 +------------------ .../releases/v0.1.2/connector-packaging.json | 11 +++++++++ .../releases/v0.1.3/connector-packaging.json | 11 +++++++++ .../releases/v0.1.0/connector-packaging.json | 11 +++++++++ .../releases/v0.1.0/connector-packaging.json | 11 +++++++++ 6 files changed, 55 insertions(+), 24 deletions(-) create mode 100644 registry/hasura/azure-cosmos/releases/v0.1.2/connector-packaging.json create mode 100644 registry/hasura/azure-cosmos/releases/v0.1.3/connector-packaging.json create mode 100644 registry/hasura/mysql/releases/v0.1.0/connector-packaging.json create mode 100644 registry/hasura/oracle/releases/v0.1.0/connector-packaging.json diff --git a/registry-automation/cmd/ci.go b/registry-automation/cmd/ci.go index d80dd6e6..9bfdbf9c 100644 --- a/registry-automation/cmd/ci.go +++ b/registry-automation/cmd/ci.go @@ -446,7 +446,7 @@ func buildRegistryPayload( uploadedConnectorDefinitionTgzUrl string, ) (ConnectorVersion, error) { var connectorVersion ConnectorVersion - var connectorVersionDockerImage string + var connectorVersionDockerImage string = "" connectorVersionPackagingDefinition, ok := connectorVersionMetadata["packagingDefinition"].(map[interface{}]interface{}) if !ok { return connectorVersion, fmt.Errorf("could not find the 'packagingDefinition' of the connector %s version %s in the connector's metadata", connectorName, version) @@ -483,11 +483,19 @@ func buildRegistryPayload( connectorVersionType = ManagedDockerBuild } + var connectorVersionImage *string + + if connectorVersionDockerImage == "" { + connectorVersionImage = nil + } else { + connectorVersionImage = &connectorVersionDockerImage + } + connectorVersion = ConnectorVersion{ Namespace: connectorNamespace, Name: connectorName, Version: version, - Image: &connectorVersionDockerImage, + Image: connectorVersionImage, PackageDefinitionURL: uploadedConnectorDefinitionTgzUrl, IsMultitenant: connectorInfo.HubRegistryConnector[0].MultitenantConnector != nil, Type: connectorVersionType, diff --git a/registry/hasura/azure-cosmos/metadata.json b/registry/hasura/azure-cosmos/metadata.json index 46b72c45..74caad96 100644 --- a/registry/hasura/azure-cosmos/metadata.json +++ b/registry/hasura/azure-cosmos/metadata.json @@ -15,28 +15,7 @@ "is_verified": true, "is_hosted_by_hasura": true, "packages": [ - { - "version": "0.1.3", - "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.1.3/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "34655ff615be0d5738ffe1811972776808e9880a6fa3ec673123844c648154d7" - }, - "source": { - "hash": "97032d1a41fd932d637b5ba24ca6611d9e1f4905" - } - }, - { - "version": "0.1.2", - "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.1.2/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "09ce246a9039d2aaf799a7e0402b243fb3763ba802535348a9fee243de1bf1b7" - }, - "source": { - "hash": "f67b2f80d64175a055a9489d4e59f30d5d3870a0" - } - } + ], "source_code": { "is_open_source": true, diff --git a/registry/hasura/azure-cosmos/releases/v0.1.2/connector-packaging.json b/registry/hasura/azure-cosmos/releases/v0.1.2/connector-packaging.json new file mode 100644 index 00000000..4feb205e --- /dev/null +++ b/registry/hasura/azure-cosmos/releases/v0.1.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.2", + "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.1.2/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "09ce246a9039d2aaf799a7e0402b243fb3763ba802535348a9fee243de1bf1b7" + }, + "source": { + "hash": "f67b2f80d64175a055a9489d4e59f30d5d3870a0" + } +} diff --git a/registry/hasura/azure-cosmos/releases/v0.1.3/connector-packaging.json b/registry/hasura/azure-cosmos/releases/v0.1.3/connector-packaging.json new file mode 100644 index 00000000..3d4242c9 --- /dev/null +++ b/registry/hasura/azure-cosmos/releases/v0.1.3/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.3", + "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.1.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "34655ff615be0d5738ffe1811972776808e9880a6fa3ec673123844c648154d7" + }, + "source": { + "hash": "97032d1a41fd932d637b5ba24ca6611d9e1f4905" + } +} diff --git a/registry/hasura/mysql/releases/v0.1.0/connector-packaging.json b/registry/hasura/mysql/releases/v0.1.0/connector-packaging.json new file mode 100644 index 00000000..ef79399f --- /dev/null +++ b/registry/hasura/mysql/releases/v0.1.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/mysql%2Fv0.1.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "09b51f9be725099345159880d21efb712776bfd09291a0daa81d7e7b1418ca2c" + }, + "source": { + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" + } +} diff --git a/registry/hasura/oracle/releases/v0.1.0/connector-packaging.json b/registry/hasura/oracle/releases/v0.1.0/connector-packaging.json new file mode 100644 index 00000000..535615bc --- /dev/null +++ b/registry/hasura/oracle/releases/v0.1.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/oracle%2Fv0.1.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "0d837408a213f55df34062b96a2ac7fabcf8c61891918b6b2754d90fc61dd24c" + }, + "source": { + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" + } +} From 765197ab5cdfd746d7c71d301c5fa08d89016c6f Mon Sep 17 00:00:00 2001 From: gneeri Date: Tue, 13 Aug 2024 17:17:05 -0400 Subject: [PATCH 050/135] Update metadata.json (#239) --- registry/hasura/open-api-lambda/metadata.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/registry/hasura/open-api-lambda/metadata.json b/registry/hasura/open-api-lambda/metadata.json index 1a5a25eb..9163d8f5 100644 --- a/registry/hasura/open-api-lambda/metadata.json +++ b/registry/hasura/open-api-lambda/metadata.json @@ -1,8 +1,8 @@ { "overview": { "namespace": "hasura", - "description": "The Open API Lambda Connector allows you to import already existing APIs specified by the Open API Spec into you Hasura DDN subgraphs", - "title": "Open API Lambda Connector", + "description": "The OpenAPI Lambda Connector allows you to import already existing APIs specified by the Open API Spec into you Hasura DDN subgraphs", + "title": "OpenAPI Lambda Connector", "logo": "logo.png", "tags": [], "latest_version": "v0.1.1" From 8a2bb13f900b5d0b19dee4b9f4c133f5508b10ec Mon Sep 17 00:00:00 2001 From: gneeri Date: Tue, 13 Aug 2024 17:17:30 -0400 Subject: [PATCH 051/135] added registration automation files for elasticsearch (#236) --- registry/hasura/elasticsearch/README.md | 24 +++++++++---------- .../releases/v0.1.0/connector-packaging.json | 11 +++++++++ .../releases/v0.1.1/connector-packaging.json | 11 +++++++++ .../releases/v0.2.0/connector-packaging.json | 11 +++++++++ .../releases/v1.0.0/connector-packaging.json | 11 +++++++++ .../releases/v1.0.1/connector-packaging.json | 11 +++++++++ 6 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 registry/hasura/elasticsearch/releases/v0.1.0/connector-packaging.json create mode 100644 registry/hasura/elasticsearch/releases/v0.1.1/connector-packaging.json create mode 100644 registry/hasura/elasticsearch/releases/v0.2.0/connector-packaging.json create mode 100644 registry/hasura/elasticsearch/releases/v1.0.0/connector-packaging.json create mode 100644 registry/hasura/elasticsearch/releases/v1.0.1/connector-packaging.json diff --git a/registry/hasura/elasticsearch/README.md b/registry/hasura/elasticsearch/README.md index 52c529ed..1fa8fc77 100644 --- a/registry/hasura/elasticsearch/README.md +++ b/registry/hasura/elasticsearch/README.md @@ -19,18 +19,18 @@ Below, you'll find a matrix of all supported features for the Elasticsearch conn | Feature | Supported | Notes | -| ------------------------------- | --------- | ----- | -| Native Queries + Logical Models | ❌ | | -| Simple Object Query | ✅ | | -| Filter / Search | ✅ | | -| Simple Aggregation | ✅ | | -| Sort | ✅ | | -| Paginate | ✅ | | -| Nested Objects | ✅ | | -| Nested Arrays | ✅ | | -| Nested Filtering | ❌ | | -| Nested Sorting | ❌ | | -| Nested Relationships | ❌ | | +| ------------------------------- | -------- | ----- | +| Native Queries + Logical Models | ✅ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Nested Objects | ✅ | | +| Nested Arrays | ✅ | | +| Nested Filtering | ❌ | | +| Nested Sorting | ❌ | | +| Nested Relationships | ❌ | | ## Before you get Started diff --git a/registry/hasura/elasticsearch/releases/v0.1.0/connector-packaging.json b/registry/hasura/elasticsearch/releases/v0.1.0/connector-packaging.json new file mode 100644 index 00000000..e0a3d864 --- /dev/null +++ b/registry/hasura/elasticsearch/releases/v0.1.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v0.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "a856e10b6b30b516db2bb38af08037ad5db32bfd4ec072270fb8685872e13d5b" + }, + "source": { + "hash": "4c6fabedaf3a28cdd6c55a18a37e1db974a83262" + } +} diff --git a/registry/hasura/elasticsearch/releases/v0.1.1/connector-packaging.json b/registry/hasura/elasticsearch/releases/v0.1.1/connector-packaging.json new file mode 100644 index 00000000..000cd437 --- /dev/null +++ b/registry/hasura/elasticsearch/releases/v0.1.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.1", + "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v0.1.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "60629c9b24467fa4ed58c87732410203eedbdee31cdd18e90c635f10d23a8e23" + }, + "source": { + "hash": "413a2a4ddfd1910757c40c38e9a18148bc3b3bdc" + } +} diff --git a/registry/hasura/elasticsearch/releases/v0.2.0/connector-packaging.json b/registry/hasura/elasticsearch/releases/v0.2.0/connector-packaging.json new file mode 100644 index 00000000..d794b284 --- /dev/null +++ b/registry/hasura/elasticsearch/releases/v0.2.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v0.2.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "7ba4762ae3863a2ea149a5ecf4a93f19a7889f9d36dde27b1cb60b6758ad0e3a" + }, + "source": { + "hash": "f5938f8c76829de7f16cf291c95a06f590b16d9a" + } +} diff --git a/registry/hasura/elasticsearch/releases/v1.0.0/connector-packaging.json b/registry/hasura/elasticsearch/releases/v1.0.0/connector-packaging.json new file mode 100644 index 00000000..adf38221 --- /dev/null +++ b/registry/hasura/elasticsearch/releases/v1.0.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.0", + "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v1.0.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "6ca06b00361a272b0afd7ce5ac314a12460b9c99336e43a4a317de00f00ae6ae" + }, + "source": { + "hash": "9f1f508f551b4a9dec02c49e3312f38c24bb16c4" + } +} diff --git a/registry/hasura/elasticsearch/releases/v1.0.1/connector-packaging.json b/registry/hasura/elasticsearch/releases/v1.0.1/connector-packaging.json new file mode 100644 index 00000000..79c1cbd2 --- /dev/null +++ b/registry/hasura/elasticsearch/releases/v1.0.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.1", + "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v1.0.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "83b0b4f5b1f60a50e303f6354c4d48d397fc7d0a361eb8a14d8fe11b63fe6abd" + }, + "source": { + "hash": "72fad205f57e88781da6acafe1e03a7d220467c7" + } +} From ac312246df69c2ed61ea139e1269b975fb0f8bfa Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Thu, 15 Aug 2024 14:47:52 -0400 Subject: [PATCH 052/135] release v0.2.11 & v1.0.0 (#242) Release clickhouse v0.2.11 Release clickhouse v1.0.0 --- registry/hasura/clickhouse/metadata.json | 34 +++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/registry/hasura/clickhouse/metadata.json b/registry/hasura/clickhouse/metadata.json index 7a20886e..824604b1 100644 --- a/registry/hasura/clickhouse/metadata.json +++ b/registry/hasura/clickhouse/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.2.10" + "latest_version": "v1.0.0" }, "author": { "support_email": "support@hasura.io", @@ -17,6 +17,28 @@ "is_verified": true, "is_hosted_by_hasura": false, "packages": [ + { + "version": "1.0.0", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v1.0.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "e872f3a10ac9a3c6ab81fe958263941b0a998e5bce2d978685a65cfe679e53c6" + }, + "source": { + "hash": "3da872909893964aabaedb4659af129f0ceaa565" + } + }, + { + "version": "0.2.11", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.11/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "97dccf8cfac9865eb6a0e3aee65fcd91a7c14a48e1f65cf985df3734f596e13b" + }, + "source": { + "hash": "7ef634c61649a17deb867e5a36db4220c66f0013" + } + }, { "version": "0.2.10", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.10/connector-definition.tgz", @@ -143,6 +165,16 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-clickhouse/", "version": [ + { + "tag": "v1.0.0", + "hash": "3da872909893964aabaedb4659af129f0ceaa565", + "is_verified": true + }, + { + "tag": "v0.2.11", + "hash": "7ef634c61649a17deb867e5a36db4220c66f0013", + "is_verified": true + }, { "tag": "v0.2.10", "hash": "dbe5b7765b1c9276e5734c8fbc5005e7b71d0500", From 3ac48166983337eef4e5a0e8489a08d5993510d6 Mon Sep 17 00:00:00 2001 From: Gil Mizrahi Date: Fri, 16 Aug 2024 20:00:29 +0300 Subject: [PATCH 053/135] update ndc-postgres to v1.1.0 (#243) https://github.com/hasura/ndc-postgres/releases/tag/v1.1.0 --- registry/hasura/aurora/metadata.json | 7 ++++++- registry/hasura/citus/metadata.json | 7 ++++++- registry/hasura/cockroach/metadata.json | 7 ++++++- registry/hasura/neon/metadata.json | 7 ++++++- registry/hasura/postgres-alloydb/metadata.json | 7 ++++++- registry/hasura/postgres-azure/metadata.json | 7 ++++++- registry/hasura/postgres-cosmos/metadata.json | 7 ++++++- registry/hasura/postgres-gcp/metadata.json | 7 ++++++- registry/hasura/postgres-timescaledb/metadata.json | 7 ++++++- registry/hasura/postgres/metadata.json | 7 ++++++- .../postgres/releases/v1.1.0/connector-packaging.json | 11 +++++++++++ 11 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 registry/hasura/postgres/releases/v1.1.0/connector-packaging.json diff --git a/registry/hasura/aurora/metadata.json b/registry/hasura/aurora/metadata.json index fd1f453b..592d940e 100644 --- a/registry/hasura/aurora/metadata.json +++ b/registry/hasura/aurora/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.2" + "latest_version": "v1.1.0" }, "author": { "support_email": "support@hasura.io", @@ -59,6 +59,11 @@ "tag": "v1.0.2", "hash": "1378805", "is_verified": true + }, + { + "tag": "v1.1.0", + "hash": "a57c0b5", + "is_verified": true } ] } diff --git a/registry/hasura/citus/metadata.json b/registry/hasura/citus/metadata.json index 76480564..ace7f559 100644 --- a/registry/hasura/citus/metadata.json +++ b/registry/hasura/citus/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.2" + "latest_version": "v1.1.0" }, "author": { "support_email": "support@hasura.io", @@ -59,6 +59,11 @@ "tag": "v1.0.2", "hash": "1378805", "is_verified": true + }, + { + "tag": "v1.1.0", + "hash": "a57c0b5", + "is_verified": true } ] } diff --git a/registry/hasura/cockroach/metadata.json b/registry/hasura/cockroach/metadata.json index f4115c5d..e9fbc622 100644 --- a/registry/hasura/cockroach/metadata.json +++ b/registry/hasura/cockroach/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.2" + "latest_version": "v1.1.0" }, "author": { "support_email": "support@hasura.io", @@ -59,6 +59,11 @@ "tag": "v1.0.2", "hash": "1378805", "is_verified": true + }, + { + "tag": "v1.1.0", + "hash": "a57c0b5", + "is_verified": true } ] } diff --git a/registry/hasura/neon/metadata.json b/registry/hasura/neon/metadata.json index ca88bf34..7342a15c 100644 --- a/registry/hasura/neon/metadata.json +++ b/registry/hasura/neon/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.2" + "latest_version": "v1.1.0" }, "author": { "support_email": "support@hasura.io", @@ -59,6 +59,11 @@ "tag": "v1.0.2", "hash": "1378805", "is_verified": true + }, + { + "tag": "v1.1.0", + "hash": "a57c0b5", + "is_verified": true } ] } diff --git a/registry/hasura/postgres-alloydb/metadata.json b/registry/hasura/postgres-alloydb/metadata.json index 7c9faa60..0faa527f 100644 --- a/registry/hasura/postgres-alloydb/metadata.json +++ b/registry/hasura/postgres-alloydb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.2" + "latest_version": "v1.1.0" }, "author": { "support_email": "support@hasura.io", @@ -59,6 +59,11 @@ "tag": "v1.0.2", "hash": "1378805", "is_verified": true + }, + { + "tag": "v1.1.0", + "hash": "a57c0b5", + "is_verified": true } ] } diff --git a/registry/hasura/postgres-azure/metadata.json b/registry/hasura/postgres-azure/metadata.json index 4abff6a4..53e4d6b7 100644 --- a/registry/hasura/postgres-azure/metadata.json +++ b/registry/hasura/postgres-azure/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.2" + "latest_version": "v1.1.0" }, "author": { "support_email": "support@hasura.io", @@ -59,6 +59,11 @@ "tag": "v1.0.2", "hash": "1378805", "is_verified": true + }, + { + "tag": "v1.1.0", + "hash": "a57c0b5", + "is_verified": true } ] } diff --git a/registry/hasura/postgres-cosmos/metadata.json b/registry/hasura/postgres-cosmos/metadata.json index 8c2bb20e..11d1bbea 100644 --- a/registry/hasura/postgres-cosmos/metadata.json +++ b/registry/hasura/postgres-cosmos/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.2" + "latest_version": "v1.1.0" }, "author": { "support_email": "support@hasura.io", @@ -59,6 +59,11 @@ "tag": "v1.0.2", "hash": "1378805", "is_verified": true + }, + { + "tag": "v1.1.0", + "hash": "a57c0b5", + "is_verified": true } ] } diff --git a/registry/hasura/postgres-gcp/metadata.json b/registry/hasura/postgres-gcp/metadata.json index 33c4a3db..83db222b 100644 --- a/registry/hasura/postgres-gcp/metadata.json +++ b/registry/hasura/postgres-gcp/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.2" + "latest_version": "v1.1.0" }, "author": { "support_email": "support@hasura.io", @@ -59,6 +59,11 @@ "tag": "v1.0.2", "hash": "1378805", "is_verified": true + }, + { + "tag": "v1.1.0", + "hash": "a57c0b5", + "is_verified": true } ] } diff --git a/registry/hasura/postgres-timescaledb/metadata.json b/registry/hasura/postgres-timescaledb/metadata.json index 201e71b3..8eaf5ebe 100644 --- a/registry/hasura/postgres-timescaledb/metadata.json +++ b/registry/hasura/postgres-timescaledb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.2" + "latest_version": "v1.1.0" }, "author": { "support_email": "support@hasura.io", @@ -59,6 +59,11 @@ "tag": "v1.0.2", "hash": "1378805", "is_verified": true + }, + { + "tag": "v1.1.0", + "hash": "a57c0b5", + "is_verified": true } ] } diff --git a/registry/hasura/postgres/metadata.json b/registry/hasura/postgres/metadata.json index 501c2b73..d89a9b8e 100644 --- a/registry/hasura/postgres/metadata.json +++ b/registry/hasura/postgres/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.2" + "latest_version": "v1.1.0" }, "author": { "support_email": "support@hasura.io", @@ -59,6 +59,11 @@ "tag": "v1.0.2", "hash": "1378805", "is_verified": true + }, + { + "tag": "v1.1.0", + "hash": "a57c0b5", + "is_verified": true } ] } diff --git a/registry/hasura/postgres/releases/v1.1.0/connector-packaging.json b/registry/hasura/postgres/releases/v1.1.0/connector-packaging.json new file mode 100644 index 00000000..8bce4e87 --- /dev/null +++ b/registry/hasura/postgres/releases/v1.1.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.1.0", + "uri": "https://github.com/hasura/ndc-postgres/releases/download/v1.1.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "a5f358cea0bade28b00fa868e055a29bab158173ec8a65ec2a2d4cc9ff060d3d" + }, + "source": { + "hash": "a57c0b5c76f98ea1da33d5aa649b6e8d071c3d4a" + } +} From 7185028d83b2b992ff7e55a8899d79c4399ab4a4 Mon Sep 17 00:00:00 2001 From: Brandon Martin Date: Fri, 16 Aug 2024 13:13:28 -0600 Subject: [PATCH 054/135] MongoDB v1.1.0 (#244) --- registry/hasura/mongodb/metadata.json | 18 +++++++++++++++++- .../releases/0.0.1/connector-packaging.json | 11 +++++++++++ .../releases/0.0.2/connector-packaging.json | 11 +++++++++++ .../releases/0.0.3/connector-packaging.json | 11 +++++++++++ .../releases/0.0.4/connector-packaging.json | 11 +++++++++++ .../releases/0.0.5/connector-packaging.json | 11 +++++++++++ .../releases/0.0.6/connector-packaging.json | 11 +++++++++++ .../releases/0.1.0/connector-packaging.json | 11 +++++++++++ .../releases/1.0.0/connector-packaging.json | 11 +++++++++++ .../releases/1.1.0/connector-packaging.json | 11 +++++++++++ 10 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 registry/hasura/mongodb/releases/0.0.1/connector-packaging.json create mode 100644 registry/hasura/mongodb/releases/0.0.2/connector-packaging.json create mode 100644 registry/hasura/mongodb/releases/0.0.3/connector-packaging.json create mode 100644 registry/hasura/mongodb/releases/0.0.4/connector-packaging.json create mode 100644 registry/hasura/mongodb/releases/0.0.5/connector-packaging.json create mode 100644 registry/hasura/mongodb/releases/0.0.6/connector-packaging.json create mode 100644 registry/hasura/mongodb/releases/0.1.0/connector-packaging.json create mode 100644 registry/hasura/mongodb/releases/1.0.0/connector-packaging.json create mode 100644 registry/hasura/mongodb/releases/1.1.0/connector-packaging.json diff --git a/registry/hasura/mongodb/metadata.json b/registry/hasura/mongodb/metadata.json index 53e9e124..43923c03 100644 --- a/registry/hasura/mongodb/metadata.json +++ b/registry/hasura/mongodb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.0" + "latest_version": "v1.1.0" }, "author": { "support_email": "support@hasura.io", @@ -17,6 +17,17 @@ "is_verified": true, "is_hosted_by_hasura": false, "packages": [ + { + "version": "1.1.0", + "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v1.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "e0b616454261c1d07b058578f26ba928c832b11805ade1474e274c945e12e088" + }, + "source": { + "hash": "eab726516ecfcee76abeab1b92f3b5d6cba10976" + } + }, { "version": "1.0.0", "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v1.0.0/connector-definition.tgz", @@ -110,6 +121,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-mongodb/", "version": [ + { + "tag": "v1.1.0", + "hash": "eab726516ecfcee76abeab1b92f3b5d6cba10976", + "is_verified": true + }, { "tag": "v1.0.0", "hash": "4beb7ddabddc3035ca5cc7bd85493a71a2e34147", diff --git a/registry/hasura/mongodb/releases/0.0.1/connector-packaging.json b/registry/hasura/mongodb/releases/0.0.1/connector-packaging.json new file mode 100644 index 00000000..68e8ce45 --- /dev/null +++ b/registry/hasura/mongodb/releases/0.0.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.1", + "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "2cd3584557be7e2870f3488a30cac6219924b3f7accd9f5f473285323843a0f4" + }, + "source": { + "hash": "c32adbde478147518f65ff465c40a0703239288a" + } +} \ No newline at end of file diff --git a/registry/hasura/mongodb/releases/0.0.2/connector-packaging.json b/registry/hasura/mongodb/releases/0.0.2/connector-packaging.json new file mode 100644 index 00000000..9b5acaed --- /dev/null +++ b/registry/hasura/mongodb/releases/0.0.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.2", + "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.2/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "f014459e9dbcce8bafe1c33c74b1fa1720d544bc283cc819c81d719028219846" + }, + "source": { + "hash": "90c336c4d1d949d62dd25b04742e650fb6d458e0" + } +} \ No newline at end of file diff --git a/registry/hasura/mongodb/releases/0.0.3/connector-packaging.json b/registry/hasura/mongodb/releases/0.0.3/connector-packaging.json new file mode 100644 index 00000000..69037da8 --- /dev/null +++ b/registry/hasura/mongodb/releases/0.0.3/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.3", + "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "0019dfc4b32d63c1392aa264aed2253c1e0c2fb09216f8e2cc269bbfb8bb49b5" + }, + "source": { + "hash": "b50094a368f8fbab7c37e4b83ef5dc1249a4a5d5" + } +} \ No newline at end of file diff --git a/registry/hasura/mongodb/releases/0.0.4/connector-packaging.json b/registry/hasura/mongodb/releases/0.0.4/connector-packaging.json new file mode 100644 index 00000000..32d838ee --- /dev/null +++ b/registry/hasura/mongodb/releases/0.0.4/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.4", + "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.4/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "7b826a79686b48e58819751091fac62071df75ca9fd617b80709fe098a054f26" + }, + "source": { + "hash": "38a4a56134a909001b645c659062ae393c2cebe0" + } +} \ No newline at end of file diff --git a/registry/hasura/mongodb/releases/0.0.5/connector-packaging.json b/registry/hasura/mongodb/releases/0.0.5/connector-packaging.json new file mode 100644 index 00000000..c5804ba4 --- /dev/null +++ b/registry/hasura/mongodb/releases/0.0.5/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.5", + "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.5/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "2064a98d223240b912720f0528c6b9a7107a42e4452407c2b75e77dcfdbd4227" + }, + "source": { + "hash": "055154b5d84f05ff0049aa75a29b85caf89822f6" + } +} \ No newline at end of file diff --git a/registry/hasura/mongodb/releases/0.0.6/connector-packaging.json b/registry/hasura/mongodb/releases/0.0.6/connector-packaging.json new file mode 100644 index 00000000..f7915551 --- /dev/null +++ b/registry/hasura/mongodb/releases/0.0.6/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.6", + "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.6/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "24370c44a8ff92dce488569717956069f2a50de7a8f54547b140d85a17b52875" + }, + "source": { + "hash": "6e842c308eeee38d3bc393e6b99157961ca3ed03" + } +} \ No newline at end of file diff --git a/registry/hasura/mongodb/releases/0.1.0/connector-packaging.json b/registry/hasura/mongodb/releases/0.1.0/connector-packaging.json new file mode 100644 index 00000000..899794ce --- /dev/null +++ b/registry/hasura/mongodb/releases/0.1.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "adb5ce24e053117ba33c16ecf54bdc5a678790f3b31801645911fdf7091a58e0" + }, + "source": { + "hash": "175272912b86a11359a9b6b7fd72c7a6e2326bf1" + } +} \ No newline at end of file diff --git a/registry/hasura/mongodb/releases/1.0.0/connector-packaging.json b/registry/hasura/mongodb/releases/1.0.0/connector-packaging.json new file mode 100644 index 00000000..4e4ab11c --- /dev/null +++ b/registry/hasura/mongodb/releases/1.0.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.0", + "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v1.0.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "0dc038620f40911a2c5662b61d8e2ac9605876c80b3eb3cbae5cc1ebcd5b611f" + }, + "source": { + "hash": "4beb7ddabddc3035ca5cc7bd85493a71a2e34147" + } +} \ No newline at end of file diff --git a/registry/hasura/mongodb/releases/1.1.0/connector-packaging.json b/registry/hasura/mongodb/releases/1.1.0/connector-packaging.json new file mode 100644 index 00000000..047f7ec3 --- /dev/null +++ b/registry/hasura/mongodb/releases/1.1.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.1.0", + "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v1.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "e0b616454261c1d07b058578f26ba928c832b11805ade1474e274c945e12e088" + }, + "source": { + "hash": "eab726516ecfcee76abeab1b92f3b5d6cba10976" + } +} \ No newline at end of file From c3adab7d962d1ef0cb63760f6d82ef396a7651f5 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Sat, 17 Aug 2024 10:02:33 -0400 Subject: [PATCH 055/135] Release clickhouse v1.0.1 (#246) --- registry/hasura/clickhouse/metadata.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/registry/hasura/clickhouse/metadata.json b/registry/hasura/clickhouse/metadata.json index 824604b1..c3ed1dd5 100644 --- a/registry/hasura/clickhouse/metadata.json +++ b/registry/hasura/clickhouse/metadata.json @@ -17,6 +17,17 @@ "is_verified": true, "is_hosted_by_hasura": false, "packages": [ + { + "version": "1.0.1", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v1.0.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "0069c1d611e0edaafc88de0ee3d22f5f6ed813757d077885c0c3caa1d8ef7d14" + }, + "source": { + "hash": "a5df7ec5d5a7ca65dcf6a16460dacbd0b81e39f2" + } + }, { "version": "1.0.0", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v1.0.0/connector-definition.tgz", @@ -165,6 +176,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-clickhouse/", "version": [ + { + "tag": "v1.0.1", + "hash": "a5df7ec5d5a7ca65dcf6a16460dacbd0b81e39f2", + "is_verified": true + }, { "tag": "v1.0.0", "hash": "3da872909893964aabaedb4659af129f0ceaa565", From cdd4a2d3e0cd2623bfea0f195ce11d61496b2495 Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Tue, 20 Aug 2024 15:38:52 +0530 Subject: [PATCH 056/135] add azure-cosmos v0.1.6 (#249) --- .../releases/v0.1.6/connector-packaging.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 registry/hasura/azure-cosmos/releases/v0.1.6/connector-packaging.json diff --git a/registry/hasura/azure-cosmos/releases/v0.1.6/connector-packaging.json b/registry/hasura/azure-cosmos/releases/v0.1.6/connector-packaging.json new file mode 100644 index 00000000..3b23bbb9 --- /dev/null +++ b/registry/hasura/azure-cosmos/releases/v0.1.6/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.6", + "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.1.6/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "c95285f38d38b213c1163ce60be87d868645d065c36ed4bac6b99ed89f5e5184" + }, + "source": { + "hash": "eb6beadf7d6102c647820a8ebb957b6f99b68f59" + } +} From 62c0b2363b8fb24906370ede5a676b7692e0aabd Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Tue, 20 Aug 2024 16:31:12 +0530 Subject: [PATCH 057/135] update `metadata.json` of the azure-cosmos connector (#250) Same as title --- registry/hasura/azure-cosmos/metadata.json | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/registry/hasura/azure-cosmos/metadata.json b/registry/hasura/azure-cosmos/metadata.json index 74caad96..209dc85b 100644 --- a/registry/hasura/azure-cosmos/metadata.json +++ b/registry/hasura/azure-cosmos/metadata.json @@ -5,7 +5,7 @@ "title": "Azure Cosmos DB for NoSQL Connector", "logo": "logo.png", "tags": [], - "latest_version": "v0.1.3" + "latest_version": "v0.1.6" }, "author": { "support_email": "support@hasura.io", @@ -14,9 +14,7 @@ }, "is_verified": true, "is_hosted_by_hasura": true, - "packages": [ - - ], + "packages": [], "source_code": { "is_open_source": true, "repository": "https://github.com/hasura/ndc-azure-cosmos-connector/", @@ -30,6 +28,11 @@ "tag": "v0.1.2", "hash": "f67b2f80d64175a055a9489d4e59f30d5d3870a0", "is_verified": true + }, + { + "tag": "v0.1.6", + "hash": "eb6beadf7d6102c647820a8ebb957b6f99b68f59", + "is_verified": true } ] } From 5f4d928965634546418b6ed264807b7bdf025367 Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Wed, 21 Aug 2024 12:04:46 +0530 Subject: [PATCH 058/135] Add automation for `README.md` and `logo.png` (#215) This is the second PR towards the automation of publishing a connector version. This PR handles updates in the `README.md` and the `logo.png/logo.svg` and will update the registry DB accordingly. We need to also merge this [PR](https://github.com/hasura/v3-connector-platform/pull/224) which adds the relevant permissions to the `connector_overview` table. --------- Co-authored-by: Lyndon Maydwell --- .github/workflows/registry-updates.yaml | 1 + registry-automation/cmd/ci.go | 280 +++++++++++++++++-- registry-automation/cmd/ci_test.go | 100 +++++++ registry-automation/cmd/utils.go | 18 +- registry-automation/go.mod | 23 +- registry-automation/go.sum | 53 ++-- rfcs/0006-connector-publishing-automation.md | 1 + 7 files changed, 405 insertions(+), 71 deletions(-) create mode 100644 registry-automation/cmd/ci_test.go diff --git a/.github/workflows/registry-updates.yaml b/.github/workflows/registry-updates.yaml index 6c95b010..2147750f 100644 --- a/.github/workflows/registry-updates.yaml +++ b/.github/workflows/registry-updates.yaml @@ -54,6 +54,7 @@ jobs: GCP_BUCKET_NAME: ${{ secrets.GCP_BUCKET_NAME }} GCP_SERVICE_ACCOUNT_DETAILS: ${{ secrets.GCP_SERVICE_ACCOUNT_DETAILS }} CONNECTOR_PUBLICATION_KEY: ${{ secrets.CONNECTOR_PUBLICATION_KEY }} + CLOUDINARY_URL: ${{ secrets.CLOUDINARY_URL }} run: | mv changed_files.json registry-automation/changed_files.json cd registry-automation diff --git a/registry-automation/cmd/ci.go b/registry-automation/cmd/ci.go index 9bfdbf9c..cd9c31f9 100644 --- a/registry-automation/cmd/ci.go +++ b/registry-automation/cmd/ci.go @@ -1,6 +1,7 @@ package cmd import ( + "bytes" "context" "encoding/json" "fmt" @@ -10,6 +11,8 @@ import ( "regexp" "cloud.google.com/go/storage" + "github.com/cloudinary/cloudinary-go/v2" + "github.com/cloudinary/cloudinary-go/v2/api/uploader" "github.com/machinebox/graphql" "github.com/spf13/cobra" "google.golang.org/api/option" @@ -57,6 +60,33 @@ type ConnectionVersionMetadata struct { Image *string `yaml:"image,omitempty"` } +type WhereClause struct { + ConnectorName string + ConnectorNamespace string +} + +func (wc WhereClause) MarshalJSON() ([]byte, error) { + where := map[string]interface{}{ + "_and": []map[string]interface{}{ + {"name": map[string]string{"_eq": wc.ConnectorName}}, + {"namespace": map[string]string{"_eq": wc.ConnectorNamespace}}, + }, + } + return json.Marshal(where) +} + +type ConnectorOverviewUpdate struct { + Set struct { + Docs *string `json:"docs,omitempty"` + Logo *string `json:"logo,omitempty"` + } `json:"_set"` + Where WhereClause `json:"where"` +} + +type ConnectorOverviewUpdates struct { + Updates []ConnectorOverviewUpdate `json:"updates"` +} + const ( ManagedDockerBuild = "ManagedDockerBuild" PrebuiltDockerImage = "PrebuiltDockerImage" @@ -70,6 +100,7 @@ type ConnectorRegistryArgs struct { ConnectorPublicationKey string GCPServiceAccountDetails string GCPBucketName string + CloudinaryUrl string } var ciCmdArgs ConnectorRegistryArgs @@ -126,6 +157,15 @@ func buildContext() { } else { ciCmdArgs.GCPBucketName = gcpBucketName } + + cloudinaryUrl := os.Getenv("CLOUDINARY_URL") + + if cloudinaryUrl == "" { + log.Fatalf("CLOUDINARY_URL is not set") + } else { + ciCmdArgs.CloudinaryUrl = cloudinaryUrl + } + } // processChangedFiles processes the files in the PR and extracts the connector name and version @@ -133,16 +173,19 @@ func buildContext() { // 1. If a new connector version is added, it adds the connector version to the `newlyAddedConnectorVersions` map. // 2. If the logo file is modified, it adds the connector name and the path to the modified logo to the `modifiedLogos` map. // 3. If the README file is modified, it adds the connector name and the path to the modified README to the `modifiedReadmes` map. -func processChangedFiles(changedFiles ChangedFiles) NewConnectorVersions { +func processChangedFiles(changedFiles ChangedFiles) (NewConnectorVersions, ModifiedLogos, ModifiedReadmes) { newlyAddedConnectorVersions := make(map[Connector]map[string]string) + modifiedLogos := make(map[Connector]string) + modifiedReadmes := make(map[Connector]string) var connectorVersionPackageRegex = regexp.MustCompile(`^registry/([^/]+)/([^/]+)/releases/([^/]+)/connector-packaging\.json$`) + var logoPngRegex = regexp.MustCompile(`^registry/([^/]+)/([^/]+)/logo\.(png|svg)$`) + var readmeMdRegex = regexp.MustCompile(`^registry/([^/]+)/([^/]+)/README\.md$`) - files := append(changedFiles.Added, changedFiles.Modified...) + for _, file := range changedFiles.Added { - for _, file := range files { - // Extract the connector name and version from the file path + // Check if the file is a connector version package if connectorVersionPackageRegex.MatchString(file) { matches := connectorVersionPackageRegex.FindStringSubmatch(file) @@ -164,11 +207,54 @@ func processChangedFiles(changedFiles ChangedFiles) NewConnectorVersions { } } else { - fmt.Println("Skipping file: ", file) + fmt.Println("Skipping newly added file: ", file) + } + + } + + for _, file := range changedFiles.Modified { + if logoPngRegex.MatchString(file) { + // Process the logo file + // print the name of the connector and the version + matches := logoPngRegex.FindStringSubmatch(file) + if len(matches) == 4 { + + connectorNamespace := matches[1] + connectorName := matches[2] + connector := Connector{ + Name: connectorName, + Namespace: connectorNamespace, + } + modifiedLogos[connector] = file + fmt.Printf("Processing logo file for connector: %s\n", connectorName) + } + + } else if readmeMdRegex.MatchString(file) { + // Process the README file + // print the name of the connector and the version + matches := readmeMdRegex.FindStringSubmatch(file) + + if len(matches) == 3 { + + connectorNamespace := matches[1] + connectorName := matches[2] + connector := Connector{ + Name: connectorName, + Namespace: connectorNamespace, + } + + modifiedReadmes[connector] = file + + fmt.Printf("Processing README file for connector: %s\n", connectorName) + } + } else { + fmt.Println("Skipping modified file: ", file) } + } - return newlyAddedConnectorVersions + return newlyAddedConnectorVersions, modifiedLogos, modifiedReadmes + } // runCI is the main function that runs the CI workflow @@ -199,15 +285,117 @@ func runCI(cmd *cobra.Command, args []string) { } + // Separate the modified files according to the type of file + // Collect the added or modified connectors - addedOrModifiedConnectorVersions := processChangedFiles(changedFiles) + newlyAddedConnectorVersions, modifiedLogos, modifiedReadmes := processChangedFiles(changedFiles) + // check if the map is empty - if len(addedOrModifiedConnectorVersions) == 0 { - fmt.Println("No connector versions found in the changed files.") + if len(newlyAddedConnectorVersions) == 0 && len(modifiedLogos) == 0 && len(modifiedReadmes) == 0 { + fmt.Println("No connectors to be added or modified in the registry") return } else { - processNewlyAddedConnectorVersions(client, addedOrModifiedConnectorVersions) + if len(newlyAddedConnectorVersions) > 0 { + processNewlyAddedConnectorVersions(client, newlyAddedConnectorVersions) + } + + if len(modifiedReadmes) > 0 { + err := processModifiedReadmes(modifiedReadmes) + if err != nil { + log.Fatalf("Failed to process the modified READMEs: %v", err) + } + fmt.Println("Successfully updated the READMEs in the registry.") + } + + if len(modifiedLogos) > 0 { + err := processModifiedLogos(modifiedLogos) + if err != nil { + log.Fatalf("Failed to process the modified logos: %v", err) + } + fmt.Println("Successfully updated the logos in the registry.") + } + } + + fmt.Println("Successfully processed the changed files in the PR") +} + +func processModifiedLogos(modifiedLogos ModifiedLogos) error { + // Iterate over the modified logos and update the logos in the registry + var connectorOverviewUpdates []ConnectorOverviewUpdate + // upload the logo to cloudinary + cloudinary, err := cloudinary.NewFromURL(ciCmdArgs.CloudinaryUrl) + if err != nil { + return err + } + + for connector, logoPath := range modifiedLogos { + // open the logo file + logoContent, err := readFile(logoPath) + if err != nil { + fmt.Printf("Failed to read the logo file: %v", err) + return err + } + + imageReader := bytes.NewReader(logoContent) + + uploadResult, err := cloudinary.Upload.Upload(context.Background(), imageReader, uploader.UploadParams{ + PublicID: fmt.Sprintf("%s-%s", connector.Namespace, connector.Name), + Format: "png", + }) + if err != nil { + fmt.Printf("Failed to upload the logo to cloudinary for the connector: %s, Error: %v\n", connector.Name, err) + return err + } else { + fmt.Printf("Successfully uploaded the logo to cloudinary for the connector: %s\n", connector.Name) + } + + var connectorOverviewUpdate ConnectorOverviewUpdate + + if connectorOverviewUpdate.Set.Logo == nil { + connectorOverviewUpdate.Set.Logo = new(string) + } else { + *connectorOverviewUpdate.Set.Logo = "" + } + + *connectorOverviewUpdate.Set.Logo = string(uploadResult.SecureURL) + + connectorOverviewUpdate.Where.ConnectorName = connector.Name + connectorOverviewUpdate.Where.ConnectorNamespace = connector.Namespace + + connectorOverviewUpdates = append(connectorOverviewUpdates, connectorOverviewUpdate) + + } + + return updateConnectorOverview(ConnectorOverviewUpdates{Updates: connectorOverviewUpdates}) + +} + +func processModifiedReadmes(modifiedReadmes ModifiedReadmes) error { + // Iterate over the modified READMEs and update the READMEs in the registry + var connectorOverviewUpdates []ConnectorOverviewUpdate + + for connector, readmePath := range modifiedReadmes { + // open the README file + readmeContent, err := readFile(readmePath) + if err != nil { + return err + + } + + readMeContentString := string(readmeContent) + + var connectorOverviewUpdate ConnectorOverviewUpdate + connectorOverviewUpdate.Set.Docs = &readMeContentString + + connectorOverviewUpdate.Where.ConnectorName = connector.Name + connectorOverviewUpdate.Where.ConnectorNamespace = connector.Namespace + + connectorOverviewUpdates = append(connectorOverviewUpdates, connectorOverviewUpdate) + } + + return updateConnectorOverview(ConnectorOverviewUpdates{Updates: connectorOverviewUpdates}) + } func processNewlyAddedConnectorVersions(client *storage.Client, newlyAddedConnectorVersions NewConnectorVersions) { @@ -222,33 +410,34 @@ func processNewlyAddedConnectorVersions(client *storage.Client, newlyAddedConnec connectorVersion, uploadConnectorVersionErr = uploadConnectorVersionPackage(client, connectorName, version, connectorVersionPath) if uploadConnectorVersionErr != nil { + fmt.Printf("Error while processing version and connector: %s - %s, Error: %v", version, connectorName, uploadConnectorVersionErr) encounteredError = true break - - } else { - connectorVersions = append(connectorVersions, connectorVersion) } - + connectorVersions = append(connectorVersions, connectorVersion) } - if encounteredError { + break + } + } + + if encounteredError { + // attempt to cleanup the uploaded connector versions + _ = cleanupUploadedConnectorVersions(client, connectorVersions) // ignore errors while cleaning up + // delete the uploaded connector versions from the registry + log.Fatalf("Failed to upload the connector version: %v", uploadConnectorVersionErr) + + } else { + fmt.Printf("Connector versions to be added to the registry: %+v\n", connectorVersions) + err := updateRegistryGQL(connectorVersions) + if err != nil { // attempt to cleanup the uploaded connector versions _ = cleanupUploadedConnectorVersions(client, connectorVersions) // ignore errors while cleaning up - // delete the uploaded connector versions from the registry - log.Fatalf("Failed to upload the connector version: %v", uploadConnectorVersionErr) - - } else { - fmt.Printf("Connector versions to be added to the registry: %+v\n", connectorVersions) - err := updateRegistryGQL(connectorVersions) - if err != nil { - // attempt to cleanup the uploaded connector versions - _ = cleanupUploadedConnectorVersions(client, connectorVersions) // ignore errors while cleaning up - log.Fatalf("Failed to update the registry: %v", err) - } + log.Fatalf("Failed to update the registry: %v", err) } - - fmt.Println("Successfully added connector versions to the registry.") } + fmt.Println("Successfully added connector versions to the registry.") + } func cleanupUploadedConnectorVersions(client *storage.Client, connectorVersions []ConnectorVersion) error { @@ -274,6 +463,12 @@ type Connector struct { type NewConnectorVersions map[Connector]map[string]string +// ModifiedLogos represents the modified logos in the PR, the key is the connector name and the value is the path to the modified logo +type ModifiedLogos map[Connector]string + +// ModifiedReadmes represents the modified READMEs in the PR, the key is the connector name and the value is the path to the modified README +type ModifiedReadmes map[Connector]string + // uploadConnectorVersionPackage uploads the connector version package to the registry func uploadConnectorVersionPackage(client *storage.Client, connector Connector, version string, changedConnectorVersionPath string) (ConnectorVersion, error) { @@ -329,6 +524,7 @@ func getConnectorVersionMetadata(tgzUrl string, connector Connector, connectorVe return connectorVersionMetadata, "", fmt.Errorf("failed to get the temp file path: %v", err) } err = downloadFile(tgzUrl, tgzPath, map[string]string{}) + if err != nil { return connectorVersionMetadata, "", fmt.Errorf("failed to download the connector version metadata file from the URL: %v - err: %v", tgzUrl, err) } @@ -531,3 +727,31 @@ mutation InsertConnectorVersion($connectorVersion: [hub_registry_connector_versi return nil } + +func updateConnectorOverview(updates ConnectorOverviewUpdates) error { + var respData map[string]interface{} + client := graphql.NewClient(ciCmdArgs.ConnectorRegistryGQLUrl) + ctx := context.Background() + + req := graphql.NewRequest(` +mutation UpdateConnector ($updates: [connector_overview_updates!]!) { + update_connector_overview_many(updates: $updates) { + affected_rows + } +}`) + + // add the payload to the request + req.Var("updates", updates.Updates) + + req.Header.Set("x-hasura-role", "connector_publishing_automation") + req.Header.Set("x-connector-publication-key", ciCmdArgs.ConnectorPublicationKey) + + // Execute the GraphQL query and check the response. + if err := client.Run(ctx, req, &respData); err != nil { + return err + } else { + fmt.Printf("Successfully updated the connector overview: %+v\n", respData) + } + + return nil +} diff --git a/registry-automation/cmd/ci_test.go b/registry-automation/cmd/ci_test.go new file mode 100644 index 00000000..e68cabaf --- /dev/null +++ b/registry-automation/cmd/ci_test.go @@ -0,0 +1,100 @@ +package cmd + +import ( + "testing" +) + +func TestProcessAddedOrModifiedConnectorVersions(t *testing.T) { + // Define test cases + testCases := []struct { + name string + files []string + expectedAddedOrModifiedConnectors map[string]map[string]string + }{ + { + name: "Test case 1", + files: []string{ + "registry/hasura/releases/v1.0.0/connector-packaging.json", + "registry/hasura/releases/v2.0.0/connector-packaging.json", + "registry/other/releases/v1.0.0/connector-packaging.json", + }, + expectedAddedOrModifiedConnectors: map[string]map[string]string{ + "hasura": { + "v1.0.0": "registry/hasura/releases/v1.0.0/connector-packaging.json", + "v2.0.0": "registry/hasura/releases/v2.0.0/connector-packaging.json", + }, + "other": { + "v1.0.0": "registry/other/releases/v1.0.0/connector-packaging.json", + }, + }, + }, + { + name: "Test case 2", + files: []string{ + "registry/hasura/releases/v1.0.0/connector-packaging.json", + "registry/hasura/releases/v1.0.0/other-file.json", + }, + expectedAddedOrModifiedConnectors: map[string]map[string]string{ + "hasura": { + "v1.0.0": "registry/hasura/releases/v1.0.0/connector-packaging.json", + }, + }, + }, + { + name: "Test case 3", + files: []string{ + "registry/hasura/releases/v1.0.0/other-file.json", + "registry/other/releases/v1.0.0/connector-packaging.json", + }, + expectedAddedOrModifiedConnectors: map[string]map[string]string{ + "other": { + "v1.0.0": "registry/other/releases/v1.0.0/connector-packaging.json", + }, + }, + }, + } + + // Run the test cases + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Initialize the map to store the added or modified connectors + addedOrModifiedConnectorVersions := make(map[string]map[string]string) + + var changedFiles ChangedFiles + + changedFiles.Added = tc.files + + // Call the function under test + processChangedFiles(changedFiles) + + // Compare the actual result with the expected result + if len(addedOrModifiedConnectorVersions) != len(tc.expectedAddedOrModifiedConnectors) { + t.Errorf("Unexpected number of connectors. Expected: %d, Got: %d", len(tc.expectedAddedOrModifiedConnectors), len(addedOrModifiedConnectorVersions)) + } + + for connectorName, versions := range addedOrModifiedConnectorVersions { + expectedVersions, ok := tc.expectedAddedOrModifiedConnectors[connectorName] + if !ok { + t.Errorf("Unexpected connector name: %s", connectorName) + continue + } + + if len(versions) != len(expectedVersions) { + t.Errorf("Unexpected number of versions for connector %s. Expected: %d, Got: %d", connectorName, len(expectedVersions), len(versions)) + } + + for version, connectorVersionPath := range versions { + expectedPath, ok := expectedVersions[version] + if !ok { + t.Errorf("Unexpected version for connector %s: %s", connectorName, version) + continue + } + + if connectorVersionPath != expectedPath { + t.Errorf("Unexpected connector version path for connector %s, version %s. Expected: %s, Got: %s", connectorName, version, expectedPath, connectorVersionPath) + } + } + } + }) + } +} diff --git a/registry-automation/cmd/utils.go b/registry-automation/cmd/utils.go index 15357b07..45af32a3 100644 --- a/registry-automation/cmd/utils.go +++ b/registry-automation/cmd/utils.go @@ -56,9 +56,9 @@ func downloadFile(sourceURL, destination string, headers map[string]string) erro func readJSONFile[T any](location string) (T, error) { // Read the file var result T - fileBytes, err := os.ReadFile("../" + location) + fileBytes, err := readFile(location) if err != nil { - return result, fmt.Errorf("error reading file at location: %s %v", location, err) + return result, err } if err := json.Unmarshal(fileBytes, &result); err != nil { @@ -68,8 +68,21 @@ func readJSONFile[T any](location string) (T, error) { return result, nil } +// Note: The location is relative to the root of the repository +func readFile(location string) ([]byte, error) { + // Read the file + + fileBytes, err := os.ReadFile("../" + location) + if err != nil { + return fileBytes, fmt.Errorf("error reading file at location: %s %v", location, err) + } + + return fileBytes, nil +} + // getTempFilePath generates a random file name in the specified directory. func getTempFilePath(directory string) (string, error) { + // Ensure the directory exists err := os.MkdirAll(directory, os.ModePerm) if err != nil { @@ -77,6 +90,7 @@ func getTempFilePath(directory string) (string, error) { } // Generate a random file name + tempFile, err := os.CreateTemp(directory, "connector-*.tar.gz") if err != nil { return "", fmt.Errorf("error creating temp file: %v", err) diff --git a/registry-automation/go.mod b/registry-automation/go.mod index 59b7ef16..e2eca410 100644 --- a/registry-automation/go.mod +++ b/registry-automation/go.mod @@ -2,7 +2,16 @@ module github.com/hasura/ndc-hub/registry-automation go 1.21.4 -require github.com/spf13/cobra v1.8.0 +require ( + github.com/cloudinary/cloudinary-go/v2 v2.8.0 + github.com/spf13/cobra v1.8.0 +) + +require ( + github.com/creasty/defaults v1.7.0 // indirect + github.com/gorilla/schema v1.4.1 // indirect + github.com/matryer/is v1.4.1 // indirect +) require ( cloud.google.com/go v0.115.0 // indirect @@ -10,26 +19,20 @@ require ( cloud.google.com/go/auth/oauth2adapt v0.2.3 // indirect cloud.google.com/go/compute/metadata v0.5.0 // indirect cloud.google.com/go/iam v1.1.11 // indirect - cloud.google.com/go/storage v1.43.0 // indirect - github.com/andybalholm/brotli v1.0.1 // indirect + cloud.google.com/go/storage v1.43.0 github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/golang/snappy v0.0.4 // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.5 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/klauspost/pgzip v1.2.5 // indirect - github.com/machinebox/graphql v0.2.2 // indirect - github.com/nwaples/rardecode v1.1.0 // indirect + github.com/machinebox/graphql v0.2.2 github.com/pkg/errors v0.9.1 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/ulikunitz/xz v0.5.9 // indirect - github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect @@ -43,7 +46,7 @@ require ( golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect - google.golang.org/api v0.188.0 // indirect + google.golang.org/api v0.188.0 google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect diff --git a/registry-automation/go.sum b/registry-automation/go.sum index 5d0aac40..c06e0b27 100644 --- a/registry-automation/go.sum +++ b/registry-automation/go.sum @@ -9,20 +9,22 @@ cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJ cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw= cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ= +cloud.google.com/go/longrunning v0.5.9 h1:haH9pAuXdPAMqHvzX0zlWQigXT7B0+CL4/2nXXdBo5k= +cloud.google.com/go/longrunning v0.5.9/go.mod h1:HD+0l9/OOW0za6UWdKJtXoFAX/BGg/3Wj8p10NeWF7c= cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= -github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudinary/cloudinary-go/v2 v2.8.0 h1:6o2mL5Obm92Q0TuX6yXfdpXSImbsYVYlOPOnpwjfobo= +github.com/cloudinary/cloudinary-go/v2 v2.8.0/go.mod h1:ireC4gqVetsjVhYlwjUJwKTbZuWjEIynbR9zQTlqsvo= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creasty/defaults v1.7.0 h1:eNdqZvc5B509z18lD8yc212CAqJNvfT1Jq6L8WowdBA= +github.com/creasty/defaults v1.7.0/go.mod h1:iGzKe6pbEHnpMPtfDXZEr0NVxWnPTjb1bbDy08fPzYM= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY= -github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= -github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -50,17 +52,16 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw= -github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= +github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -70,28 +71,17 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA= github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E= +github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= +github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.11.4 h1:kz40R/YWls3iqT9zX9AHN3WoVsrAWVyui5sxuLqiXqU= -github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= -github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/machinebox/graphql v0.2.2 h1:dWKpJligYKhYKO5A2gvNhkJdQMNZeChZYyBbrZkBZfo= github.com/machinebox/graphql v0.2.2/go.mod h1:F+kbVMHuwrQ5tYgU9JXlnskM8nOaFxCAEolaQybkjWA= -github.com/mholt/archiver v3.1.1+incompatible h1:1dCVxuqs0dJseYEhi5pl7MYPH9zDa1wBi7mF09cbNkU= -github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU= -github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= -github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= -github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ= -github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= -github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= -github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4/v4 v4.1.2 h1:qvY3YFXRQE/XB8MlLzJH7mSzBs74eA2gg52YTk6jUPM= -github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ= +github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -105,11 +95,8 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I= -github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= -github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= @@ -120,6 +107,8 @@ go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= +go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -195,10 +184,12 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/rfcs/0006-connector-publishing-automation.md b/rfcs/0006-connector-publishing-automation.md index ef4081ea..d1a21a11 100644 --- a/rfcs/0006-connector-publishing-automation.md +++ b/rfcs/0006-connector-publishing-automation.md @@ -44,6 +44,7 @@ registry// The `registry` folder will contain a folder for each connector. Each connector folder will contain the following files: - `logo.png`: The logo of the connector. The logo should be in PNG format. + - `metadata.json`: The metadata of the connector. Metadata format is described in the [Github Distribution RFC](./0002-distribution-gh.md). - `README.md`: The README file of the connector. The README file should contain information about the connector, how to use it, and any other relevant information. The contents of the README file would be displayed in the landing page of the connector in the Hasura. - `releases`: The releases folder will contain a folder for each version of the connector. Each version folder will contain a `connector-packaging.json` file. More details about the `connector-packaging.json` file are provided below. From d737341acc9b93f357a6f7bda6421128309e3823 Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Wed, 21 Aug 2024 15:13:43 +0530 Subject: [PATCH 059/135] Rename `open-api-lambda` to `openapi`and `nodejs-lambda` to `nodejs` (#251) We make this change because the `open-api-lambda` connector is saved as `openapi` and the `nodejs-lambda` is saved as `nodejs` in the registry DB. So, to make the registry automation workflow work, we will have to keep the naming consistent across the registry DB and the `ndc-hub`. This PR only renames the folder and nothing else. --- registry/hasura/{nodejs-lambda => nodejs}/README.md | 0 registry/hasura/{nodejs-lambda => nodejs}/logo.png | Bin .../hasura/{nodejs-lambda => nodejs}/metadata.json | 0 .../hasura/{open-api-lambda => openapi}/README.md | 0 .../hasura/{open-api-lambda => openapi}/logo.png | Bin .../{open-api-lambda => openapi}/metadata.json | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename registry/hasura/{nodejs-lambda => nodejs}/README.md (100%) rename registry/hasura/{nodejs-lambda => nodejs}/logo.png (100%) rename registry/hasura/{nodejs-lambda => nodejs}/metadata.json (100%) rename registry/hasura/{open-api-lambda => openapi}/README.md (100%) rename registry/hasura/{open-api-lambda => openapi}/logo.png (100%) rename registry/hasura/{open-api-lambda => openapi}/metadata.json (100%) diff --git a/registry/hasura/nodejs-lambda/README.md b/registry/hasura/nodejs/README.md similarity index 100% rename from registry/hasura/nodejs-lambda/README.md rename to registry/hasura/nodejs/README.md diff --git a/registry/hasura/nodejs-lambda/logo.png b/registry/hasura/nodejs/logo.png similarity index 100% rename from registry/hasura/nodejs-lambda/logo.png rename to registry/hasura/nodejs/logo.png diff --git a/registry/hasura/nodejs-lambda/metadata.json b/registry/hasura/nodejs/metadata.json similarity index 100% rename from registry/hasura/nodejs-lambda/metadata.json rename to registry/hasura/nodejs/metadata.json diff --git a/registry/hasura/open-api-lambda/README.md b/registry/hasura/openapi/README.md similarity index 100% rename from registry/hasura/open-api-lambda/README.md rename to registry/hasura/openapi/README.md diff --git a/registry/hasura/open-api-lambda/logo.png b/registry/hasura/openapi/logo.png similarity index 100% rename from registry/hasura/open-api-lambda/logo.png rename to registry/hasura/openapi/logo.png diff --git a/registry/hasura/open-api-lambda/metadata.json b/registry/hasura/openapi/metadata.json similarity index 100% rename from registry/hasura/open-api-lambda/metadata.json rename to registry/hasura/openapi/metadata.json From f324d1b32523638eac80aeb2fc37bbcf6aff71a7 Mon Sep 17 00:00:00 2001 From: Brandon Martin Date: Wed, 21 Aug 2024 03:24:01 -0700 Subject: [PATCH 060/135] Update remaining connectors for packages folders (#245) Co-authored-by: Karthikeyan Chinnakonda --- .../releases/v0.2.1/connector-packaging.json | 11 +++++++++++ .../releases/v0.2.10/connector-packaging.json | 11 +++++++++++ .../releases/v0.2.11/connector-packaging.json | 11 +++++++++++ .../releases/v0.2.2/connector-packaging.json | 11 +++++++++++ .../releases/v0.2.3/connector-packaging.json | 11 +++++++++++ .../releases/v0.2.4/connector-packaging.json | 11 +++++++++++ .../releases/v0.2.5/connector-packaging.json | 11 +++++++++++ .../releases/v0.2.6/connector-packaging.json | 11 +++++++++++ .../releases/v0.2.7/connector-packaging.json | 11 +++++++++++ .../releases/v0.2.8/connector-packaging.json | 11 +++++++++++ .../releases/v0.2.9/connector-packaging.json | 11 +++++++++++ .../releases/v1.0.0/connector-packaging.json | 11 +++++++++++ .../go/releases/v0.4.0/connector-packaging.json | 11 +++++++++++ .../go/releases/v0.5.2/connector-packaging.json | 11 +++++++++++ .../go/releases/v0.6.3/connector-packaging.json | 11 +++++++++++ .../go/releases/v1.0.0/connector-packaging.json | 11 +++++++++++ .../go/releases/v1.1.2/connector-packaging.json | 11 +++++++++++ .../go/releases/v1.2.3/connector-packaging.json | 11 +++++++++++ .../graphql/releases/v0.1.0/connector-packaging.json | 11 +++++++++++ .../graphql/releases/v0.1.1/connector-packaging.json | 11 +++++++++++ .../graphql/releases/v0.1.2/connector-packaging.json | 11 +++++++++++ .../graphql/releases/v0.1.3/connector-packaging.json | 11 +++++++++++ 22 files changed, 242 insertions(+) create mode 100644 registry/hasura/clickhouse/releases/v0.2.1/connector-packaging.json create mode 100644 registry/hasura/clickhouse/releases/v0.2.10/connector-packaging.json create mode 100644 registry/hasura/clickhouse/releases/v0.2.11/connector-packaging.json create mode 100644 registry/hasura/clickhouse/releases/v0.2.2/connector-packaging.json create mode 100644 registry/hasura/clickhouse/releases/v0.2.3/connector-packaging.json create mode 100644 registry/hasura/clickhouse/releases/v0.2.4/connector-packaging.json create mode 100644 registry/hasura/clickhouse/releases/v0.2.5/connector-packaging.json create mode 100644 registry/hasura/clickhouse/releases/v0.2.6/connector-packaging.json create mode 100644 registry/hasura/clickhouse/releases/v0.2.7/connector-packaging.json create mode 100644 registry/hasura/clickhouse/releases/v0.2.8/connector-packaging.json create mode 100644 registry/hasura/clickhouse/releases/v0.2.9/connector-packaging.json create mode 100644 registry/hasura/clickhouse/releases/v1.0.0/connector-packaging.json create mode 100644 registry/hasura/go/releases/v0.4.0/connector-packaging.json create mode 100644 registry/hasura/go/releases/v0.5.2/connector-packaging.json create mode 100644 registry/hasura/go/releases/v0.6.3/connector-packaging.json create mode 100644 registry/hasura/go/releases/v1.0.0/connector-packaging.json create mode 100644 registry/hasura/go/releases/v1.1.2/connector-packaging.json create mode 100644 registry/hasura/go/releases/v1.2.3/connector-packaging.json create mode 100644 registry/hasura/graphql/releases/v0.1.0/connector-packaging.json create mode 100644 registry/hasura/graphql/releases/v0.1.1/connector-packaging.json create mode 100644 registry/hasura/graphql/releases/v0.1.2/connector-packaging.json create mode 100644 registry/hasura/graphql/releases/v0.1.3/connector-packaging.json diff --git a/registry/hasura/clickhouse/releases/v0.2.1/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.1/connector-packaging.json new file mode 100644 index 00000000..ca4da984 --- /dev/null +++ b/registry/hasura/clickhouse/releases/v0.2.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.1", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "5e88d1b7fb14638ceeaf5b6fac775b6cc68d62d8537fc25cd8e87cdf4dfb443e" + }, + "source": { + "hash": "521365decd10db124c9865bd29fc4e60025a6892" + } +} \ No newline at end of file diff --git a/registry/hasura/clickhouse/releases/v0.2.10/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.10/connector-packaging.json new file mode 100644 index 00000000..4588d858 --- /dev/null +++ b/registry/hasura/clickhouse/releases/v0.2.10/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.10", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.10/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "4eb32262e528d0261afd0f6a4b283a6fe3fd0edf395b732fe6abcacfdf4ff999" + }, + "source": { + "hash": "dbe5b7765b1c9276e5734c8fbc5005e7b71d0500" + } +} \ No newline at end of file diff --git a/registry/hasura/clickhouse/releases/v0.2.11/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.11/connector-packaging.json new file mode 100644 index 00000000..4df2fe21 --- /dev/null +++ b/registry/hasura/clickhouse/releases/v0.2.11/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.11", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.11/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "97dccf8cfac9865eb6a0e3aee65fcd91a7c14a48e1f65cf985df3734f596e13b" + }, + "source": { + "hash": "7ef634c61649a17deb867e5a36db4220c66f0013" + } +} \ No newline at end of file diff --git a/registry/hasura/clickhouse/releases/v0.2.2/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.2/connector-packaging.json new file mode 100644 index 00000000..da7f9a11 --- /dev/null +++ b/registry/hasura/clickhouse/releases/v0.2.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.2", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.2/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "198ed9a830a403cf855d449b3d99313ad01de4df21663c0648ab95fa25b58325" + }, + "source": { + "hash": "6b349d7f0e8449611a24d6b8cad34aeb3162b583" + } +} \ No newline at end of file diff --git a/registry/hasura/clickhouse/releases/v0.2.3/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.3/connector-packaging.json new file mode 100644 index 00000000..c321dba6 --- /dev/null +++ b/registry/hasura/clickhouse/releases/v0.2.3/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.3", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "f1b1020e57fdb969b545f0e5ad37f1000c2e5084041695cc2e885e4cb634b35c" + }, + "source": { + "hash": "97175685b51a31a5ac99672746901d0df6d4eb35" + } +} \ No newline at end of file diff --git a/registry/hasura/clickhouse/releases/v0.2.4/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.4/connector-packaging.json new file mode 100644 index 00000000..758f847d --- /dev/null +++ b/registry/hasura/clickhouse/releases/v0.2.4/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.4", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.4/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "8ab07763d887848a555f26aae973e34e872ec0617ccc17d2eac96d67fe223e87" + }, + "source": { + "hash": "cd1f81b98b264df1e20f7f84a664fb272fac19b1" + } +} \ No newline at end of file diff --git a/registry/hasura/clickhouse/releases/v0.2.5/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.5/connector-packaging.json new file mode 100644 index 00000000..2cdea3c6 --- /dev/null +++ b/registry/hasura/clickhouse/releases/v0.2.5/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.5", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.5/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "8504769a2bd8ac63f979dc5447dc106da4360cfbcdcacc9edb8765eb434e1e11" + }, + "source": { + "hash": "c89d9410cf885cbfe4156c9e7bf65211144018df" + } +} \ No newline at end of file diff --git a/registry/hasura/clickhouse/releases/v0.2.6/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.6/connector-packaging.json new file mode 100644 index 00000000..29ab3b91 --- /dev/null +++ b/registry/hasura/clickhouse/releases/v0.2.6/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.6", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.6/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "c20dd539761084f9a3a0effa68011a6d57da92dbdf4f805bac93bc825f5c40ef" + }, + "source": { + "hash": "7bafb9fd2b9c3288b6f7279c3d62793cc78d8fe0" + } +} \ No newline at end of file diff --git a/registry/hasura/clickhouse/releases/v0.2.7/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.7/connector-packaging.json new file mode 100644 index 00000000..fa17cc7c --- /dev/null +++ b/registry/hasura/clickhouse/releases/v0.2.7/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.7", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.7/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "a6acbd32400b2a74009009933a8469892bf7781969e58aef7532121198af1e4f" + }, + "source": { + "hash": "ece8fb0fcfcd9650dd5060f882baa94889eccf2e" + } +} \ No newline at end of file diff --git a/registry/hasura/clickhouse/releases/v0.2.8/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.8/connector-packaging.json new file mode 100644 index 00000000..ceb0ce8f --- /dev/null +++ b/registry/hasura/clickhouse/releases/v0.2.8/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.8", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.8/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "4de1a70042d222040523faf6aa1771be23d5156258318272fc31fa1dd49c41ea" + }, + "source": { + "hash": "f1629f715770358e587a25f9a0ca015728d422dd" + } +} \ No newline at end of file diff --git a/registry/hasura/clickhouse/releases/v0.2.9/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.9/connector-packaging.json new file mode 100644 index 00000000..dc6c0452 --- /dev/null +++ b/registry/hasura/clickhouse/releases/v0.2.9/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.9", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.9/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "source": { + "hash": "93752f433f4e7c91f0c13d92ea9369deb97d1970" + } +} \ No newline at end of file diff --git a/registry/hasura/clickhouse/releases/v1.0.0/connector-packaging.json b/registry/hasura/clickhouse/releases/v1.0.0/connector-packaging.json new file mode 100644 index 00000000..56f19e77 --- /dev/null +++ b/registry/hasura/clickhouse/releases/v1.0.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.0", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v1.0.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "e872f3a10ac9a3c6ab81fe958263941b0a998e5bce2d978685a65cfe679e53c6" + }, + "source": { + "hash": "3da872909893964aabaedb4659af129f0ceaa565" + } +} \ No newline at end of file diff --git a/registry/hasura/go/releases/v0.4.0/connector-packaging.json b/registry/hasura/go/releases/v0.4.0/connector-packaging.json new file mode 100644 index 00000000..bd289378 --- /dev/null +++ b/registry/hasura/go/releases/v0.4.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.4.0", + "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v0.4.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "13e6c4e970e032307cbb9edbb9d79ad555880c46d8a58d98f23ce441cef7d7b2" + }, + "source": { + "hash": "ac27498b6dbd5e803ca97e0fc702f52e2d9b429d" + } +} \ No newline at end of file diff --git a/registry/hasura/go/releases/v0.5.2/connector-packaging.json b/registry/hasura/go/releases/v0.5.2/connector-packaging.json new file mode 100644 index 00000000..90a5ffc1 --- /dev/null +++ b/registry/hasura/go/releases/v0.5.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.5.2", + "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v0.5.2/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "dfb2ea7499744a1ad00673703eed28bccaf38b4866721f5b0aacb546d788a659" + }, + "source": { + "hash": "79788195359a5e3cf0fc8896b61eb8f4d9196427" + } +} \ No newline at end of file diff --git a/registry/hasura/go/releases/v0.6.3/connector-packaging.json b/registry/hasura/go/releases/v0.6.3/connector-packaging.json new file mode 100644 index 00000000..61753179 --- /dev/null +++ b/registry/hasura/go/releases/v0.6.3/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.6.3", + "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v0.6.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "e6ebd14bc1a75ab384da80eae7a823dd6883af6a574b42d720358d873491f96e" + }, + "source": { + "hash": "726b3fbb442fae62d18840905545f1d663baf87b" + } +} \ No newline at end of file diff --git a/registry/hasura/go/releases/v1.0.0/connector-packaging.json b/registry/hasura/go/releases/v1.0.0/connector-packaging.json new file mode 100644 index 00000000..8df6d091 --- /dev/null +++ b/registry/hasura/go/releases/v1.0.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v1.0.0", + "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.0.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "906db79cf5565eaca731436180295d2d7ee81246b57cc7dcdde14585841f53a5" + }, + "source": { + "hash": "42259e9a9c719131721f0058c552e9b8a4a36973" + } +} \ No newline at end of file diff --git a/registry/hasura/go/releases/v1.1.2/connector-packaging.json b/registry/hasura/go/releases/v1.1.2/connector-packaging.json new file mode 100644 index 00000000..f24a3e90 --- /dev/null +++ b/registry/hasura/go/releases/v1.1.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v1.1.2", + "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.1.2/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "2e037c86fd4da3f07417a7216a7921b885a4e13b8da15210e1cd13cc4ee728f1" + }, + "source": { + "hash": "32e28e549f11b790c320b6a79ad33ad8e6df5bd7" + } +} \ No newline at end of file diff --git a/registry/hasura/go/releases/v1.2.3/connector-packaging.json b/registry/hasura/go/releases/v1.2.3/connector-packaging.json new file mode 100644 index 00000000..b70abe80 --- /dev/null +++ b/registry/hasura/go/releases/v1.2.3/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v1.2.3", + "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.2.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "9573485be49d633ab3a7b39e8777da2d3524702fafac1739e42217caf5b3ad9a" + }, + "source": { + "hash": "1fdc72d31dccae129d6d626dea6e31b5cd3b0b18" + } +} \ No newline at end of file diff --git a/registry/hasura/graphql/releases/v0.1.0/connector-packaging.json b/registry/hasura/graphql/releases/v0.1.0/connector-packaging.json new file mode 100644 index 00000000..f3bebe33 --- /dev/null +++ b/registry/hasura/graphql/releases/v0.1.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "30d6883c57b146812fb141feb3b4680a9ffe214cb13e04b0618a8da069d1286c" + }, + "source": { + "hash": "8fb41a151b3852fadcfadbe17695605f77aaa240" + } +} \ No newline at end of file diff --git a/registry/hasura/graphql/releases/v0.1.1/connector-packaging.json b/registry/hasura/graphql/releases/v0.1.1/connector-packaging.json new file mode 100644 index 00000000..8e7f0769 --- /dev/null +++ b/registry/hasura/graphql/releases/v0.1.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.1", + "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "8a5acec98e28953b22932d7a3734f7e7e535ac9478058b4d06ad9da5dc21ce1d" + }, + "source": { + "hash": "85b80185e28eb7f6721fc50ecd2552f96633e5db" + } +} \ No newline at end of file diff --git a/registry/hasura/graphql/releases/v0.1.2/connector-packaging.json b/registry/hasura/graphql/releases/v0.1.2/connector-packaging.json new file mode 100644 index 00000000..ffea7300 --- /dev/null +++ b/registry/hasura/graphql/releases/v0.1.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.2", + "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.2/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "85aa0294a4a13da85c2932254878814f60f8e9b61621232675b5dfa551248a77" + }, + "source": { + "hash": "1cfb5d3e52d914acf4e5e96edd54d7fc744ec304" + } +} \ No newline at end of file diff --git a/registry/hasura/graphql/releases/v0.1.3/connector-packaging.json b/registry/hasura/graphql/releases/v0.1.3/connector-packaging.json new file mode 100644 index 00000000..37aee93b --- /dev/null +++ b/registry/hasura/graphql/releases/v0.1.3/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.3", + "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "4045cfd23f6ed4bf747241f967a7717dd391b5fe8285ec486584427698cf9881" + }, + "source": { + "hash": "4262e34d57255c622a47daa408eba8c25fb279f7" + } +} \ No newline at end of file From a212ae2d4bd5883d54172f8dbc8230503f54a0b7 Mon Sep 17 00:00:00 2001 From: Samir Talwar Date: Thu, 22 Aug 2024 12:36:03 +0200 Subject: [PATCH 061/135] ndc-postgres: Publish v1.1.1 (#256) --- registry/hasura/aurora/metadata.json | 7 ++++++- registry/hasura/citus/metadata.json | 7 ++++++- registry/hasura/cockroach/metadata.json | 7 ++++++- registry/hasura/neon/metadata.json | 7 ++++++- registry/hasura/postgres-alloydb/metadata.json | 7 ++++++- registry/hasura/postgres-azure/metadata.json | 7 ++++++- registry/hasura/postgres-cosmos/metadata.json | 7 ++++++- registry/hasura/postgres-gcp/metadata.json | 7 ++++++- registry/hasura/postgres-timescaledb/metadata.json | 7 ++++++- registry/hasura/postgres/metadata.json | 7 ++++++- 10 files changed, 60 insertions(+), 10 deletions(-) diff --git a/registry/hasura/aurora/metadata.json b/registry/hasura/aurora/metadata.json index 592d940e..6dcf0551 100644 --- a/registry/hasura/aurora/metadata.json +++ b/registry/hasura/aurora/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.1.0" + "latest_version": "v1.1.1" }, "author": { "support_email": "support@hasura.io", @@ -64,6 +64,11 @@ "tag": "v1.1.0", "hash": "a57c0b5", "is_verified": true + }, + { + "tag": "v1.1.1", + "hash": "fc6a7a7", + "is_verified": true } ] } diff --git a/registry/hasura/citus/metadata.json b/registry/hasura/citus/metadata.json index ace7f559..fb75e63f 100644 --- a/registry/hasura/citus/metadata.json +++ b/registry/hasura/citus/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.1.0" + "latest_version": "v1.1.1" }, "author": { "support_email": "support@hasura.io", @@ -64,6 +64,11 @@ "tag": "v1.1.0", "hash": "a57c0b5", "is_verified": true + }, + { + "tag": "v1.1.1", + "hash": "fc6a7a7", + "is_verified": true } ] } diff --git a/registry/hasura/cockroach/metadata.json b/registry/hasura/cockroach/metadata.json index e9fbc622..2323ee2f 100644 --- a/registry/hasura/cockroach/metadata.json +++ b/registry/hasura/cockroach/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.1.0" + "latest_version": "v1.1.1" }, "author": { "support_email": "support@hasura.io", @@ -64,6 +64,11 @@ "tag": "v1.1.0", "hash": "a57c0b5", "is_verified": true + }, + { + "tag": "v1.1.1", + "hash": "fc6a7a7", + "is_verified": true } ] } diff --git a/registry/hasura/neon/metadata.json b/registry/hasura/neon/metadata.json index 7342a15c..84a94970 100644 --- a/registry/hasura/neon/metadata.json +++ b/registry/hasura/neon/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.1.0" + "latest_version": "v1.1.1" }, "author": { "support_email": "support@hasura.io", @@ -64,6 +64,11 @@ "tag": "v1.1.0", "hash": "a57c0b5", "is_verified": true + }, + { + "tag": "v1.1.1", + "hash": "fc6a7a7", + "is_verified": true } ] } diff --git a/registry/hasura/postgres-alloydb/metadata.json b/registry/hasura/postgres-alloydb/metadata.json index 0faa527f..53f3d91d 100644 --- a/registry/hasura/postgres-alloydb/metadata.json +++ b/registry/hasura/postgres-alloydb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.1.0" + "latest_version": "v1.1.1" }, "author": { "support_email": "support@hasura.io", @@ -64,6 +64,11 @@ "tag": "v1.1.0", "hash": "a57c0b5", "is_verified": true + }, + { + "tag": "v1.1.1", + "hash": "fc6a7a7", + "is_verified": true } ] } diff --git a/registry/hasura/postgres-azure/metadata.json b/registry/hasura/postgres-azure/metadata.json index 53e4d6b7..e5f4f2c9 100644 --- a/registry/hasura/postgres-azure/metadata.json +++ b/registry/hasura/postgres-azure/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.1.0" + "latest_version": "v1.1.1" }, "author": { "support_email": "support@hasura.io", @@ -64,6 +64,11 @@ "tag": "v1.1.0", "hash": "a57c0b5", "is_verified": true + }, + { + "tag": "v1.1.1", + "hash": "fc6a7a7", + "is_verified": true } ] } diff --git a/registry/hasura/postgres-cosmos/metadata.json b/registry/hasura/postgres-cosmos/metadata.json index 11d1bbea..1e52afdd 100644 --- a/registry/hasura/postgres-cosmos/metadata.json +++ b/registry/hasura/postgres-cosmos/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.1.0" + "latest_version": "v1.1.1" }, "author": { "support_email": "support@hasura.io", @@ -64,6 +64,11 @@ "tag": "v1.1.0", "hash": "a57c0b5", "is_verified": true + }, + { + "tag": "v1.1.1", + "hash": "fc6a7a7", + "is_verified": true } ] } diff --git a/registry/hasura/postgres-gcp/metadata.json b/registry/hasura/postgres-gcp/metadata.json index 83db222b..adb538a3 100644 --- a/registry/hasura/postgres-gcp/metadata.json +++ b/registry/hasura/postgres-gcp/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.1.0" + "latest_version": "v1.1.1" }, "author": { "support_email": "support@hasura.io", @@ -64,6 +64,11 @@ "tag": "v1.1.0", "hash": "a57c0b5", "is_verified": true + }, + { + "tag": "v1.1.1", + "hash": "fc6a7a7", + "is_verified": true } ] } diff --git a/registry/hasura/postgres-timescaledb/metadata.json b/registry/hasura/postgres-timescaledb/metadata.json index 8eaf5ebe..3e89786e 100644 --- a/registry/hasura/postgres-timescaledb/metadata.json +++ b/registry/hasura/postgres-timescaledb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.1.0" + "latest_version": "v1.1.1" }, "author": { "support_email": "support@hasura.io", @@ -64,6 +64,11 @@ "tag": "v1.1.0", "hash": "a57c0b5", "is_verified": true + }, + { + "tag": "v1.1.1", + "hash": "fc6a7a7", + "is_verified": true } ] } diff --git a/registry/hasura/postgres/metadata.json b/registry/hasura/postgres/metadata.json index d89a9b8e..ea1ba8b6 100644 --- a/registry/hasura/postgres/metadata.json +++ b/registry/hasura/postgres/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.1.0" + "latest_version": "v1.1.1" }, "author": { "support_email": "support@hasura.io", @@ -64,6 +64,11 @@ "tag": "v1.1.0", "hash": "a57c0b5", "is_verified": true + }, + { + "tag": "v1.1.1", + "hash": "fc6a7a7", + "is_verified": true } ] } From 17642193c19cc319b2fcff4cd1ead7b287b8be87 Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Thu, 22 Aug 2024 18:02:36 +0530 Subject: [PATCH 062/135] Enable the registry automation in prod (#254) This PR copies the `registry-automation` GitHub workflow (that deploys to staging) to `registry-automation-prod` . This workflow will only run when there is a `push` to the `main` branch. --- .github/workflows/registry-updates-prod.yaml | 60 ++++++++++++++++++++ .github/workflows/registry-updates.yaml | 2 +- 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/registry-updates-prod.yaml diff --git a/.github/workflows/registry-updates-prod.yaml b/.github/workflows/registry-updates-prod.yaml new file mode 100644 index 00000000..32e8d71e --- /dev/null +++ b/.github/workflows/registry-updates-prod.yaml @@ -0,0 +1,60 @@ +name: Update Hub DB from GH Registry (prod) + +on: + push: + branches: + - main + paths: + - registry/** + +jobs: + update_registry_db: + runs-on: ubuntu-latest + environment: production + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + fetch_depth: 1 + + - name: Get all connector version package changes + id: connector-version-changed-files + uses: tj-actions/changed-files@v44 + with: + json: true + escape_json: false + files: | + registry/** + + - name: Print out all the changed filse + env: + ADDED_FILES: ${{ steps.connector-version-changed-files.outputs.added_files }} + MODIFIED_FILES: ${{ steps.connector-version-changed-files.outputs.modified_files }} + DELETED_FILES: ${{ steps.connector-version-changed-files.outputs.deleted_files }} + run: | + echo "{\"added_files\": $ADDED_FILES, \"modified_files\": $MODIFIED_FILES, \"deleted_files\": $DELETED_FILES}" > changed_files.json + + - name: List changed files + id: list_files + run: | + cat changed_files.json + + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: 1.21.x + + - name: Run registry automation program + env: + CHANGED_FILES_PATH: "changed_files.json" + PUBLICATION_ENV: "production" + CONNECTOR_REGISTRY_GQL_URL: ${{ secrets.CONNECTOR_REGISTRY_GQL_URL }} + GCP_BUCKET_NAME: ${{ secrets.GCP_BUCKET_NAME }} + GCP_SERVICE_ACCOUNT_DETAILS: ${{ secrets.GCP_SERVICE_ACCOUNT_DETAILS }} + CONNECTOR_PUBLICATION_KEY: ${{ secrets.CONNECTOR_PUBLICATION_KEY }} + CLOUDINARY_URL: ${{ secrets.CLOUDINARY_URL }} + run: | + mv changed_files.json registry-automation/changed_files.json + cd registry-automation + go run main.go ci diff --git a/.github/workflows/registry-updates.yaml b/.github/workflows/registry-updates.yaml index 2147750f..3c4f5463 100644 --- a/.github/workflows/registry-updates.yaml +++ b/.github/workflows/registry-updates.yaml @@ -1,4 +1,4 @@ -name: Update Hub DB from GH Registry +name: Update Hub DB from GH Registry (Staging) on: pull_request: From 82ae6a16a8a8730a9f3d38a1c782e26b5942b878 Mon Sep 17 00:00:00 2001 From: Mohd Bilal Date: Thu, 22 Aug 2024 21:07:32 +0530 Subject: [PATCH 063/135] update OpenAPI readme for CLI version v2.1 (#258) --- registry/hasura/openapi/README.md | 141 +++++++++++------------------- 1 file changed, 51 insertions(+), 90 deletions(-) diff --git a/registry/hasura/openapi/README.md b/registry/hasura/openapi/README.md index 4b52a93e..8ba92e54 100644 --- a/registry/hasura/openapi/README.md +++ b/registry/hasura/openapi/README.md @@ -1,8 +1,8 @@ # OpenAPI Lambda Connector -[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/getting-started/overview/) -[![ndc-hub](https://img.shields.io/badge/ndc--hub-postgres-blue.svg?style=flat)](https://hasura.io/connectors) -[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-openapi-blue.svg?style=flat)](https://hasura.io/connectors/open-api-lambda) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0) The OpenAPI Lambda Connector allows you to import APIs that are documented in the OpenAPI/Swagger format into the Hasura Supergraph. The connector exposes REST API endpoints as Typescript functions, which can be exposed as GraphQL queries or mutations via the [NodeJS Lambda Connector](https://github.com/hasura/ndc-nodejs-lambda). @@ -10,9 +10,18 @@ Functions that wrap GET requests are marked with a `@readonly` annotation, and a This Connector implements the [Data Connector Spec](https://github.com/hasura/ndc-spec) -- [Hasura V3 Documentation](https://hasura.io/docs/3.0) +- [See the listing in the Hasura Hub](https://hasura.io/connectors/open-api-lambda) +- [Hasura DDN Documentation](https://hasura.io/docs/3.0) +- [Hasura DDN Quickstart](https://hasura.io/docs/3.0/getting-started/quickstart) - [NodeJS Lambda Connector](https://github.com/hasura/ndc-nodejs-lambda) +Docs for the OpenAPI data connector: + +- [Documentation](https://github.com/hasura/ndc-open-api-lambda/blob/main/docs/documentation.md) +- [Contributing](https://github.com/hasura/ndc-open-api-lambda/blob/main/docs/contributing.md) +- [Code of Conduct](https://github.com/hasura/ndc-open-api-lambda/blob/main/docs/code-of-conduct.md) +- [Relase Document](https://github.com/hasura/ndc-open-api-lambda/blob/main/docs/release.md) + ## Features - Convert Open API/swagger documentation into Typescript functions compatible with NodeJS Lambda Connector @@ -29,120 +38,72 @@ This Connector implements the [Data Connector Spec](https://github.com/hasura/nd ## Before you get Started 1. Create a [Hasura Cloud account](https://console.hasura.io) -2. Install the [DDN CLI](https://hasura.io/docs/3.0/cli/installation/) -3. Please ensure that you have Docker installed and the Docker daemon is running. -4. If you want to make changes to the generated Typescript files, please ensure you have Node.js v20+ installed - -## Quickstart using the DDN CLI - -> [!TIP] -> The following instructions are intended to get you quickly started with using the OpenAPI Lambda connector. -> For further information on DDN, please check out the [Hasura DDN Getting Started Guide](https://hasura.io/docs/3.0/getting-started/overview/). +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) +5. If you want to make changes to the generated Typescript files, please ensure you have Node.js v20+ installed -> [!NOTE] -> This section assumes that you have already setup a Supergraph and added a Subgraph. +## Using the OpenAPI connector -1. Initialize the connector +### Step 1: Authenticate your CLI session +```bash +ddn auth login ``` -ddn connector init my_openapi --subgraph my_subgraph --hub-connector hasura/openapi -``` - -This will generate the necessary files into `my_subgraph/connector/my_openapi` directory. Supporting Typescript files for API calls will be created in this directory. - -2. Add the correct environment variables to `/my_subgraph/connector/my_openapi/.env.local`. Supported environment variables and their description are listed under [Supported Environment Variables](#supported-environment-variables) section. -3. Modify the Docker container port in `my_subgraph/connector/my_openapi/docker-compose.my_openapi.yaml`. Typically, connectors default to port 8080. Each time you add a connector, please increment the published port by one to avoid port collisions. For example: +### Step 2: Configure the connector -``` -ports: - - mode: ingress - target: 8080 - published: '8082' - protocol: tcp -``` +Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while +providing a name for the connector in the prompt: -4. Introspect the OpenAPI document using the connector - -``` -ddn connector introspect --connector my_subgraph/connector/my_openapi/connector.yaml +```bash +ddn connector init -i ``` -This will introspect your OpenAPI document and create an `api.ts` file, a `functions.ts` file and other supporting files required to run the Typescript project. +#### Step 2.1: Choose `hasura/openapi` from the list -- The `api.ts` file contains the Data Types and API calls from the OpenAPI document -- The `functions.ts` file contains functions that wrap API calls. You can modify this `functions.ts` file to introduce business logic if you want to. See [Saving User Changes](#saving-user-changes) if you want to preserve your changes in this file when you introspect the OpenAPI document again. +#### Step 2.2: Choose a port for the connector -5. Add a [Data Connector Link](https://hasura.io/docs/3.0/supergraph-modeling/data-connector-links) - -``` -ddn connector-link add my_openapi --subgraph my_subgraph -``` +The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the +default suggested port. -This will create a file `my_subgraph/metadata/my_openapi.hml` that links your OpenAPI Connector to your Hasura Supergraph. +#### Step 2.3: Provide the env vars required for the connector -6. Update the evironment variables listed in `my_subgraph/metadata/my_openapi.hml` (here, `MY_SUBGRAPH_MY_OPENAPI_READ_URL` and `MY_SUBGRAPH_MY_OPENAPI_WRITE_URL`) in `my_subgraph/.env.my_subgraph`. +Environment variables that can be used to configure the connector are listed under [Supported Environment Variables](https://github.com/hasura/ndc-open-api-lambda/blob/main/docs/documentation.md#supported-environment-variables). -7. Add the connector's Docker Compose file to your project's Docker Compose file (your project's Docker Compose file is the one that's located in the root directory your project): +## Step 3: Introspect the connector +```bash +ddn connector introspect ``` -include: - - path: my_subpgraph/connector/my_openapi/docker-compose.my_openapi.yaml -``` - -Start the GraphQL engine, observability tools, and the connector: -``` -HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yaml watch -``` +This will generate the required metadata and TypeScript files. -The `http://localhost:${your-docker-container-port}/schema/` should return the schema of your OpenAPI Connector. All functions that wrap `GET` requests will be listed in the `functions` array, while all other functions will be listed in the `procedures` array. +## Step 4: Add your resources -8. Add the connector schema to [Data Connector Link](<(https://hasura.io/docs/3.0/supergraph-modeling/data-connector-links)>) - -``` -ddn connector-link update my_openapi --subgraph my_subgraph +```bash +ddn connector-link add-resources ``` -This command will modify `my_subgraph/metadata/my_openapi.hml`, and the schema of the connector will be added to the `definition.schema` key. +This command will track all the API endpoints in your OpenAPI Document as [Commands](https://hasura.io/docs/3.0/supergraph-modeling/commands/). -9. Add all resources in your connector schema to your GraphQL API +## Saving User Changes -``` -ddn connector-link update my_openapi --subgraph my_subgraph --add-all-resources -``` - -This will create HML files that represent resources in your connector schema at `my_subgraph/metadata`. These HML files specify your GraphQL API. - -You have now added the OpenAPI Connector and imported all of your APIs in your supergraph. You can now: +Please refer to [Saving User Changes](https://github.com/hasura/ndc-open-api-lambda/blob/main/docs/documentation.md#saving-user-changes). -- Deploy the supergraph to Hasura DDN (Please follow the steps [here](https://hasura.io/docs/3.0/getting-started/deployment/)) -- Run the supergraph locally for debugging (Please follow the steps [here](https://hasura.io/docs/3.0/getting-started/build-your-api)) +## Known Limiations -## Documentation +- Support for [Relaxed Types](https://github.com/hasura/ndc-nodejs-lambda/tree/main?tab=readme-ov-file#relaxed-types) is a WiP. +- [Types not supported by the NodeJS Lambda Connector](https://github.com/hasura/ndc-nodejs-lambda?tab=readme-ov-file#unsupported-types) are not supported. -This connector is published as a Docker Image. The image name is `ghcr.io/hasura/ndc-open-api-lambda`. The Docker Image accepts the following environment variables that can be used to alter its functionality. +## Contributing -### Supported Environment Variables +Check out our [contributing guide](.docs/contributing.md) for more details. -1. `NDC_OAS_DOCUMENT_URI` (optional): The URI to your Open API Document. If you're using a file instead of a HTTP link, please ensure that it is named `swagger.json` and is present in the root directory of the volume being mounted to `/etc/connector` (for this tutorial, the `swagger.json` file should be present at `my_subgraph/connector/my_openapi/`). -2. `NDC_OAS_BASE_URL` (optional): The base URL of your API. -3. `NDC_OAS_FILE_OVERWRITE` (optional): A Boolean flag to allow previously generated files to be over-written. Defaults to `false`. -4. `HASURA_PLUGIN_LOG_LEVEL` (optional): The log level. Possible values: `trace`, `debug`, `info`, `warn`, `error`, `fatal`, `panic`. Defaults to `info` -5. `NDC_OAS_LAMBDA_PRETTY_LOGS` (optional): A Boolean flag to print human readable logs instead of JSON. Defaults to `false` +## Changelog -### Saving User Changes +Please refer to the [changelog](https://github.com/hasura/ndc-open-api-lambda/blob/main/changelog.md). -When re-introspecting the connector, user changes in `functions.ts` can be preserved by adding an `@save` JS Doc Tag to the documentation comment of a function. This will ensure that that function is not overwritten and the saved function will be added if missing in the newly generated `functions.ts` +## License -Example - -``` -/** - * Dummy function that mutates an API response - * @save - */ -function mutateResponse(response: ApiResponseObject) { - response.description = "This API does some work. I hope that's helpful"; -} -``` +The Open API Lambda Connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). From b942679bf3a1480515b1c86272c9899dff02c7be Mon Sep 17 00:00:00 2001 From: Mohd Bilal Date: Thu, 22 Aug 2024 21:08:13 +0530 Subject: [PATCH 064/135] update ElasticSearch readme for CLI version v2.1 (#259) --- registry/hasura/elasticsearch/README.md | 168 +++++++----------------- 1 file changed, 51 insertions(+), 117 deletions(-) diff --git a/registry/hasura/elasticsearch/README.md b/registry/hasura/elasticsearch/README.md index 1fa8fc77..7edacec6 100644 --- a/registry/hasura/elasticsearch/README.md +++ b/registry/hasura/elasticsearch/README.md @@ -1,25 +1,34 @@ # Elasticsearch Connector -[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/latest/connectors/elasticsearch/) -[![ndc-hub](https://img.shields.io/badge/ndc--hub-elasticsearch-blue.svg?style=flat)](https://hasura.io/connectors/ndc-elasticsearch) -[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) -[![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-elasticsearch-blue.svg?style=flat)](https://hasura.io/connectors/elasticsearch) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0) With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your documents in Elasticsearch. This connector supports Elasticsearch functionalities listed in the table below, allowing for efficient and scalable data operations. Additionally, you will benefit from all the powerful features of Hasura’s Data Delivery Network (DDN) platform, including query pushdown capabilities that delegate all query operations to the Elasticsearch, thereby enhancing query optimization and performance. This connector is built using the [Go Data Connector SDK](https://github.com/hasura/ndc-sdk-go) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). -- [Connector information in the Hasura Hub](https://hasura.io/connectors/elasticsearch) -- [Hasura V3 Documentation](https://hasura.io/docs/3.0) +- [See the listing in the Hasura Hub](https://hasura.io/connectors/elasticsearch) +- [Hasura DDN Documentation](https://hasura.io/docs/3.0) +- [Hasura DDN Quickstart](https://hasura.io/docs/3.0/getting-started/quickstart) +- [GraphQL on Elasticsearch](https://hasura.io/graphql/database/elasticsearch) + +Docs for the Elasticsearch data connector: + +- [Architecture](https://github.com/hasura/ndc-elasticsearch/blob/main/docs/architecture.md) +- [Code of Conduct](https://github.com/hasura/ndc-elasticsearch/blob/main/docs/code-of-conduct.md) +- [Contributing](https://github.com/hasura/ndc-elasticsearch/blob/main/docs/contributing.md) +- [Configuration](https://github.com/hasura/ndc-elasticsearch/blob/main/docs/configuration.md) +- [Development](https://github.com/hasura/ndc-elasticsearch/blob/main/docs/development.md) +- [Security](https://github.com/hasura/ndc-elasticsearch/blob/main/docs/security.md) +- [Support](https://github.com/hasura/ndc-elasticsearch/blob/main/docs/support.md) ## Features Below, you'll find a matrix of all supported features for the Elasticsearch connector: - - | Feature | Supported | Notes | -| ------------------------------- | -------- | ----- | +| ------------------------------- | --------- | ----- | | Native Queries + Logical Models | ✅ | | | Simple Object Query | ✅ | | | Filter / Search | ✅ | | @@ -28,148 +37,73 @@ Below, you'll find a matrix of all supported features for the Elasticsearch conn | Paginate | ✅ | | | Nested Objects | ✅ | | | Nested Arrays | ✅ | | -| Nested Filtering | ❌ | | +| Nested Filtering | ✅ | | | Nested Sorting | ❌ | | | Nested Relationships | ❌ | | - ## Before you get Started 1. Create a [Hasura Cloud account](https://console.hasura.io) -2. Install the [CLI](https://hasura.io/docs/3.0/cli/installation/) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed 3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) 4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -## Using the connector - -To use the Elasticsearch connector, follow these steps in a Hasura project: -(Note: for more information on the following steps, please refer to the Postgres connector documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) - - -### 1. Init the connector -(Note: here and following we are naming the subgraph "my_subgraph" and the connector "my_elastic") - - ```bash - ddn connector init my_elastic --subgraph my_subgraph --hub-connector hasura/elasticsearch - ``` - -### 2. Add your Elasticsearch credentials: - -```env title="my_subgraph/connector/my_elastic/.env.local" -OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 -OTEL_SERVICE_NAME=my_subgraph_my_elastic -ELASTICSEARCH_URL= -ELASTICSEARCH_USERNAME= -ELASTICSEARCH_PASSWORD= -``` - -To configure the connector, the following environment variables need to be set: - -| Environment Variable | Description | Required | Example Value | -| ----------------------------- | --------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------- | -| `ELASTICSEARCH_URL` | The comma-separated list of Elasticsearch host addresses for connection | Yes | `https://example.es.gcp.cloud.es.io:9200` | -| `ELASTICSEARCH_USERNAME` | The username for authenticating to the Elasticsearch cluster | Yes | `admin` | -| `ELASTICSEARCH_PASSWORD` | The password for the Elasticsearch user account | Yes | `default` | -| `ELASTICSEARCH_API_KEY` | The Elasticsearch API key for authenticating to the Elasticsearch cluster | No | `ABCzYWk0NEI0aDRxxxxxxxxxx1k6LWVQa2gxMUpRTUstbjNwTFIzbGoyUQ==` | -| `ELASTICSEARCH_CA_CERT_PATH` | The path to the Certificate Authority (CA) certificate for verifying the Elasticsearch server's SSL certificate | No | `/etc/connector/cacert.pem` | -| `ELASTICSEARCH_INDEX_PATTERN` | The pattern for matching Elasticsearch indices, potentially including wildcards, used by the connector | No | `hasura*` | - - -### 3. Introspect your indices - -```bash title="From the root of your project run:" -ddn connector introspect --connector my_subgraph/connector/my_elastic/connector.yaml -``` - -If you look at the `configuration.json` for your connector, you'll see metadata describing your Elasticsearch mappings. +## Using the Elasticsearch connector -### 4. Create the Hasura metadata - -```bash title="Run the following from the root of your project:" -ddn connector-link add my_elastic --subgraph my_subgraph -``` - -The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your -subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the -connector. Ensure the port value matches what is published in your connector's docker compose file. - -```env title="my_subgraph/.env.my_subgraph" -MY_SUBGRAPH_MY_ELASTIC_READ_URL=http://local.hasura.dev:8081 -MY_SUBGRAPH_MY_ELASTIC_WRITE_URL=http://local.hasura.dev:8081 -``` - -### 5. Start the connector's docker compose - -Let's start our connector's docker compose file. - -```bash title="Run the following from the connector's subdirectory inside a subgraph:" -docker compose -f docker-compose.my_elastic.yaml up -``` - -This starts our PostgreSQL connector on the specified port. We can navigate to the following address, with the port -modified, to see the schema of our Elasticsearch data source: +### Step 1: Authenticate your CLI session ```bash -http://localhost:8081/schema +ddn auth login ``` -### 6. Include the connector in your docker compose +### Step 2: Configure the connector -Kill the connector by pressing `CTRL+C` in the terminal tab in which the connector is running. +Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while +providing a name for the connector in the prompt: -Then, add the following inclusion to the docker compose in your project's root directory, taking care to modify the -subgraph's name. - -```yaml title="docker-compose.hasura.yaml" -include: - - path: my_subgraph/connector/my_elastic/docker-compose.my_elastic.yaml +```bash +ddn connector init -i ``` -Now, whenever running the following, you'll bring up the GraphQL engine, observability tools, and any connectors you've -included: +#### Step 2.1: Choose `hasura/elasticsearch` from the list -```bash title="From the root of your project, run:" -HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yaml watch -``` +#### Step 2.2: Choose a port for the connector -### 7. Update the new DataConnectorLink object +The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the +default suggested port. -Finally, now that our `DataConnectorLink` has the correct environment variables configured for the Elasticsearch connector, -we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's -schema in `hml` format. In a new terminal tab, run: - -```bash title="From the root of your project, run:" -ddn connector-link update my_elastic --subgraph my_subgraph -``` +#### Step 2.3: Provide the env vars required for the connector -After this command runs, you can open your `my_subgraph/metadata/my_elastic.hml` file and see your metadata completely -scaffolded out for you 🎉 +To configure the connector, the following environment variables need to be set: -### 8. Import _all_ your indices +| Environment Variable | Description | Required | Example Value | +| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------- | +| `ELASTICSEARCH_URL` | The comma-separated list of Elasticsearch host addresses for connection (Use `local.hasura.dev` instead of `localhost` if your connector is running on your local machine) | Yes | `https://example.es.gcp.cloud.es.io:9200` | +| `ELASTICSEARCH_USERNAME` | The username for authenticating to the Elasticsearch cluster | Yes | `admin` | +| `ELASTICSEARCH_PASSWORD` | The password for the Elasticsearch user account | Yes | `default` | +| `ELASTICSEARCH_API_KEY` | The Elasticsearch API key for authenticating to the Elasticsearch cluster | No | `ABCzYWk0NEI0aDRxxxxxxxxxx1k6LWVQa2gxMUpRTUstbjNwTFIzbGoyUQ==` | +| `ELASTICSEARCH_CA_CERT_PATH` | The path to the Certificate Authority (CA) certificate for verifying the Elasticsearch server's SSL certificate | No | `/etc/connector/cacert.pem` | +| `ELASTICSEARCH_INDEX_PATTERN` | The pattern for matching Elasticsearch indices, potentially including wildcards, used by the connector | No | `hasura*` | -You can do this in one convenience command. +## Step 3: Introspect the connector -```bash title="From the root of your project, run:" -ddn connector-link update my_elastic --subgraph my_subgraph --add-all-resources +```bash +ddn connector introspect ``` -### 9. Create a supergraph build +This will generate a `configuration.json` file that will have the schema of your Elasticsearch DB. -Pass the `local` subcommand along with specifying the output directory as `./engine` in the root of the project. This -directory is used by the docker-compose file to serve the engine locally: +## Step 4: Add your resources -```bash title="From the root of your project, run:" -ddn supergraph build local --output-dir ./engine +```bash +ddn connector-link add-resources ``` -You can now navigate to -[`https://console.hasura.io/local/graphql?url=http://localhost:3000`](https://console.hasura.io/local/graphql?url=http://localhost:3000) -and interact with your API using the Hasura Console. - +This command will track all the indices in your Elasticsearch DB as [Models](https://hasura.io/docs/3.0/supergraph-modeling/models). ## Contributing -Check out our [contributing guide](./docs/contributing.md) for more details. +Check out our [contributing guide](https://github.com/hasura/ndc-elasticsearch/blob/main/docs/contributing.md) for more details. ## License From df29dc35e1a9eac25f7bf23a73096f0f1fc24a05 Mon Sep 17 00:00:00 2001 From: Akshaya Acharya Date: Mon, 26 Aug 2024 10:33:37 +0530 Subject: [PATCH 065/135] RFC: Add documentationPage to packaging spec (#260) Add `documentationPage` to the packaging spec to link to connector specific getting started instructions to be shown by the CLI post running `ddn connector init` Example: ```yaml documentationPage: "https://hasura.io/docs/3.0/getting-started/build/add-business-logic?db=TypeScript" ``` [Rendered](https://github.com/hasura/ndc-hub/blob/ak/docs-page-packaging-spec/rfcs/0007-packaging-documentation-page.md) --------- Co-authored-by: Daniel Chambers --- rfcs/0007-packaging-documentation-page.md | 101 ++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 rfcs/0007-packaging-documentation-page.md diff --git a/rfcs/0007-packaging-documentation-page.md b/rfcs/0007-packaging-documentation-page.md new file mode 100644 index 00000000..c748e739 --- /dev/null +++ b/rfcs/0007-packaging-documentation-page.md @@ -0,0 +1,101 @@ +# RFC: add documentation page to packaging spec + +> [!NOTE] +> This RFC builds upon the concepts defined in [Native Connector Packaging](./0004-native-packaging.md) + +Connectors that run in the native environment such as typescript have a different getting started workflow for local development compared to connectors that run in docker such as postgres. + +Users expect the same steps that they tried with one connector to work with another. + +The CLI wishes to link users to the docs page for a specific connector on running `ddn connector init` so that users have clear directions to next steps. + +## Solution + +Extend the packaging spec definition to include `documentationPage` which points to a connector-specific getting started page. The primary use for this is for the CLI to link to getting started instructions after the user adds the connector to their project. + +This should NOT point to the homepage or repository page for the connector, unless that page also contains getting started instructions. This should NOT point to any other reference pages aside from getting started instructions. + +The page may be hosted on the Hasura docs, on Hasura hub, or on the repository. Hasura connector authors are encouraged to point to Hasura docs as this serves as the primary channel through which users are otherwise onboarded to ddn. + +It is highly recommended that you create a redirection URL to the actual page you want to use (for example, creating https://hasura.info/nodejs-getting-started that redirects to https://hasura.io/docs/3.0/getting-started/build/add-business-logic/?db=TypeScript). This will enable you to update the target of the redirection URL in the future if the documentation ever moves. + +**connector-metadata.yaml** + +```yaml +documentationPage: "https://hasura.info/nodejs-getting-started" +``` + + +## `connector-metadata.yaml` types + +```typescript +type ConnectorMetadataDefinition = { + packagingDefinition: PackagingDefinition + nativeToolchainDefinition?: NativeToolchainDefinition + supportedEnvironmentVariables: EnvironmentVariableDefinition[] + commands: Commands + cliPlugin?: CliPluginDefinition + dockerComposeWatch: DockerComposeWatch + documentationPage: string // NEW +} + +type PackagingDefinition = PrebuiltDockerImagePackaging | ManagedDockerBuildPackaging + +type PrebuiltDockerImagePackaging = { + type: "PrebuiltDockerImage" + dockerImage: string +} + +type ManagedDockerBuildPackaging = { + type: "ManagedDockerBuild" +} + +type NativeToolchainDefinition = { + commands: NativeToolchainCommands +} + +type NativeToolchainCommands = { + start: string | DockerizedCommand | ShellScriptCommand // Compulsory + update?: string | DockerizedCommand | ShellScriptCommand + watch: string | DockerizedCommand | ShellScriptCommand // Compulsory +} + +type EnvironmentVariableDefinition = { + name: string + description: string + defaultValue?: string +} + +type Commands = { + update?: string | DockerizedCommand | ShellScriptCommand + watch?: string | DockerizedCommand | ShellScriptCommand +} + +// From https://github.com/hasura/ndc-hub/pull/129 (outside of this RFC) +type DockerizedCommand = { + type: "Dockerized" + dockerImage: string + commandArgs: string[] +} + +type ShellScriptCommand = { + type: "ShellScript" + bash: string + powershell: string +} + +type CliPluginDefinition = { + name: string + version: string +} + +// From: https://github.com/compose-spec/compose-spec/blob/1938efd103f8e0817ca90e5f15177ec0317bbaf8/schema/compose-spec.json#L455 +type DockerComposeWatch = DockerComposeWatchItem[] + +type DockerComposeWatchItem = { + path: string + action: "rebuild" | "sync" | "sync+restart" + target?: string + ignore?: string[] +} +``` \ No newline at end of file From cadddd73fcf0802bfafb66d35c78159459f0d04c Mon Sep 17 00:00:00 2001 From: Daniel Chambers Date: Wed, 28 Aug 2024 10:29:10 +1000 Subject: [PATCH 066/135] Split NodeJS Lambda Connector packages into the new releases structure and add new v1.7.0 (#267) --- registry/hasura/nodejs/metadata.json | 97 ++----------------- .../releases/v1.0.0/connector-packaging.json | 11 +++ .../releases/v1.1.0/connector-packaging.json | 11 +++ .../releases/v1.2.0/connector-packaging.json | 11 +++ .../releases/v1.3.0/connector-packaging.json | 11 +++ .../releases/v1.4.0/connector-packaging.json | 11 +++ .../releases/v1.4.1/connector-packaging.json | 11 +++ .../releases/v1.5.0/connector-packaging.json | 11 +++ .../releases/v1.6.0/connector-packaging.json | 11 +++ .../releases/v1.7.0/connector-packaging.json | 11 +++ 10 files changed, 105 insertions(+), 91 deletions(-) create mode 100644 registry/hasura/nodejs/releases/v1.0.0/connector-packaging.json create mode 100644 registry/hasura/nodejs/releases/v1.1.0/connector-packaging.json create mode 100644 registry/hasura/nodejs/releases/v1.2.0/connector-packaging.json create mode 100644 registry/hasura/nodejs/releases/v1.3.0/connector-packaging.json create mode 100644 registry/hasura/nodejs/releases/v1.4.0/connector-packaging.json create mode 100644 registry/hasura/nodejs/releases/v1.4.1/connector-packaging.json create mode 100644 registry/hasura/nodejs/releases/v1.5.0/connector-packaging.json create mode 100644 registry/hasura/nodejs/releases/v1.6.0/connector-packaging.json create mode 100644 registry/hasura/nodejs/releases/v1.7.0/connector-packaging.json diff --git a/registry/hasura/nodejs/metadata.json b/registry/hasura/nodejs/metadata.json index d5bb15a6..e029c2cb 100644 --- a/registry/hasura/nodejs/metadata.json +++ b/registry/hasura/nodejs/metadata.json @@ -5,7 +5,7 @@ "title": "NodeJS Lambda Connector", "logo": "logo.png", "tags": [], - "latest_version": "v1.6.0" + "latest_version": "v1.7.0" }, "author": { "support_email": "support@hasura.io", @@ -14,100 +14,15 @@ }, "is_verified": true, "is_hosted_by_hasura": false, - "packages": [ - { - "version": "1.6.0", - "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.6.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "f69645af8190a93484a8c374830c788035ebf91135e53f57e214b04fe69475e7" - }, - "source": { - "hash": "2fb76722db449b5525d1dcce33cf48ee0cf44ad8" - } - }, - { - "version": "1.5.0", - "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.5.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "d89466e19ad8aeb94bff9e34623f075fee1cb955d5e8ae5ed316df38f1b400c6" - }, - "source": { - "hash": "2a9a04d0a1c8116d9b864a83d81817ccddae355d" - } - }, - { - "version": "1.4.1", - "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.4.1/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "18c7be3cbf6fd507233577729df248852ead22a7f4b29e0b8538cc74925c83c0" - }, - "source": { - "hash": "9b5f795aca98854205ba5646162d1df7f060d642" - } - }, - { - "version": "1.4.0", - "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.4.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "f0ea6693f5a37159882695f5cb330359e7124bf9e08ac81363ed065790200077" - }, - "source": { - "hash": "53ae3870e4f332310a7b6e359188371aa16714cf" - } - }, - { - "version": "1.3.0", - "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.3.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "29c521170a74b3cf67bff824c293af15d683651b7727d5884423fcfd2ac44777" - }, - "source": { - "hash": "faf8cc78db442e53ca0cf6cdf79c9feb0cfc8052" - } - }, - { - "version": "1.2.0", - "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.2.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "fd8bd48a32226894ad617d7b60c60b2966ab942dccd6e92823ef0d87d847350e" - }, - "source": { - "hash": "a13236051b836e4506463ff8c7e152f69c787680" - } - }, - { - "version": "1.1.0", - "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.1.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "22a80de2739d7aaaea55dbc8c9d668dcfd0919eedc4f611b171de65db7548d03" - }, - "source": { - "hash": "32e33529d5cfc5c1dbc4245e384f22099654d02d" - } - }, - { - "version": "1.0.0", - "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.0.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "8b24669349ab79b0222268d11b4a3396c5caced4764192fb5b49ccde2bfc6e34" - }, - "source": { - "hash": "c7ef1aa899e1f83cc2935c2f91f4b9010411d716" - } - } - ], "source_code": { "is_open_source": true, "repository": "https://github.com/hasura/ndc-nodejs-lambda/", "version": [ + { + "tag": "v1.7.0", + "hash": "1adf00b7c36dd811d5e15894c1a141149db6325f", + "is_verified": true + }, { "tag": "v1.6.0", "hash": "2fb76722db449b5525d1dcce33cf48ee0cf44ad8", diff --git a/registry/hasura/nodejs/releases/v1.0.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.0.0/connector-packaging.json new file mode 100644 index 00000000..c8428361 --- /dev/null +++ b/registry/hasura/nodejs/releases/v1.0.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.0", + "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.0.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "8b24669349ab79b0222268d11b4a3396c5caced4764192fb5b49ccde2bfc6e34" + }, + "source": { + "hash": "c7ef1aa899e1f83cc2935c2f91f4b9010411d716" + } +} diff --git a/registry/hasura/nodejs/releases/v1.1.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.1.0/connector-packaging.json new file mode 100644 index 00000000..96db88f4 --- /dev/null +++ b/registry/hasura/nodejs/releases/v1.1.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.1.0", + "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "22a80de2739d7aaaea55dbc8c9d668dcfd0919eedc4f611b171de65db7548d03" + }, + "source": { + "hash": "32e33529d5cfc5c1dbc4245e384f22099654d02d" + } +} diff --git a/registry/hasura/nodejs/releases/v1.2.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.2.0/connector-packaging.json new file mode 100644 index 00000000..2e946362 --- /dev/null +++ b/registry/hasura/nodejs/releases/v1.2.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.2.0", + "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.2.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "fd8bd48a32226894ad617d7b60c60b2966ab942dccd6e92823ef0d87d847350e" + }, + "source": { + "hash": "a13236051b836e4506463ff8c7e152f69c787680" + } +} diff --git a/registry/hasura/nodejs/releases/v1.3.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.3.0/connector-packaging.json new file mode 100644 index 00000000..4ec46b4d --- /dev/null +++ b/registry/hasura/nodejs/releases/v1.3.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.3.0", + "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.3.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "29c521170a74b3cf67bff824c293af15d683651b7727d5884423fcfd2ac44777" + }, + "source": { + "hash": "faf8cc78db442e53ca0cf6cdf79c9feb0cfc8052" + } +} diff --git a/registry/hasura/nodejs/releases/v1.4.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.4.0/connector-packaging.json new file mode 100644 index 00000000..9a4923fd --- /dev/null +++ b/registry/hasura/nodejs/releases/v1.4.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.4.0", + "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.4.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "f0ea6693f5a37159882695f5cb330359e7124bf9e08ac81363ed065790200077" + }, + "source": { + "hash": "53ae3870e4f332310a7b6e359188371aa16714cf" + } +} diff --git a/registry/hasura/nodejs/releases/v1.4.1/connector-packaging.json b/registry/hasura/nodejs/releases/v1.4.1/connector-packaging.json new file mode 100644 index 00000000..e39a6ebd --- /dev/null +++ b/registry/hasura/nodejs/releases/v1.4.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.4.1", + "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.4.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "18c7be3cbf6fd507233577729df248852ead22a7f4b29e0b8538cc74925c83c0" + }, + "source": { + "hash": "9b5f795aca98854205ba5646162d1df7f060d642" + } +} diff --git a/registry/hasura/nodejs/releases/v1.5.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.5.0/connector-packaging.json new file mode 100644 index 00000000..00e593dc --- /dev/null +++ b/registry/hasura/nodejs/releases/v1.5.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.5.0", + "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.5.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "d89466e19ad8aeb94bff9e34623f075fee1cb955d5e8ae5ed316df38f1b400c6" + }, + "source": { + "hash": "2a9a04d0a1c8116d9b864a83d81817ccddae355d" + } +} diff --git a/registry/hasura/nodejs/releases/v1.6.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.6.0/connector-packaging.json new file mode 100644 index 00000000..cc6c7616 --- /dev/null +++ b/registry/hasura/nodejs/releases/v1.6.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.6.0", + "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.6.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "f69645af8190a93484a8c374830c788035ebf91135e53f57e214b04fe69475e7" + }, + "source": { + "hash": "2fb76722db449b5525d1dcce33cf48ee0cf44ad8" + } +} diff --git a/registry/hasura/nodejs/releases/v1.7.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.7.0/connector-packaging.json new file mode 100644 index 00000000..77926b29 --- /dev/null +++ b/registry/hasura/nodejs/releases/v1.7.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.7.0", + "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.7.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "3d3a7f5595751ed1fabb9ce493454fce55f8410fca4f1632dd30605155426327" + }, + "source": { + "hash": "1adf00b7c36dd811d5e15894c1a141149db6325f" + } +} From 97106008b0644697946a26522b78cbeda8c061d6 Mon Sep 17 00:00:00 2001 From: Varun Dey Date: Fri, 30 Aug 2024 14:50:14 +0530 Subject: [PATCH 067/135] RFC: Connector plugin to output NDC schema (#212) [Rendered](https://github.com/hasura/ndc-hub/blob/print-schema-capabilities-rfc/rfcs/006-print-schema-capabilities.md) --- rfcs/008-print-schema-and-capabilities.md | 122 ++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 rfcs/008-print-schema-and-capabilities.md diff --git a/rfcs/008-print-schema-and-capabilities.md b/rfcs/008-print-schema-and-capabilities.md new file mode 100644 index 00000000..11eecc9b --- /dev/null +++ b/rfcs/008-print-schema-and-capabilities.md @@ -0,0 +1,122 @@ +# RFC: `printSchemaAndCapabilities` command for all connectors + +Currently, the only way to get complete connector schema for CLI is to call `/schema` and `/capabilities` endpoints on a running NDC connector instance. In case of local connector build, CLI builds and runs the respective NDC connector in a docker container and calls the `/schema` and `/capabilities` endpoints on it. This is required by the CLI to build the DataConnectorLink which can then be used by the engine to query the underlying data source. The new local CLI workflow is aimed at reducing the number of steps to get a working API. In this workflow users should be able to update the DataConnectorLink without any dependency. + +This RFC proposes to add a new command `printSchemaAndCapabilities` to the connector plugin which prints out entire NDC schema and Connector capabilities of the underlying data source to STDOUT. CLI can then call the plugin with relevant command to get the schema and construct DataConnectorLink from the output. All connector plugins are expected to have this command going forward. DDN CLI will use this to generate NDC schema if this command is present. In case, the command is not implemented on plugin (in older versions of connectors), CLI will rely on running the connector in docker to get the schema. + +## Changes to the packaging spec +There is a new command `printSchemaAndCapabilities` in the `commands` section: + +```diff +packagingDefinition: + type: ManagedDockerBuild/PrebuiltDockerImage +supportedEnvironmentVariables: [...] +commands: + update: hasura-ndc-plugin update ++ printSchemaAndCapabilities: hasura-ndc-plugin print-schema-and-capabilities +... +``` + +This will output a JSON to STDOUT which will contain `schema` and `capabilities` as objects +```shell +{ + "schema": { + "scalar_types": {}, + "object_types": {}, + "collections": [], + "functions": [], + "procedures": [] + }, + "capabilities": { + "version": "", + "capabilities": { + "query": {}, + "mutation": {}, + "relationships": {} + } + } +} +``` + +The runtime behavior is the same as the other commands like `update`. CLI will set all the env vars required by the connector plugin (like `HASURA_DDN_CONNECTOR_CONTEXT_PATH`, `CONNECTION_URI`(for postgres connector), etc.) and call this command. + +The equivalent plugin invocation can be done from DDN CLI as below: +```shell +ddn connector plugin --connector ./connector.yaml -- print-schema-and-capabilities + +// Prints JSON containing schema and capabilities to STDOUT +``` + +## `connector-metadata.yaml` types + +```diff +type ConnectorMetadataDefinition = { + packagingDefinition: PackagingDefinition + nativeToolchainDefinition?: NativeToolchainDefinition + supportedEnvironmentVariables: EnvironmentVariableDefinition[] + commands: Commands + cliPlugin?: CliPluginDefinition + dockerComposeWatch: DockerComposeWatch +} + +type PackagingDefinition = PrebuiltDockerImagePackaging | ManagedDockerBuildPackaging + +type PrebuiltDockerImagePackaging = { + type: "PrebuiltDockerImage" + dockerImage: string +} + +type ManagedDockerBuildPackaging = { + type: "ManagedDockerBuild" +} + +type NativeToolchainDefinition = { + commands: NativeToolchainCommands +} + + +type NativeToolchainCommands = { + start: string | DockerizedCommand | ShellScriptCommand + update?: string | DockerizedCommand | ShellScriptCommand + watch: string | DockerizedCommand | ShellScriptCommand +} + +type EnvironmentVariableDefinition = { + name: string + description: string + defaultValue?: string +} + +type Commands = { + update?: string | DockerizedCommand | ShellScriptCommand + watch?: string | DockerizedCommand | ShellScriptCommand ++ printSchemaAndCapabilities?: string | DockerizedCommand | ShellScriptCommand +} + + +type DockerizedCommand = { + type: "Dockerized" + dockerImage: string + commandArgs: string[] +} + +type ShellScriptCommand = { + type: "ShellScript" + bash: string + powershell: string +} + +type CliPluginDefinition = { + name: string + version: string +} + +type DockerComposeWatch = DockerComposeWatchItem[] + +type DockerComposeWatchItem = { + path: string + action: "rebuild" | "sync" | "sync+restart" + target?: string + ignore?: string[] +} +``` From 82d6195ebfe2f1b17c8f0f697c4cc7816d3b26cd Mon Sep 17 00:00:00 2001 From: Tristen Harr Date: Fri, 30 Aug 2024 11:21:10 -0500 Subject: [PATCH 068/135] Update turso connector to v0.1.0 (#261) This PR updates the turso connector metadata to version 0.1.0. --------- Co-authored-by: GitHub Action --- registry/hasura/turso/README.md | 123 ++++++------------ registry/hasura/turso/metadata.json | 20 +-- .../releases/v0.0.15/connector-packaging.json | 12 ++ .../releases/v0.1.0/connector-packaging.json | 11 ++ 4 files changed, 71 insertions(+), 95 deletions(-) create mode 100644 registry/hasura/turso/releases/v0.0.15/connector-packaging.json create mode 100644 registry/hasura/turso/releases/v0.1.0/connector-packaging.json diff --git a/registry/hasura/turso/README.md b/registry/hasura/turso/README.md index 389bbe79..c82b38e5 100644 --- a/registry/hasura/turso/README.md +++ b/registry/hasura/turso/README.md @@ -1,6 +1,7 @@ # Hasura Turso Connector + [![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/connectors/turso) [![ndc-hub](https://img.shields.io/badge/ndc--hub-turso-blue.svg?style=flat)](https://hasura.io/connectors/turso) [![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](https://github.com/hasura/ndc-turso/blob/main/LICENSE.txt) @@ -10,8 +11,8 @@ The Hasura Turso Connector allows for connecting to a LibSQL/SQLite database or This connector is built using the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). -* [Connector information in the Hasura Hub](https://hasura.io/connectors/turso) -* [Hasura V3 Documentation](https://hasura.io/docs/3.0/index/) +- [See the listing in the Hasura Hub](https://hasura.io/connectors/turso) +- [Hasura V3 Documentation](https://hasura.io/docs/3.0/index/) ## Features @@ -34,8 +35,6 @@ Below, you'll find a matrix of all supported features for the Turso connector: ## Before you get Started -[Prerequisites or recommended steps before using the connector.] - 1. The [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed 2. A [supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) 3. A [subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) @@ -52,114 +51,76 @@ connector — after it's been configured — [here](https://hasura.io/docs/3.0/g ddn auth login ``` -### Step 2: Initialize the connector +### Step 2: Configure the connector + +Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while providing a name for the connector in the prompt: ```bash -ddn connector init turso --subgraph my_subgraph --hub-connector hasura/turso +ddn connector init turso -i ``` -In the snippet above, we've used the subgraph `my_subgraph` as an example; however, you should change this -value to match any subgraph which you've created in your project. +#### Step 2.1: Choose the `hasura/turso` option from the list -### Step 3: Modify the connector's port +#### Step 2.2: Choose a port for the connector -When you initialized your connector, the CLI generated a set of configuration files, including a Docker Compose file for -the connector. Typically, connectors default to port `8080`. Each time you add a connector, we recommend incrementing the published port by one to avoid port collisions. - -As an example, if your connector's configuration is in `my_subgraph/connector/turso/docker-compose.turso.yaml`, you can modify the published port to reflect a value that isn't currently being used by any other connectors: - -```yaml -ports: - - mode: ingress - target: 8080 - published: "8082" - protocol: tcp -``` +The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the default suggested port. -### Step 4: Add environment variables +#### Step 2.3: Provide the env var(s) for the connector -Now that our connector has been scaffolded out for us, we need to provide a connection string so that the data source can be introspected and the boilerplate configuration can be taken care of by the CLI. +| Name | Description | +|-|-| +| TURSO_URL | The connection string for the Turso database, or the file path to the SQLite file | +| TURSO_AUTH_TOKEN | The turso auth token | -The CLI has provided an `.env.local` file for our connector in the `my_subgraph/connector/turso` directory. We can add a key-value pair -of `TURSO_URL` along with the connection string itself to this file, and our connector will use this to connect to our database. If you are connecting to a cloud hosted Turso database you can also provide the environment variable for the `TURSO_AUTH_TOKEN` which allows the connector to authenticate. +You'll find the environment variables in the `.env` file and they will be in the format: +`__` -The file, after adding the `TURSO_URL`, should look like this example if connecting to a Turso hosted database instance: +Here is an example of what your `.env` file might look like: -```env -OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 -OTEL_SERVICE_NAME=my_subgraph_turso -TURSO_URL=libsql://chinook-tristenharr.turso.io -TURSO_AUTH_TOKEN=eyJhb... ``` - -To connect to a local SQLite file, you can add the persistent SQLite database file into the `my_subgraph/connector/turso` directory, and since all files in this directory will get mounted to the container at `/etc/connector/` you can then point the `TURSO_URL` to the local file. Assuming that the Turso file was named `chinook.sqlite` the file should look like this example: - -```env -OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 -OTEL_SERVICE_NAME=my_subgraph_turso -TURSO_URL=file:/etc/connector/chinook.sqlite +APP_TURSO_AUTHORIZATION_HEADER="Bearer QTJ7rl19SvKa0rwOZjYILQ==" +APP_TURSO_HASURA_SERVICE_TOKEN_SECRET="QTJ7rl19SvKa0rwOZjYILQ==" +APP_TURSO_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://local.hasura.dev:4317" +APP_TURSO_OTEL_SERVICE_NAME="app_turso" +APP_TURSO_READ_URL="http://local.hasura.dev:4362" +APP_TURSO_TURSO_AUTH_TOKEN="eyJ..." +APP_TURSO_TURSO_URL="libsql://chinook-tristenharr.turso.io" +APP_TURSO_WRITE_URL="http://local.hasura.dev:4362" ``` -### Step 5: Introspect your data source +If you are attaching to a local SQLite file, first make sure that the file is located inside the connector directory. For example, if you had a `data.sqlite` file you could place it at `/app/connector/turso/data.sqlite`. Files in the connector directory get mounted to `/etc/connector/`. -With the connector configured, we can now use the CLI to introspect our database and create a source-specific configuration file for our connector. +In this instance, you would set the `TURSO_URL=/etc/connector/data.sqlite` and leave the `TURSO_AUTH_TOKEN` as blank/null. Now your `.env` might look like this: -```bash -ddn connector introspect --connector my_subgraph/connector/turso/connector.yaml ``` - -### Step 6. Create the Hasura metadata - -Hasura DDN uses a concept called "connector linking" to take [NDC-compliant](https://github.com/hasura/ndc-spec) -configuration JSON files for a data connector and transform them into an `hml` (Hasura Metadata Language) file as a -[`DataConnectorLink` metadata object](https://hasura.io/docs/3.0/supergraph-modeling/data-connectors#dataconnectorlink-dataconnectorlink). - -Basically, metadata objects in `hml` files define our API. - -First we need to create this `hml` file with the `connector-link add` command and then convert our configuration files -into `hml` syntax and add it to this file with the `connector-link update` command. - -Let's name the `hml` file the same as our connector, `turso`: - -```bash -ddn connector-link add turso --subgraph my_subgraph +APP_TURSO_AUTHORIZATION_HEADER="Bearer QTJ7rl19SvKa0rwOZjYILQ==" +APP_TURSO_HASURA_SERVICE_TOKEN_SECRET="QTJ7rl19SvKa0rwOZjYILQ==" +APP_TURSO_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://local.hasura.dev:4317" +APP_TURSO_OTEL_SERVICE_NAME="app_turso" +APP_TURSO_READ_URL="http://local.hasura.dev:4362" +APP_TURSO_TURSO_URL="/etc/connector/data.sqlite" +APP_TURSO_WRITE_URL="http://local.hasura.dev:4362" ``` -The new file is scaffolded out at `my_subgraph/metadata/turso/turso.hml`. - -### Step 7. Update the environment variables +Your experience mounting files may vary, and while useful to explore a file locally, it's not recommended to attempt to deploy a connector using a locally mounted file. -The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the connector. Ensure the port value matches what is published in your connector's docker compose file. +### Step 3: Introspect the connector -As an example: - -```env -MY_SUBGRAPH_TURSO_READ_URL=http://local.hasura.dev: -MY_SUBGRAPH_TURSO_WRITE_URL=http://local.hasura.dev: -``` - -These values are for the connector itself and utilize `local.hasura.dev` to ensure proper resolution within the docker container. - -### Step 8. Start the connector's Docker Compose - -Let's start our connector's Docker Compose file by running the following from inside the connector's subgraph: +Introspecting the connector will generate a `config.json` file and a `turso.hml` file. ```bash -docker compose -f docker-compose.turso.yaml up +ddn connector introspect turso ``` -### Step 9. Update the new `DataConnectorLink` object +### Step 4: Add your resources -Finally, now that our `DataConnectorLink` has the correct environment variables configured for the connector, we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's schema in `hml` format. In a new terminal tab, run: +You can add the models, commands, and relationships to your API by tracking them which generates the HML files. ```bash -ddn connector-link update turso --subgraph my_subgraph +ddn connector-link add-resources turso ``` -After this command runs, you can open your `my_subgraph/metadata/turso.hml` file and see your metadata completely -scaffolded out for you 🎉 - ## Documentation View the full documentation for the Turso connector [here](https://github.com/hasura/ndc-turso/blob/main/docs/index.md). diff --git a/registry/hasura/turso/metadata.json b/registry/hasura/turso/metadata.json index 8562d6e7..9e0072b0 100644 --- a/registry/hasura/turso/metadata.json +++ b/registry/hasura/turso/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.0.15" + "latest_version": "v0.1.0" }, "author": { "support_email": "support@hasura.io", @@ -16,19 +16,6 @@ }, "is_verified": false, "is_hosted_by_hasura": true, - "packages": [ - { - "version": "0.0.15", - "uri": "https://github.com/hasura/ndc-turso/releases/download/v0.0.15/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "a2c8426c443bf8c94b0f706d8438bd06eeeef30c0d2b40389c0e37be4be920a6" - }, - "source": { - "hash": "6bae967daf7b9aa718d62103e077a739c41d5a6d" - } - } - ], "source_code": { "is_open_source": true, "repository": "https://github.com/hasura/ndc-turso", @@ -37,6 +24,11 @@ "tag": "v0.0.15", "hash": "6bae967daf7b9aa718d62103e077a739c41d5a6d", "is_verified": false + }, + { + "tag": "v0.1.0", + "hash": "ef4b124ea384a13f3d051e30ce33623fcc6847c5", + "is_verified": false } ] } diff --git a/registry/hasura/turso/releases/v0.0.15/connector-packaging.json b/registry/hasura/turso/releases/v0.0.15/connector-packaging.json new file mode 100644 index 00000000..74e749a8 --- /dev/null +++ b/registry/hasura/turso/releases/v0.0.15/connector-packaging.json @@ -0,0 +1,12 @@ +{ + "version": "0.0.15", + "uri": "https://github.com/hasura/ndc-turso/releases/download/v0.0.15/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "a2c8426c443bf8c94b0f706d8438bd06eeeef30c0d2b40389c0e37be4be920a6" + }, + "source": { + "hash": "6bae967daf7b9aa718d62103e077a739c41d5a6d" + } + } + \ No newline at end of file diff --git a/registry/hasura/turso/releases/v0.1.0/connector-packaging.json b/registry/hasura/turso/releases/v0.1.0/connector-packaging.json new file mode 100644 index 00000000..969af0c3 --- /dev/null +++ b/registry/hasura/turso/releases/v0.1.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-turso/releases/download/v0.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "b884688c3e328b181af19a23c01cfb5615267469af3c2517dd46b2d21b0e579d" + }, + "source": { + "hash": "ef4b124ea384a13f3d051e30ce33623fcc6847c5" + } +} From a76f5fff590244babd2ca0f9503d70fc3c9b2a02 Mon Sep 17 00:00:00 2001 From: Tristen Harr Date: Fri, 30 Aug 2024 11:21:28 -0500 Subject: [PATCH 069/135] Update qdrant connector to v0.3.0 (#263) This PR updates the qdrant connector metadata to version 0.3.0. --------- Co-authored-by: GitHub Action --- registry/hasura/qdrant/README.md | 117 +++++------------- registry/hasura/qdrant/metadata.json | 72 +++++------ .../releases/v0.2.1/connector-packaging.json | 12 ++ .../releases/v0.3.0/connector-packaging.json | 11 ++ 4 files changed, 88 insertions(+), 124 deletions(-) create mode 100644 registry/hasura/qdrant/releases/v0.2.1/connector-packaging.json create mode 100644 registry/hasura/qdrant/releases/v0.3.0/connector-packaging.json diff --git a/registry/hasura/qdrant/README.md b/registry/hasura/qdrant/README.md index 98138040..02fa25cc 100644 --- a/registry/hasura/qdrant/README.md +++ b/registry/hasura/qdrant/README.md @@ -10,8 +10,8 @@ The Hasura Qdrant Connector allows for connecting to a Qdrant database to give y This connector is built using the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). -* [Connector information in the Hasura Hub](https://hasura.io/connectors/qdrant) -* [Hasura V3 Documentation](https://hasura.io/docs/3.0/index/) +- [See the listing in the Hasura Hub](https://hasura.io/connectors/qdrant) +- [Hasura V3 Documentation](https://hasura.io/docs/3.0/index/) ## Features @@ -52,113 +52,60 @@ connector — after it's been configured — [here](https://hasura.io/docs/3.0/g ddn auth login ``` -### Step 2: Initialize the connector +### Step 2: Configure the connector -```bash -ddn connector init qdrant --subgraph my_subgraph --hub-connector hasura/qdrant -``` - -In the snippet above, we've used the subgraph `my_subgraph` as an example; however, you should change this -value to match any subgraph which you've created in your project. - -### Step 3: Modify the connector's port - -When you initialized your connector, the CLI generated a set of configuration files, including a Docker Compose file for -the connector. Typically, connectors default to port `8080`. Each time you add a connector, we recommend incrementing the published port by one to avoid port collisions. - -As an example, if your connector's configuration is in `my_subgraph/connector/qdrant/docker-compose.qdrant.yaml`, you can modify the published port to reflect a value that isn't currently being used by any other connectors: - -```yaml -ports: - - mode: ingress - target: 8080 - published: "8082" - protocol: tcp -``` - -### Step 4: Add environment variables - -Now that our connector has been scaffolded out for us, we need to provide a connection string so that the data source can be introspected and the boilerplate configuration can be taken care of by the CLI. - -The CLI has provided an `.env.local` file for our connector in the `my_subgraph/connector/qdrant` directory. We can add a key-value pair of `QDRANT_URL` along with the connection string itself to this file, and our connector will use this to connect to our database. If the Qdrant database has an API key you can also provide the environment variable for the `QDRANT_API_KEY` which allows the connector to authenticate. - - -The file, after adding the `QDRANT_URL`, should look like this example if connecting to a Qdrant hosted database instance: - -```env -OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 -OTEL_SERVICE_NAME=my_subgraph_qdrant -QDRANT_URL=https://7312d6c4-3f6c-432c-987c-34d7d96428ef.us-east4-0.gcp.cloud.qdrant.io -QDRANT_API_KEY=Ch8I... -``` - -To connect to a locally running Qdrant instance you can then point the `QDRANT_URL` to the local database. Assuming the Qdrant database is running on port 6333 without any API key, you should be able to use this example: - -```env -OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 -OTEL_SERVICE_NAME=my_subgraph_qdrant -QDRANT_URL=http://local.hasura.dev:6333 -``` - -### Step 5: Introspect your data source - -With the connector configured, we can now use the CLI to introspect our database and create a source-specific configuration file for our connector. +Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while providing a name for the connector in the prompt: ```bash -ddn connector introspect --connector my_subgraph/connector/qdrant/connector.yaml +ddn connector init qdrant -i ``` -### Step 6. Create the Hasura metadata +#### Step 2.1: Choose the `hasura/qdrant` option from the list -Hasura DDN uses a concept called "connector linking" to take [NDC-compliant](https://github.com/hasura/ndc-spec) -configuration JSON files for a data connector and transform them into an `hml` (Hasura Metadata Language) file as a -[`DataConnectorLink` metadata object](https://hasura.io/docs/3.0/supergraph-modeling/data-connectors#dataconnectorlink-dataconnectorlink). +#### Step 2.2: Choose a port for the connector -Basically, metadata objects in `hml` files define our API. +The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the default suggested port. -First we need to create this `hml` file with the `connector-link add` command and then convert our configuration files -into `hml` syntax and add it to this file with the `connector-link update` command. +#### Step 2.3: Provide the env var(s) for the connector -Let's name the `hml` file the same as our connector, `qdrant`: +| Name | Description | +|-|-| +| QDRANT_URL | The connection string for the Qdrant database | +| QDRANT_API_KEY | The Qdrant API Key | -```bash -ddn connector-link add qdrant --subgraph my_subgraph -``` - -The new file is scaffolded out at `my_subgraph/metadata/qdrant/qdrant.hml`. - -### Step 7. Update the environment variables +You'll find the environment variables in the `.env` file and they will be in the format: -The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the connector. Ensure the port value matches what is published in your connector's docker compose file. +`__` -As an example: +Here is an example of what your `.env` file might look like: -```env -MY_SUBGRAPH_QDRANT_READ_URL=http://local.hasura.dev: -MY_SUBGRAPH_QDRANT_WRITE_URL=http://local.hasura.dev: +``` +APP_QDRANT_AUTHORIZATION_HEADER="Bearer B9-PceSL1QrUE_Z1gJNdGQ==" +APP_QDRANT_HASURA_SERVICE_TOKEN_SECRET="B9-PceSL1QrUE_Z1gJNdGQ==" +APP_QDRANT_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://local.hasura.dev:4317" +APP_QDRANT_OTEL_SERVICE_NAME="app_qdrant" +APP_QDRANT_QDRANT_API_KEY="5PX..." +APP_QDRANT_QDRANT_URL="https://2a4ae326-fdef-473e-a13c-7dc07f2f2759.us-east4-0.gcp.cloud.qdrant.io" +APP_QDRANT_READ_URL="http://local.hasura.dev:5963" +APP_QDRANT_WRITE_URL="http://local.hasura.dev:5963" ``` -These values are for the connector itself and utilize `local.hasura.dev` to ensure proper resolution within the docker container. - -### Step 8. Start the connector's Docker Compose +### Step 3: Introspect the connector -Let's start our connector's Docker Compose file by running the following from inside the connector's subgraph: +Introspecting the connector will generate a `config.json` file and a `qdrant.hml` file. ```bash -docker compose -f docker-compose.qdrant.yaml up +ddn connector introspect qdrant ``` -### Step 9. Update the new `DataConnectorLink` object +### Step 4: Add your resources -Finally, now that our `DataConnectorLink` has the correct environment variables configured for the connector, we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's schema in `hml` format. In a new terminal tab, run: +You can add the models, commands, and relationships to your API by tracking them which generates the HML files. ```bash -ddn connector-link update qdrant --subgraph my_subgraph +ddn connector-link add-resources qdrant ``` -After this command runs, you can open your `my_subgraph/metadata/qdrant.hml` file and see your metadata completely -scaffolded out for you 🎉 - ## Documentation View the full documentation for the Qdrant connector [here](https://github.com/hasura/ndc-qdrant/blob/main/docs/index.md). @@ -169,4 +116,4 @@ Check out our [contributing guide](https://github.com/hasura/ndc-qdrant/blob/mai ## License -The Qdrant connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file +The Qdrant connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/registry/hasura/qdrant/metadata.json b/registry/hasura/qdrant/metadata.json index 260ca973..19361494 100644 --- a/registry/hasura/qdrant/metadata.json +++ b/registry/hasura/qdrant/metadata.json @@ -1,41 +1,35 @@ { - "overview":{ - "namespace":"hasura", - "description":"The Qdrant Data Connector allows for connecting to a Qdrant instance giving you an instant GraphQL API on top of your Qdrant Vector Data.", - "title":"Qdrant Data Connector", - "logo":"logo.png", - "tags":["database"], - "latest_version":"v0.2.1" - }, - "author":{ - "support_email":"support@hasura.io", - "homepage":"https://hasura.io", - "name":"Hasura" - }, - "is_verified":false, - "is_hosted_by_hasura":false, - "packages": [ - { - "version": "0.2.1", - "uri": "https://github.com/hasura/ndc-qdrant/releases/download/v0.2.1/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "007cfaa76e45d3df2c2f50e1fdf0d4a3122a48895088958eaa972aee5ce49ac8" - }, - "source": { - "hash": "2effed689bd2f97c9649d1b8f9966533ed1d82a0" - } - } + "overview": { + "namespace": "hasura", + "description": "The Qdrant Data Connector allows for connecting to a Qdrant instance giving you an instant GraphQL API on top of your Qdrant Vector Data.", + "title": "Qdrant Data Connector", + "logo": "logo.png", + "tags": [ + "database" ], - "source_code":{ - "is_open_source":true, - "repository":"https://github.com/hasura/ndc-qdrant", - "version":[ - { - "tag":"v0.2.1", - "hash":"2effed689bd2f97c9649d1b8f9966533ed1d82a0", - "is_verified": false - } - ] - } -} \ No newline at end of file + "latest_version": "v0.3.0" + }, + "author": { + "support_email": "support@hasura.io", + "homepage": "https://hasura.io", + "name": "Hasura" + }, + "is_verified": false, + "is_hosted_by_hasura": false, + "source_code": { + "is_open_source": true, + "repository": "https://github.com/hasura/ndc-qdrant", + "version": [ + { + "tag": "v0.2.1", + "hash": "2effed689bd2f97c9649d1b8f9966533ed1d82a0", + "is_verified": false + }, + { + "tag": "v0.3.0", + "hash": "5eda2128fcbe710741f07a404a6eb69214da2731", + "is_verified": false + } + ] + } +} diff --git a/registry/hasura/qdrant/releases/v0.2.1/connector-packaging.json b/registry/hasura/qdrant/releases/v0.2.1/connector-packaging.json new file mode 100644 index 00000000..dd888aee --- /dev/null +++ b/registry/hasura/qdrant/releases/v0.2.1/connector-packaging.json @@ -0,0 +1,12 @@ +{ + "version": "0.2.1", + "uri": "https://github.com/hasura/ndc-qdrant/releases/download/v0.2.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "007cfaa76e45d3df2c2f50e1fdf0d4a3122a48895088958eaa972aee5ce49ac8" + }, + "source": { + "hash": "2effed689bd2f97c9649d1b8f9966533ed1d82a0" + } + } + \ No newline at end of file diff --git a/registry/hasura/qdrant/releases/v0.3.0/connector-packaging.json b/registry/hasura/qdrant/releases/v0.3.0/connector-packaging.json new file mode 100644 index 00000000..30849afa --- /dev/null +++ b/registry/hasura/qdrant/releases/v0.3.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.3.0", + "uri": "https://github.com/hasura/ndc-qdrant/releases/download/v0.3.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "bc0c8761906430f0309f68ea9e843c543889833471cdcdcfb15414c4d510eaee" + }, + "source": { + "hash": "5eda2128fcbe710741f07a404a6eb69214da2731" + } +} From 882d7be402e3cf22d39315719b736396d990e78a Mon Sep 17 00:00:00 2001 From: Tristen Harr Date: Fri, 30 Aug 2024 11:21:42 -0500 Subject: [PATCH 070/135] Update duckdb connector to v0.1.0 (#262) This PR updates the duckdb connector metadata to version 0.1.0. --------- Co-authored-by: GitHub Action --- registry/hasura/duckdb/README.md | 124 ++++++------------ registry/hasura/duckdb/metadata.json | 72 +++++----- .../releases/v0.0.17/connector-packaging.json | 12 ++ .../releases/v0.1.0/connector-packaging.json | 11 ++ 4 files changed, 94 insertions(+), 125 deletions(-) create mode 100644 registry/hasura/duckdb/releases/v0.0.17/connector-packaging.json create mode 100644 registry/hasura/duckdb/releases/v0.1.0/connector-packaging.json diff --git a/registry/hasura/duckdb/README.md b/registry/hasura/duckdb/README.md index c9c3ddd4..4d1a7347 100644 --- a/registry/hasura/duckdb/README.md +++ b/registry/hasura/duckdb/README.md @@ -10,8 +10,8 @@ The Hasura DuckDB Connector allows for connecting to a DuckDB database or a Moth This connector is built using the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). -* [Connector information in the Hasura Hub](https://hasura.io/connectors/duckdb) -* [Hasura V3 Documentation](https://hasura.io/docs/3.0/index/) +- [See the listing in the Hasura Hub](https://hasura.io/connectors/duckdb) +- [Hasura V3 Documentation](https://hasura.io/docs/3.0/index/) ## Features @@ -34,8 +34,6 @@ Below, you'll find a matrix of all supported features for the DuckDB connector: ## Before you get Started -[Prerequisites or recommended steps before using the connector.] - 1. The [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed 2. A [supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) 3. A [subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) @@ -52,118 +50,74 @@ connector — after it's been configured — [here](https://hasura.io/docs/3.0/g ddn auth login ``` -### Step 2: Initialize the connector +### Step 2: Configure the connector + +Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while providing a name for the connector in the prompt: ```bash -ddn connector init duckdb --subgraph my_subgraph --hub-connector hasura/duckdb +ddn connector init duckdb -i ``` -In the snippet above, we've used the subgraph `my_subgraph` as an example; however, you should change this -value to match any subgraph which you've created in your project. - -### Step 3: Modify the connector's port +#### Step 2.1: Choose the `hasura/duckdb` option from the list -When you initialized your connector, the CLI generated a set of configuration files, including a Docker Compose file for -the connector. Typically, connectors default to port `8080`. Each time you add a connector, we recommend incrementing the published port by one to avoid port collisions. +#### Step 2.2: Choose a port for the connector -As an example, if your connector's configuration is in `my_subgraph/connector/duckdb/docker-compose.duckdb.yaml`, you can modify the published port to -reflect a value that isn't currently being used by any other connectors: +The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the default suggested port. -```yaml -ports: - - mode: ingress - target: 8080 - published: "8082" - protocol: tcp -``` - -### Step 4: Add environment variables +#### Step 2.3: Provide the env var(s) for the connector -Now that our connector has been scaffolded out for us, we need to provide a connection string so that the data source can be introspected and the -boilerplate configuration can be taken care of by the CLI. +| Name | Description | +|-|-| +| DUCKDB_URL | The connection string for the DuckDB database, or the file path to the DuckDB database file | -The CLI has provided an `.env.local` file for our connector in the `my_subgraph/connector/duckdb` directory. We can add a key-value pair -of `DUCKDB_URL` along with the connection string itself to this file, and our connector will use this to connect to our database. +You'll find the environment variables in the `.env` file and they will be in the format: +`__` -The file, after adding the `DUCKDB_URL`, should look like this example if connecting to a MotherDuck hosted DuckDB instance: +Here is an example of what your `.env` file might look like: -```env -OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 -OTEL_SERVICE_NAME=my_subgraph_duckdb -DUCKDB_URL=md:?motherduck_token=eyJhbGc... ``` - -To connect to a local DuckDB file, you can add the persistent DuckDB database file into the `my_subgraph/connector/duckdb` directory, and since all files in this directory will get mounted to the container at `/etc/connector/` you can then point the `DUCKDB_URL` to the local file. Assuming that the duckdb file was named `chinook.db` the file should look like this example: - -```env -OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 -OTEL_SERVICE_NAME=my_subgraph_duckdb -DUCKDB_URL=/etc/connector/chinook.db -``` - -### Step 5: Introspect your data source - -With the connector configured, we can now use the CLI to introspect our database and create a source-specific configuration file for our connector. - -```bash -ddn connector introspect --connector my_subgraph/connector/duckdb/connector.yaml +APP_DUCKDB_AUTHORIZATION_HEADER="Bearer SPHZWfL7P3Jdc9mDMF9ZNA==" +APP_DUCKDB_DUCKDB_URL="md:?motherduck_token=ey..." +APP_DUCKDB_HASURA_SERVICE_TOKEN_SECRET="SPHZWfL7P3Jdc9mDMF9ZNA==" +APP_DUCKDB_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://local.hasura.dev:4317" +APP_DUCKDB_OTEL_SERVICE_NAME="app_duckdb" +APP_DUCKDB_READ_URL="http://local.hasura.dev:7525" +APP_DUCKDB_WRITE_URL="http://local.hasura.dev:7525" ``` -### Step 6. Create the Hasura metadata - -Hasura DDN uses a concept called "connector linking" to take [NDC-compliant](https://github.com/hasura/ndc-spec) -configuration JSON files for a data connector and transform them into an `hml` (Hasura Metadata Language) file as a -[`DataConnectorLink` metadata object](https://hasura.io/docs/3.0/supergraph-modeling/data-connectors#dataconnectorlink-dataconnectorlink). - -Basically, metadata objects in `hml` files define our API. +If you are attaching to a local DuckDB file, first make sure that the file is located inside the connector directory. For example, if you had a `data.duckdb` file you could place it at `/app/connector/duckdb/data.duckdb`. Files in the connector directory get mounted to `/etc/connector/`. -First we need to create this `hml` file with the `connector-link add` command and then convert our configuration files -into `hml` syntax and add it to this file with the `connector-link update` command. +In this instance, you would set the `DUCKDB_URL=/etc/connector/data.duckdb`. Now your `.env` might look like this: -Let's name the `hml` file the same as our connector, `duckdb`: - -```bash -ddn connector-link add duckdb --subgraph my_subgraph ``` - -The new file is scaffolded out at `my_subgraph/metadata/duckdb/duckdb.hml`. - -### Step 7. Update the environment variables - -The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your subgraph's `.env.my_subgraph` file. -Each key is prefixed by the subgraph name, an underscore, and the name of the connector. Ensure the port value matches what is published in your connector's docker compose file. - -As an example: - -```env -MY_SUBGRAPH_DUCKDB_READ_URL=http://local.hasura.dev: -MY_SUBGRAPH_DUCKDB_WRITE_URL=http://local.hasura.dev: +APP_DUCKDB_AUTHORIZATION_HEADER="Bearer SPHZWfL7P3Jdc9mDMF9ZNA==" +APP_DUCKDB_DUCKDB_URL="/etc/connector/data.duckdb" +APP_DUCKDB_HASURA_SERVICE_TOKEN_SECRET="SPHZWfL7P3Jdc9mDMF9ZNA==" +APP_DUCKDB_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://local.hasura.dev:4317" +APP_DUCKDB_OTEL_SERVICE_NAME="app_duckdb" +APP_DUCKDB_READ_URL="http://local.hasura.dev:7525" +APP_DUCKDB_WRITE_URL="http://local.hasura.dev:7525" ``` -These values are for the connector itself and utilize `local.hasura.dev` to ensure proper resolution within the docker container. +Your experience mounting files may vary, and while useful to explore a file locally, it's not recommended to attempt to deploy a connector using a locally mounted file. -### Step 8. Start the connector's Docker Compose +### Step 3: Introspect the connector -Let's start our connector's Docker Compose file by running the following from inside the connector's subgraph: +Introspecting the connector will generate a `config.json` file and a `duckdb.hml` file. ```bash -docker compose -f docker-compose.duckdb.yaml up +ddn connector introspect duckdb ``` -### Step 9. Update the new `DataConnectorLink` object +### Step 4: Add your resources -Finally, now that our `DataConnectorLink` has the correct environment variables configured for the connector, -we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's -schema in `hml` format. In a new terminal tab, run: +You can add the models, commands, and relationships to your API by tracking them which generates the HML files. ```bash -ddn connector-link update duckdb --subgraph my_subgraph +ddn connector-link add-resources duckdb ``` -After this command runs, you can open your `my_subgraph/metadata/duckdb.hml` file and see your metadata completely -scaffolded out for you 🎉 - ## Documentation View the full documentation for the DuckDB connector [here](https://github.com/hasura/ndc-duckdb/blob/main/docs/index.md). diff --git a/registry/hasura/duckdb/metadata.json b/registry/hasura/duckdb/metadata.json index 1d1c9044..ba77c800 100644 --- a/registry/hasura/duckdb/metadata.json +++ b/registry/hasura/duckdb/metadata.json @@ -1,43 +1,35 @@ { - "overview": { - "namespace": "hasura", - "description": "Connect to a DuckDB database and expose them to Hasura v3 Project", - "title": "(MotherDuck) DuckDB Native Data Connector", - "logo": "logo.svg", - "tags": [ - "database" - ], - "latest_version": "v0.0.17" - }, - "author": { - "support_email": "support@hasura.io", - "homepage": "https://hasura.io", - "name": "Hasura" - }, - "is_verified": false, - "is_hosted_by_hasura": true, - "packages": [ + "overview": { + "namespace": "hasura", + "description": "Connect to a DuckDB database and expose them to Hasura v3 Project", + "title": "(MotherDuck) DuckDB Native Data Connector", + "logo": "logo.svg", + "tags": [ + "database" + ], + "latest_version": "v0.1.0" + }, + "author": { + "support_email": "support@hasura.io", + "homepage": "https://hasura.io", + "name": "Hasura" + }, + "is_verified": false, + "is_hosted_by_hasura": true, + "source_code": { + "is_open_source": true, + "repository": "https://github.com/hasura/ndc-duckdb", + "version": [ + { + "tag": "v0.0.17", + "hash": "875c5fb4539febea0e5dad569fd8b64557870c1c", + "is_verified": false + }, { - "version": "0.0.17", - "uri": "https://github.com/hasura/ndc-duckdb/releases/download/v0.0.17/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "3449766fff1794f0866f19505355b37d151d91682e1f784aef664b91abd57570" - }, - "source": { - "hash": "875c5fb4539febea0e5dad569fd8b64557870c1c" - } + "tag": "v0.1.0", + "hash": "580d059cf6250da21e7fdb9bcfc78f6803c626f5", + "is_verified": false } - ], - "source_code": { - "is_open_source": true, - "repository": "https://github.com/hasura/ndc-duckdb", - "version": [ - { - "tag": "v0.0.17", - "hash": "875c5fb4539febea0e5dad569fd8b64557870c1c", - "is_verified": false - } - ] - } - } \ No newline at end of file + ] + } +} diff --git a/registry/hasura/duckdb/releases/v0.0.17/connector-packaging.json b/registry/hasura/duckdb/releases/v0.0.17/connector-packaging.json new file mode 100644 index 00000000..1665ecbf --- /dev/null +++ b/registry/hasura/duckdb/releases/v0.0.17/connector-packaging.json @@ -0,0 +1,12 @@ +{ + "version": "0.0.17", + "uri": "https://github.com/hasura/ndc-duckdb/releases/download/v0.0.17/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "3449766fff1794f0866f19505355b37d151d91682e1f784aef664b91abd57570" + }, + "source": { + "hash": "875c5fb4539febea0e5dad569fd8b64557870c1c" + } + } + \ No newline at end of file diff --git a/registry/hasura/duckdb/releases/v0.1.0/connector-packaging.json b/registry/hasura/duckdb/releases/v0.1.0/connector-packaging.json new file mode 100644 index 00000000..60793934 --- /dev/null +++ b/registry/hasura/duckdb/releases/v0.1.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-duckdb/releases/download/v0.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "fefe1c9bb0299af3eb9a7b8c6219ce8bebb7f8b45f08efc83b091a79eb389378" + }, + "source": { + "hash": "580d059cf6250da21e7fdb9bcfc78f6803c626f5" + } +} From 351a0575ac13a4c694e405e72b28ec45647cb68f Mon Sep 17 00:00:00 2001 From: Tristen Harr Date: Fri, 30 Aug 2024 16:01:34 -0500 Subject: [PATCH 071/135] Update turso connector v0.1.0 (#269) Fix README --------- Co-authored-by: GitHub Action --- registry/hasura/turso/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/registry/hasura/turso/README.md b/registry/hasura/turso/README.md index c82b38e5..2d3977b0 100644 --- a/registry/hasura/turso/README.md +++ b/registry/hasura/turso/README.md @@ -91,7 +91,7 @@ APP_TURSO_WRITE_URL="http://local.hasura.dev:4362" If you are attaching to a local SQLite file, first make sure that the file is located inside the connector directory. For example, if you had a `data.sqlite` file you could place it at `/app/connector/turso/data.sqlite`. Files in the connector directory get mounted to `/etc/connector/`. -In this instance, you would set the `TURSO_URL=/etc/connector/data.sqlite` and leave the `TURSO_AUTH_TOKEN` as blank/null. Now your `.env` might look like this: +In this instance, you would set the `TURSO_URL=file:/etc/connector/data.sqlite` and leave the `TURSO_AUTH_TOKEN` as blank/null. Now your `.env` might look like this: ``` APP_TURSO_AUTHORIZATION_HEADER="Bearer QTJ7rl19SvKa0rwOZjYILQ==" @@ -99,7 +99,7 @@ APP_TURSO_HASURA_SERVICE_TOKEN_SECRET="QTJ7rl19SvKa0rwOZjYILQ==" APP_TURSO_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://local.hasura.dev:4317" APP_TURSO_OTEL_SERVICE_NAME="app_turso" APP_TURSO_READ_URL="http://local.hasura.dev:4362" -APP_TURSO_TURSO_URL="/etc/connector/data.sqlite" +APP_TURSO_TURSO_URL="file:/etc/connector/data.sqlite" APP_TURSO_WRITE_URL="http://local.hasura.dev:4362" ``` From 2997f55db1137ac5fbdc467adf8430ad952e4fae Mon Sep 17 00:00:00 2001 From: Tristen Harr Date: Fri, 30 Aug 2024 16:02:18 -0500 Subject: [PATCH 072/135] add python (#264) --- registry/hasura/python/README.md | 102 ++++++++++++++++++ registry/hasura/python/logo.svg | 2 + registry/hasura/python/metadata.json | 33 ++++++ .../releases/v0.0.45/connector-packaging.json | 11 ++ .../releases/v0.1.0/connector-packaging.json | 11 ++ 5 files changed, 159 insertions(+) create mode 100644 registry/hasura/python/README.md create mode 100644 registry/hasura/python/logo.svg create mode 100644 registry/hasura/python/metadata.json create mode 100644 registry/hasura/python/releases/v0.0.45/connector-packaging.json create mode 100644 registry/hasura/python/releases/v0.1.0/connector-packaging.json diff --git a/registry/hasura/python/README.md b/registry/hasura/python/README.md new file mode 100644 index 00000000..ed0093bc --- /dev/null +++ b/registry/hasura/python/README.md @@ -0,0 +1,102 @@ +# Hasura Python Lambda Connector + + +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/connectors/python) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-python-blue.svg?style=flat)](https://hasura.io/connectors/python) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](https://github.com/hasura/ndc-python-lambda/blob/main/LICENSE.txt) +[![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](https://github.com/hasura/ndc-python-lambda/blob/main/README.md) + +This connector allows you to write Python code and call it using Hasura! + +With Hasura, you can integrate -- and even host -- this business logic directly with Hasura DDN and your API. + +You can handle custom business logic using the Python Lambda data connector. Using this connector, you can transform or enrich data before it reaches your customers, or perform any other business logic you may need. + +You can then integrate these functions as individual commands in your metadata and API. This process enables you to simplify client applications and speed up your backend development! + +This connector is built using the [Python Data Connector SDK](https://github.com/hasura/ndc-sdk-python) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). + +## Before you get Started + +1. The [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed +2. A [supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +3. A [subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) + +The steps below explain how to Initialize and configure a connector for local development. You can learn how to deploy a connector — after it's been configured — [here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). + +## Using the Python connector + +### Step 1: Authenticate your CLI session + +```bash +ddn auth login +``` + +### Step 2: Configure the connector + +Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while providing a name for the connector in the prompt: + +```bash +ddn connector init python -i +``` + +#### Step 2.1: Choose the `hasura/python` option from the list + +#### Step 2.2: Choose a port for the connector + +The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the default suggested port. + +### Step 3: Introspect the connector + +Introspecting the connector will generate a `config.json` file and a `python.hml` file. + +```bash +ddn connector introspect python +``` + +### Step 4: Add your resources + +You can add the models, commands, and relationships to your API by tracking them which generates the HML files. + +```bash +ddn connector-link add-resources python +``` + +### Step 5: Run your connector + +You can run your connector locally, or include it in the docker setup. + +#### Run the connector in Docker + +To include your connector in the docker setup, include its compose file at the top of your supergraph `compose.yaml` file like this: + +```yaml +include: + - path: app/connector/python/compose.yaml +``` + +#### Run the connector locally + +To run your connector outside of Docker first go into the connector directory: + +`cd app/connector/python` + +Install the requirements: + +`pip3 install -r requirements.txt` + +Then run the connector locally: + +```ddn connector setenv --connector connector.yaml -- python3 functions.py serve``` + +## Documentation + +View the full documentation for the Python Lambda connector [here](https://github.com/hasura/ndc-python-lambda/blob/main/docs/index.md). + +## Contributing + +Check out our [contributing guide](https://github.com/hasura/ndc-python-lambda/blob/main/docs/contributing.md) for more details. + +## License + +The Turso connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file diff --git a/registry/hasura/python/logo.svg b/registry/hasura/python/logo.svg new file mode 100644 index 00000000..e771ee25 --- /dev/null +++ b/registry/hasura/python/logo.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/registry/hasura/python/metadata.json b/registry/hasura/python/metadata.json new file mode 100644 index 00000000..4a448104 --- /dev/null +++ b/registry/hasura/python/metadata.json @@ -0,0 +1,33 @@ +{ + "overview":{ + "namespace":"hasura", + "description":"The Python Lambda Connector allows you to expose Python functions as NDC functions/procedures for use in your Hasura DDN subgraphs.", + "title":"Python Lambda Connector", + "logo":"logo.svg", + "tags":["lambda"], + "latest_version":"v0.1.0" + }, + "author":{ + "support_email":"support@hasura.io", + "homepage":"https://hasura.io", + "name":"Hasura" + }, + "is_verified":false, + "is_hosted_by_hasura":false, + "source_code":{ + "is_open_source":true, + "repository":"https://github.com/hasura/ndc-python-lambda", + "version":[ + { + "tag":"v0.0.45", + "hash":"76a3d43d8ccf990b14812d9c0c354c4320b810f6", + "is_verified": false + }, + { + "tag":"v0.1.0", + "hash":"6f83afe355a60bd9677536e1bb13b212dca5460a", + "is_verified": false + } + ] + } +} \ No newline at end of file diff --git a/registry/hasura/python/releases/v0.0.45/connector-packaging.json b/registry/hasura/python/releases/v0.0.45/connector-packaging.json new file mode 100644 index 00000000..fcd49dc9 --- /dev/null +++ b/registry/hasura/python/releases/v0.0.45/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.45", + "uri": "https://github.com/hasura/ndc-python-lambda/releases/download/v0.0.45/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "e9ba6388e4d3fad8c09dd3b696df5c97666f4551d47062b8dd7f311f1918269d" + }, + "source": { + "hash": "76a3d43d8ccf990b14812d9c0c354c4320b810f6" + } +} \ No newline at end of file diff --git a/registry/hasura/python/releases/v0.1.0/connector-packaging.json b/registry/hasura/python/releases/v0.1.0/connector-packaging.json new file mode 100644 index 00000000..c9ee9e54 --- /dev/null +++ b/registry/hasura/python/releases/v0.1.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.0", + "uri": "https://github.com/hasura/ndc-python-lambda/releases/download/v0.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "4bd56df0920b1f889292a1ef12a0735a9883c47edef7a3cfbdc4c7db37dcf644" + }, + "source": { + "hash": "6f83afe355a60bd9677536e1bb13b212dca5460a" + } +} \ No newline at end of file From 6664700e56b03fd57aeadff57e667d34432893ad Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Mon, 2 Sep 2024 12:47:23 +0530 Subject: [PATCH 073/135] Allow forked PRs to deploy connector version publishing in the staging environment (#268) This PR extends the `registry-updates` workflow to access the repository secrets for forked repository PRs, like this [one](https://github.com/hasura/ndc-hub/pull/257) . It should be noted that, we are allowing this only for the staging environment and this is not needed for the production environment. --- .github/workflows/registry-updates.yaml | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/workflows/registry-updates.yaml b/.github/workflows/registry-updates.yaml index 3c4f5463..943c03d7 100644 --- a/.github/workflows/registry-updates.yaml +++ b/.github/workflows/registry-updates.yaml @@ -1,7 +1,7 @@ name: Update Hub DB from GH Registry (Staging) on: - pull_request: + pull_request_target: branches: - main types: [opened, synchronize, reopened] @@ -19,6 +19,26 @@ jobs: with: fetch_depth: 1 + + - name: Check for PR approvals + id: check-approval + uses: actions/github-script@v6 + with: + script: | + const { data: reviews } = await github.pulls.listReviews({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.payload.pull_request.number, + }); + const approved = reviews.some(review => review.state === 'APPROVED'); + return approved; + + - name: Cancel if not approved + if: steps.check-approval.outputs.approved == 'false' + run: | + echo "The PR has not been approved. Cancelling the workflow." + exit 1 # This will exit the workflow early + - name: Get all connector version package changes id: connector-version-changed-files uses: tj-actions/changed-files@v44 From 9c75f932e9087281a24fae7b060f89553f1c8b88 Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Mon, 2 Sep 2024 16:00:43 +0530 Subject: [PATCH 074/135] Use the `github-script@v7` to correctly get the approval status on PR (#273) This PR fixes the logic of checking the approval status on the PR and uses the `github-script@v7` to do the same. --- .github/workflows/registry-updates.yaml | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/.github/workflows/registry-updates.yaml b/.github/workflows/registry-updates.yaml index 943c03d7..f3b39177 100644 --- a/.github/workflows/registry-updates.yaml +++ b/.github/workflows/registry-updates.yaml @@ -19,25 +19,23 @@ jobs: with: fetch_depth: 1 - - name: Check for PR approvals id: check-approval - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: | - const { data: reviews } = await github.pulls.listReviews({ + const { owner, repo } = context.issue; + const pull_number = context.payload.pull_request.number; + console.log("Owner and repo and pull_number", owner, repo, pull_number); + const { data: reviews } = await github.rest.pulls.listReviews({ owner: context.repo.owner, repo: context.repo.repo, pull_number: context.payload.pull_request.number, }); const approved = reviews.some(review => review.state === 'APPROVED'); - return approved; - - - name: Cancel if not approved - if: steps.check-approval.outputs.approved == 'false' - run: | - echo "The PR has not been approved. Cancelling the workflow." - exit 1 # This will exit the workflow early + if (!approved) { + core.setFailed('This workflow will only run when the PR is approved by someone in Hasura') + } - name: Get all connector version package changes id: connector-version-changed-files From 37d20a5765ebbd3181a932c827ba70db7071dee0 Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Mon, 2 Sep 2024 17:12:09 +0530 Subject: [PATCH 075/135] Fix bug in registry update automation (#275) This PR modifies the check out logic a bit for PRs opened on forked repositories. If the PR opened is from a forked repository, the code will be checked out to that repo's `ref` commit to access the files present in that branch, in the case the PR is opened directly in this repo, the behaviour will be the same as it was earlier. --- .github/workflows/registry-updates.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/registry-updates.yaml b/.github/workflows/registry-updates.yaml index f3b39177..fd0a6afe 100644 --- a/.github/workflows/registry-updates.yaml +++ b/.github/workflows/registry-updates.yaml @@ -17,7 +17,11 @@ jobs: - name: Checkout repository uses: actions/checkout@v2 with: - fetch_depth: 1 + # In the case of forked PRs, the forked repository will + # be checked out. + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} + fetch-depth: 1 - name: Check for PR approvals id: check-approval From df6b987ccff98dd7314b59270aeec44b7909820f Mon Sep 17 00:00:00 2001 From: AdalbertMemSQL Date: Mon, 2 Sep 2024 14:52:45 +0300 Subject: [PATCH 076/135] Add SingleStore connector (#257) This PR adds singlestore connector. --------- Co-authored-by: Adalbert Makarovych --- registry/hasura/singlestore/README.md | 147 ++++++++++++++++++ registry/hasura/singlestore/logo.png | Bin 0 -> 47417 bytes registry/hasura/singlestore/metadata.json | 43 +++++ .../releases/v0.0.1/connector-packaging.json | 11 ++ 4 files changed, 201 insertions(+) create mode 100644 registry/hasura/singlestore/README.md create mode 100644 registry/hasura/singlestore/logo.png create mode 100644 registry/hasura/singlestore/metadata.json create mode 100644 registry/hasura/singlestore/releases/v0.0.1/connector-packaging.json diff --git a/registry/hasura/singlestore/README.md b/registry/hasura/singlestore/README.md new file mode 100644 index 00000000..f5efeef7 --- /dev/null +++ b/registry/hasura/singlestore/README.md @@ -0,0 +1,147 @@ +# SingleStore Data Connector + + + + +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/latest/connectors/singesltore/) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-singlestore-blue.svg?style=flat)](https://hasura.io/connectors/singlestore) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE) +[![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) + +The Hasura SingleStore Connector ("the connector") enables you to connect to a SingleStore database and gives instant access to a GraphQL API on top of your data. + +This connector is built using the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and, it implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). + + +- [See the listing in the Hasura Hub](https://hasura.io/connectors/singlestore) +- [Hasura V3 Documentation](https://hasura.io/docs/3.0) + +## Features + +The following matrix lists the features supported by the Hasura SingleStore connector: + +| Feature | Supported | Notes | +| ------------------------------- | --------- | ----- | +| Native Queries + Logical Models | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ✅ | | +| Views | ✅ | | +| Distinct | ✅ | | +| Remote Relationships | ✅ | | +| Mutations | ❌ | coming soon | + +## Prerequisites + +Ensure that the following prerequisites are met before using the connector: + +1. Install [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/). +2. Initialize a [supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph). +3. Initialize a [subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph). +4. An active [SingleStore](https://www.singlestore.com/) deployment that serves as the data source for the API. + + +## Using the SingleStore connector + +The following steps explain how to initialize and configure the connector for local development. For information on deploying a connector after it has been configured, refer to [Deploy a Connector](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). + +### Step 1: Authenticate your CLI session + +```bash +ddn auth login +``` + +### Step 2: Configure the connector + +After the supergraph and subgraph have been initialized (refer to [Prerequisites](#Prerequisites), run the initialization command in interactive mode. Specify a name for the connector in the command. + +```bash +ddn connector init -i +``` + +#### Step 2.1: Select the SingleStore connector + +From the list of connectors, select `singlestore`. + +#### Step 2.2: Select a port for the connector +The CLI prompts you to specify a port for running the connector. Either select the default port suggested or choose a port that is not currently in use. + +#### Step 2.3: Provide the environment variable(s) for the connector + +Specify the connection string used to connect to the SingleStore database using the `SINGLESTORE_URL` variable. The connection string must be in the `mysql://[[:]][@:[]]/[][?=[&=]]` format. + +For example: + +```env +SINGLESTORE_URL=singlestore://username:password@hostname/database +``` +The connector uses [MySQL2](https://sidorares.github.io/node-mysql2/docs) library to establish a connection. +For more information, refer to [Connection options](https://www.npmjs.com/package/mysql#connection-options) and [Pool options](https://www.npmjs.com/package/mysql#pool-options). + +Alternatively, you can also set following environment variables instead of the `SINGLELSTORE_URL` variable: + +| Name | Default | Description | +|-------------------------------------|-------------|-------------| +| SINGLESTORE_HOST | localhost | Hostname of the SingleStore database to connect with. | +| SINGLESTORE_PORT | 3306 | Port number of the SingleStore database. | +| SINGLESTORE_PASSWORD | | Password of the SingleStore database user. | +| SINGLESTORE_DATABASE | | Name of the SingleStore database to connect with. | +| SINGLESTORE_SSL_CA | | Path to the trusted CA certificate file. | +| SINGLESTORE_SSL_CERT | | Path to the certificate chain file in PEM format. | +| SINGLESTORE_SSL_KEY | | Path to the private key file in PEM format. | +| SINGLESTORE_SSL_CIPHERS | | Cipher suite specification. If specified, it replaces the default value. | +| SINGLESTORE_SSL_PASSPHRASE | | Cipher suite specification. If specified, it replaces the default value. | +| SINGLESTORE_SSL_REJECT_UNAUTHORIZED | true | If enabled, the server rejects any connection that is not authorized with the list of supplied CAs. | + +If `SINGLELSTORE_URL` is set these variables are ignored. + +### Step 3: Introspect your data source + +After configuring the connector, use the CLI to introspect the SingleStore database and create a source-specific configuration file for the connector (`configuration.json`). + +```bash +ddn connector introspect +``` + +## Step 4: Add your resources + +This command will create `.hml` files for each table and view in your database +and an `.hml` file with information about SingleStore data types. + +```bash +ddn connector-link add-resources +``` + +## Step 5. Add relationships + +SingleStore does not support foreign keys. Relationships between tables must be added manually. You can define relationships by appending relationship information to the `.hml` files generated in the previous step. +For information on defining relationships, refer to [Relationships](https://hasura.io/docs/3.0/supergraph-modeling/relationships/). +For example, to add a relationship from a `message` table to the `user` table, append following text to the +`DbMessage.hml` file: +```hml +--- +kind: Relationship +version: v1 +definition: + name: user + sourceType: DbMessage + target: + model: + name: DbUser + subgraph: app + relationshipType: Object + mapping: + - source: + fieldPath: + - fieldName: userId + target: + modelField: + - fieldName: id + description: The user details for a message +``` +## License + +The SingleStore connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/registry/hasura/singlestore/logo.png b/registry/hasura/singlestore/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c3eee058bdb65969472ad142a6d5f4b993c4b75a GIT binary patch literal 47417 zcmYg%WmFu^)-~>ypg{%?ZV5IxAq01K2@)*G;O_1k0t^xo+=A<%L4&*d;0^-;hL_y? zea~}$^we~()vM~9K4;giv#X+1m1S_T$gvO*5OC#W->V}aAn!f@pTt0W{#__N`1#ym zI?3vR5D-Wh|6Yi4>I`Sk4-rA?GVc&7M=AH8Z&0iyl_U`mY7(#?%uo>!nnvZ`OKN%| z9zEiw8tJ$L&`$hJh~e|LBn*x32v#k%Oq1I zte`}GZXicZM!?d#9vuZ*pZbk9S7D)GHNj?ls%~URR()VAPd;nyu%)#|*az-dDr4lY z=UgE8sm*)Am*H9ndj#H8=%P=~nFyGWkQ||RQWH@LcU8dZB8?(Y7Q!*dVZZW9I zt}sRbBF0TbNGW>5W`^a{-Aiq!k_(g${Ifs!NSs0c?}fk32ec34OgIp1-c$SoXN(~s zMDH*vR<5E5ou|xhwm%yi1NToE57i3rLmdwsIF#63V-EM9uJVn@B-bQwe=;3_UAYk04iv|CC?ipfvd`ok zir()c+XT#{T=($>X5i~h0RO)?x=cS&ei-+lX)6$0LliV(K8VUzP-|w$*9j}Y%Z31q zN$wG#_?ft?|MlHpSCEIixZ>F4YZAMRWNHBCjsD4j6(i5NNxTI&hR<>G^asHDFusPKvGJ#z;9T#W@7G8x(FO3iPn^izhv+I!CoQa(b;y9- zpht;e(G;y@KnK)0yUlu&b1f;w)#>S!QN|N9U%v&_u1X9&!h8Hp2bSw1mydDupmgex z7u{~>b{p2xA*9T+RSND+a})!=d_{lok3+l8Ou2(O&n$ecuzpyHviZ%PlBo0!LLy|4 zcdU|sGYBPKiltlxa^t*dj^8$nYDv75?Uob!7E?z_uaxk#?>SJe6Y2kT6cVrk+EDP* z6@Q}ieR^3J%H?yt24VO7`AEnt@2$06oWXyangJL94mv4%9me=$j|KD|o&Gz9YR02a z!2sDi<9Wa3l--YDmoabu2WCPmrUOr!#gUdC0(Ckg*45rr13A9p(s((oge$`$mH~l6 zON7)@o|+KX5lu#pj(d6|DD8mTnbwpHt3Ny#?`SOB~Tcqm)`R zeNFt}Vw8o?V*DE=?^A{(;Y7!N5>NB%?9fEvn)Zxg5=%gGa@FDVWx3~ILcmD?c0k+2 z^7UMx)eU0y6^bunNoBS|J?#DL%mrueWs`XlY|ZElIalDY_1`RP6L-gv44_!e39QV%5a9~65q@=efxelpXNX|Yku{x`Cy~WAB&r44e{#1g;d9M z=Ru`=1Hc=Ym<2HSNjst-4Xb|l6@+IS6j9(PG$1IQ4;9npyKMq4)>Yq^Jnx z#;cHjOVoQ$Hp5xQaI8gSM))sfyLi41zIEoraIdQ(Ep1|5vkf98rU+XXj&<88RLxEV zJu17M3o5-rVNUZ-&%!4m4B4Hk!U?OQ!gf1KE?{w$CJPgmhJgi{i^T$_Wo3C{GIf8nn7H$-ku%{De$)eIMr%>YyV=!uUCZ9G@Sc$FpsN}O|u>;gcv6G_T;;-J^7NhY)G7dGIw z*iQw}3s7KKeNLSN1<`x4lw`tqEEk?*!xv=uf|;pHIT~w4EPTa!q$yH&K zjCrNJP&$_1s0|nU*@AgMMz$+0bTIui@%wQ>UiJxcr~-Va8A?&z{-lsM)!V$!gWq1) z`c2aKxwzjDLJ1S@UQA~L*|rw zq&B}9pWj?Q;Di-NsD6Gi)U&B3KAfvrk8Wy>n6PJI+%`IHgnqlpH|q93-Z{RC1A@@&ahV)u=_K80Jg?gOF=9>GakOv=Q2Se9a{Ei?R(#Hvq+g*XI zQH7|%azlB1Mo_T6W zqPp5)YsRw@Yi~+0$5}fI_wc_6Iu9hneje7PQ8l3as6W(G=HMVTPpX7-PRow**EMcG!loZ}Yzr&Jp=@66+4*7;<2>obAiglLh360^=}$b>F`X*X`mΝ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⩔PuzDH{2E&d-r(>0%cRE54xFY%_v;hCeVD}e~ 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 literal 0 HcmV?d00001 diff --git a/registry/hasura/singlestore/metadata.json b/registry/hasura/singlestore/metadata.json new file mode 100644 index 00000000..29d8d6d6 --- /dev/null +++ b/registry/hasura/singlestore/metadata.json @@ -0,0 +1,43 @@ +{ + "overview": { + "namespace": "hasura", + "description": "The Hasura SingleStore Connector enables you to connect to a SingleStore database and gives instant access to a GraphQL API on top of your data.", + "title": "SingleStore Data Connector", + "logo": "logo.png", + "tags": [ + "database" + ], + "latest_version": "v0.0.1" + }, + "author": { + "support_email": "integrations@singlestore.com", + "homepage": "https://www.singlestore.com/", + "name": "SingleStore" + }, + "is_verified": false, + "is_hosted_by_hasura": false, + "packages": [ + { + "version": "0.0.1", + "uri": "https://github.com/singlestore-labs/singlestore-hasura-connector/releases/download/v0.0.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "7cc9f73cb966c2b69ef54d5f0e346407d3555ed1ac08f361f16157540bb80041" + }, + "source": { + "hash": "a9caa889c13a251040003c0934c7e67fccfd7de4" + } + } + ], + "source_code": { + "is_open_source": true, + "repository": "https://github.com/singlestore-labs/singlestore-hasura-connector/", + "version": [ + { + "tag": "v0.0.1", + "hash": "a9caa889c13a251040003c0934c7e67fccfd7de4", + "is_verified": false + } + ] + } +} \ No newline at end of file diff --git a/registry/hasura/singlestore/releases/v0.0.1/connector-packaging.json b/registry/hasura/singlestore/releases/v0.0.1/connector-packaging.json new file mode 100644 index 00000000..ba22dd94 --- /dev/null +++ b/registry/hasura/singlestore/releases/v0.0.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.1", + "uri": "https://github.com/singlestore-labs/singlestore-hasura-connector/releases/download/v0.0.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "7cc9f73cb966c2b69ef54d5f0e346407d3555ed1ac08f361f16157540bb80041" + }, + "source": { + "hash": "a9caa889c13a251040003c0934c7e67fccfd7de4" + } +} \ No newline at end of file From aee1a0c44ec66c1df4714885b2c85b9eb9d62ddc Mon Sep 17 00:00:00 2001 From: Mohd Bilal Date: Tue, 3 Sep 2024 09:30:19 +0530 Subject: [PATCH 077/135] release openapi connector version `v0.1.2` (#277) --- registry/hasura/openapi/metadata.json | 48 +------------------ .../releases/v0.1.2/connector-packaging.json | 11 +++++ 2 files changed, 12 insertions(+), 47 deletions(-) create mode 100644 registry/hasura/openapi/releases/v0.1.2/connector-packaging.json diff --git a/registry/hasura/openapi/metadata.json b/registry/hasura/openapi/metadata.json index 9163d8f5..f63b5f59 100644 --- a/registry/hasura/openapi/metadata.json +++ b/registry/hasura/openapi/metadata.json @@ -5,7 +5,7 @@ "title": "OpenAPI Lambda Connector", "logo": "logo.png", "tags": [], - "latest_version": "v0.1.1" + "latest_version": "v0.1.2" }, "author": { "support_email": "support@hasura.io", @@ -14,52 +14,6 @@ }, "is_verified": true, "is_hosted_by_hasura": false, - "packages": [ - { - "version": "v0.0.1-alpha", - "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.0.1-alpha/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "0fd96c602f79f50a11b0cc94980559af1a4fc5f26e356bfba9859d53ab92ddcc" - }, - "source": { - "hash": "3cc70a7c4715c72e8dcb56c78c66967c5f687148" - } - }, - { - "version": "v0.0.2-alpha", - "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.0.2-alpha/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "25ec7152d795871e1d2944665ef48012520181afaf6f7c66a030c3a443edbeb3" - }, - "source": { - "hash": "35ba5da05dba1602fea40a3a8fba3652fd1c3e12" - } - }, - { - "version": "v0.1.0", - "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.1.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "f371014bc0f8a873644bd0127531aa6354b9fca1e5680b12c567c3a3fc4204a5" - }, - "source": { - "hash": "d0c628e9206d397373f42faaf3733f6ada94b56c" - } - }, - { - "version": "v0.1.1", - "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.1.1/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "a7365a6f7780dcfae85cc787e2de83ea22d416a1d4a9fc597b68227bf978e264" - }, - "source": { - "hash": "4b70712933de7a7ed475407ccd0be7bed1611ae8" - } - } - ], "source_code": { "is_open_source": true, "repository": "https://github.com/hasura/ndc-open-api-lambda/", diff --git a/registry/hasura/openapi/releases/v0.1.2/connector-packaging.json b/registry/hasura/openapi/releases/v0.1.2/connector-packaging.json new file mode 100644 index 00000000..81aec720 --- /dev/null +++ b/registry/hasura/openapi/releases/v0.1.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.2", + "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.1.2/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "2b7199b43c48e8823f99a037921935f4ad500161ff8df4c5ae868cbd58f25b5b" + }, + "source": { + "hash": "a1fd7e016fc24107d35374a09fad24b4fc9c09d7" + } +} From d298964e408a9a560d3039c9e51263e6ec22c2d2 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Tue, 3 Sep 2024 01:39:46 -0400 Subject: [PATCH 078/135] Release clickhouse v1.0.2 (#278) --- registry/hasura/clickhouse/metadata.json | 163 +----------------- .../releases/v1.0.1/connector-packaging.json | 11 ++ .../releases/v1.0.2/connector-packaging.json | 11 ++ 3 files changed, 28 insertions(+), 157 deletions(-) create mode 100644 registry/hasura/clickhouse/releases/v1.0.1/connector-packaging.json create mode 100644 registry/hasura/clickhouse/releases/v1.0.2/connector-packaging.json diff --git a/registry/hasura/clickhouse/metadata.json b/registry/hasura/clickhouse/metadata.json index c3ed1dd5..34c0808e 100644 --- a/registry/hasura/clickhouse/metadata.json +++ b/registry/hasura/clickhouse/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.0" + "latest_version": "v1.0.2" }, "author": { "support_email": "support@hasura.io", @@ -16,166 +16,15 @@ }, "is_verified": true, "is_hosted_by_hasura": false, - "packages": [ - { - "version": "1.0.1", - "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v1.0.1/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "0069c1d611e0edaafc88de0ee3d22f5f6ed813757d077885c0c3caa1d8ef7d14" - }, - "source": { - "hash": "a5df7ec5d5a7ca65dcf6a16460dacbd0b81e39f2" - } - }, - { - "version": "1.0.0", - "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v1.0.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "e872f3a10ac9a3c6ab81fe958263941b0a998e5bce2d978685a65cfe679e53c6" - }, - "source": { - "hash": "3da872909893964aabaedb4659af129f0ceaa565" - } - }, - { - "version": "0.2.11", - "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.11/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "97dccf8cfac9865eb6a0e3aee65fcd91a7c14a48e1f65cf985df3734f596e13b" - }, - "source": { - "hash": "7ef634c61649a17deb867e5a36db4220c66f0013" - } - }, - { - "version": "0.2.10", - "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.10/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "4eb32262e528d0261afd0f6a4b283a6fe3fd0edf395b732fe6abcacfdf4ff999" - }, - "source": { - "hash": "dbe5b7765b1c9276e5734c8fbc5005e7b71d0500" - } - }, - { - "version": "0.2.9", - "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.9/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "source": { - "hash": "93752f433f4e7c91f0c13d92ea9369deb97d1970" - } - }, - { - "version": "0.2.8", - "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.8/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "4de1a70042d222040523faf6aa1771be23d5156258318272fc31fa1dd49c41ea" - }, - "source": { - "hash": "f1629f715770358e587a25f9a0ca015728d422dd" - } - }, - { - "version": "0.2.7", - "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.7/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "a6acbd32400b2a74009009933a8469892bf7781969e58aef7532121198af1e4f" - }, - "source": { - "hash": "ece8fb0fcfcd9650dd5060f882baa94889eccf2e" - } - }, - { - "version": "0.2.6", - "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.6/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "c20dd539761084f9a3a0effa68011a6d57da92dbdf4f805bac93bc825f5c40ef" - }, - "source": { - "hash": "7bafb9fd2b9c3288b6f7279c3d62793cc78d8fe0" - } - }, - { - "version": "0.2.5", - "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.5/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "8504769a2bd8ac63f979dc5447dc106da4360cfbcdcacc9edb8765eb434e1e11" - }, - "source": { - "hash": "c89d9410cf885cbfe4156c9e7bf65211144018df" - } - }, - { - "version": "0.2.4", - "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.4/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "8ab07763d887848a555f26aae973e34e872ec0617ccc17d2eac96d67fe223e87" - }, - "source": { - "hash": "cd1f81b98b264df1e20f7f84a664fb272fac19b1" - } - }, - { - "version": "0.2.3", - "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.3/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "f1b1020e57fdb969b545f0e5ad37f1000c2e5084041695cc2e885e4cb634b35c" - }, - "source": { - "hash": "97175685b51a31a5ac99672746901d0df6d4eb35" - } - }, - { - "version": "0.2.2", - "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.2/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "198ed9a830a403cf855d449b3d99313ad01de4df21663c0648ab95fa25b58325" - }, - "source": { - "hash": "6b349d7f0e8449611a24d6b8cad34aeb3162b583" - } - }, - { - "version": "0.2.1", - "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.1/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "5e88d1b7fb14638ceeaf5b6fac775b6cc68d62d8537fc25cd8e87cdf4dfb443e" - }, - "source": { - "hash": "521365decd10db124c9865bd29fc4e60025a6892" - } - }, - { - "version": "0.2.0", - "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "94bacc789b3c3ea5e92b324e43bf054abaef1c0b7ce87d78ea12a34b33d7d6e5" - }, - "source": { - "hash": "4ec3b65c4fdbb37896e105ca89f8bdb1c25b277b" - } - } - ], "source_code": { "is_open_source": true, "repository": "https://github.com/hasura/ndc-clickhouse/", "version": [ + { + "tag": "v1.0.2", + "hash": "ec2463375b9244e008005d44a2b82288867c2d4e", + "is_verified": true + }, { "tag": "v1.0.1", "hash": "a5df7ec5d5a7ca65dcf6a16460dacbd0b81e39f2", diff --git a/registry/hasura/clickhouse/releases/v1.0.1/connector-packaging.json b/registry/hasura/clickhouse/releases/v1.0.1/connector-packaging.json new file mode 100644 index 00000000..ea1d3a58 --- /dev/null +++ b/registry/hasura/clickhouse/releases/v1.0.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.1", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v1.0.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "0069c1d611e0edaafc88de0ee3d22f5f6ed813757d077885c0c3caa1d8ef7d14" + }, + "source": { + "hash": "a5df7ec5d5a7ca65dcf6a16460dacbd0b81e39f2" + } +} \ No newline at end of file diff --git a/registry/hasura/clickhouse/releases/v1.0.2/connector-packaging.json b/registry/hasura/clickhouse/releases/v1.0.2/connector-packaging.json new file mode 100644 index 00000000..492c2f09 --- /dev/null +++ b/registry/hasura/clickhouse/releases/v1.0.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.2", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v1.0.2/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "4eec86f9b52036cd1d6642b8fb3cb27ccc0dfe4a9a273fe2186c02cf0482f2fc" + }, + "source": { + "hash": "ec2463375b9244e008005d44a2b82288867c2d4e" + } +} \ No newline at end of file From a10f637dd96a3ac0640f6d2f9c498324bf6a88df Mon Sep 17 00:00:00 2001 From: AdalbertMemSQL Date: Tue, 3 Sep 2024 16:47:27 +0300 Subject: [PATCH 079/135] Update singlestore connector metadata to version 0.0.2 (#279) This PR updates the singlestore connector metadata to version 0.0.2. Co-authored-by: GitHub Action --- registry/hasura/singlestore/metadata.json | 74 +++++++++---------- .../releases/v0.0.2/connector-packaging.json | 11 +++ 2 files changed, 44 insertions(+), 41 deletions(-) create mode 100644 registry/hasura/singlestore/releases/v0.0.2/connector-packaging.json diff --git a/registry/hasura/singlestore/metadata.json b/registry/hasura/singlestore/metadata.json index 29d8d6d6..c421d274 100644 --- a/registry/hasura/singlestore/metadata.json +++ b/registry/hasura/singlestore/metadata.json @@ -1,43 +1,35 @@ { - "overview": { - "namespace": "hasura", - "description": "The Hasura SingleStore Connector enables you to connect to a SingleStore database and gives instant access to a GraphQL API on top of your data.", - "title": "SingleStore Data Connector", - "logo": "logo.png", - "tags": [ - "database" - ], - "latest_version": "v0.0.1" - }, - "author": { - "support_email": "integrations@singlestore.com", - "homepage": "https://www.singlestore.com/", - "name": "SingleStore" - }, - "is_verified": false, - "is_hosted_by_hasura": false, - "packages": [ - { - "version": "0.0.1", - "uri": "https://github.com/singlestore-labs/singlestore-hasura-connector/releases/download/v0.0.1/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "7cc9f73cb966c2b69ef54d5f0e346407d3555ed1ac08f361f16157540bb80041" - }, - "source": { - "hash": "a9caa889c13a251040003c0934c7e67fccfd7de4" - } - } + "overview": { + "namespace": "hasura", + "description": "The Hasura SingleStore Connector enables you to connect to a SingleStore database and gives instant access to a GraphQL API on top of your data.", + "title": "SingleStore Data Connector", + "logo": "logo.png", + "tags": [ + "database" ], - "source_code": { - "is_open_source": true, - "repository": "https://github.com/singlestore-labs/singlestore-hasura-connector/", - "version": [ - { - "tag": "v0.0.1", - "hash": "a9caa889c13a251040003c0934c7e67fccfd7de4", - "is_verified": false - } - ] - } -} \ No newline at end of file + "latest_version": "v0.0.2" + }, + "author": { + "support_email": "integrations@singlestore.com", + "homepage": "https://www.singlestore.com/", + "name": "SingleStore" + }, + "is_verified": false, + "is_hosted_by_hasura": false, + "source_code": { + "is_open_source": true, + "repository": "https://github.com/singlestore-labs/singlestore-hasura-connector/", + "version": [ + { + "tag": "v0.0.1", + "hash": "a9caa889c13a251040003c0934c7e67fccfd7de4", + "is_verified": false + }, + { + "tag": "v0.0.2", + "hash": "2afe3150215fbd6bf8a93ee6f853ad232e5d101d", + "is_verified": false + } + ] + } +} diff --git a/registry/hasura/singlestore/releases/v0.0.2/connector-packaging.json b/registry/hasura/singlestore/releases/v0.0.2/connector-packaging.json new file mode 100644 index 00000000..f795e617 --- /dev/null +++ b/registry/hasura/singlestore/releases/v0.0.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.2", + "uri": "https://github.com/singlestore-labs/singlestore-hasura-connector/releases/download/v0.0.2/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "7faa80c1d6c64137f45582aec7a052ca046376b66a081589925d8b7975cc3fe9" + }, + "source": { + "hash": "2afe3150215fbd6bf8a93ee6f853ad232e5d101d" + } +} From ca455d73b10fac4c4d3246da86257b3f54ec983d Mon Sep 17 00:00:00 2001 From: gneeri Date: Wed, 4 Sep 2024 10:23:28 -0400 Subject: [PATCH 080/135] added v1.0.2 release for Elasticsearch (#266) Co-authored-by: Karthikeyan Chinnakonda --- registry/hasura/elasticsearch/metadata.json | 18 +++++++++++++++++- .../releases/v1.0.2/connector-packaging.json | 11 +++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 registry/hasura/elasticsearch/releases/v1.0.2/connector-packaging.json diff --git a/registry/hasura/elasticsearch/metadata.json b/registry/hasura/elasticsearch/metadata.json index 75b74dcb..0c3c24ec 100644 --- a/registry/hasura/elasticsearch/metadata.json +++ b/registry/hasura/elasticsearch/metadata.json @@ -7,7 +7,7 @@ "tags": [ "search" ], - "latest_version": "v1.0.1" + "latest_version": "v1.0.2" }, "author": { "support_email": "support@hasura.io", @@ -71,6 +71,17 @@ "source": { "hash": "72fad205f57e88781da6acafe1e03a7d220467c7" } + }, + { + "version": "1.0.2", + "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v1.0.2/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "d9548c6463e29f2b7c2d40923cee2c2073b0ff7cefe83b68f7cb7b0d485cf8f1" + }, + "source": { + "hash": "19c1dfbce44db9fb9a71e9ca68c93de2d5fade6c" + } } ], "source_code": { @@ -101,6 +112,11 @@ "tag": "v1.0.1", "hash": "72fad205f57e88781da6acafe1e03a7d220467c7", "is_verified": true + }, + { + "tag": "v1.0.2", + "hash": "19c1dfbce44db9fb9a71e9ca68c93de2d5fade6c", + "is_verified": true } ] } diff --git a/registry/hasura/elasticsearch/releases/v1.0.2/connector-packaging.json b/registry/hasura/elasticsearch/releases/v1.0.2/connector-packaging.json new file mode 100644 index 00000000..e907f61f --- /dev/null +++ b/registry/hasura/elasticsearch/releases/v1.0.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.2", + "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v1.0.2/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "d9548c6463e29f2b7c2d40923cee2c2073b0ff7cefe83b68f7cb7b0d485cf8f1" + }, + "source": { + "hash": "19c1dfbce44db9fb9a71e9ca68c93de2d5fade6c" + } +} From 2e7437b77e591d29dfbe0e5407fe43ba9a6e23c6 Mon Sep 17 00:00:00 2001 From: Mohd Bilal Date: Mon, 9 Sep 2024 19:15:31 +0530 Subject: [PATCH 081/135] release openapi connector version `v0.1.3` (#282) --- registry/hasura/openapi/metadata.json | 2 +- .../openapi/releases/v0.1.3/connector-packaging.json | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 registry/hasura/openapi/releases/v0.1.3/connector-packaging.json diff --git a/registry/hasura/openapi/metadata.json b/registry/hasura/openapi/metadata.json index f63b5f59..19f8aa1a 100644 --- a/registry/hasura/openapi/metadata.json +++ b/registry/hasura/openapi/metadata.json @@ -5,7 +5,7 @@ "title": "OpenAPI Lambda Connector", "logo": "logo.png", "tags": [], - "latest_version": "v0.1.2" + "latest_version": "v0.1.3" }, "author": { "support_email": "support@hasura.io", diff --git a/registry/hasura/openapi/releases/v0.1.3/connector-packaging.json b/registry/hasura/openapi/releases/v0.1.3/connector-packaging.json new file mode 100644 index 00000000..254d8023 --- /dev/null +++ b/registry/hasura/openapi/releases/v0.1.3/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.3", + "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.1.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "9fd6e2785d437b4a8b95eb0586dbe1b03f1d634d85a9c17394af7b734ebd4634" + }, + "source": { + "hash": "7a0177198da5e0691e01ba4378b90d7ad1e42044" + } +} From 1779793f6926f22b3180b5d3cefd85000cb00fca Mon Sep 17 00:00:00 2001 From: Harish Nair Date: Tue, 10 Sep 2024 13:10:48 +0530 Subject: [PATCH 082/135] RFC: Modify packaging spec to allow specifying required environment variables (#280) --- rfcs/0009-mandatory-env-vars.md | 112 ++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 rfcs/0009-mandatory-env-vars.md diff --git a/rfcs/0009-mandatory-env-vars.md b/rfcs/0009-mandatory-env-vars.md new file mode 100644 index 00000000..56300118 --- /dev/null +++ b/rfcs/0009-mandatory-env-vars.md @@ -0,0 +1,112 @@ +# RFC: Support Mandatory Environment Variables in Packaging Spec + +> **Note:** +> This RFC builds upon the concepts defined in [add documentation page to packaging spec](./0007-packaging-documentation-page.md). + +Some environment variables are mandatory for certain connectors. These connectors may make a distinction between the environment variable not being set and being set as an empty string. + +Currently, when a user provides an empty string for an environment variable during `ddn connector init -i`, the CLI does not include these variables in the environment variable mapping or the `.env` file. Users must manually add these environment variables to both the `.env` file and the mapping to ensure proper functionality. + +The CLI does not currently have a way to distinguish between optional environment variables (where an empty value should be ignored) and required environment variables (where an empty value must be written as an empty string). + +This RFC aims to improve the user experience by eliminating the need for this manual step. + +## Proposed Solution + +We propose adding a new optional field, `required`, to specify that an environment variable is mandatory. If this field is set, the CLI will include the environment variable in the mapping and `.env` file even if the user provides an empty string. + +The table below describes whether or not the tooling writes the environment variable to the .env files based on the `defaultValue` and `required` fields: + +| defaultValue/required | true | false\|undefined | +|---------------------------|-------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------| +| Non-empty string | YES | YES (discouraged: tooling always writes default values even for non-required env vars) | +| Empty string | YES | NO (discouraged: inconsistent behavior) (backward-compatible behavior) | +| Undefined | YES (discouraged: should provide a default value for required flags) (write user-provided string or empty string by default) | NO | + +#### Recommendations for Connector Authors + +- **If the environment variable should be written to `.env` files:** + - Mark the environment variable as required. + - Provide a default value, even if it is an empty string. + +- **If the environment variable should not be written to `.env` files:** + - Do not mark the environment variable as required. + - Do not provide a default value. + +**Note:** Discouraged combinations are still valid and has a well defined behaviour but not recommended due to potential inconsistencies or behavior that may not align with best practices. + + +## `connector-metadata.yaml` types + +```typescript +type ConnectorMetadataDefinition = { + packagingDefinition: PackagingDefinition + nativeToolchainDefinition?: NativeToolchainDefinition + supportedEnvironmentVariables: EnvironmentVariableDefinition[] + commands: Commands + cliPlugin?: CliPluginDefinition + dockerComposeWatch: DockerComposeWatch + documentationPage: string +} + +type PackagingDefinition = PrebuiltDockerImagePackaging | ManagedDockerBuildPackaging + +type PrebuiltDockerImagePackaging = { + type: "PrebuiltDockerImage" + dockerImage: string +} + +type ManagedDockerBuildPackaging = { + type: "ManagedDockerBuild" +} + +type NativeToolchainDefinition = { + commands: NativeToolchainCommands +} + +type NativeToolchainCommands = { + start: string | DockerizedCommand | ShellScriptCommand // Compulsory + update?: string | DockerizedCommand | ShellScriptCommand + watch: string | DockerizedCommand | ShellScriptCommand // Compulsory +} + +type EnvironmentVariableDefinition = { + name: string + description: string + defaultValue?: string + required?: boolean // NEW +} + +type Commands = { + update?: string | DockerizedCommand | ShellScriptCommand + watch?: string | DockerizedCommand | ShellScriptCommand +} + +// From https://github.com/hasura/ndc-hub/pull/129 (outside of this RFC) +type DockerizedCommand = { + type: "Dockerized" + dockerImage: string + commandArgs: string[] +} + +type ShellScriptCommand = { + type: "ShellScript" + bash: string + powershell: string +} + +type CliPluginDefinition = { + name: string + version: string +} + +// From: https://github.com/compose-spec/compose-spec/blob/1938efd103f8e0817ca90e5f15177ec0317bbaf8/schema/compose-spec.json#L455 +type DockerComposeWatch = DockerComposeWatchItem[] + +type DockerComposeWatchItem = { + path: string + action: "rebuild" | "sync" | "sync+restart" + target?: string + ignore?: string[] +} +``` From 106d92e35b611b9f4d3c8783841d8b7bc252c5c4 Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Tue, 10 Sep 2024 19:44:13 +0530 Subject: [PATCH 083/135] SQL server `v0.2.0` (#283) --- registry/hasura/sqlserver/README.md | 120 ++++++------------ .../releases/v0.2.0/connector-packaging.json | 11 ++ 2 files changed, 48 insertions(+), 83 deletions(-) create mode 100644 registry/hasura/sqlserver/releases/v0.2.0/connector-packaging.json diff --git a/registry/hasura/sqlserver/README.md b/registry/hasura/sqlserver/README.md index 314e32d3..791e90b7 100644 --- a/registry/hasura/sqlserver/README.md +++ b/registry/hasura/sqlserver/README.md @@ -1,6 +1,6 @@ # SQL Server Connector -[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/getting-started/overview/) +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0) [![ndc-hub](https://img.shields.io/badge/ndc--hub-sqlserver-blue.svg?style=flat)](https://hasura.io/connectors/sqlserver) [![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) [![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) @@ -14,8 +14,8 @@ thereby enhancing query optimization and performance. This connector is built using the [Rust Data Connector SDK](https://github.com/hasura/ndc-hub#rusk-sdk) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). -- [Connector information in the Hasura Hub](https://hasura.io/connectors/sqlserver) -- [Hasura V3 Documentation](https://hasura.io/docs/3.0) +- [See the listing in the Hasura Hub](https://hasura.io/connectors/sqlserver) +- [Hasura V3 Documentation](https://hasura.io/docs/3.0/) ## Features @@ -33,8 +33,9 @@ Below, you'll find a matrix of all supported features for the SQL Server connect | Table Relationships | ✅ | | | Views | ✅ | | | Remote Relationships | ✅ | | +| Stored Procedures | ✅ | | | Custom Fields | ❌ | | -| Mutations | ✅ | Only native mutations are suppported | +| Mutations | ❌ | Only native mutations are suppported | | Distinct | ✅ | | | Enums | ❌ | | | Naming Conventions | ❌ | | @@ -44,113 +45,66 @@ Below, you'll find a matrix of all supported features for the SQL Server connect ## Before you get Started 1. Create a [Hasura Cloud account](https://console.hasura.io) -2. Install the [CLI](https://hasura.io/docs/3.0/cli/installation/) -3. Install the [Hasura VS Code extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) -4. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) -5. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -## Using the connector +The steps below explain how to Initialize and configure a connector for local development. You can learn how to deploy a +connector — after it's been configured — [here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). -To use the SQL Server connector, follow these steps in a Hasura project: -(Note: for more information on the following steps, please refer to the Postgres connector documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) +## Using the SQL Server connector -### 1. Init the connector -(Note: here and following we are naming the subgraph "my_subgraph" and the connector "ms_sql") +### Step 1: Authenticate your CLI session - ```bash - ddn connector init ms_sql --subgraph my_subgraph/subgraph.yaml --hub-connector hasura/sqlserver --configure-port 8081 --add-to-compose-file compose.yaml - ``` - -### 2. Add your SQLServer credentials - -Add your credentials to `my_subgraph/connector/ms_sql/.env.local` - -```env title="my_subgraph/connector/ms_sql/.env.local" -OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 -OTEL_SERVICE_NAME=my_subgraph_ms_sql -CONNECTION_URI= -``` - -### 3. Introspect your Database - -From the root of your project run: - -```bash title="From the root of your project run:" -ddn connector introspect --connector my_subgraph/connector/ms_sql/connector.local.yaml -``` - -If you look at the `configuration.json` for your connector, you'll see metadata describing your SQL Server mappings. - -### 4. Restart the services - -Let's restart the docker compose services. Run the folowing from the root of your project: - -```bash title="From the root of your project run:" -HASURA_DDN_PAT=$(ddn auth print-pat) docker compose up --build --watch +```bash +ddn auth login ``` -### 5. Create the Hasura metadata +### Step 2: Configure the connector -In a new terminal tab from your project's root directory run: +Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while +providing a name for the connector in the prompt: -```bash title="Run the following from the root of your project:" -ddn connector-link add ms_sql --subgraph my_subgraph/subgraph.yaml --configure-host http://local.hasura.dev:8081 --target-env-file my_subgraph/.env.my_subgraph.local +```bash +ddn connector init -i ``` -The above step will add the following env vars to the `.env.my_subgraph.local` file. - -```env title="my_subgraph/.env.my_subgraph.local" -MY_SUBGRAPH_MS_SQL_READ_URL=http://local.hasura.dev:8081 -MY_SUBGRAPH_MS_SQL_WRITE_URL=http://local.hasura.dev:8081 -``` +#### Step 2.1: Choose the `hasura/sqlserver` from the list -The generated file has two environment variables — one for reads and one for writes. -Each key is prefixed by the subgraph name, an underscore, and the name of the -connector. - -### 6. Update the new DataConnectorLink object - -Finally, now that our `DataConnectorLink` has the correct environment variables configured for the SQL Server connector, -we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's -schema in `hml` format. From your project's root directory, run: - -```bash title="From the root of your project, run:" -ddn connector-link update ms_sql --subgraph my_subgraph/subgraph.yaml --env-file my_subgraph/.env.my_subgraph.local -``` +#### Step 2.2: Choose a port for the connector -After this command runs, you can open your `my_subgraph/metadata/ms_sql.hml` file and see your metadata completely -scaffolded out for you 🎉 +The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the +default suggested port. -The schema of the database can be viewed at http://localhost:8081/schema. +#### Step 2.3: Provide the env vars for the connector -### 7. Import _all_ your indices +| Name | Description | Required | Default | +|----------------|--------------------------------------------------|----------|---------| +| CONNECTION_URI | The connection string of the SQL Server database | Yes | N/A | -You can do this with just one command. From your project's root directory, run: +## Step 3: Introspect the connector -```bash title="From the root of your project, run:" -ddn connector-link update ms_sql --subgraph my_subgraph/subgraph.yaml --env-file my_subgraph/.env.my_subgraph.local --add-all-resources +```bash +ddn connector introspect ``` -### 8. Create a supergraph build +This will generate a `configuration.json` file that will have the schema of your SQL Server database. -Pass the `local` subcommand along with specifying the output directory as `./engine` in the root of the project. This -directory is used by the docker-compose file to serve the engine locally. From your project's root directory, run: +## Step 4: Add your resources -```bash title="From the root of your project, run:" -ddn supergraph build local --output-dir ./engine --subgraph-env-file my_subgraph:my_subgraph/.env.my_subgraph.local +```bash +ddn connector-link add-resources ``` -You can now navigate to -[`https://console.hasura.io/local/graphql?url=http://localhost:3000`](https://console.hasura.io/local/graphql?url=http://localhost:3000) -and interact with your API using the Hasura Console. +This command will track all the containers in your SQL Server DB as [Models](https://hasura.io/docs/3.0/supergraph-modeling/models). ## Documentation -View the full documentation for the ndc-sqlserver connector [here](https://github.com/hasura/ndc-sqlserver/blob/main/docs/readme.md). +View the full documentation for the ndc-sqlserver connector [here](./docs/readme.md). ## Contributing -We're happy to receive any contributions from the community. Please refer to our [development guide](https://github.com/hasura/ndc-sqlserver/blob/main/docs/development.md). +We're happy to receive any contributions from the community. Please refer to our [development guide](./docs/development.md). ## License diff --git a/registry/hasura/sqlserver/releases/v0.2.0/connector-packaging.json b/registry/hasura/sqlserver/releases/v0.2.0/connector-packaging.json new file mode 100644 index 00000000..0c6a545a --- /dev/null +++ b/registry/hasura/sqlserver/releases/v0.2.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.2.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "5fe8c9461acc6eeb8290d3e41e4f4d77f2b3ecc30898194746e469b1c45e2365" + }, + "source": { + "hash": "368b38f" + } +} From c5091164819f49571a60775b97664f97a70548b9 Mon Sep 17 00:00:00 2001 From: Mohd Bilal Date: Thu, 12 Sep 2024 15:49:10 +0530 Subject: [PATCH 084/135] release openapi connector `v0.1.4` (#286) --- .../openapi/releases/v0.1.4/connector-packaging.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 registry/hasura/openapi/releases/v0.1.4/connector-packaging.json diff --git a/registry/hasura/openapi/releases/v0.1.4/connector-packaging.json b/registry/hasura/openapi/releases/v0.1.4/connector-packaging.json new file mode 100644 index 00000000..7b9d28a0 --- /dev/null +++ b/registry/hasura/openapi/releases/v0.1.4/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.4", + "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.1.4/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "228a792a958ebc57869eb7bc47bc7b8e80dc94ca2121047aa81eac90da855b82" + }, + "source": { + "hash": "95b64da4484b7cf547e0436ab4dd56f5ff4991a7" + } +} From a9ebe4476781300028f3229e6d46b38c3b1d50a5 Mon Sep 17 00:00:00 2001 From: Brandon Martin Date: Mon, 16 Sep 2024 14:57:52 -0600 Subject: [PATCH 085/135] MongoDB release version 1.2.0 (#287) --- .../{0.0.1 => v0.0.1}/connector-packaging.json | 0 .../{0.0.2 => v0.0.2}/connector-packaging.json | 0 .../{0.0.3 => v0.0.3}/connector-packaging.json | 0 .../{0.0.4 => v0.0.4}/connector-packaging.json | 0 .../{0.0.5 => v0.0.5}/connector-packaging.json | 0 .../{0.0.6 => v0.0.6}/connector-packaging.json | 0 .../{0.1.0 => v0.1.0}/connector-packaging.json | 0 .../{1.0.0 => v1.0.0}/connector-packaging.json | 0 .../{1.1.0 => v1.1.0}/connector-packaging.json | 0 .../mongodb/releases/v1.2.0/connector-packaging.json | 11 +++++++++++ 10 files changed, 11 insertions(+) rename registry/hasura/mongodb/releases/{0.0.1 => v0.0.1}/connector-packaging.json (100%) rename registry/hasura/mongodb/releases/{0.0.2 => v0.0.2}/connector-packaging.json (100%) rename registry/hasura/mongodb/releases/{0.0.3 => v0.0.3}/connector-packaging.json (100%) rename registry/hasura/mongodb/releases/{0.0.4 => v0.0.4}/connector-packaging.json (100%) rename registry/hasura/mongodb/releases/{0.0.5 => v0.0.5}/connector-packaging.json (100%) rename registry/hasura/mongodb/releases/{0.0.6 => v0.0.6}/connector-packaging.json (100%) rename registry/hasura/mongodb/releases/{0.1.0 => v0.1.0}/connector-packaging.json (100%) rename registry/hasura/mongodb/releases/{1.0.0 => v1.0.0}/connector-packaging.json (100%) rename registry/hasura/mongodb/releases/{1.1.0 => v1.1.0}/connector-packaging.json (100%) create mode 100644 registry/hasura/mongodb/releases/v1.2.0/connector-packaging.json diff --git a/registry/hasura/mongodb/releases/0.0.1/connector-packaging.json b/registry/hasura/mongodb/releases/v0.0.1/connector-packaging.json similarity index 100% rename from registry/hasura/mongodb/releases/0.0.1/connector-packaging.json rename to registry/hasura/mongodb/releases/v0.0.1/connector-packaging.json diff --git a/registry/hasura/mongodb/releases/0.0.2/connector-packaging.json b/registry/hasura/mongodb/releases/v0.0.2/connector-packaging.json similarity index 100% rename from registry/hasura/mongodb/releases/0.0.2/connector-packaging.json rename to registry/hasura/mongodb/releases/v0.0.2/connector-packaging.json diff --git a/registry/hasura/mongodb/releases/0.0.3/connector-packaging.json b/registry/hasura/mongodb/releases/v0.0.3/connector-packaging.json similarity index 100% rename from registry/hasura/mongodb/releases/0.0.3/connector-packaging.json rename to registry/hasura/mongodb/releases/v0.0.3/connector-packaging.json diff --git a/registry/hasura/mongodb/releases/0.0.4/connector-packaging.json b/registry/hasura/mongodb/releases/v0.0.4/connector-packaging.json similarity index 100% rename from registry/hasura/mongodb/releases/0.0.4/connector-packaging.json rename to registry/hasura/mongodb/releases/v0.0.4/connector-packaging.json diff --git a/registry/hasura/mongodb/releases/0.0.5/connector-packaging.json b/registry/hasura/mongodb/releases/v0.0.5/connector-packaging.json similarity index 100% rename from registry/hasura/mongodb/releases/0.0.5/connector-packaging.json rename to registry/hasura/mongodb/releases/v0.0.5/connector-packaging.json diff --git a/registry/hasura/mongodb/releases/0.0.6/connector-packaging.json b/registry/hasura/mongodb/releases/v0.0.6/connector-packaging.json similarity index 100% rename from registry/hasura/mongodb/releases/0.0.6/connector-packaging.json rename to registry/hasura/mongodb/releases/v0.0.6/connector-packaging.json diff --git a/registry/hasura/mongodb/releases/0.1.0/connector-packaging.json b/registry/hasura/mongodb/releases/v0.1.0/connector-packaging.json similarity index 100% rename from registry/hasura/mongodb/releases/0.1.0/connector-packaging.json rename to registry/hasura/mongodb/releases/v0.1.0/connector-packaging.json diff --git a/registry/hasura/mongodb/releases/1.0.0/connector-packaging.json b/registry/hasura/mongodb/releases/v1.0.0/connector-packaging.json similarity index 100% rename from registry/hasura/mongodb/releases/1.0.0/connector-packaging.json rename to registry/hasura/mongodb/releases/v1.0.0/connector-packaging.json diff --git a/registry/hasura/mongodb/releases/1.1.0/connector-packaging.json b/registry/hasura/mongodb/releases/v1.1.0/connector-packaging.json similarity index 100% rename from registry/hasura/mongodb/releases/1.1.0/connector-packaging.json rename to registry/hasura/mongodb/releases/v1.1.0/connector-packaging.json diff --git a/registry/hasura/mongodb/releases/v1.2.0/connector-packaging.json b/registry/hasura/mongodb/releases/v1.2.0/connector-packaging.json new file mode 100644 index 00000000..28c279f4 --- /dev/null +++ b/registry/hasura/mongodb/releases/v1.2.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.2.0", + "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v1.2.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "b5c317d6b122f191d2e72227d587076153cd93e5101d5830446d131dd32311a5" + }, + "source": { + "hash": "2e0696e8bd587c18f067e683ec367f6ba350537f" + } +} From b6e7f2b379d2986fa9b4aba867fef5e9da64c9df Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Tue, 17 Sep 2024 11:54:56 +0530 Subject: [PATCH 086/135] publish ndc-sqlserver: v0.2.1 (#288) --- registry/hasura/sqlserver/metadata.json | 4 ++-- .../releases/v0.2.1/connector-packaging.json | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 registry/hasura/sqlserver/releases/v0.2.1/connector-packaging.json diff --git a/registry/hasura/sqlserver/metadata.json b/registry/hasura/sqlserver/metadata.json index 1017adf9..4607df8d 100644 --- a/registry/hasura/sqlserver/metadata.json +++ b/registry/hasura/sqlserver/metadata.json @@ -5,7 +5,7 @@ "title": "SQL Server Connector", "logo": "logo.png", "tags": ["database"], - "latest_version": "v0.1.2" + "latest_version": "v0.2.1" }, "author": { "support_email": "support@hasura.io", @@ -70,4 +70,4 @@ } ] } -} \ No newline at end of file +} diff --git a/registry/hasura/sqlserver/releases/v0.2.1/connector-packaging.json b/registry/hasura/sqlserver/releases/v0.2.1/connector-packaging.json new file mode 100644 index 00000000..22dde26a --- /dev/null +++ b/registry/hasura/sqlserver/releases/v0.2.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.1", + "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.2.1/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "ab32dcdbf66df75a7ca6a319d433b6057afe89bec203378abad857a13608f285" + }, + "source": { + "hash": "35dd850de629234553b3338f4c1ab976b20d77b6" + } +} From fc269931eaaa3869254dc48cd5852615149d7f70 Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Wed, 18 Sep 2024 15:46:08 +0530 Subject: [PATCH 087/135] release `v0.2.0` for azure cosmos (#289) --- .../releases/v0.2.0/connector-packaging.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 registry/hasura/azure-cosmos/releases/v0.2.0/connector-packaging.json diff --git a/registry/hasura/azure-cosmos/releases/v0.2.0/connector-packaging.json b/registry/hasura/azure-cosmos/releases/v0.2.0/connector-packaging.json new file mode 100644 index 00000000..0e557006 --- /dev/null +++ b/registry/hasura/azure-cosmos/releases/v0.2.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.2.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "4457e122a608f055fae0cc312b6850c0213ddbbfbce1b0af8356b5c00f2f322f" + }, + "source": { + "hash": "5478d2a3b282d7a61961a8de8f7df3ebbb29c5c4" + } +} From 02640a04fec0dc06b9b33927d388cc18ba07d126 Mon Sep 17 00:00:00 2001 From: Daniel Chambers Date: Fri, 20 Sep 2024 15:44:54 +1000 Subject: [PATCH 088/135] Add nodejs v1.8.0 (#293) Adds NodeJS Lambda Connector v1.8.0 --- registry/hasura/nodejs/metadata.json | 7 ++++++- .../nodejs/releases/v1.8.0/connector-packaging.json | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 registry/hasura/nodejs/releases/v1.8.0/connector-packaging.json diff --git a/registry/hasura/nodejs/metadata.json b/registry/hasura/nodejs/metadata.json index e029c2cb..4bb64ce5 100644 --- a/registry/hasura/nodejs/metadata.json +++ b/registry/hasura/nodejs/metadata.json @@ -5,7 +5,7 @@ "title": "NodeJS Lambda Connector", "logo": "logo.png", "tags": [], - "latest_version": "v1.7.0" + "latest_version": "v1.8.0" }, "author": { "support_email": "support@hasura.io", @@ -18,6 +18,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-nodejs-lambda/", "version": [ + { + "tag": "v1.8.0", + "hash": "c1442716e822f7748e06aa25dd4f348e536d60cd", + "is_verified": true + }, { "tag": "v1.7.0", "hash": "1adf00b7c36dd811d5e15894c1a141149db6325f", diff --git a/registry/hasura/nodejs/releases/v1.8.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.8.0/connector-packaging.json new file mode 100644 index 00000000..a5c8a627 --- /dev/null +++ b/registry/hasura/nodejs/releases/v1.8.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.8.0", + "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.8.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "4df5634a7afc6cfacdb019257138a234b3a60b846e3740e38886ce80d43c3fdd" + }, + "source": { + "hash": "c1442716e822f7748e06aa25dd4f348e536d60cd" + } +} From b465c86aa2e6231ae8580f644853c12537849b24 Mon Sep 17 00:00:00 2001 From: Toan Nguyen Date: Fri, 20 Sep 2024 14:01:34 +0700 Subject: [PATCH 089/135] Add ndc-go v1.3.1 (#292) Add NDC SDK Go v1.3.1 --- registry/hasura/go/README.md | 5 ++ registry/hasura/go/metadata.json | 75 ++----------------- .../releases/v1.3.1/connector-packaging.json | 11 +++ 3 files changed, 22 insertions(+), 69 deletions(-) create mode 100644 registry/hasura/go/releases/v1.3.1/connector-packaging.json diff --git a/registry/hasura/go/README.md b/registry/hasura/go/README.md index 2b108ff1..6434f6df 100644 --- a/registry/hasura/go/README.md +++ b/registry/hasura/go/README.md @@ -15,3 +15,8 @@ See the README file in the boilerplate which is generated from [this template](h | ---------- | ----------- | | 1.21+ | v1.x | | 1.19+ | v0.x | + +## More Information + +- [Hasura DDN Documentation](https://hasura.io/docs/3.0/business-logic/go) +- [GitHub Repository](https://github.com/hasura/ndc-sdk-go/tree/main/cmd/hasura-ndc-go) diff --git a/registry/hasura/go/metadata.json b/registry/hasura/go/metadata.json index 7ec5ece4..02719841 100644 --- a/registry/hasura/go/metadata.json +++ b/registry/hasura/go/metadata.json @@ -5,7 +5,7 @@ "title": "Go Connector", "logo": "logo.svg", "tags": [], - "latest_version": "v1.2.3" + "latest_version": "v1.3.1" }, "author": { "support_email": "support@hasura.io", @@ -14,78 +14,15 @@ }, "is_verified": true, "is_hosted_by_hasura": false, - "packages": [ - { - "version": "v1.2.3", - "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.2.3/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "9573485be49d633ab3a7b39e8777da2d3524702fafac1739e42217caf5b3ad9a" - }, - "source": { - "hash": "1fdc72d31dccae129d6d626dea6e31b5cd3b0b18" - } - }, - { - "version": "v1.1.2", - "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.1.2/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "2e037c86fd4da3f07417a7216a7921b885a4e13b8da15210e1cd13cc4ee728f1" - }, - "source": { - "hash": "32e28e549f11b790c320b6a79ad33ad8e6df5bd7" - } - }, - { - "version": "v1.0.0", - "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.0.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "906db79cf5565eaca731436180295d2d7ee81246b57cc7dcdde14585841f53a5" - }, - "source": { - "hash": "42259e9a9c719131721f0058c552e9b8a4a36973" - } - }, - { - "version": "v0.6.3", - "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v0.6.3/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "e6ebd14bc1a75ab384da80eae7a823dd6883af6a574b42d720358d873491f96e" - }, - "source": { - "hash": "726b3fbb442fae62d18840905545f1d663baf87b" - } - }, - { - "version": "v0.5.2", - "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v0.5.2/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "dfb2ea7499744a1ad00673703eed28bccaf38b4866721f5b0aacb546d788a659" - }, - "source": { - "hash": "79788195359a5e3cf0fc8896b61eb8f4d9196427" - } - }, - { - "version": "v0.4.0", - "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v0.4.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "13e6c4e970e032307cbb9edbb9d79ad555880c46d8a58d98f23ce441cef7d7b2" - }, - "source": { - "hash": "ac27498b6dbd5e803ca97e0fc702f52e2d9b429d" - } - } - ], "source_code": { "is_open_source": true, "repository": "https://github.com/hasura/ndc-sdk-go", "version": [ + { + "tag": "v1.3.1", + "hash": "f6093ca96fe64063df786159a2bb061c01d9197d", + "is_verified": true + }, { "tag": "v1.2.3", "hash": "1fdc72d31dccae129d6d626dea6e31b5cd3b0b18", diff --git a/registry/hasura/go/releases/v1.3.1/connector-packaging.json b/registry/hasura/go/releases/v1.3.1/connector-packaging.json new file mode 100644 index 00000000..3628891b --- /dev/null +++ b/registry/hasura/go/releases/v1.3.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v1.3.1", + "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.3.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "be6e634b8c989e4e13d68959e1daed9b76d64ae1337c52e0a0295f3bc5873d2e" + }, + "source": { + "hash": "f6093ca96fe64063df786159a2bb061c01d9197d" + } +} From f4ea877c2f7a7d5997bc38d15f488e0c5eb65537 Mon Sep 17 00:00:00 2001 From: pranshi06 <85474619+pranshi06@users.noreply.github.com> Date: Fri, 20 Sep 2024 22:56:37 +0530 Subject: [PATCH 090/135] release BigQuery (#295) --- registry/hasura/bigquery/README.md | 114 ++++++++++++++++++ registry/hasura/bigquery/logo.png | Bin 0 -> 3065 bytes registry/hasura/bigquery/metadata.json | 41 +++++++ .../releases/v0.1.1/connector-packaging.json | 11 ++ 4 files changed, 166 insertions(+) create mode 100644 registry/hasura/bigquery/README.md create mode 100644 registry/hasura/bigquery/logo.png create mode 100644 registry/hasura/bigquery/metadata.json create mode 100644 registry/hasura/bigquery/releases/v0.1.1/connector-packaging.json diff --git a/registry/hasura/bigquery/README.md b/registry/hasura/bigquery/README.md new file mode 100644 index 00000000..e182c2c0 --- /dev/null +++ b/registry/hasura/bigquery/README.md @@ -0,0 +1,114 @@ +# BigQuery Connector + +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-bigquery-blue.svg?style=flat)](https://hasura.io/connectors/bigquery) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) +[![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) + +With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in +BigQuery. This connector supports BigQuery's functionalities listed in the table below, allowing for +efficient and scalable data operations. Additionally, users benefit from all the powerful features of Hasura’s Data +Delivery Network (DDN) platform, including query pushdown capabilities that delegate query operations to the database, +thereby enhancing query optimization and performance. + +This connector is built using the [Rust Data Connector SDK](https://github.com/hasura/ndc-hub#rusk-sdk) and implements +the [Data Connector Spec](https://github.com/hasura/ndc-spec). + +- [See the listing in the Hasura Hub](https://hasura.io/connectors/bigquery) +- [Hasura V3 Documentation](https://hasura.io/docs/3.0/) + +## Features + +Below, you'll find a matrix of all supported features for the BigQuery connector: + +| Feature | Supported | Notes | +|---------------------------------|-----------|--------------------------------------| +| Native Queries + Logical Models | ❌ | | +| Native Mutations | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ❌ | | +| Views | ✅ | | +| Remote Relationships | ❌ | | +| Stored Procedures | ❌ | | +| Custom Fields | ❌ | | +| Mutations | ❌ | | +| Distinct | ✅ | | +| Enums | ❌ | | +| Naming Conventions | ❌ | | +| Default Values | ❌ | | +| User-defined Functions | ❌ | | + +## Before you get Started + +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) + +The steps below explain how to Initialize and configure a connector for local development. You can learn how to deploy a +connector — after it's been configured — [here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). + +## Using the BigQuery connector + +### Step 1: Authenticate your CLI session + +```bash +ddn auth login +``` + +### Step 2: Configure the connector + +Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while +providing a name for the connector in the prompt: + +```bash +ddn connector init -i +``` + +#### Step 2.1: Choose the `hasura/bigquery` from the list + +#### Step 2.2: Choose a port for the connector + +The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the +default suggested port. + +#### Step 2.3: Provide the env vars for the connector + +| Name | Description | Required | Default | +|-----------------------------|--------------------------------------------------|----------|---------| +| HASURA_BIGQUERY_SERVICE_KEY | The service key of the BigQuery project | Yes | N/A | +| HASURA_BIGQUERY_PROJECT_ID | The project ID of the BigQuery databse project | Yes | N/A | +| HASURA_BIGQUERY_DATASET_ID | The dataset ID of the BigQuery databse project | Yes | N/A | + +## Step 3: Introspect the connector + +```bash +ddn connector introspect +``` + +This will generate a `configuration.json` file that will have the schema of your BigQuery database. + +## Step 4: Add your resources + +```bash +ddn model add '*' +``` + +This command will track all the containers in your BigQuery DB as [Models](https://hasura.io/docs/3.0/supergraph-modeling/models). + +## Documentation + +View the full documentation for the ndc-bigquery connector [here](./docs/readme.md). + +## Contributing + +We're happy to receive any contributions from the community. Please refer to our [development guide](./docs/development.md). + +## License + +The Hasura BigQuery connector is available under the [Apache License +2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/registry/hasura/bigquery/logo.png b/registry/hasura/bigquery/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..997915e29ffe55c2b2825eb51a998abcdc3bcdc5 GIT binary patch literal 3065 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 Date: Fri, 20 Sep 2024 20:45:51 +0300 Subject: [PATCH 091/135] release singlestore v0.0.3(#294) --- registry/hasura/singlestore/README.md | 2 +- registry/hasura/singlestore/metadata.json | 7 ++++++- .../releases/v0.0.3/connector-packaging.json | 11 +++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 registry/hasura/singlestore/releases/v0.0.3/connector-packaging.json diff --git a/registry/hasura/singlestore/README.md b/registry/hasura/singlestore/README.md index f5efeef7..9a707795 100644 --- a/registry/hasura/singlestore/README.md +++ b/registry/hasura/singlestore/README.md @@ -1,6 +1,6 @@ # SingleStore Data Connector - + [![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/latest/connectors/singesltore/) diff --git a/registry/hasura/singlestore/metadata.json b/registry/hasura/singlestore/metadata.json index c421d274..46c26690 100644 --- a/registry/hasura/singlestore/metadata.json +++ b/registry/hasura/singlestore/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.0.2" + "latest_version": "v0.0.3" }, "author": { "support_email": "integrations@singlestore.com", @@ -29,6 +29,11 @@ "tag": "v0.0.2", "hash": "2afe3150215fbd6bf8a93ee6f853ad232e5d101d", "is_verified": false + }, + { + "tag": "v0.0.3", + "hash": "72ed900d5cc6819614fa27bba7bdba8977eedc6d", + "is_verified": false } ] } diff --git a/registry/hasura/singlestore/releases/v0.0.3/connector-packaging.json b/registry/hasura/singlestore/releases/v0.0.3/connector-packaging.json new file mode 100644 index 00000000..36603350 --- /dev/null +++ b/registry/hasura/singlestore/releases/v0.0.3/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.3", + "uri": "https://github.com/singlestore-labs/singlestore-hasura-connector/releases/download/v0.0.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "69b44fa9549c041bb1d0570847f18180402eef3d3ee1281b20fae45693444d5b" + }, + "source": { + "hash": "72ed900d5cc6819614fa27bba7bdba8977eedc6d" + } +} From 91ee98b410e1a76696aa3720a91a24e8500436ec Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Fri, 20 Sep 2024 10:47:05 -0700 Subject: [PATCH 092/135] fix doc link in mongodb connector readme (#285) --- registry/hasura/mongodb/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/hasura/mongodb/README.md b/registry/hasura/mongodb/README.md index de06d1b5..23d3ef46 100644 --- a/registry/hasura/mongodb/README.md +++ b/registry/hasura/mongodb/README.md @@ -10,7 +10,7 @@ The connector implements the [NDC Specification](https://hasura.github.io/ndc-sp but does not currently support mutations, column relationship arguments in queries, functions or procedures. Visit the -[Hasura v3 Documentation](https://hasura.io/docs/3.0/native-data-connectors/mongodb) +[Hasura v3 Documentation](https://hasura.io/docs/3.0/connectors/mongodb/) for more information. ## Usage From 065ba7df1846854c30b8b76077ddca2630c46d41 Mon Sep 17 00:00:00 2001 From: Mohd Bilal Date: Mon, 23 Sep 2024 22:28:41 +0530 Subject: [PATCH 093/135] release openapi connector v0.1.5 (#297) --- registry/hasura/openapi/metadata.json | 2 +- .../openapi/releases/v0.1.5/connector-packaging.json | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 registry/hasura/openapi/releases/v0.1.5/connector-packaging.json diff --git a/registry/hasura/openapi/metadata.json b/registry/hasura/openapi/metadata.json index 19f8aa1a..45b2a3bd 100644 --- a/registry/hasura/openapi/metadata.json +++ b/registry/hasura/openapi/metadata.json @@ -5,7 +5,7 @@ "title": "OpenAPI Lambda Connector", "logo": "logo.png", "tags": [], - "latest_version": "v0.1.3" + "latest_version": "v0.1.5" }, "author": { "support_email": "support@hasura.io", diff --git a/registry/hasura/openapi/releases/v0.1.5/connector-packaging.json b/registry/hasura/openapi/releases/v0.1.5/connector-packaging.json new file mode 100644 index 00000000..82565a90 --- /dev/null +++ b/registry/hasura/openapi/releases/v0.1.5/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.5", + "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.1.5/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "253f250632159b8e7929ca461ab05d0101418b01826541762372e56f00a276cc" + }, + "source": { + "hash": "934491f158736401449c8144186330a1eeac78b7" + } +} From 6ca5f2d15a55373b84e3ea64c42a99f48ea92147 Mon Sep 17 00:00:00 2001 From: Akshaya Acharya Date: Tue, 24 Sep 2024 05:37:54 +0530 Subject: [PATCH 094/135] Rename file to fix RFC numbering sequence (#281) Renamed a file, noop otherwise --- ...-and-capabilities.md => 0008-print-schema-and-capabilities.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename rfcs/{008-print-schema-and-capabilities.md => 0008-print-schema-and-capabilities.md} (100%) diff --git a/rfcs/008-print-schema-and-capabilities.md b/rfcs/0008-print-schema-and-capabilities.md similarity index 100% rename from rfcs/008-print-schema-and-capabilities.md rename to rfcs/0008-print-schema-and-capabilities.md From 5de98d35fdfc51ddcb5bbcfa7459e131f5335861 Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Tue, 24 Sep 2024 10:51:35 +0530 Subject: [PATCH 095/135] Update azure cosmos README (#299) --- registry/hasura/azure-cosmos/README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/registry/hasura/azure-cosmos/README.md b/registry/hasura/azure-cosmos/README.md index ede56fad..5b011b80 100644 --- a/registry/hasura/azure-cosmos/README.md +++ b/registry/hasura/azure-cosmos/README.md @@ -17,18 +17,18 @@ This connector is built using the [TypeScript Data Connector SDK](https://github Below, you'll find a matrix of all supported features for the Azure Cosmos DB for NoSQL connector: | Feature | Supported | Notes | -| ------------------------------- | --------- | ----- | -| Native Queries + Logical Models | ✅ | | -| Simple Object Query | ✅ | | -| Filter / Search | ✅ | | -| Simple Aggregation | ✅ | | -| Sort | ✅ | | -| Paginate | ✅ | | -| Nested Objects | ✅ | | -| Nested Arrays | ✅ | | -| Nested Filtering | ❌ | | -| Nested Sorting | ❌ | | -| Nested Relationships | ❌ | | +|---------------------------------|-----------|-------| +| Native Queries + Logical Models | ✅ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Nested Objects | ✅ | | +| Nested Arrays | ✅ | | +| Nested Filtering | ✅ | | +| Nested Sorting | ❌ | | +| Nested Relationships | ❌ | | ## Before you get Started From 79f6e2ea7077d0b8ef20806620a451ce3602947f Mon Sep 17 00:00:00 2001 From: Gavin Ray Date: Tue, 24 Sep 2024 13:50:39 -0400 Subject: [PATCH 096/135] Initial Apache Phoenix connector (#291) Co-authored-by: gneeri --- registry/hasura/phoenix/README.md | 68 ++++++++++++++++++ registry/hasura/phoenix/logo.png | Bin 0 -> 29188 bytes registry/hasura/phoenix/metadata.json | 43 +++++++++++ .../releases/v1.0.0/connector-packaging.json | 11 +++ 4 files changed, 122 insertions(+) create mode 100644 registry/hasura/phoenix/README.md create mode 100644 registry/hasura/phoenix/logo.png create mode 100644 registry/hasura/phoenix/metadata.json create mode 100644 registry/hasura/phoenix/releases/v1.0.0/connector-packaging.json diff --git a/registry/hasura/phoenix/README.md b/registry/hasura/phoenix/README.md new file mode 100644 index 00000000..ce1330f8 --- /dev/null +++ b/registry/hasura/phoenix/README.md @@ -0,0 +1,68 @@ +# Apache Phoenix Connector + +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/getting-started/overview/) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-phoenix-blue.svg?style=flat)](https://hasura.io/connectors/phoenix) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) +[![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) + +With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in +Phoenix. This connector supports Phoenix's functionalities listed in the table below, allowing for +efficient and scalable data operations. Additionally, users benefit from all the powerful features of Hasura’s Data +Delivery Network (DDN) platform, including query pushdown capabilities that delegate query operations to the database, +thereby enhancing query optimization and performance. + +This connector implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). + +- [Connector information in the Hasura Hub](https://hasura.io/connectors/phoenix) +- [Hasura V3 Documentation](https://hasura.io/docs/3.0) + +## Features + +Below, you'll find a matrix of all supported features for the Phoenix connector: + +| Feature | Supported | Notes | +| ------------------------------- | --------- | ----- | +| Native Queries + Logical Models | ✅ | | +| Native Mutations | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ❌ | | +| Views | ✅ | | +| Remote Relationships | ✅ | | +| Custom Fields | ❌ | | +| Mutations | ❌ | | +| Distinct | ❌ | | +| Enums | ❌ | | +| Naming Conventions | ❌ | | +| Default Values | ❌ | | +| User-defined Functions | ❌ | | + +## Before you get Started + +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Install the [CLI](https://hasura.io/docs/3.0/cli/installation/) +3. Install the [Hasura VS Code extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) +4. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +5. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) + +## Using the connector + +To use the Phoenix connector, follow these steps in a Hasura project: +(Note: for more information on the following steps, please refer to the Postgres connector +documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) + + +The connector requires a JDBC URL to function. +For example: + +```sh +JDBC_URL="jdbc:phoenix:localhost:2181:/hbase" +``` + +## License + +The Hasura Phoenix connector is available under the [Apache License +2.0](https://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file diff --git a/registry/hasura/phoenix/logo.png b/registry/hasura/phoenix/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9a1e8ca51da8f9a838f6341c16321c0a3eb0438d GIT binary patch literal 29188 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 Date: Wed, 25 Sep 2024 14:19:45 +0530 Subject: [PATCH 097/135] Move the `postgres` aliased connectors within the postgres folder and nuke `typescript-deno` (#302) This PR moves the following connector folders within the `postgres` folder under `aliased_connectors`. 1. postgres-alloydb 2. postgres-timescaledb 3. postgres-gcp 4. postgres-cosmos 5. postgres-azure 6. citus 7. yugabyte 8. neon 9. aurora Also, the `typescript-deno` is completely removed as it is not used anywhere anymore. --- .../aliased_connectors}/aurora/README.md | 0 .../aliased_connectors}/aurora/logo.svg | 0 .../aliased_connectors}/aurora/metadata.json | 0 .../aliased_connectors}/citus/README.md | 0 .../aliased_connectors}/citus/logo.svg | 0 .../aliased_connectors}/citus/metadata.json | 0 .../aliased_connectors}/neon/README.md | 0 .../aliased_connectors}/neon/logo.svg | 0 .../aliased_connectors}/neon/metadata.json | 0 .../postgres-alloydb/README.md | 0 .../postgres-alloydb/logo.png | Bin .../postgres-alloydb/metadata.json | 0 .../postgres-azure/README.md | 0 .../postgres-azure/logo.png | Bin .../postgres-azure/metadata.json | 0 .../postgres-cosmos/README.md | 0 .../postgres-cosmos/logo.png | Bin .../postgres-cosmos/metadata.json | 0 .../postgres-gcp/README.md | 0 .../aliased_connectors}/postgres-gcp/logo.png | Bin .../postgres-gcp/metadata.json | 0 .../postgres-timescaledb/README.md | 0 .../postgres-timescaledb/logo.png | Bin .../postgres-timescaledb/metadata.json | 0 .../aliased_connectors}/yugabyte/README.md | 0 .../aliased_connectors}/yugabyte/logo.svg | 0 .../yugabyte/metadata.json | 0 registry/hasura/typescript-deno/README.md | 157 ------------------ registry/hasura/typescript-deno/logo.png | Bin 40438 -> 0 bytes registry/hasura/typescript-deno/metadata.json | 53 ------ 30 files changed, 210 deletions(-) rename registry/hasura/{ => postgres/aliased_connectors}/aurora/README.md (100%) rename registry/hasura/{ => postgres/aliased_connectors}/aurora/logo.svg (100%) rename registry/hasura/{ => postgres/aliased_connectors}/aurora/metadata.json (100%) rename registry/hasura/{ => postgres/aliased_connectors}/citus/README.md (100%) rename registry/hasura/{ => postgres/aliased_connectors}/citus/logo.svg (100%) rename registry/hasura/{ => postgres/aliased_connectors}/citus/metadata.json (100%) rename registry/hasura/{ => postgres/aliased_connectors}/neon/README.md (100%) rename registry/hasura/{ => postgres/aliased_connectors}/neon/logo.svg (100%) rename registry/hasura/{ => postgres/aliased_connectors}/neon/metadata.json (100%) rename registry/hasura/{ => postgres/aliased_connectors}/postgres-alloydb/README.md (100%) rename registry/hasura/{ => postgres/aliased_connectors}/postgres-alloydb/logo.png (100%) rename registry/hasura/{ => postgres/aliased_connectors}/postgres-alloydb/metadata.json (100%) rename registry/hasura/{ => postgres/aliased_connectors}/postgres-azure/README.md (100%) rename registry/hasura/{ => postgres/aliased_connectors}/postgres-azure/logo.png (100%) rename registry/hasura/{ => postgres/aliased_connectors}/postgres-azure/metadata.json (100%) rename registry/hasura/{ => postgres/aliased_connectors}/postgres-cosmos/README.md (100%) rename registry/hasura/{ => postgres/aliased_connectors}/postgres-cosmos/logo.png (100%) rename registry/hasura/{ => postgres/aliased_connectors}/postgres-cosmos/metadata.json (100%) rename registry/hasura/{ => postgres/aliased_connectors}/postgres-gcp/README.md (100%) rename registry/hasura/{ => postgres/aliased_connectors}/postgres-gcp/logo.png (100%) rename registry/hasura/{ => postgres/aliased_connectors}/postgres-gcp/metadata.json (100%) rename registry/hasura/{ => postgres/aliased_connectors}/postgres-timescaledb/README.md (100%) rename registry/hasura/{ => postgres/aliased_connectors}/postgres-timescaledb/logo.png (100%) rename registry/hasura/{ => postgres/aliased_connectors}/postgres-timescaledb/metadata.json (100%) rename registry/hasura/{ => postgres/aliased_connectors}/yugabyte/README.md (100%) rename registry/hasura/{ => postgres/aliased_connectors}/yugabyte/logo.svg (100%) rename registry/hasura/{ => postgres/aliased_connectors}/yugabyte/metadata.json (100%) delete mode 100644 registry/hasura/typescript-deno/README.md delete mode 100644 registry/hasura/typescript-deno/logo.png delete mode 100644 registry/hasura/typescript-deno/metadata.json diff --git a/registry/hasura/aurora/README.md b/registry/hasura/postgres/aliased_connectors/aurora/README.md similarity index 100% rename from registry/hasura/aurora/README.md rename to registry/hasura/postgres/aliased_connectors/aurora/README.md diff --git a/registry/hasura/aurora/logo.svg b/registry/hasura/postgres/aliased_connectors/aurora/logo.svg similarity index 100% rename from registry/hasura/aurora/logo.svg rename to registry/hasura/postgres/aliased_connectors/aurora/logo.svg diff --git a/registry/hasura/aurora/metadata.json b/registry/hasura/postgres/aliased_connectors/aurora/metadata.json similarity index 100% rename from registry/hasura/aurora/metadata.json rename to registry/hasura/postgres/aliased_connectors/aurora/metadata.json diff --git a/registry/hasura/citus/README.md b/registry/hasura/postgres/aliased_connectors/citus/README.md similarity index 100% rename from registry/hasura/citus/README.md rename to registry/hasura/postgres/aliased_connectors/citus/README.md diff --git a/registry/hasura/citus/logo.svg b/registry/hasura/postgres/aliased_connectors/citus/logo.svg similarity index 100% rename from registry/hasura/citus/logo.svg rename to registry/hasura/postgres/aliased_connectors/citus/logo.svg diff --git a/registry/hasura/citus/metadata.json b/registry/hasura/postgres/aliased_connectors/citus/metadata.json similarity index 100% rename from registry/hasura/citus/metadata.json rename to registry/hasura/postgres/aliased_connectors/citus/metadata.json diff --git a/registry/hasura/neon/README.md b/registry/hasura/postgres/aliased_connectors/neon/README.md similarity index 100% rename from registry/hasura/neon/README.md rename to registry/hasura/postgres/aliased_connectors/neon/README.md diff --git a/registry/hasura/neon/logo.svg b/registry/hasura/postgres/aliased_connectors/neon/logo.svg similarity index 100% rename from registry/hasura/neon/logo.svg rename to registry/hasura/postgres/aliased_connectors/neon/logo.svg diff --git a/registry/hasura/neon/metadata.json b/registry/hasura/postgres/aliased_connectors/neon/metadata.json similarity index 100% rename from registry/hasura/neon/metadata.json rename to registry/hasura/postgres/aliased_connectors/neon/metadata.json diff --git a/registry/hasura/postgres-alloydb/README.md b/registry/hasura/postgres/aliased_connectors/postgres-alloydb/README.md similarity index 100% rename from registry/hasura/postgres-alloydb/README.md rename to registry/hasura/postgres/aliased_connectors/postgres-alloydb/README.md diff --git a/registry/hasura/postgres-alloydb/logo.png b/registry/hasura/postgres/aliased_connectors/postgres-alloydb/logo.png similarity index 100% rename from registry/hasura/postgres-alloydb/logo.png rename to registry/hasura/postgres/aliased_connectors/postgres-alloydb/logo.png diff --git a/registry/hasura/postgres-alloydb/metadata.json b/registry/hasura/postgres/aliased_connectors/postgres-alloydb/metadata.json similarity index 100% rename from registry/hasura/postgres-alloydb/metadata.json rename to registry/hasura/postgres/aliased_connectors/postgres-alloydb/metadata.json diff --git a/registry/hasura/postgres-azure/README.md b/registry/hasura/postgres/aliased_connectors/postgres-azure/README.md similarity index 100% rename from registry/hasura/postgres-azure/README.md rename to registry/hasura/postgres/aliased_connectors/postgres-azure/README.md diff --git a/registry/hasura/postgres-azure/logo.png b/registry/hasura/postgres/aliased_connectors/postgres-azure/logo.png similarity index 100% rename from registry/hasura/postgres-azure/logo.png rename to registry/hasura/postgres/aliased_connectors/postgres-azure/logo.png diff --git a/registry/hasura/postgres-azure/metadata.json b/registry/hasura/postgres/aliased_connectors/postgres-azure/metadata.json similarity index 100% rename from registry/hasura/postgres-azure/metadata.json rename to registry/hasura/postgres/aliased_connectors/postgres-azure/metadata.json diff --git a/registry/hasura/postgres-cosmos/README.md b/registry/hasura/postgres/aliased_connectors/postgres-cosmos/README.md similarity index 100% rename from registry/hasura/postgres-cosmos/README.md rename to registry/hasura/postgres/aliased_connectors/postgres-cosmos/README.md diff --git a/registry/hasura/postgres-cosmos/logo.png b/registry/hasura/postgres/aliased_connectors/postgres-cosmos/logo.png similarity index 100% rename from registry/hasura/postgres-cosmos/logo.png rename to registry/hasura/postgres/aliased_connectors/postgres-cosmos/logo.png diff --git a/registry/hasura/postgres-cosmos/metadata.json b/registry/hasura/postgres/aliased_connectors/postgres-cosmos/metadata.json similarity index 100% rename from registry/hasura/postgres-cosmos/metadata.json rename to registry/hasura/postgres/aliased_connectors/postgres-cosmos/metadata.json diff --git a/registry/hasura/postgres-gcp/README.md b/registry/hasura/postgres/aliased_connectors/postgres-gcp/README.md similarity index 100% rename from registry/hasura/postgres-gcp/README.md rename to registry/hasura/postgres/aliased_connectors/postgres-gcp/README.md diff --git a/registry/hasura/postgres-gcp/logo.png b/registry/hasura/postgres/aliased_connectors/postgres-gcp/logo.png similarity index 100% rename from registry/hasura/postgres-gcp/logo.png rename to registry/hasura/postgres/aliased_connectors/postgres-gcp/logo.png diff --git a/registry/hasura/postgres-gcp/metadata.json b/registry/hasura/postgres/aliased_connectors/postgres-gcp/metadata.json similarity index 100% rename from registry/hasura/postgres-gcp/metadata.json rename to registry/hasura/postgres/aliased_connectors/postgres-gcp/metadata.json diff --git a/registry/hasura/postgres-timescaledb/README.md b/registry/hasura/postgres/aliased_connectors/postgres-timescaledb/README.md similarity index 100% rename from registry/hasura/postgres-timescaledb/README.md rename to registry/hasura/postgres/aliased_connectors/postgres-timescaledb/README.md diff --git a/registry/hasura/postgres-timescaledb/logo.png b/registry/hasura/postgres/aliased_connectors/postgres-timescaledb/logo.png similarity index 100% rename from registry/hasura/postgres-timescaledb/logo.png rename to registry/hasura/postgres/aliased_connectors/postgres-timescaledb/logo.png diff --git a/registry/hasura/postgres-timescaledb/metadata.json b/registry/hasura/postgres/aliased_connectors/postgres-timescaledb/metadata.json similarity index 100% rename from registry/hasura/postgres-timescaledb/metadata.json rename to registry/hasura/postgres/aliased_connectors/postgres-timescaledb/metadata.json diff --git a/registry/hasura/yugabyte/README.md b/registry/hasura/postgres/aliased_connectors/yugabyte/README.md similarity index 100% rename from registry/hasura/yugabyte/README.md rename to registry/hasura/postgres/aliased_connectors/yugabyte/README.md diff --git a/registry/hasura/yugabyte/logo.svg b/registry/hasura/postgres/aliased_connectors/yugabyte/logo.svg similarity index 100% rename from registry/hasura/yugabyte/logo.svg rename to registry/hasura/postgres/aliased_connectors/yugabyte/logo.svg diff --git a/registry/hasura/yugabyte/metadata.json b/registry/hasura/postgres/aliased_connectors/yugabyte/metadata.json similarity index 100% rename from registry/hasura/yugabyte/metadata.json rename to registry/hasura/postgres/aliased_connectors/yugabyte/metadata.json diff --git a/registry/hasura/typescript-deno/README.md b/registry/hasura/typescript-deno/README.md deleted file mode 100644 index f4e2311b..00000000 --- a/registry/hasura/typescript-deno/README.md +++ /dev/null @@ -1,157 +0,0 @@ -## Overview - -The Typescript (Deno) Connector allows a running connector to be inferred from a Typescript file (optionally with dependencies) and interpreted by [Deno](https://deno.com). - -[github.com/hasura/ndc-typescript-deno](https://github.com/hasura/ndc-typescript-deno/tree/main#ndc-typescript-deno) - -The connector runs in the following manner: - -* Dependencies are fetched -* Inference is performed -* The functions are served via the [connector protocol](https://github.com/hasura/ndc-spec/tree/main#ndc-specification) - -It assumes that dependencies are specified in accordance with [Deno](https://deno.com) conventions. - -## Typescript Functions Format - -Your functions should be organised into a directory with `index.ts` file acting as the entrypoint. - -``` -// ./functions/index.ts - -import { Hash, encode } from "https://deno.land/x/checksum@1.2.0/mod.ts"; - -/** - * Returns an MD5 hash of the given password - * - * @param pw - Password string - * @returns The MD5 hash of the password string - * @pure This function should only query data without making modifications - */ -export function make_password_hash(pw: string): string { - return new Hash("md5").digest(encode(pw)).hex(); -} -``` - -* JSDoc comments and tags are exposed in the schema -* Async, and normal functions are both supported -* Only exported functions are exposed -* Functions tagged with `@pure` annotations are exposed as functions -* Those without `@pure` annotations are exposed as procedures -* Optional parameters are supported -* Exceptions can be thrown and will be reported to the user - -## Function Development - -For the best user-experience you should develop your functions in the following manner: - -* Have [Deno](https://deno.com) installed -* Have [VSCode](https://code.visualstudio.com) installed -* Have the [Deno VSCode extension](https://marketplace.visualstudio.com/items?itemName=denoland.vscode-deno) installed -* Have the Hasura V3 CLI Installed -* Have the Hasura VSCode extension - -An example session: - -``` -> tree -. -├── config.json -├── functions - ├── index.ts - -> cat config.json -{ - "functions": "./functions/index.ts" -} - -> cat functions/index.ts - -export function hello(): string { - return "hello world"; -} - -function foo() { -} - -> deno run -A --watch --check https://deno.land/x/hasura_typescript_connector@0.20/mod.ts serve --configuration ./config.json -Watcher Process started. -Check file:///Users/me/projects/example/functions/index.ts -Inferring schema with map location ./vendor -Vendoring dependencies: /Users/me/bin/binaries/deno vendor --output /Users/me/projects/example/vendor --force /Users/me/projects/example/functions/index.ts -Skipping non-exported function: foo -{"level":30,"time":1697018006809,"pid":89762,"hostname":"spaceship.local","msg":"Server listening at http://0.0.0.0:8100"} -``` - -Alternatively, if you have the `hasura3` CLI installed you can use the `hasura3 watch` command to watch and serve your functions and tunnel them automatically into a hasura project and console. - -If you are happy with your definitions you can deploy your connector via the `hasura3 connector` commands. - - -## Deployment - -You will need: - -* [V3 CLI](https://github.com/hasura/v3-cli) (with a logged in session) -* [Connector Plugin](https://hasura.io/docs/latest/hasura-cli/connector-plugin/) -* A connector configuration file -* Secret service token (optional) - -Your functions directory should be added as a volume to `/functions` - -``` ---volume ./my-functions:/functions -``` - -Create the connector: - -``` -hasura3 connector create my-cool-connector:v1 \ - --github-repo-url https://github.com/hasura/ndc-typescript-deno/tree/v0.20 \ - --config-file config.json \ - --volume ./functions:/functions \ - --env SERVICE_TOKEN_SECRET=MY-SERVICE-TOKEN -``` - -Monitor the deployment status by name: - -``` -hasura connector status my-cool-connector:v1 -``` - -List your connector with its deployed URL: - -``` -hasura connector list -my-cool-connector:v1 https://connector-9XXX7-hyc5v23h6a-ue.a.run.app active -``` - -See [the Typescript Deno SendGrid repository](https://github.com/hasura/ndc-sendgrid-deno) -for an example of what a project structure that uses a connector could look like. - -## Usage - -Include the connector URL in your Hasura V3 project metadata (hml format). -Hasura cloud projects must also set a matching bearer token: - -```yaml -kind: DataConnector -version: v2 -definition: - name: petdatabase - url: - singleUrl: 'https://connector-9XXX7-hyc5v23h6a-ue.a.run.app' - - # And optionally if you have configured a service secret: - headers: - Authorization: - valueFromSecret: BEARER_TOKEN_SECRET -``` - -(NOTE: This will require that the secret includes the `Bearer ` prefix.) - - -## Troubleshooting - -Please [submit a Github issue](https://github.com/hasura/ndc-typescript-deno/issues/new) -if you encounter any problems! diff --git a/registry/hasura/typescript-deno/logo.png b/registry/hasura/typescript-deno/logo.png deleted file mode 100644 index 96f4c8590ce9196e84dfc18f64e58fb4d0ef20a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40438 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 Date: Wed, 25 Sep 2024 14:07:47 -0400 Subject: [PATCH 098/135] Version 1.0.3 for elasticsearch (#307) --- registry/hasura/elasticsearch/metadata.json | 18 +++++++++++++++++- .../releases/v1.0.3/connector-packaging.json | 11 +++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 registry/hasura/elasticsearch/releases/v1.0.3/connector-packaging.json diff --git a/registry/hasura/elasticsearch/metadata.json b/registry/hasura/elasticsearch/metadata.json index 0c3c24ec..05f0f659 100644 --- a/registry/hasura/elasticsearch/metadata.json +++ b/registry/hasura/elasticsearch/metadata.json @@ -7,7 +7,7 @@ "tags": [ "search" ], - "latest_version": "v1.0.2" + "latest_version": "v1.0.3" }, "author": { "support_email": "support@hasura.io", @@ -82,6 +82,17 @@ "source": { "hash": "19c1dfbce44db9fb9a71e9ca68c93de2d5fade6c" } + }, + { + "version": "1.0.3", + "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v1.0.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "42090a8ad64abe5002b2053041c308ab66dde430186eeb7b6ee76eb9bf8095be" + }, + "source": { + "hash": "4993fed05687b9464c64d44140cd801471ef32b9" + } } ], "source_code": { @@ -117,6 +128,11 @@ "tag": "v1.0.2", "hash": "19c1dfbce44db9fb9a71e9ca68c93de2d5fade6c", "is_verified": true + }, + { + "tag": "v1.0.3", + "hash": "4993fed05687b9464c64d44140cd801471ef32b9", + "is_verified": true } ] } diff --git a/registry/hasura/elasticsearch/releases/v1.0.3/connector-packaging.json b/registry/hasura/elasticsearch/releases/v1.0.3/connector-packaging.json new file mode 100644 index 00000000..9044dc58 --- /dev/null +++ b/registry/hasura/elasticsearch/releases/v1.0.3/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.3", + "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v1.0.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "42090a8ad64abe5002b2053041c308ab66dde430186eeb7b6ee76eb9bf8095be" + }, + "source": { + "hash": "4993fed05687b9464c64d44140cd801471ef32b9" + } +} From da87c6c1d140e6b7f4125d22745da062b50df55f Mon Sep 17 00:00:00 2001 From: Tristen Harr Date: Thu, 26 Sep 2024 03:38:24 -0500 Subject: [PATCH 099/135] update supporter for community supported connectors (#308) Changed supporters to be Community Supported --- registry/hasura/duckdb/metadata.json | 2 +- registry/hasura/qdrant/metadata.json | 2 +- registry/hasura/turso/metadata.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/registry/hasura/duckdb/metadata.json b/registry/hasura/duckdb/metadata.json index ba77c800..9231638a 100644 --- a/registry/hasura/duckdb/metadata.json +++ b/registry/hasura/duckdb/metadata.json @@ -10,7 +10,7 @@ "latest_version": "v0.1.0" }, "author": { - "support_email": "support@hasura.io", + "support_email": "Community Supported", "homepage": "https://hasura.io", "name": "Hasura" }, diff --git a/registry/hasura/qdrant/metadata.json b/registry/hasura/qdrant/metadata.json index 19361494..5d8cfcac 100644 --- a/registry/hasura/qdrant/metadata.json +++ b/registry/hasura/qdrant/metadata.json @@ -10,7 +10,7 @@ "latest_version": "v0.3.0" }, "author": { - "support_email": "support@hasura.io", + "support_email": "Community Supported", "homepage": "https://hasura.io", "name": "Hasura" }, diff --git a/registry/hasura/turso/metadata.json b/registry/hasura/turso/metadata.json index 9e0072b0..e85076eb 100644 --- a/registry/hasura/turso/metadata.json +++ b/registry/hasura/turso/metadata.json @@ -10,7 +10,7 @@ "latest_version": "v0.1.0" }, "author": { - "support_email": "support@hasura.io", + "support_email": "Community Supported", "homepage": "https://hasura.io", "name": "Hasura" }, From d0b97de2ba8c2193e5dc4ab2dab2d8f812d40675 Mon Sep 17 00:00:00 2001 From: Toan Nguyen Date: Thu, 26 Sep 2024 20:59:52 +0700 Subject: [PATCH 100/135] Add ndc-prometheus v0.0.4 (#303) --- registry/hasura/prometheus/README.md | 20 ++++++++ registry/hasura/prometheus/logo.svg | 50 +++++++++++++++++++ registry/hasura/prometheus/metadata.json | 28 +++++++++++ .../releases/v0.0.4/connector-packaging.json | 11 ++++ 4 files changed, 109 insertions(+) create mode 100644 registry/hasura/prometheus/README.md create mode 100644 registry/hasura/prometheus/logo.svg create mode 100644 registry/hasura/prometheus/metadata.json create mode 100644 registry/hasura/prometheus/releases/v0.0.4/connector-packaging.json diff --git a/registry/hasura/prometheus/README.md b/registry/hasura/prometheus/README.md new file mode 100644 index 00000000..e4d1c7ed --- /dev/null +++ b/registry/hasura/prometheus/README.md @@ -0,0 +1,20 @@ +## Overview + +The Hasura Prometheus Connector allows for connecting Hasura to a Prometheus API server giving you an instant GraphQL API on top of your Prometheus data. + +Data Connectors are the way to connect the Hasura Data Delivery Network (DDN) to external data sources. A data connector is an HTTP service that exposes a set of APIs that Hasura uses to communicate with the data source. Data connectors are built to conform to the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html) using one of Hasura's available SDKs. The data connector is responsible for interpreting work to be done on behalf of the Hasura Engine, using the native query language of the data source. + +The data connector is open source and can be found in the [ndc-prometheus GitHub repository](https://github.com/hasura/ndc-prometheus). + +## Deployment + +The connector is hosted by Hasura and can be used from the [Hasura v3 Console](https://console.hasura.io). + +## Usage + +The Hasura Prometheus connector can be deployed using the [Hasura CLI](https://hasura.io/docs/3.0/cli/overview) by following either the [Quick Start Guide](https://hasura.io/docs/3.0/getting-started/overview/) or [deploying the connector](https://hasura.io/docs/3.0/connectors/deployment). + +## Troubleshooting + +Please [submit a Github issue](https://github.com/hasura/ndc-prometheus/issues/new) +if you encounter any problems! diff --git a/registry/hasura/prometheus/logo.svg b/registry/hasura/prometheus/logo.svg new file mode 100644 index 00000000..5c51f66d --- /dev/null +++ b/registry/hasura/prometheus/logo.svg @@ -0,0 +1,50 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/registry/hasura/prometheus/metadata.json b/registry/hasura/prometheus/metadata.json new file mode 100644 index 00000000..3a70b4b9 --- /dev/null +++ b/registry/hasura/prometheus/metadata.json @@ -0,0 +1,28 @@ +{ + "overview": { + "namespace": "hasura", + "description": "Connect Hasura DDN to a Prometheus API server", + "title": "Prometheus Data Connector", + "logo": "logo.svg", + "tags": ["database"], + "latest_version": "v0.0.4" + }, + "author": { + "support_email": "support@hasura.io", + "homepage": "https://hasura.io", + "name": "Hasura" + }, + "is_verified": true, + "is_hosted_by_hasura": true, + "source_code": { + "is_open_source": true, + "repository": "https://github.com/hasura/ndc-prometheus", + "version": [ + { + "tag": "v0.0.4", + "hash": "69915e6c9736f38a0952c5ce8ad9a2d180783a43", + "is_verified": true + } + ] + } +} diff --git a/registry/hasura/prometheus/releases/v0.0.4/connector-packaging.json b/registry/hasura/prometheus/releases/v0.0.4/connector-packaging.json new file mode 100644 index 00000000..566010dc --- /dev/null +++ b/registry/hasura/prometheus/releases/v0.0.4/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.0.4", + "uri": "https://github.com/hasura/ndc-prometheus/releases/download/v0.0.4/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "83acab73b703ff37c6322b990e2782331cffbfe64bf67fb0b2734b3f651689d9" + }, + "source": { + "hash": "69915e6c9736f38a0952c5ce8ad9a2d180783a43" + } +} From 67db552891033de75304f89778fbdd5faf7be502 Mon Sep 17 00:00:00 2001 From: Mohd Bilal Date: Thu, 26 Sep 2024 22:20:48 +0530 Subject: [PATCH 101/135] release version v0.2.0 of the openapi connector (#310) --- registry/hasura/openapi/metadata.json | 2 +- .../openapi/releases/v0.2.0/connector-packaging.json | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 registry/hasura/openapi/releases/v0.2.0/connector-packaging.json diff --git a/registry/hasura/openapi/metadata.json b/registry/hasura/openapi/metadata.json index 45b2a3bd..3a04de96 100644 --- a/registry/hasura/openapi/metadata.json +++ b/registry/hasura/openapi/metadata.json @@ -5,7 +5,7 @@ "title": "OpenAPI Lambda Connector", "logo": "logo.png", "tags": [], - "latest_version": "v0.1.5" + "latest_version": "v0.2.0" }, "author": { "support_email": "support@hasura.io", diff --git a/registry/hasura/openapi/releases/v0.2.0/connector-packaging.json b/registry/hasura/openapi/releases/v0.2.0/connector-packaging.json new file mode 100644 index 00000000..59202d50 --- /dev/null +++ b/registry/hasura/openapi/releases/v0.2.0/connector-packaging.json @@ -0,0 +1,12 @@ +{ + "version": "0.2.0", + "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.2.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "6b766e1e2c7c21eddc8d6b7aa024c791a51716f8cdccdf8b8ae2e77f5b3b70e2" + }, + "source": { + "hash": "fa033ba34c5a40e5907a6c6277ecbe941a08edfc" + } + } + \ No newline at end of file From 2b437475484b7cd34c6d315c7657d361aa883878 Mon Sep 17 00:00:00 2001 From: Gavin Ray Date: Thu, 26 Sep 2024 13:39:02 -0400 Subject: [PATCH 102/135] Updates to MySQL, Oracle, Snowflake (#311) --- registry/hasura/mysql/metadata.json | 34 ++++++++++++++++++- .../releases/v1.0.1/connector-packaging.json | 11 ++++++ .../releases/v1.0.2/connector-packaging.json | 11 ++++++ registry/hasura/oracle/metadata.json | 34 ++++++++++++++++++- .../releases/v1.0.1/connector-packaging.json | 11 ++++++ .../releases/v1.0.2/connector-packaging.json | 11 ++++++ registry/hasura/snowflake/metadata.json | 18 +++++++++- .../releases/v1.0.1/connector-packaging.json | 11 ++++++ 8 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 registry/hasura/mysql/releases/v1.0.1/connector-packaging.json create mode 100644 registry/hasura/mysql/releases/v1.0.2/connector-packaging.json create mode 100644 registry/hasura/oracle/releases/v1.0.1/connector-packaging.json create mode 100644 registry/hasura/oracle/releases/v1.0.2/connector-packaging.json create mode 100644 registry/hasura/snowflake/releases/v1.0.1/connector-packaging.json diff --git a/registry/hasura/mysql/metadata.json b/registry/hasura/mysql/metadata.json index 38652674..e255fa48 100644 --- a/registry/hasura/mysql/metadata.json +++ b/registry/hasura/mysql/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.1.0" + "latest_version": "v1.0.2" }, "author": { "support_email": "support@hasura.io", @@ -27,6 +27,28 @@ "source": { "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" } + }, + { + "version": "1.0.1", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/mysql%2Fv1.0.1/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "4503cb8961e3c2c8aede3183187fb69862ac1442a89085d35cf1d4a4989d6db9" + }, + "source": { + "hash": "fbeb926e1d5550bec78a042a36d5ac2a8fba4c9f" + } + }, + { + "version": "1.0.2", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/mysql%2Fv1.0.2/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "86be6695432bef7cfcdccfc376c18f3c89ffefe6d139869ab4739709dd980141" + }, + "source": { + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" + } } ], "source_code": { @@ -37,6 +59,16 @@ "tag": "mysql/v0.1.0", "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e", "is_verified": true + }, + { + "tag": "mysql/v1.0.1", + "hash": "fbeb926e1d5550bec78a042a36d5ac2a8fba4c9f", + "is_verified": true + }, + { + "tag": "mysql/v1.0.2", + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e", + "is_verified": true } ] } diff --git a/registry/hasura/mysql/releases/v1.0.1/connector-packaging.json b/registry/hasura/mysql/releases/v1.0.1/connector-packaging.json new file mode 100644 index 00000000..b4b7a4fc --- /dev/null +++ b/registry/hasura/mysql/releases/v1.0.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.1", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/mysql%2Fv1.0.1/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "4503cb8961e3c2c8aede3183187fb69862ac1442a89085d35cf1d4a4989d6db9" + }, + "source": { + "hash": "fbeb926e1d5550bec78a042a36d5ac2a8fba4c9f" + } +} diff --git a/registry/hasura/mysql/releases/v1.0.2/connector-packaging.json b/registry/hasura/mysql/releases/v1.0.2/connector-packaging.json new file mode 100644 index 00000000..5d6f1b75 --- /dev/null +++ b/registry/hasura/mysql/releases/v1.0.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.2", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/mysql%2Fv1.0.2/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "86be6695432bef7cfcdccfc376c18f3c89ffefe6d139869ab4739709dd980141" + }, + "source": { + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" + } +} diff --git a/registry/hasura/oracle/metadata.json b/registry/hasura/oracle/metadata.json index 94604b66..85bea5dc 100644 --- a/registry/hasura/oracle/metadata.json +++ b/registry/hasura/oracle/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.1.0" + "latest_version": "v1.0.2" }, "author": { "support_email": "support@hasura.io", @@ -27,6 +27,28 @@ "source": { "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" } + }, + { + "version": "1.0.1", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/oracle%2Fv1.0.1/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "58ed43d43e0afc74d24c6ec1552ab3fbcc48cf108420f1f6dd6f7bd960b2d126" + }, + "source": { + "hash": "fbeb926e1d5550bec78a042a36d5ac2a8fba4c9f" + } + }, + { + "version": "1.0.2", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/oracle%2Fv1.0.2/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "14891c40124d06c7732f0ca6559c62f3f8bdb1a0d802d4079868aae8a6013935" + }, + "source": { + "hash": "ef3dd9d851e62c18fc1fbee5d049b61065f37f72" + } } ], "source_code": { @@ -37,6 +59,16 @@ "tag": "oracle/v0.1.0", "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e", "is_verified": true + }, + { + "tag": "oracle/v1.0.1", + "hash": "fbeb926e1d5550bec78a042a36d5ac2a8fba4c9f", + "is_verified": true + }, + { + "tag": "oracle/v1.0.2", + "hash": "ef3dd9d851e62c18fc1fbee5d049b61065f37f72", + "is_verified": true } ] } diff --git a/registry/hasura/oracle/releases/v1.0.1/connector-packaging.json b/registry/hasura/oracle/releases/v1.0.1/connector-packaging.json new file mode 100644 index 00000000..56b25785 --- /dev/null +++ b/registry/hasura/oracle/releases/v1.0.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.1", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/oracle%2Fv1.0.1/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "58ed43d43e0afc74d24c6ec1552ab3fbcc48cf108420f1f6dd6f7bd960b2d126" + }, + "source": { + "hash": "fbeb926e1d5550bec78a042a36d5ac2a8fba4c9f" + } +} diff --git a/registry/hasura/oracle/releases/v1.0.2/connector-packaging.json b/registry/hasura/oracle/releases/v1.0.2/connector-packaging.json new file mode 100644 index 00000000..e83d968d --- /dev/null +++ b/registry/hasura/oracle/releases/v1.0.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.2", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/oracle%2Fv1.0.2/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "14891c40124d06c7732f0ca6559c62f3f8bdb1a0d802d4079868aae8a6013935" + }, + "source": { + "hash": "ef3dd9d851e62c18fc1fbee5d049b61065f37f72" + } +} diff --git a/registry/hasura/snowflake/metadata.json b/registry/hasura/snowflake/metadata.json index 93084ae9..cfdbc20d 100644 --- a/registry/hasura/snowflake/metadata.json +++ b/registry/hasura/snowflake/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.1.0" + "latest_version": "v1.0.1" }, "author": { "support_email": "support@hasura.io", @@ -27,6 +27,17 @@ "source": { "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" } + }, + { + "version": "1.0.1", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/snowflake%2Fv1.0.1/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "01791312a91e41e59dd638f7efed7472a37c3d1fe174cc71a844a5cde65e23a5" + }, + "source": { + "hash": "fbeb926e1d5550bec78a042a36d5ac2a8fba4c9f" + } } ], "source_code": { @@ -37,6 +48,11 @@ "tag": "snowflake/v0.1.0", "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e", "is_verified": true + }, + { + "tag": "snowflake/v1.0.1", + "hash": "fbeb926e1d5550bec78a042a36d5ac2a8fba4c9f", + "is_verified": true } ] } diff --git a/registry/hasura/snowflake/releases/v1.0.1/connector-packaging.json b/registry/hasura/snowflake/releases/v1.0.1/connector-packaging.json new file mode 100644 index 00000000..1df80206 --- /dev/null +++ b/registry/hasura/snowflake/releases/v1.0.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.1", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/snowflake%2Fv1.0.1/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "01791312a91e41e59dd638f7efed7472a37c3d1fe174cc71a844a5cde65e23a5" + }, + "source": { + "hash": "fbeb926e1d5550bec78a042a36d5ac2a8fba4c9f" + } +} From faa8be057b8e6a2dff0051e521490594de03de3c Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Fri, 27 Sep 2024 15:06:21 +0530 Subject: [PATCH 103/135] New connector publication automation (#304) This PR adds support to publish a new connector and improves the existing code quality by refactoring it and making the code more testable. The whole connector publication process is also documented [here](https://docs.google.com/document/d/1Biu1_rSNeGOS4CiFaDSc4SnVAd2NVlBJGu107zphXm0/edit#heading=h.nsi7idklva07) --- registry-automation/README.md | 38 ++ registry-automation/cmd/ci.go | 679 +++++++++++-------------- registry-automation/cmd/ci_test.go | 282 +++++++--- registry-automation/cmd/gcp.go | 5 +- registry-automation/cmd/registry_db.go | 283 +++++++++++ registry-automation/cmd/types.go | 185 +++++++ registry-automation/cmd/utils.go | 28 + registry-automation/go.mod | 5 + registry-automation/go.sum | 2 + 9 files changed, 1059 insertions(+), 448 deletions(-) create mode 100644 registry-automation/README.md create mode 100644 registry-automation/cmd/registry_db.go create mode 100644 registry-automation/cmd/types.go diff --git a/registry-automation/README.md b/registry-automation/README.md new file mode 100644 index 00000000..2c0d4852 --- /dev/null +++ b/registry-automation/README.md @@ -0,0 +1,38 @@ +# Introduction + +## Steps to runs + +1. Consider the following `changed_files.json` file: +```json + +{ + "added_files": [ + "registry/hasura/azure-cosmos/releases/v0.1.6/connector-packaging.json" + ], + "modified_files": [ + "registry/hasura/azure-cosmos/metadata.json" + ], + "deleted_files": [] +} +``` + +2. You will require the following environment variables: + +1. GCP_BUCKET_NAME +2. CLOUDINARY_URL +3. GCP_SERVICE_ACCOUNT_KEY +4. CONNECTOR_REGISTRY_GQL_URL +5. CONNECTOR_PUBLICATION_KEY +6. GCP_SERVICE_ACCOUNT_DETAILS + + + +```bash + + +2. Run the following command from the `registry-automation` directory: + + +```bash +go run main.go ci --changed-files-path changed_files.json +``` diff --git a/registry-automation/cmd/ci.go b/registry-automation/cmd/ci.go index cd9c31f9..11847204 100644 --- a/registry-automation/cmd/ci.go +++ b/registry-automation/cmd/ci.go @@ -16,7 +16,6 @@ import ( "github.com/machinebox/graphql" "github.com/spf13/cobra" "google.golang.org/api/option" - "gopkg.in/yaml.v2" ) // ciCmd represents the ci command @@ -26,83 +25,6 @@ var ciCmd = &cobra.Command{ Run: runCI, } -type ChangedFiles struct { - Added []string `json:"added_files"` - Modified []string `json:"modified_files"` - Deleted []string `json:"deleted_files"` -} - -// ConnectorVersion represents a version of a connector, this type is -// used to insert a new version of a connector in the registry. -type ConnectorVersion struct { - // Namespace of the connector, e.g. "hasura" - Namespace string `json:"namespace"` - // Name of the connector, e.g. "mongodb" - Name string `json:"name"` - // Semantic version of the connector version, e.g. "v1.0.0" - Version string `json:"version"` - // Docker image of the connector version (optional) - // This field is only required if the connector version is of type `PrebuiltDockerImage` - Image *string `json:"image,omitempty"` - // URL to the connector's metadata - PackageDefinitionURL string `json:"package_definition_url"` - // Is the connector version multitenant? - IsMultitenant bool `json:"is_multitenant"` - // Type of the connector packaging `PrebuiltDockerImage`/`ManagedDockerBuild` - Type string `json:"type"` -} - -// Create a struct with the following fields: -// type string -// image *string (optional) -type ConnectionVersionMetadata struct { - Type string `yaml:"type"` - Image *string `yaml:"image,omitempty"` -} - -type WhereClause struct { - ConnectorName string - ConnectorNamespace string -} - -func (wc WhereClause) MarshalJSON() ([]byte, error) { - where := map[string]interface{}{ - "_and": []map[string]interface{}{ - {"name": map[string]string{"_eq": wc.ConnectorName}}, - {"namespace": map[string]string{"_eq": wc.ConnectorNamespace}}, - }, - } - return json.Marshal(where) -} - -type ConnectorOverviewUpdate struct { - Set struct { - Docs *string `json:"docs,omitempty"` - Logo *string `json:"logo,omitempty"` - } `json:"_set"` - Where WhereClause `json:"where"` -} - -type ConnectorOverviewUpdates struct { - Updates []ConnectorOverviewUpdate `json:"updates"` -} - -const ( - ManagedDockerBuild = "ManagedDockerBuild" - PrebuiltDockerImage = "PrebuiltDockerImage" -) - -// Make a struct with the fields expected in the command line arguments -type ConnectorRegistryArgs struct { - ChangedFilesPath string - PublicationEnv string - ConnectorRegistryGQLUrl string - ConnectorPublicationKey string - GCPServiceAccountDetails string - GCPBucketName string - CloudinaryUrl string -} - var ciCmdArgs ConnectorRegistryArgs func init() { @@ -125,13 +47,20 @@ func init() { } -func buildContext() { +func buildContext() Context { // Connector registry Hasura GraphQL URL registryGQLURL := os.Getenv("CONNECTOR_REGISTRY_GQL_URL") + var registryGQLClient *graphql.Client + var storageClient *storage.Client + var cloudinaryClient *cloudinary.Cloudinary + var cloudinaryWrapper *CloudinaryWrapper + var storageWrapper *StorageClientWrapper + if registryGQLURL == "" { log.Fatalf("CONNECTOR_REGISTRY_GQL_URL is not set") } else { ciCmdArgs.ConnectorRegistryGQLUrl = registryGQLURL + registryGQLClient = graphql.NewClient(registryGQLURL) } // Connector publication key @@ -147,6 +76,15 @@ func buildContext() { if gcpServiceAccountDetails == "" { log.Fatalf("GCP_SERVICE_ACCOUNT_DETAILS is not set") } else { + var err error + storageClient, err = storage.NewClient(context.Background(), option.WithCredentialsJSON([]byte(gcpServiceAccountDetails))) + if err != nil { + log.Fatalf("Failed to create Google bucket client: %v", err) + } + defer storageClient.Close() + + storageWrapper = &StorageClientWrapper{storageClient} + ciCmdArgs.GCPServiceAccountDetails = gcpServiceAccountDetails } @@ -163,115 +101,211 @@ func buildContext() { if cloudinaryUrl == "" { log.Fatalf("CLOUDINARY_URL is not set") } else { - ciCmdArgs.CloudinaryUrl = cloudinaryUrl + var err error + cloudinaryClient, err = cloudinary.NewFromURL(cloudinaryUrl) + if err != nil { + log.Fatalf("Failed to create cloudinary client: %v", err) + + } + cloudinaryWrapper = &CloudinaryWrapper{cloudinaryClient} + + } + + return Context{ + Env: ciCmdArgs.PublicationEnv, + RegistryGQLClient: registryGQLClient, + StorageClient: storageWrapper, + Cloudinary: cloudinaryWrapper, } } -// processChangedFiles processes the files in the PR and extracts the connector name and version -// This function checks for the following things: -// 1. If a new connector version is added, it adds the connector version to the `newlyAddedConnectorVersions` map. -// 2. If the logo file is modified, it adds the connector name and the path to the modified logo to the `modifiedLogos` map. -// 3. If the README file is modified, it adds the connector name and the path to the modified README to the `modifiedReadmes` map. -func processChangedFiles(changedFiles ChangedFiles) (NewConnectorVersions, ModifiedLogos, ModifiedReadmes) { +type fileProcessor struct { + regex *regexp.Regexp + process func(matches []string, file string) +} - newlyAddedConnectorVersions := make(map[Connector]map[string]string) - modifiedLogos := make(map[Connector]string) - modifiedReadmes := make(map[Connector]string) +// processChangedFiles categorizes changes in connector files within a registry system. +// It handles new and modified files including metadata, logos, READMEs, and connector versions. +// +// The function takes a ChangedFiles struct containing slices of added and modified filenames, +// and returns a ProcessedChangedFiles struct with categorized changes. +// +// Files are processed based on their path and type: +// - metadata.json: New connectors +// - logo.(png|svg): New or modified logos +// - README.md: New or modified READMEs +// - connector-packaging.json: New connector versions +// +// Any files not matching these patterns are logged as skipped. +// +// Example usage: +// +// changedFiles := ChangedFiles{ +// Added: []string{"registry/namespace1/connector1/metadata.json"}, +// Modified: []string{"registry/namespace2/connector2/README.md"}, +// } +// result := processChangedFiles(changedFiles) +func processChangedFiles(changedFiles ChangedFiles) ProcessedChangedFiles { + result := ProcessedChangedFiles{ + NewConnectorVersions: make(map[Connector]map[string]string), + ModifiedLogos: make(map[Connector]string), + ModifiedReadmes: make(map[Connector]string), + NewConnectors: make(map[Connector]MetadataFile), + NewLogos: make(map[Connector]string), + NewReadmes: make(map[Connector]string), + } + + processors := []fileProcessor{ + { + regex: regexp.MustCompile(`^registry/([^/]+)/([^/]+)/metadata.json$`), + process: func(matches []string, file string) { + // IsNew is set to true because we are processing newly added metadata.json + connector := Connector{Name: matches[2], Namespace: matches[1]} + result.NewConnectors[connector] = MetadataFile(file) + fmt.Printf("Processing metadata file for connector: %s\n", connector.Name) + }, + }, + { + regex: regexp.MustCompile(`^registry/([^/]+)/([^/]+)/logo\.(png|svg)$`), + process: func(matches []string, file string) { + connector := Connector{Name: matches[2], Namespace: matches[1]} + result.NewLogos[connector] = file + fmt.Printf("Processing logo file for connector: %s\n", connector.Name) + }, + }, + { + regex: regexp.MustCompile(`^registry/([^/]+)/([^/]+)/README\.md$`), + process: func(matches []string, file string) { + connector := Connector{Name: matches[2], Namespace: matches[1]} + result.NewReadmes[connector] = file + fmt.Printf("Processing README file for connector: %s\n", connector.Name) + }, + }, + { + regex: regexp.MustCompile(`^registry/([^/]+)/([^/]+)/releases/([^/]+)/connector-packaging\.json$`), + process: func(matches []string, file string) { + connector := Connector{Name: matches[2], Namespace: matches[1]} + version := matches[3] + if _, exists := result.NewConnectorVersions[connector]; !exists { + result.NewConnectorVersions[connector] = make(map[string]string) + } + result.NewConnectorVersions[connector][version] = file + }, + }, + } - var connectorVersionPackageRegex = regexp.MustCompile(`^registry/([^/]+)/([^/]+)/releases/([^/]+)/connector-packaging\.json$`) - var logoPngRegex = regexp.MustCompile(`^registry/([^/]+)/([^/]+)/logo\.(png|svg)$`) - var readmeMdRegex = regexp.MustCompile(`^registry/([^/]+)/([^/]+)/README\.md$`) + processFile := func(file string, isModified bool) { + for _, processor := range processors { + if matches := processor.regex.FindStringSubmatch(file); matches != nil { + if isModified { + connector := Connector{Name: matches[2], Namespace: matches[1]} + if processor.regex.String() == processors[1].regex.String() { + result.ModifiedLogos[connector] = file + } else if processor.regex.String() == processors[2].regex.String() { + result.ModifiedReadmes[connector] = file + } + } else { + processor.process(matches, file) + } + return + } + } + fmt.Printf("Skipping %s file: %s\n", map[bool]string{true: "modified", false: "newly added"}[isModified], file) + } for _, file := range changedFiles.Added { + processFile(file, false) + } - // Check if the file is a connector version package - if connectorVersionPackageRegex.MatchString(file) { + for _, file := range changedFiles.Modified { + processFile(file, true) + } - matches := connectorVersionPackageRegex.FindStringSubmatch(file) - if len(matches) == 4 { - connectorNamespace := matches[1] - connectorName := matches[2] - connectorVersion := matches[3] + return result +} - connector := Connector{ - Name: connectorName, - Namespace: connectorNamespace, - } +func processNewConnector(ciCtx Context, connector Connector, metadataFile MetadataFile) (ConnectorOverviewInsert, HubRegistryConnectorInsertInput, error) { + // Process the newly added connector + // Get the string value from metadataFile + var connectorOverviewAndAuthor ConnectorOverviewInsert + var hubRegistryConnectorInsertInput HubRegistryConnectorInsertInput - if _, exists := newlyAddedConnectorVersions[connector]; !exists { - newlyAddedConnectorVersions[connector] = make(map[string]string) - } + connectorMetadata, err := readJSONFile[ConnectorMetadata](string(metadataFile)) + if err != nil { + return connectorOverviewAndAuthor, hubRegistryConnectorInsertInput, fmt.Errorf("Failed to parse the connector metadata file: %v", err) + } - newlyAddedConnectorVersions[connector][connectorVersion] = file - } + docs, err := readFile(fmt.Sprintf("registry/%s/%s/README.md", connector.Namespace, connector.Name)) - } else { - fmt.Println("Skipping newly added file: ", file) - } + if err != nil { + return connectorOverviewAndAuthor, hubRegistryConnectorInsertInput, fmt.Errorf("Failed to read the README file of the connector: %s : %v", connector.Name, err) } - for _, file := range changedFiles.Modified { - if logoPngRegex.MatchString(file) { - // Process the logo file - // print the name of the connector and the version - matches := logoPngRegex.FindStringSubmatch(file) - if len(matches) == 4 { - - connectorNamespace := matches[1] - connectorName := matches[2] - connector := Connector{ - Name: connectorName, - Namespace: connectorNamespace, - } - modifiedLogos[connector] = file - fmt.Printf("Processing logo file for connector: %s\n", connectorName) - } - - } else if readmeMdRegex.MatchString(file) { - // Process the README file - // print the name of the connector and the version - matches := readmeMdRegex.FindStringSubmatch(file) + logoPath := fmt.Sprintf("registry/%s/%s/logo.png", connector.Namespace, connector.Name) - if len(matches) == 3 { + uploadedLogoUrl, err := uploadLogoToCloudinary(ciCtx.Cloudinary, Connector{Name: connector.Name, Namespace: connector.Namespace}, logoPath) + if err != nil { + return connectorOverviewAndAuthor, hubRegistryConnectorInsertInput, err + } - connectorNamespace := matches[1] - connectorName := matches[2] - connector := Connector{ - Name: connectorName, - Namespace: connectorNamespace, - } + // Get connector info from the registry + connectorInfo, err := getConnectorInfoFromRegistry(ciCtx.RegistryGQLClient, connector.Name, connector.Namespace) + if err != nil { + return connectorOverviewAndAuthor, hubRegistryConnectorInsertInput, + fmt.Errorf("Failed to get the connector info from the registry: %v", err) + } - modifiedReadmes[connector] = file + // Check if the connector already exists in the registry + if len(connectorInfo.HubRegistryConnector) > 0 { + if ciCtx.Env == "staging" { + fmt.Printf("Connector already exists in the registry: %s/%s\n", connector.Namespace, connector.Name) + fmt.Println("The connector is going to be overwritten in the registry.") - fmt.Printf("Processing README file for connector: %s\n", connectorName) - } } else { - fmt.Println("Skipping modified file: ", file) + + return connectorOverviewAndAuthor, hubRegistryConnectorInsertInput, fmt.Errorf("Attempting to create a new hub connector, but the connector already exists in the registry: %s/%s", connector.Namespace, connector.Name) } } - return newlyAddedConnectorVersions, modifiedLogos, modifiedReadmes + hubRegistryConnectorInsertInput = HubRegistryConnectorInsertInput{ + Name: connector.Name, + Namespace: connector.Namespace, + Title: connectorMetadata.Overview.Title, + } + + connectorOverviewAndAuthor = ConnectorOverviewInsert{ + Name: connector.Name, + Namespace: connector.Namespace, + Docs: string(docs), + Logo: uploadedLogoUrl, + Title: connectorMetadata.Overview.Title, + Description: connectorMetadata.Overview.Description, + IsVerified: connectorMetadata.IsVerified, + IsHosted: connectorMetadata.IsHostedByHasura, + Author: ConnectorAuthorNestedInsert{ + Data: ConnectorAuthor{ + Name: connectorMetadata.Author.Name, + SupportEmail: connectorMetadata.Author.SupportEmail, + Website: connectorMetadata.Author.Homepage, + }, + }, + } + return connectorOverviewAndAuthor, hubRegistryConnectorInsertInput, nil } // runCI is the main function that runs the CI workflow func runCI(cmd *cobra.Command, args []string) { - buildContext() + ctx := buildContext() changedFilesContent, err := os.Open(ciCmdArgs.ChangedFilesPath) if err != nil { log.Fatalf("Failed to open the file: %v, err: %v", ciCmdArgs.ChangedFilesPath, err) } defer changedFilesContent.Close() - client, err := storage.NewClient(context.Background(), option.WithCredentialsJSON([]byte(ciCmdArgs.GCPServiceAccountDetails))) - if err != nil { - log.Fatalf("Failed to create Google bucket client: %v", err) - } - defer client.Close() - // Read the changed file's contents. This file contains all the changed files in the PR changedFilesByteValue, err := io.ReadAll(changedFilesContent) if err != nil { @@ -288,65 +322,110 @@ func runCI(cmd *cobra.Command, args []string) { // Separate the modified files according to the type of file // Collect the added or modified connectors - newlyAddedConnectorVersions, modifiedLogos, modifiedReadmes := processChangedFiles(changedFiles) + processChangedFiles := processChangedFiles(changedFiles) - // check if the map is empty - if len(newlyAddedConnectorVersions) == 0 && len(modifiedLogos) == 0 && len(modifiedReadmes) == 0 { - fmt.Println("No connectors to be added or modified in the registry") - return - } else { - if len(newlyAddedConnectorVersions) > 0 { - processNewlyAddedConnectorVersions(client, newlyAddedConnectorVersions) - } + newlyAddedConnectorVersions := processChangedFiles.NewConnectorVersions + modifiedLogos := processChangedFiles.ModifiedLogos + modifiedReadmes := processChangedFiles.ModifiedReadmes + + newlyAddedConnectors := processChangedFiles.NewConnectors + + var newConnectorsToBeAdded NewConnectorsInsertInput + var newConnectorVersionsToBeAdded []ConnectorVersion + + newConnectorOverviewsToBeAdded := make([](ConnectorOverviewInsert), 0) + hubRegistryConnectorsToBeAdded := make([](HubRegistryConnectorInsertInput), 0) + connectorOverviewUpdates := make([]ConnectorOverviewUpdate, 0) + + if len(newlyAddedConnectors) > 0 { + fmt.Println("New connectors to be added to the registry: ", newlyAddedConnectors) + + for connector, metadataFile := range newlyAddedConnectors { + connectorOverviewAndAuthor, hubRegistryConnector, err := processNewConnector(ctx, connector, metadataFile) - if len(modifiedReadmes) > 0 { - err := processModifiedReadmes(modifiedReadmes) if err != nil { - log.Fatalf("Failed to process the modified READMEs: %v", err) + log.Fatalf("Failed to process the new connector: %s/%s, Error: %v", connector.Namespace, connector.Name, err) } - fmt.Println("Successfully updated the READMEs in the registry.") + newConnectorOverviewsToBeAdded = append(newConnectorOverviewsToBeAdded, connectorOverviewAndAuthor) + hubRegistryConnectorsToBeAdded = append(hubRegistryConnectorsToBeAdded, hubRegistryConnector) + } - if len(modifiedLogos) > 0 { - err := processModifiedLogos(modifiedLogos) - if err != nil { - log.Fatalf("Failed to process the modified logos: %v", err) - } - fmt.Println("Successfully updated the logos in the registry.") + newConnectorsToBeAdded.HubRegistryConnectors = hubRegistryConnectorsToBeAdded + newConnectorsToBeAdded.ConnectorOverviews = newConnectorOverviewsToBeAdded + + } + + if len(newlyAddedConnectorVersions) > 0 { + newlyAddedConnectors := make(map[Connector]bool) + for connector := range newlyAddedConnectorVersions { + newlyAddedConnectors[connector] = true + } + newConnectorVersionsToBeAdded = processNewlyAddedConnectorVersions(ctx, newlyAddedConnectorVersions, newlyAddedConnectors) + } + + if len(modifiedReadmes) > 0 { + readMeUpdates, err := processModifiedReadmes(modifiedReadmes) + if err != nil { + log.Fatalf("Failed to process the modified READMEs: %v", err) + } + connectorOverviewUpdates = append(connectorOverviewUpdates, readMeUpdates...) + fmt.Println("Successfully updated the READMEs in the registry.") + } + + if len(modifiedLogos) > 0 { + logoUpdates, err := processModifiedLogos(modifiedLogos, ctx.Cloudinary) + if err != nil { + log.Fatalf("Failed to process the modified logos: %v", err) } + connectorOverviewUpdates = append(connectorOverviewUpdates, logoUpdates...) + fmt.Println("Successfully updated the logos in the registry.") + } + + if ctx.Env == "production" { + err = registryDbMutation(ctx.RegistryGQLClient, newConnectorsToBeAdded, connectorOverviewUpdates, newConnectorVersionsToBeAdded) + + } else if ctx.Env == "staging" { + err = registryDbMutationStaging(ctx.RegistryGQLClient, newConnectorsToBeAdded, connectorOverviewUpdates, newConnectorVersionsToBeAdded) + } else { + log.Fatalf("Unexpected: invalid publication environment: %s", ctx.Env) + } + + if err != nil { + log.Fatalf("Failed to update the registry: %v", err) } fmt.Println("Successfully processed the changed files in the PR") } -func processModifiedLogos(modifiedLogos ModifiedLogos) error { - // Iterate over the modified logos and update the logos in the registry - var connectorOverviewUpdates []ConnectorOverviewUpdate - // upload the logo to cloudinary - cloudinary, err := cloudinary.NewFromURL(ciCmdArgs.CloudinaryUrl) +func uploadLogoToCloudinary(cloudinary CloudinaryInterface, connector Connector, logoPath string) (string, error) { + logoContent, err := readFile(logoPath) if err != nil { - return err + fmt.Printf("Failed to read the logo file: %v", err) + return "", err } + imageReader := bytes.NewReader(logoContent) + + uploadResult, err := cloudinary.Upload(context.Background(), imageReader, uploader.UploadParams{ + PublicID: fmt.Sprintf("%s-%s", connector.Namespace, connector.Name), + Format: "png", + }) + if err != nil { + return "", fmt.Errorf("Failed to upload the logo to cloudinary for the connector: %s, Error: %v\n", connector.Name, err) + } + return uploadResult.SecureURL, nil +} + +func processModifiedLogos(modifiedLogos ModifiedLogos, cloudinaryClient CloudinaryInterface) ([]ConnectorOverviewUpdate, error) { + // Iterate over the modified logos and update the logos in the registry + var connectorOverviewUpdates []ConnectorOverviewUpdate + for connector, logoPath := range modifiedLogos { // open the logo file - logoContent, err := readFile(logoPath) + uploadedLogoUrl, err := uploadLogoToCloudinary(cloudinaryClient, connector, logoPath) if err != nil { - fmt.Printf("Failed to read the logo file: %v", err) - return err - } - - imageReader := bytes.NewReader(logoContent) - - uploadResult, err := cloudinary.Upload.Upload(context.Background(), imageReader, uploader.UploadParams{ - PublicID: fmt.Sprintf("%s-%s", connector.Namespace, connector.Name), - Format: "png", - }) - if err != nil { - fmt.Printf("Failed to upload the logo to cloudinary for the connector: %s, Error: %v\n", connector.Name, err) - return err - } else { - fmt.Printf("Successfully uploaded the logo to cloudinary for the connector: %s\n", connector.Name) + return connectorOverviewUpdates, err } var connectorOverviewUpdate ConnectorOverviewUpdate @@ -357,7 +436,7 @@ func processModifiedLogos(modifiedLogos ModifiedLogos) error { *connectorOverviewUpdate.Set.Logo = "" } - *connectorOverviewUpdate.Set.Logo = string(uploadResult.SecureURL) + *connectorOverviewUpdate.Set.Logo = uploadedLogoUrl connectorOverviewUpdate.Where.ConnectorName = connector.Name connectorOverviewUpdate.Where.ConnectorNamespace = connector.Namespace @@ -366,11 +445,11 @@ func processModifiedLogos(modifiedLogos ModifiedLogos) error { } - return updateConnectorOverview(ConnectorOverviewUpdates{Updates: connectorOverviewUpdates}) + return connectorOverviewUpdates, nil } -func processModifiedReadmes(modifiedReadmes ModifiedReadmes) error { +func processModifiedReadmes(modifiedReadmes ModifiedReadmes) ([]ConnectorOverviewUpdate, error) { // Iterate over the modified READMEs and update the READMEs in the registry var connectorOverviewUpdates []ConnectorOverviewUpdate @@ -378,7 +457,7 @@ func processModifiedReadmes(modifiedReadmes ModifiedReadmes) error { // open the README file readmeContent, err := readFile(readmePath) if err != nil { - return err + return connectorOverviewUpdates, err } @@ -394,11 +473,11 @@ func processModifiedReadmes(modifiedReadmes ModifiedReadmes) error { } - return updateConnectorOverview(ConnectorOverviewUpdates{Updates: connectorOverviewUpdates}) + return connectorOverviewUpdates, nil } -func processNewlyAddedConnectorVersions(client *storage.Client, newlyAddedConnectorVersions NewConnectorVersions) { +func processNewlyAddedConnectorVersions(ciCtx Context, newlyAddedConnectorVersions NewConnectorVersions, newConnectorsAdded map[Connector]bool) []ConnectorVersion { // Iterate over the added or modified connectors and upload the connector versions var connectorVersions []ConnectorVersion var uploadConnectorVersionErr error @@ -407,7 +486,8 @@ func processNewlyAddedConnectorVersions(client *storage.Client, newlyAddedConnec for connectorName, versions := range newlyAddedConnectorVersions { for version, connectorVersionPath := range versions { var connectorVersion ConnectorVersion - connectorVersion, uploadConnectorVersionErr = uploadConnectorVersionPackage(client, connectorName, version, connectorVersionPath) + isNewConnector := newConnectorsAdded[connectorName] + connectorVersion, uploadConnectorVersionErr = uploadConnectorVersionPackage(ciCtx, connectorName, version, connectorVersionPath, isNewConnector) if uploadConnectorVersionErr != nil { fmt.Printf("Error while processing version and connector: %s - %s, Error: %v", version, connectorName, uploadConnectorVersionErr) @@ -423,24 +503,18 @@ func processNewlyAddedConnectorVersions(client *storage.Client, newlyAddedConnec if encounteredError { // attempt to cleanup the uploaded connector versions - _ = cleanupUploadedConnectorVersions(client, connectorVersions) // ignore errors while cleaning up + _ = cleanupUploadedConnectorVersions(ciCtx.StorageClient, connectorVersions) // ignore errors while cleaning up // delete the uploaded connector versions from the registry log.Fatalf("Failed to upload the connector version: %v", uploadConnectorVersionErr) - - } else { - fmt.Printf("Connector versions to be added to the registry: %+v\n", connectorVersions) - err := updateRegistryGQL(connectorVersions) - if err != nil { - // attempt to cleanup the uploaded connector versions - _ = cleanupUploadedConnectorVersions(client, connectorVersions) // ignore errors while cleaning up - log.Fatalf("Failed to update the registry: %v", err) - } } + fmt.Println("Successfully added connector versions to the registry.") + return connectorVersions + } -func cleanupUploadedConnectorVersions(client *storage.Client, connectorVersions []ConnectorVersion) error { +func cleanupUploadedConnectorVersions(client StorageClientInterface, connectorVersions []ConnectorVersion) error { // Iterate over the connector versions and delete the uploaded files // from the google bucket fmt.Println("Cleaning up the uploaded connector versions") @@ -455,22 +529,8 @@ func cleanupUploadedConnectorVersions(client *storage.Client, connectorVersions return nil } -// Type that uniquely identifies a connector -type Connector struct { - Name string `json:"name"` - Namespace string `json:"namespace"` -} - -type NewConnectorVersions map[Connector]map[string]string - -// ModifiedLogos represents the modified logos in the PR, the key is the connector name and the value is the path to the modified logo -type ModifiedLogos map[Connector]string - -// ModifiedReadmes represents the modified READMEs in the PR, the key is the connector name and the value is the path to the modified README -type ModifiedReadmes map[Connector]string - // uploadConnectorVersionPackage uploads the connector version package to the registry -func uploadConnectorVersionPackage(client *storage.Client, connector Connector, version string, changedConnectorVersionPath string) (ConnectorVersion, error) { +func uploadConnectorVersionPackage(ciCtx Context, connector Connector, version string, changedConnectorVersionPath string, isNewConnector bool) (ConnectorVersion, error) { var connectorVersion ConnectorVersion @@ -492,7 +552,7 @@ func uploadConnectorVersionPackage(client *storage.Client, connector Connector, return connectorVersion, err } - uploadedTgzUrl, err := uploadConnectorVersionDefinition(client, connector.Namespace, connector.Name, version, connectorMetadataTgzPath) + uploadedTgzUrl, err := uploadConnectorVersionDefinition(ciCtx, connector.Namespace, connector.Name, version, connectorMetadataTgzPath) if err != nil { return connectorVersion, fmt.Errorf("failed to upload the connector version definition - connector: %v version:%v - err: %v", connector.Name, version, err) } else { @@ -501,13 +561,13 @@ func uploadConnectorVersionPackage(client *storage.Client, connector Connector, } // Build payload for registry upsert - return buildRegistryPayload(connector.Namespace, connector.Name, version, connectorVersionMetadata, uploadedTgzUrl) + return buildRegistryPayload(ciCtx, connector.Namespace, connector.Name, version, connectorVersionMetadata, uploadedTgzUrl, isNewConnector) } -func uploadConnectorVersionDefinition(client *storage.Client, connectorNamespace, connectorName string, connectorVersion string, connectorMetadataTgzPath string) (string, error) { +func uploadConnectorVersionDefinition(ciCtx Context, connectorNamespace, connectorName string, connectorVersion string, connectorMetadataTgzPath string) (string, error) { bucketName := ciCmdArgs.GCPBucketName objectName := generateGCPObjectName(connectorNamespace, connectorName, connectorVersion) - uploadedTgzUrl, err := uploadFile(client, bucketName, objectName, connectorMetadataTgzPath) + uploadedTgzUrl, err := uploadFile(ciCtx.StorageClient, bucketName, objectName, connectorMetadataTgzPath) if err != nil { return "", err @@ -552,94 +612,15 @@ func getConnectorVersionMetadata(tgzUrl string, connector Connector, connectorVe return connectorVersionMetadata, tgzPath, nil } -// Write a function that accepts a file path to a YAML file and returns -// the contents of the file as a map[string]interface{}. -// readYAMLFile accepts a file path to a YAML file and returns the contents of the file as a map[string]interface{}. -func readYAMLFile(filePath string) (map[string]interface{}, error) { - // Open the file - file, err := os.Open(filePath) - if err != nil { - return nil, fmt.Errorf("failed to open file: %w", err) - } - defer file.Close() - - // Read the file contents - data, err := io.ReadAll(file) - if err != nil { - return nil, fmt.Errorf("failed to read file: %w", err) - } - - // Unmarshal the YAML contents into a map - var result map[string]interface{} - err = yaml.Unmarshal(data, &result) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal YAML: %w", err) - } - - return result, nil -} - -func getConnectorNamespace(connectorMetadata map[string]interface{}) (string, error) { - connectorOverview, ok := connectorMetadata["overview"].(map[string]interface{}) - if !ok { - return "", fmt.Errorf("could not find connector overview in the connector's metadata") - } - connectorNamespace, ok := connectorOverview["namespace"].(string) - if !ok { - return "", fmt.Errorf("could not find the 'namespace' of the connector in the connector's overview in the connector's metadata.json") - } - return connectorNamespace, nil -} - -// struct to store the response of teh GetConnectorInfo query -type GetConnectorInfoResponse struct { - HubRegistryConnector []struct { - Name string `json:"name"` - MultitenantConnector *struct { - ID string `json:"id"` - } `json:"multitenant_connector"` - } `json:"hub_registry_connector"` -} - -func getConnectorInfoFromRegistry(connectorNamespace string, connectorName string) (GetConnectorInfoResponse, error) { - var respData GetConnectorInfoResponse - client := graphql.NewClient(ciCmdArgs.ConnectorRegistryGQLUrl) - ctx := context.Background() - - req := graphql.NewRequest(` -query GetConnectorInfo ($name: String!, $namespace: String!) { - hub_registry_connector(where: {_and: [{name: {_eq: $name}}, {namespace: {_eq: $namespace}}]}) { - name - multitenant_connector { - id - } - } -}`) - req.Var("name", connectorName) - req.Var("namespace", connectorNamespace) - - req.Header.Set("x-hasura-role", "connector_publishing_automation") - req.Header.Set("x-connector-publication-key", ciCmdArgs.ConnectorPublicationKey) - - // Execute the GraphQL query and check the response. - if err := client.Run(ctx, req, &respData); err != nil { - return respData, err - } else { - if len(respData.HubRegistryConnector) == 0 { - return respData, nil - } - } - - return respData, nil -} - // buildRegistryPayload builds the payload for the registry upsert API func buildRegistryPayload( + ciCtx Context, connectorNamespace string, connectorName string, version string, connectorVersionMetadata map[string]interface{}, uploadedConnectorDefinitionTgzUrl string, + isNewConnector bool, ) (ConnectorVersion, error) { var connectorVersion ConnectorVersion var connectorVersionDockerImage string = "" @@ -659,15 +640,31 @@ func buildRegistryPayload( } - connectorInfo, err := getConnectorInfoFromRegistry(connectorNamespace, connectorName) + connectorInfo, err := getConnectorInfoFromRegistry(ciCtx.RegistryGQLClient, connectorNamespace, connectorName) if err != nil { return connectorVersion, err } + var isMultitenant bool + // Check if the connector exists in the registry first if len(connectorInfo.HubRegistryConnector) == 0 { - return connectorVersion, fmt.Errorf("Inserting a new connector is not supported yet") + + if isNewConnector { + isMultitenant = false + } else { + return connectorVersion, fmt.Errorf("Unexpected: Couldn't get the connector info of the connector: %s", connectorName) + + } + + } else { + if len(connectorInfo.HubRegistryConnector) == 1 { + // check if the connector is multitenant + isMultitenant = connectorInfo.HubRegistryConnector[0].MultitenantConnector != nil + + } + } var connectorVersionType string @@ -693,65 +690,9 @@ func buildRegistryPayload( Version: version, Image: connectorVersionImage, PackageDefinitionURL: uploadedConnectorDefinitionTgzUrl, - IsMultitenant: connectorInfo.HubRegistryConnector[0].MultitenantConnector != nil, + IsMultitenant: isMultitenant, Type: connectorVersionType, } return connectorVersion, nil } - -func updateRegistryGQL(payload []ConnectorVersion) error { - var respData map[string]interface{} - client := graphql.NewClient(ciCmdArgs.ConnectorRegistryGQLUrl) - ctx := context.Background() - - req := graphql.NewRequest(` -mutation InsertConnectorVersion($connectorVersion: [hub_registry_connector_version_insert_input!]!) { - insert_hub_registry_connector_version(objects: $connectorVersion, on_conflict: {constraint: connector_version_namespace_name_version_key, update_columns: [image, package_definition_url, is_multitenant]}) { - affected_rows - returning { - id - } - } -}`) - // add the payload to the request - req.Var("connectorVersion", payload) - - req.Header.Set("x-hasura-role", "connector_publishing_automation") - req.Header.Set("x-connector-publication-key", ciCmdArgs.ConnectorPublicationKey) - - // Execute the GraphQL query and check the response. - if err := client.Run(ctx, req, &respData); err != nil { - return err - } - - return nil -} - -func updateConnectorOverview(updates ConnectorOverviewUpdates) error { - var respData map[string]interface{} - client := graphql.NewClient(ciCmdArgs.ConnectorRegistryGQLUrl) - ctx := context.Background() - - req := graphql.NewRequest(` -mutation UpdateConnector ($updates: [connector_overview_updates!]!) { - update_connector_overview_many(updates: $updates) { - affected_rows - } -}`) - - // add the payload to the request - req.Var("updates", updates.Updates) - - req.Header.Set("x-hasura-role", "connector_publishing_automation") - req.Header.Set("x-connector-publication-key", ciCmdArgs.ConnectorPublicationKey) - - // Execute the GraphQL query and check the response. - if err := client.Run(ctx, req, &respData); err != nil { - return err - } else { - fmt.Printf("Successfully updated the connector overview: %+v\n", respData) - } - - return nil -} diff --git a/registry-automation/cmd/ci_test.go b/registry-automation/cmd/ci_test.go index e68cabaf..2b160f8a 100644 --- a/registry-automation/cmd/ci_test.go +++ b/registry-automation/cmd/ci_test.go @@ -1,100 +1,230 @@ package cmd import ( + "context" + "testing" + + "github.com/machinebox/graphql" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "cloud.google.com/go/storage" + + "github.com/cloudinary/cloudinary-go/v2/api/uploader" ) -func TestProcessAddedOrModifiedConnectorVersions(t *testing.T) { - // Define test cases +// Mock structures +type MockStorageClient struct { + mock.Mock +} + +func (m *MockStorageClient) Bucket(name string) *storage.BucketHandle { + args := m.Called(name) + return args.Get(0).(*storage.BucketHandle) +} + +type MockCloudinaryUploader struct { + mock.Mock +} + +type MockCloudinary struct { + mock.Mock +} + +func (m *MockCloudinary) Upload(ctx context.Context, file interface{}, uploadParams uploader.UploadParams) (*uploader.UploadResult, error) { + args := m.Called(ctx, file, uploadParams) + return args.Get(0).(*uploader.UploadResult), args.Error(1) +} + +type MockGraphQLClient struct { + mock.Mock +} + +func (m *MockGraphQLClient) Run(ctx context.Context, query *graphql.Request, resp interface{}) error { + args := m.Called(ctx, query, resp) + return args.Error(0) +} + +func createTestContext() Context { + return Context{ + Env: "staging", + RegistryGQLClient: &MockGraphQLClient{}, + StorageClient: &MockStorageClient{}, + Cloudinary: &MockCloudinary{}, + } +} + +// Test processChangedFiles +func TestProcessChangedFiles(t *testing.T) { testCases := []struct { - name string - files []string - expectedAddedOrModifiedConnectors map[string]map[string]string + name string + changedFiles ChangedFiles + expected ProcessedChangedFiles }{ { - name: "Test case 1", - files: []string{ - "registry/hasura/releases/v1.0.0/connector-packaging.json", - "registry/hasura/releases/v2.0.0/connector-packaging.json", - "registry/other/releases/v1.0.0/connector-packaging.json", + name: "New connector added", + changedFiles: ChangedFiles{ + Added: []string{"registry/namespace1/connector1/metadata.json"}, }, - expectedAddedOrModifiedConnectors: map[string]map[string]string{ - "hasura": { - "v1.0.0": "registry/hasura/releases/v1.0.0/connector-packaging.json", - "v2.0.0": "registry/hasura/releases/v2.0.0/connector-packaging.json", - }, - "other": { - "v1.0.0": "registry/other/releases/v1.0.0/connector-packaging.json", - }, + expected: ProcessedChangedFiles{ + NewConnectorVersions: map[Connector]map[string]string{}, + ModifiedLogos: map[Connector]string{}, + ModifiedReadmes: map[Connector]string{}, + NewConnectors: map[Connector]MetadataFile{{Name: "connector1", Namespace: "namespace1"}: "registry/namespace1/connector1/metadata.json"}, + NewLogos: map[Connector]string{}, + NewReadmes: map[Connector]string{}, }, }, { - name: "Test case 2", - files: []string{ - "registry/hasura/releases/v1.0.0/connector-packaging.json", - "registry/hasura/releases/v1.0.0/other-file.json", - }, - expectedAddedOrModifiedConnectors: map[string]map[string]string{ - "hasura": { - "v1.0.0": "registry/hasura/releases/v1.0.0/connector-packaging.json", + name: "Modified logo and README", + changedFiles: ChangedFiles{ + Modified: []string{ + "registry/namespace1/connector1/logo.png", + "registry/namespace1/connector1/README.md", }, }, - }, - { - name: "Test case 3", - files: []string{ - "registry/hasura/releases/v1.0.0/other-file.json", - "registry/other/releases/v1.0.0/connector-packaging.json", - }, - expectedAddedOrModifiedConnectors: map[string]map[string]string{ - "other": { - "v1.0.0": "registry/other/releases/v1.0.0/connector-packaging.json", - }, + expected: ProcessedChangedFiles{ + NewConnectorVersions: map[Connector]map[string]string{}, + ModifiedLogos: map[Connector]string{{Name: "connector1", Namespace: "namespace1"}: "registry/namespace1/connector1/logo.png"}, + ModifiedReadmes: map[Connector]string{{Name: "connector1", Namespace: "namespace1"}: "registry/namespace1/connector1/README.md"}, + NewConnectors: map[Connector]MetadataFile{}, + NewLogos: map[Connector]string{}, + NewReadmes: map[Connector]string{}, }, }, } - // Run the test cases for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - // Initialize the map to store the added or modified connectors - addedOrModifiedConnectorVersions := make(map[string]map[string]string) - - var changedFiles ChangedFiles - - changedFiles.Added = tc.files - - // Call the function under test - processChangedFiles(changedFiles) - - // Compare the actual result with the expected result - if len(addedOrModifiedConnectorVersions) != len(tc.expectedAddedOrModifiedConnectors) { - t.Errorf("Unexpected number of connectors. Expected: %d, Got: %d", len(tc.expectedAddedOrModifiedConnectors), len(addedOrModifiedConnectorVersions)) - } - - for connectorName, versions := range addedOrModifiedConnectorVersions { - expectedVersions, ok := tc.expectedAddedOrModifiedConnectors[connectorName] - if !ok { - t.Errorf("Unexpected connector name: %s", connectorName) - continue - } - - if len(versions) != len(expectedVersions) { - t.Errorf("Unexpected number of versions for connector %s. Expected: %d, Got: %d", connectorName, len(expectedVersions), len(versions)) - } - - for version, connectorVersionPath := range versions { - expectedPath, ok := expectedVersions[version] - if !ok { - t.Errorf("Unexpected version for connector %s: %s", connectorName, version) - continue - } - - if connectorVersionPath != expectedPath { - t.Errorf("Unexpected connector version path for connector %s, version %s. Expected: %s, Got: %s", connectorName, version, expectedPath, connectorVersionPath) - } - } - } + result := processChangedFiles(tc.changedFiles) + assert.Equal(t, tc.expected, result) }) } } + +// func TestProcessNewConnector(t *testing.T) { +// ctx := createTestContext() +// connector := Connector{Name: "testconnector", Namespace: "testnamespace"} + +// // Create a temporary directory for our test files +// tempDir, err := os.MkdirTemp("", "connector-test") +// assert.NoError(t, err) +// defer os.RemoveAll(tempDir) // Clean up after the test + +// // Set up the directory structure +// registryDir := filepath.Join(tempDir, "registry", connector.Namespace, connector.Name) +// err = os.MkdirAll(registryDir, 0755) +// assert.NoError(t, err) + +// // Create the metadata file +// metadataFile := filepath.Join(registryDir, "metadata.json") +// tempMetadata := []byte(`{"overview": {"title": "Test Connector", "description": "A test connector"}, "isVerified": true, "isHostedByHasura": false, "author": {"name": "Test Author", "supportEmail": "support@test.com", "homepage": "https://test.com"}}`) +// err = os.WriteFile(metadataFile, tempMetadata, 0666) +// assert.NoError(t, err) + +// // Create the README file +// readmeFile := filepath.Join(registryDir, "README.md") +// err = os.WriteFile(readmeFile, []byte("# Test Connector"), 0644) +// assert.NoError(t, err) + +// // Mock the necessary functions and API calls +// mockCloudinaryUploader := &MockCloudinaryUploader{} +// mockCloudinaryUploader.On("Upload", mock.Anything, mock.Anything, mock.Anything).Return(&uploader.UploadResult{SecureURL: "https://res.cloudinary.com/demo/image/upload/logo.png"}, nil) + +// mockGraphQLClient := ctx.RegistryGQLClient.(*MockGraphQLClient) +// mockGraphQLClient.On("Run", mock.Anything, mock.Anything, mock.Anything).Return(nil) + +// // Run the function +// connectorOverviewInsert, hubRegistryConnectorInsert, err := processNewConnector(ctx, connector, MetadataFile(metadataFile)) + +// // Assert the results +// assert.NoError(t, err) +// assert.Equal(t, "testconnector", connectorOverviewInsert.Name) +// assert.Equal(t, "testnamespace", connectorOverviewInsert.Namespace) +// assert.Equal(t, "Test Connector", connectorOverviewInsert.Title) +// assert.Equal(t, "A test connector", connectorOverviewInsert.Description) +// assert.True(t, connectorOverviewInsert.IsVerified) +// assert.False(t, connectorOverviewInsert.IsHosted) +// assert.Equal(t, "Test Author", connectorOverviewInsert.Author.Data.Name) +// assert.Equal(t, "support@test.com", connectorOverviewInsert.Author.Data.SupportEmail) +// assert.Equal(t, "https://test.com", connectorOverviewInsert.Author.Data.Website) + +// assert.Equal(t, "testconnector", hubRegistryConnectorInsert.Name) +// assert.Equal(t, "testnamespace", hubRegistryConnectorInsert.Namespace) +// assert.Equal(t, "Test Connector", hubRegistryConnectorInsert.Title) + +// mockCloudinaryUploader.AssertExpectations(t) +// mockGraphQLClient.AssertExpectations(t) +// } + +// // Test uploadConnectorVersionPackage +// func TestUploadConnectorVersionPackage(t *testing.T) { +// ctx := createTestContext() +// connector := Connector{Name: "testconnector", Namespace: "testnamespace"} +// version := "v1.0.0" +// changedConnectorVersionPath := "registry/testnamespace/testconnector/releases/v1.0.0/connector-packaging.json" +// isNewConnector := true + +// // Mock necessary functions +// mockStorageClient := ctx.StorageClient.(*MockStorageClient) +// mockStorageClient.On("Bucket", mock.Anything).Return(&storage.BucketHandle{}) + +// mockGraphQLClient := ctx.RegistryGQLClient.(*MockGraphQLClient) +// mockGraphQLClient.On("Run", mock.Anything, mock.Anything, mock.Anything).Return(nil) + +// // Create temporary files +// err := os.MkdirAll("registry/testnamespace/testconnector/releases/v1.0.0", 0755) +// assert.NoError(t, err) +// defer os.RemoveAll("registry/testnamespace/testconnector") + +// packagingContent := []byte(`{"uri": "https://example.com/testconnector-v1.0.0.tgz"}`) +// err = os.WriteFile(changedConnectorVersionPath, packagingContent, 0644) +// assert.NoError(t, err) + +// // Run the function +// connectorVersion, err := uploadConnectorVersionPackage(ctx, connector, version, changedConnectorVersionPath, isNewConnector) + +// // Assert the results +// assert.NoError(t, err) +// assert.Equal(t, "testconnector", connectorVersion.Name) +// assert.Equal(t, "testnamespace", connectorVersion.Namespace) +// assert.Equal(t, "v1.0.0", connectorVersion.Version) + +// mockStorageClient.AssertExpectations(t) +// mockGraphQLClient.AssertExpectations(t) +// } + +// // Test buildRegistryPayload +// func TestBuildRegistryPayload(t *testing.T) { +// ctx := createTestContext() +// connectorNamespace := "testnamespace" +// connectorName := "testconnector" +// version := "v1.0.0" +// connectorVersionMetadata := map[string]interface{}{ +// "packagingDefinition": map[string]interface{}{ +// "type": "ManagedDockerBuild", +// }, +// } +// uploadedConnectorDefinitionTgzUrl := "https://example.com/test.tgz" +// isNewConnector := true + +// // Mock the GraphQL client +// mockGraphQLClient := ctx.RegistryGQLClient.(*MockGraphQLClient) +// mockGraphQLClient.On("Run", mock.Anything, mock.Anything, mock.Anything).Return(nil) + +// // Run the function +// connectorVersion, err := buildRegistryPayload(ctx, connectorNamespace, connectorName, version, connectorVersionMetadata, uploadedConnectorDefinitionTgzUrl, isNewConnector) + +// // Assert the results +// assert.NoError(t, err) +// assert.Equal(t, connectorNamespace, connectorVersion.Namespace) +// assert.Equal(t, connectorName, connectorVersion.Name) +// assert.Equal(t, version, connectorVersion.Version) +// assert.Equal(t, uploadedConnectorDefinitionTgzUrl, connectorVersion.PackageDefinitionURL) +// assert.Equal(t, "ManagedDockerBuild", connectorVersion.Type) +// assert.False(t, connectorVersion.IsMultitenant) +// assert.Nil(t, connectorVersion.Image) + +// mockGraphQLClient.AssertExpectations(t) +// } diff --git a/registry-automation/cmd/gcp.go b/registry-automation/cmd/gcp.go index 40d41d62..4896a92d 100644 --- a/registry-automation/cmd/gcp.go +++ b/registry-automation/cmd/gcp.go @@ -2,7 +2,6 @@ package cmd import ( - "cloud.google.com/go/storage" "context" "fmt" "io" @@ -10,7 +9,7 @@ import ( ) // deleteFile deletes a file from Google Cloud Storage -func deleteFile(client *storage.Client, bucketName, objectName string) error { +func deleteFile(client StorageClientInterface, bucketName, objectName string) error { bucket := client.Bucket(bucketName) object := bucket.Object(objectName) @@ -19,7 +18,7 @@ func deleteFile(client *storage.Client, bucketName, objectName string) error { // uploadFile uploads a file to Google Cloud Storage // document this function with comments -func uploadFile(client *storage.Client, bucketName, objectName, filePath string) (string, error) { +func uploadFile(client StorageClientInterface, bucketName, objectName, filePath string) (string, error) { bucket := client.Bucket(bucketName) object := bucket.Object(objectName) newCtx := context.Background() diff --git a/registry-automation/cmd/registry_db.go b/registry-automation/cmd/registry_db.go new file mode 100644 index 00000000..bad68d36 --- /dev/null +++ b/registry-automation/cmd/registry_db.go @@ -0,0 +1,283 @@ +package cmd + +import ( + "context" + "fmt" + + "github.com/machinebox/graphql" +) + +type HubRegistryConnectorInsertInput struct { + Name string `json:"name"` + Title string `json:"title"` + Namespace string `json:"namespace"` +} + +type NewConnectorsInsertInput struct { + HubRegistryConnectors []HubRegistryConnectorInsertInput `json:"hub_registry_connectors"` + ConnectorOverviews []ConnectorOverviewInsert `json:"connector_overviews"` +} + +// struct to store the response of teh GetConnectorInfo query +type GetConnectorInfoResponse struct { + HubRegistryConnector []struct { + Name string `json:"name"` + MultitenantConnector *struct { + ID string `json:"id"` + } `json:"multitenant_connector"` + } `json:"hub_registry_connector"` +} + +func insertHubRegistryConnector(client graphql.Client, newConnectors NewConnectorsInsertInput) error { + var respData map[string]interface{} + + ctx := context.Background() + + req := graphql.NewRequest(` +mutation InsertHubRegistryConnector ($hub_registry_connectors:[hub_registry_connector_insert_input!]!, $connector_overview_objects: [connector_overview_insert_input!]!){ + + insert_hub_registry_connector(objects: $hub_registry_connectors) { +affected_rows + } + insert_connector_overview(objects: $connector_overview_objects) { + affected_rows + } +} +`) + + // add the payload to the request + req.Var("hub_registry_connectors", newConnectors.HubRegistryConnectors) + req.Var("connectors_overviews", newConnectors.ConnectorOverviews) + + // set the headers + req.Header.Set("x-hasura-role", "connector_publishing_automation") + req.Header.Set("x-connector-publication-key", ciCmdArgs.ConnectorPublicationKey) + + // Execute the GraphQL query and check the response. + if err := client.Run(ctx, req, &respData); err != nil { + return err + } else { + connectorNames := make([]string, 0) + for _, connector := range newConnectors.HubRegistryConnectors { + connectorNames = append(connectorNames, fmt.Sprintf("%s/%s", connector.Namespace, connector.Name)) + } + fmt.Printf("Successfully inserted the following connectors in the registry: %+v\n", connectorNames) + } + + return nil +} + +func getConnectorInfoFromRegistry(client GraphQLClientInterface, connectorNamespace string, connectorName string) (GetConnectorInfoResponse, error) { + var respData GetConnectorInfoResponse + + ctx := context.Background() + + req := graphql.NewRequest(` +query GetConnectorInfo ($name: String!, $namespace: String!) { + hub_registry_connector(where: {_and: [{name: {_eq: $name}}, {namespace: {_eq: $namespace}}]}) { + name + multitenant_connector { + id + } + } +}`) + req.Var("name", connectorName) + req.Var("namespace", connectorNamespace) + + req.Header.Set("x-hasura-role", "connector_publishing_automation") + req.Header.Set("x-connector-publication-key", ciCmdArgs.ConnectorPublicationKey) + + // Execute the GraphQL query and check the response. + if err := client.Run(ctx, req, &respData); err != nil { + return respData, err + } else { + if len(respData.HubRegistryConnector) == 0 { + return respData, nil + } + } + + return respData, nil +} + +func updateRegistryGQL(client graphql.Client, payload []ConnectorVersion) error { + var respData map[string]interface{} + + ctx := context.Background() + + req := graphql.NewRequest(` +mutation InsertConnectorVersion($connectorVersion: [hub_registry_connector_version_insert_input!]!) { + insert_hub_registry_connector_version(objects: $connectorVersion, on_conflict: {constraint: connector_version_namespace_name_version_key, update_columns: [image, package_definition_url, is_multitenant]}) { + affected_rows + returning { + id + } + } +}`) + // add the payload to the request + req.Var("connectorVersion", payload) + + req.Header.Set("x-hasura-role", "connector_publishing_automation") + req.Header.Set("x-connector-publication-key", ciCmdArgs.ConnectorPublicationKey) + + // Execute the GraphQL query and check the response. + if err := client.Run(ctx, req, &respData); err != nil { + return err + } + + return nil +} + +func updateConnectorOverview(updates ConnectorOverviewUpdates) error { + var respData map[string]interface{} + client := graphql.NewClient(ciCmdArgs.ConnectorRegistryGQLUrl) + ctx := context.Background() + + req := graphql.NewRequest(` +mutation UpdateConnector ($updates: [connector_overview_updates!]!) { + update_connector_overview_many(updates: $updates) { + affected_rows + } +}`) + + // add the payload to the request + req.Var("updates", updates.Updates) + + req.Header.Set("x-hasura-role", "connector_publishing_automation") + req.Header.Set("x-connector-publication-key", ciCmdArgs.ConnectorPublicationKey) + + // Execute the GraphQL query and check the response. + if err := client.Run(ctx, req, &respData); err != nil { + return err + } else { + fmt.Printf("Successfully updated the connector overview: %+v\n", respData) + } + + return nil +} + +type ConnectorAuthorNestedInsertOnConflict struct { + Constraint string `json:"constraint"` + UpdateCols []string `json:"update_columns,omitempty"` +} + +type ConnectorAuthorNestedInsert struct { + Data ConnectorAuthor `json:"data"` + OnConflict *ConnectorAuthorNestedInsertOnConflict `json:"on_conflict,omitempty"` +} + +type ConnectorOverviewInsert struct { + Namespace string `json:"namespace"` + Name string `json:"name"` + Title string `json:"title"` + Description string `json:"description"` + Logo string `json:"logo"` + Docs string `json:"docs"` + IsVerified bool `json:"is_verified"` + IsHosted bool `json:"is_hosted_by_hasura"` + Author ConnectorAuthorNestedInsert `json:"author"` +} + +type ConnectorAuthor struct { + Name string `json:"name"` + SupportEmail string `json:"support_email"` + Website string `json:"website"` +} + +// registryDbMutation is a function to insert data into the registry database, all the mutations are done in a single transaction. +func registryDbMutation(client GraphQLClientInterface, newConnectors NewConnectorsInsertInput, connectorOverviewUpdates []ConnectorOverviewUpdate, connectorVersionInserts []ConnectorVersion) error { + var respData map[string]interface{} + ctx := context.Background() + mutationQuery := ` +mutation HubRegistryMutationRequest ( + $hub_registry_connectors:[hub_registry_connector_insert_input!]!, + $connector_overview_inserts: [connector_overview_insert_input!]!, + $connector_overview_updates: [connector_overview_updates!]!, + $connector_version_inserts: [hub_registry_connector_version_insert_input!]! +){ + + insert_hub_registry_connector(objects: $hub_registry_connectors) { +affected_rows + } + insert_connector_overview(objects: $connector_overview_inserts) { + affected_rows + } + insert_hub_registry_connector_version(objects: $connector_version_inserts, on_conflict: {constraint: connector_version_namespace_name_version_key, update_columns: [image, package_definition_url, is_multitenant]}) { + affected_rows + } + + update_connector_overview_many(updates: $connector_overview_updates) { + affected_rows + } +} +` + req := graphql.NewRequest(mutationQuery) + req.Var("hub_registry_connectors", newConnectors.HubRegistryConnectors) + req.Var("connector_overview_inserts", newConnectors.ConnectorOverviews) + req.Var("connector_overview_updates", connectorOverviewUpdates) + req.Var("connector_version_inserts", connectorVersionInserts) + + req.Header.Set("x-hasura-role", "connector_publishing_automation") + req.Header.Set("x-connector-publication-key", ciCmdArgs.ConnectorPublicationKey) + + // Execute the GraphQL query and check the response. + if err := client.Run(ctx, req, &respData); err != nil { + return err + } + + return nil + +} + +// registryDbMutation is a function to insert data into the registry database, all the mutations are done in a single transaction. +func registryDbMutationStaging(client GraphQLClientInterface, newConnectors NewConnectorsInsertInput, connectorOverviewUpdates []ConnectorOverviewUpdate, connectorVersionInserts []ConnectorVersion) error { + var respData map[string]interface{} + ctx := context.Background() + mutationQuery := ` +mutation HubRegistryMutationRequest ( + $hub_registry_connectors:[hub_registry_connector_insert_input!]!, + $connector_overview_inserts: [connector_overview_insert_input!]!, + $connector_overview_updates: [connector_overview_updates!]!, + $connector_version_inserts: [hub_registry_connector_version_insert_input!]! +){ + + insert_hub_registry_connector(objects: $hub_registry_connectors, on_conflict: {constraint: connector_pkey}) { +affected_rows + } + insert_connector_overview(objects: $connector_overview_inserts, on_conflict: {constraint: connector_overview_pkey, update_columns: [docs, logo]}) { + affected_rows + } + insert_hub_registry_connector_version(objects: $connector_version_inserts, on_conflict: {constraint: connector_version_namespace_name_version_key, update_columns: [image, package_definition_url, is_multitenant]}) { + affected_rows + } + + update_connector_overview_many(updates: $connector_overview_updates) { + affected_rows + } +} +` + + // update newConnectors.ConnectorOverviews to have on_conflict + for i := range newConnectors.ConnectorOverviews { + newConnectors.ConnectorOverviews[i].Author.OnConflict = &ConnectorAuthorNestedInsertOnConflict{ + Constraint: "connector_author_connector_title_key", + UpdateCols: []string{}, + } + } + + req := graphql.NewRequest(mutationQuery) + req.Var("hub_registry_connectors", newConnectors.HubRegistryConnectors) + req.Var("connector_overview_inserts", newConnectors.ConnectorOverviews) + req.Var("connector_overview_updates", connectorOverviewUpdates) + req.Var("connector_version_inserts", connectorVersionInserts) + + req.Header.Set("x-hasura-role", "connector_publishing_automation") + req.Header.Set("x-connector-publication-key", ciCmdArgs.ConnectorPublicationKey) + + // Execute the GraphQL query and check the response. + if err := client.Run(ctx, req, &respData); err != nil { + return err + } + + return nil + +} diff --git a/registry-automation/cmd/types.go b/registry-automation/cmd/types.go new file mode 100644 index 00000000..ae51bbf6 --- /dev/null +++ b/registry-automation/cmd/types.go @@ -0,0 +1,185 @@ +package cmd + +import ( + "cloud.google.com/go/storage" + "context" + "encoding/json" + "github.com/cloudinary/cloudinary-go/v2" + "github.com/cloudinary/cloudinary-go/v2/api/uploader" + "github.com/machinebox/graphql" +) + +type ChangedFiles struct { + Added []string `json:"added_files"` + Modified []string `json:"modified_files"` + Deleted []string `json:"deleted_files"` +} + +// ConnectorVersion represents a version of a connector, this type is +// used to insert a new version of a connector in the registry. +type ConnectorVersion struct { + // Namespace of the connector, e.g. "hasura" + Namespace string `json:"namespace"` + // Name of the connector, e.g. "mongodb" + Name string `json:"name"` + // Semantic version of the connector version, e.g. "v1.0.0" + Version string `json:"version"` + // Docker image of the connector version (optional) + // This field is only required if the connector version is of type `PrebuiltDockerImage` + Image *string `json:"image,omitempty"` + // URL to the connector's metadata + PackageDefinitionURL string `json:"package_definition_url"` + // Is the connector version multitenant? + IsMultitenant bool `json:"is_multitenant"` + // Type of the connector packaging `PrebuiltDockerImage`/`ManagedDockerBuild` + Type string `json:"type"` +} + +// Create a struct with the following fields: +// type string +// image *string (optional) +type ConnectionVersionMetadata struct { + Type string `yaml:"type"` + Image *string `yaml:"image,omitempty"` +} + +type WhereClause struct { + ConnectorName string + ConnectorNamespace string +} + +func (wc WhereClause) MarshalJSON() ([]byte, error) { + where := map[string]interface{}{ + "_and": []map[string]interface{}{ + {"name": map[string]string{"_eq": wc.ConnectorName}}, + {"namespace": map[string]string{"_eq": wc.ConnectorNamespace}}, + }, + } + return json.Marshal(where) +} + +type ConnectorOverviewUpdate struct { + Set struct { + Docs *string `json:"docs,omitempty"` + Logo *string `json:"logo,omitempty"` + } `json:"_set"` + Where WhereClause `json:"where"` +} + +type ConnectorOverviewUpdates struct { + Updates []ConnectorOverviewUpdate `json:"updates"` +} + +const ( + ManagedDockerBuild = "ManagedDockerBuild" + PrebuiltDockerImage = "PrebuiltDockerImage" +) + +// Type to represent the metadata.json file +type ConnectorMetadata struct { + Overview struct { + Namespace string `json:"namespace"` + Description string `json:"description"` + Title string `json:"title"` + Logo string `json:"logo"` + Tags []string `json:"tags"` + LatestVersion string `json:"latest_version"` + } `json:"overview"` + Author struct { + SupportEmail string `json:"support_email"` + Homepage string `json:"homepage"` + Name string `json:"name"` + } `json:"author"` + + IsVerified bool `json:"is_verified"` + IsHostedByHasura bool `json:"is_hosted_by_hasura"` + HasuraHubConnector struct { + Namespace string `json:"namespace"` + Name string `json:"name"` + } `json:"hasura_hub_connector"` + SourceCode struct { + IsOpenSource bool `json:"is_open_source"` + Repository string `json:"repository"` + } `json:"source_code"` +} + +// Make a struct with the fields expected in the command line arguments +type ConnectorRegistryArgs struct { + ChangedFilesPath string + PublicationEnv string + ConnectorRegistryGQLUrl string + ConnectorPublicationKey string + GCPServiceAccountDetails string + GCPBucketName string + CloudinaryUrl string +} + +type MetadataFile string + +type NewConnectors map[Connector]MetadataFile + +type ProcessedChangedFiles struct { + NewConnectorVersions NewConnectorVersions + ModifiedLogos ModifiedLogos + ModifiedReadmes ModifiedReadmes + NewConnectors NewConnectors + NewLogos NewLogos + NewReadmes NewReadmes +} + +type GraphQLClientInterface interface { + Run(ctx context.Context, req *graphql.Request, resp interface{}) error +} + +type StorageClientWrapper struct { + *storage.Client +} + +func (s *StorageClientWrapper) Bucket(name string) *storage.BucketHandle { + return s.Client.Bucket(name) +} + +type StorageClientInterface interface { + Bucket(name string) *storage.BucketHandle +} + +type CloudinaryInterface interface { + Upload(ctx context.Context, file interface{}, uploadParams uploader.UploadParams) (*uploader.UploadResult, error) +} + +type CloudinaryWrapper struct { + *cloudinary.Cloudinary +} + +func (c *CloudinaryWrapper) Upload(ctx context.Context, file interface{}, uploadParams uploader.UploadParams) (*uploader.UploadResult, error) { + return c.Cloudinary.Upload.Upload(ctx, file, uploadParams) +} + +// + +type Context struct { + Env string + RegistryGQLClient GraphQLClientInterface + StorageClient StorageClientInterface + Cloudinary CloudinaryInterface +} + +// Type that uniquely identifies a connector +type Connector struct { + Name string `json:"name"` + Namespace string `json:"namespace"` +} + +type NewConnectorVersions map[Connector]map[string]string + +// ModifiedLogos represents the modified logos in the PR, the key is the connector name and the value is the path to the modified logo +type ModifiedLogos map[Connector]string + +// ModifiedReadmes represents the modified READMEs in the PR, the key is the connector name and the value is the path to the modified README +type ModifiedReadmes map[Connector]string + +// ModifiedLogos represents the modified logos in the PR, the key is the connector name and the value is the path to the modified logo +type NewLogos map[Connector]string + +// ModifiedReadmes represents the modified READMEs in the PR, the key is the connector name and the value is the path to the modified README +type NewReadmes map[Connector]string diff --git a/registry-automation/cmd/utils.go b/registry-automation/cmd/utils.go index 45af32a3..178ec188 100644 --- a/registry-automation/cmd/utils.go +++ b/registry-automation/cmd/utils.go @@ -3,6 +3,7 @@ package cmd import ( "encoding/json" "fmt" + "gopkg.in/yaml.v2" "io" "net/http" "os" @@ -120,3 +121,30 @@ func extractTarGz(src, dest string) (string, error) { return fmt.Sprintf("%s/.hasura-connector/connector-metadata.yaml", filepath), nil } + +// Write a function that accepts a file path to a YAML file and returns +// the contents of the file as a map[string]interface{}. +// readYAMLFile accepts a file path to a YAML file and returns the contents of the file as a map[string]interface{}. +func readYAMLFile(filePath string) (map[string]interface{}, error) { + // Open the file + file, err := os.Open(filePath) + if err != nil { + return nil, fmt.Errorf("failed to open file: %w", err) + } + defer file.Close() + + // Read the file contents + data, err := io.ReadAll(file) + if err != nil { + return nil, fmt.Errorf("failed to read file: %w", err) + } + + // Unmarshal the YAML contents into a map + var result map[string]interface{} + err = yaml.Unmarshal(data, &result) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal YAML: %w", err) + } + + return result, nil +} diff --git a/registry-automation/go.mod b/registry-automation/go.mod index e2eca410..2c03147d 100644 --- a/registry-automation/go.mod +++ b/registry-automation/go.mod @@ -5,12 +5,17 @@ go 1.21.4 require ( github.com/cloudinary/cloudinary-go/v2 v2.8.0 github.com/spf13/cobra v1.8.0 + github.com/stretchr/testify v1.9.0 ) require ( github.com/creasty/defaults v1.7.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/gorilla/schema v1.4.1 // indirect github.com/matryer/is v1.4.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) require ( diff --git a/registry-automation/go.sum b/registry-automation/go.sum index c06e0b27..f44c7142 100644 --- a/registry-automation/go.sum +++ b/registry-automation/go.sum @@ -92,6 +92,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= From ca5c65cdda9d997c6776820ce37194823aff6319 Mon Sep 17 00:00:00 2001 From: Toan Nguyen Date: Fri, 27 Sep 2024 16:46:13 +0700 Subject: [PATCH 104/135] Add ndc-go v1.4.0 (#312) --- registry/hasura/go/metadata.json | 7 ++++++- .../go/releases/v1.4.0/connector-packaging.json | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 registry/hasura/go/releases/v1.4.0/connector-packaging.json diff --git a/registry/hasura/go/metadata.json b/registry/hasura/go/metadata.json index 02719841..87f4b21f 100644 --- a/registry/hasura/go/metadata.json +++ b/registry/hasura/go/metadata.json @@ -5,7 +5,7 @@ "title": "Go Connector", "logo": "logo.svg", "tags": [], - "latest_version": "v1.3.1" + "latest_version": "v1.4.0" }, "author": { "support_email": "support@hasura.io", @@ -18,6 +18,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-sdk-go", "version": [ + { + "tag": "v1.4.0", + "hash": "c31575e0eb0c55e0f326c859f7c1a830dc09c424", + "is_verified": true + }, { "tag": "v1.3.1", "hash": "f6093ca96fe64063df786159a2bb061c01d9197d", diff --git a/registry/hasura/go/releases/v1.4.0/connector-packaging.json b/registry/hasura/go/releases/v1.4.0/connector-packaging.json new file mode 100644 index 00000000..a0c4264b --- /dev/null +++ b/registry/hasura/go/releases/v1.4.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v1.4.0", + "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.4.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "d599976b66b18c241eb6bef9baf8c77d15d32c41db4392d198887ef848893e6f" + }, + "source": { + "hash": "c31575e0eb0c55e0f326c859f7c1a830dc09c424" + } +} From f6e9e8fe0358c922b9053ec1fc5cda1d7a1d3ebd Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Fri, 27 Sep 2024 15:34:30 +0530 Subject: [PATCH 105/135] Fix bug in the automation publishing if there are no new connectors to add (#313) --- registry-automation/cmd/ci.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/registry-automation/cmd/ci.go b/registry-automation/cmd/ci.go index 11847204..e6c38895 100644 --- a/registry-automation/cmd/ci.go +++ b/registry-automation/cmd/ci.go @@ -331,11 +331,12 @@ func runCI(cmd *cobra.Command, args []string) { newlyAddedConnectors := processChangedFiles.NewConnectors var newConnectorsToBeAdded NewConnectorsInsertInput - var newConnectorVersionsToBeAdded []ConnectorVersion - + newConnectorsToBeAdded.HubRegistryConnectors = make([]HubRegistryConnectorInsertInput, 0) + newConnectorsToBeAdded.ConnectorOverviews = make([]ConnectorOverviewInsert, 0) newConnectorOverviewsToBeAdded := make([](ConnectorOverviewInsert), 0) hubRegistryConnectorsToBeAdded := make([](HubRegistryConnectorInsertInput), 0) connectorOverviewUpdates := make([]ConnectorOverviewUpdate, 0) + newConnectorVersionsToBeAdded := make([]ConnectorVersion, 0) if len(newlyAddedConnectors) > 0 { fmt.Println("New connectors to be added to the registry: ", newlyAddedConnectors) From 4957217e92cc3116c6af47edd993e3193869d20f Mon Sep 17 00:00:00 2001 From: Karthikeyan Chinnakonda Date: Fri, 27 Sep 2024 15:42:12 +0530 Subject: [PATCH 106/135] revert back the changes in #312 (#314) The changes will be added back in a new PR to test out the connector publishing workflow. --- registry/hasura/go/metadata.json | 2 +- .../go/releases/v1.4.0/connector-packaging.json | 11 ----------- 2 files changed, 1 insertion(+), 12 deletions(-) delete mode 100644 registry/hasura/go/releases/v1.4.0/connector-packaging.json diff --git a/registry/hasura/go/metadata.json b/registry/hasura/go/metadata.json index 87f4b21f..fa065c8b 100644 --- a/registry/hasura/go/metadata.json +++ b/registry/hasura/go/metadata.json @@ -5,7 +5,7 @@ "title": "Go Connector", "logo": "logo.svg", "tags": [], - "latest_version": "v1.4.0" + "latest_version": "v1.3.1" }, "author": { "support_email": "support@hasura.io", diff --git a/registry/hasura/go/releases/v1.4.0/connector-packaging.json b/registry/hasura/go/releases/v1.4.0/connector-packaging.json deleted file mode 100644 index a0c4264b..00000000 --- a/registry/hasura/go/releases/v1.4.0/connector-packaging.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": "v1.4.0", - "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.4.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "d599976b66b18c241eb6bef9baf8c77d15d32c41db4392d198887ef848893e6f" - }, - "source": { - "hash": "c31575e0eb0c55e0f326c859f7c1a830dc09c424" - } -} From 9152eb6a38d564c70c53420bcb8df2bce2973525 Mon Sep 17 00:00:00 2001 From: Toan Nguyen Date: Fri, 27 Sep 2024 17:18:20 +0700 Subject: [PATCH 107/135] add ndc-go v1.4.0 (#315) --- registry/hasura/go/metadata.json | 2 +- .../go/releases/v1.4.0/connector-packaging.json | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 registry/hasura/go/releases/v1.4.0/connector-packaging.json diff --git a/registry/hasura/go/metadata.json b/registry/hasura/go/metadata.json index fa065c8b..87f4b21f 100644 --- a/registry/hasura/go/metadata.json +++ b/registry/hasura/go/metadata.json @@ -5,7 +5,7 @@ "title": "Go Connector", "logo": "logo.svg", "tags": [], - "latest_version": "v1.3.1" + "latest_version": "v1.4.0" }, "author": { "support_email": "support@hasura.io", diff --git a/registry/hasura/go/releases/v1.4.0/connector-packaging.json b/registry/hasura/go/releases/v1.4.0/connector-packaging.json new file mode 100644 index 00000000..a0c4264b --- /dev/null +++ b/registry/hasura/go/releases/v1.4.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v1.4.0", + "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.4.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "d599976b66b18c241eb6bef9baf8c77d15d32c41db4392d198887ef848893e6f" + }, + "source": { + "hash": "c31575e0eb0c55e0f326c859f7c1a830dc09c424" + } +} From 72f6fe07479563b2837754325007ec5979504ac8 Mon Sep 17 00:00:00 2001 From: Rob Dominguez Date: Fri, 27 Sep 2024 13:04:53 -0500 Subject: [PATCH 108/135] Docs: Update READMEs (#298) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates READMEs to include the new `ddn connector init -i` workflow. Additionally, it standarizes the READMEs by reducing the amount of updates needed to CLI commands and — instead — links out to the docs. For any README that is of a "special child" (e.g., PostgreSQL), we've linked to the docs page(s). --- registry/hasura/azure-cosmos/README.md | 138 ++++--------- registry/hasura/bigquery/README.md | 123 +++++------- registry/hasura/clickhouse/README.md | 86 ++------ registry/hasura/cockroach/README.md | 24 +-- registry/hasura/duckdb/README.md | 148 ++++++-------- registry/hasura/elasticsearch/README.md | 69 +++---- registry/hasura/go/README.md | 22 ++- registry/hasura/graphql/README.md | 38 ++-- registry/hasura/mongodb/README.md | 15 +- registry/hasura/mysql/README.md | 182 +++++------------ registry/hasura/nodejs/README.md | 45 ++--- registry/hasura/openapi/README.md | 73 +++---- registry/hasura/oracle/README.md | 184 +++++------------- registry/hasura/postgres/README.md | 4 +- .../aliased_connectors/aurora/README.md | 8 +- .../aliased_connectors/citus/README.md | 22 +-- .../aliased_connectors/neon/README.md | 24 +-- .../postgres-alloydb/README.md | 16 +- .../postgres-azure/README.md | 16 +- .../postgres-cosmos/README.md | 16 +- .../aliased_connectors/postgres-gcp/README.md | 16 +- .../postgres-timescaledb/README.md | 16 +- .../aliased_connectors/yugabyte/README.md | 24 +-- registry/hasura/python/README.md | 98 +++------- registry/hasura/qdrant/README.md | 136 +++++-------- registry/hasura/singlestore/README.md | 160 +++++++-------- registry/hasura/snowflake/README.md | 184 +++++------------- registry/hasura/sqlserver/README.md | 69 +++---- registry/hasura/turso/README.md | 143 +++++--------- 29 files changed, 672 insertions(+), 1427 deletions(-) diff --git a/registry/hasura/azure-cosmos/README.md b/registry/hasura/azure-cosmos/README.md index 5b011b80..5f89006d 100644 --- a/registry/hasura/azure-cosmos/README.md +++ b/registry/hasura/azure-cosmos/README.md @@ -5,9 +5,12 @@ [![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) [![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) -With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in Azure Cosmos DB for NoSQL Database containers. This connector supports Azure Cosmos DB for NoSQL's functionalities listed in the table below, allowing for efficient and scalable data operations. +With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in Azure +Cosmos DB for NoSQL Database containers. This connector supports Azure Cosmos DB for NoSQL's functionalities listed in +the table below, allowing for efficient and scalable data operations. -This connector is built using the [TypeScript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). +This connector is built using the [TypeScript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and +implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). - [Connector information in the Hasura Hub](https://hasura.io/connectors/azure-cosmos) - [Hasura V3 Documentation](https://hasura.io/docs/3.0) @@ -30,120 +33,49 @@ Below, you'll find a matrix of all supported features for the Azure Cosmos DB fo | Nested Sorting | ❌ | | | Nested Relationships | ❌ | | - -## Before you get Started +## Prerequisites 1. Create a [Hasura Cloud account](https://console.hasura.io) -2. Install the [CLI](https://hasura.io/docs/3.0/cli/installation/) -3. Install the [Hasura VS Code extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) -4. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) -5. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) - -## Using the connector - -To use the Azure Cosmos DB for NoSQL connector, follow these steps in a Hasura project: -(Note: for more information on the following steps, please refer to the Postgres connector documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) - +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -### 1. Init the connector -(Note: here and following we are naming the subgraph "my_subgraph" and the connector "my_azure_cosmos") +The steps below explain how to initialize and configure a connector on your local machine (typically for development +purposes).You can learn how to deploy a connector to Hasura DDN — after it's been configured — +[here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). - ```bash - ddn connector init my_azure_cosmos --subgraph my_subgraph/subgraph.yaml --hub-connector hasura/azure-cosmos --configure-port 8081 --add-to-compose-file compose.yaml - ``` +## Using the Azure Cosmos DB for NoSQL connector -### 2. Add your Azure Cosmos DB for NoSQL credentials +With the [context set](https://hasura.io/docs/3.0/cli/commands/ddn_context_set/) for an existing subgraph, initialize +the connector by choosing `hasura/azure-cosmos`. When the wizard runs, you'll also be prompted to enter the following +env vars necessary for your connector to function: -Add you credentials to `my_subgraph/connector/my_azure_cosmos/.env.local` - -```env title="my_subgraph/connector/my_azure_cosmos/.env.local" -OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://local.hasura.dev:4317 -OTEL_SERVICE_NAME=my_subgraph_my_azure_cosmos -AZURE_COSMOS_DB_NAME= -AZURE_COSMOS_ENDPOINT= -AZURE_COSMOS_KEY= -AZURE_COSMOS_NO_OF_ROWS_TO_FETCH= -``` +| Name | Description | Required | +| -------------------------------- | ----------------------------------------------------------------------------------- | -------- | +| AZURE_COSMOS_KEY | The Azure Cosmos DB for NoSQL DB key | Yes | +| AZURE_COSMOS_DB_NAME | Name of the Azure Cosmos DB for NoSQL DB | Yes | +| AZURE_COSMOS_ENDPOINT | Endpoint of the Azure Cosmos DB for NoSQL DB | Yes | +| AZURE_COSMOS_MANAGED_CLIENT_ID | Managed client ID of the Azure Cosmos DB for NoSQL | Yes | +| AZURE_COSMOS_NO_OF_ROWS_TO_FETCH | Maximum number of rows to fetch per container to infer the schema of the container. | No | Note: `AZURE_COSMOS_CONNECTOR_NO_OF_ROWS_TO_FETCH` is an optional field, with 100 rows to be fetched by default. -### 3. Introspect your Database - -From the root of your project run: - -```bash title="From the root of your project run:" -ddn connector introspect --connector my_subgraph/connector/my_azure_cosmos/connector.local.yaml -``` - -If you look at the `config.json` for your connector, you'll see metadata describing your Azure Cosmos DB for NoSQL mappings. - -### 4. Restart the services - -Let's restart the docker compose services. Run the folowing from the root of your project: - -```bash title="From the root of your project run:" -HASURA_DDN_PAT=$(ddn auth print-pat) docker compose up --build --watch -``` - -The schema of the database can be viewed at http://localhost:8081/schema. - -### 5. Create the Hasura metadata - -In a new terminal tab from your project's root directory run: - -```bash title="Run the following from the root of your project:" -ddn connector-link add my_azure_cosmos --subgraph my_subgraph/subgraph.yaml --configure-host http://local.hasura.dev:8081 --target-env-file my_subgraph/.env.my_subgraph.local -``` - -The above step will add the following env vars to the `.env.my_subgraph.local` file. - -```env title="my_subgraph/.env.my_subgraph.local" -MY_SUBGRAPH_MY_AZURE_COSMOS_READ_URL=http://local.hasura.dev:8081 -MY_SUBGRAPH_MY_AZURE_COSMOS_WRITE_URL=http://local.hasura.dev:8081 -``` - -The generated file has two environment variables — one for reads and one for writes. -Each key is prefixed by the subgraph name, an underscore, and the name of the -connector. - -### 6. Update the new DataConnectorLink object - -Finally, now that our `DataConnectorLink` has the correct environment variables configured for the Azure Cosmos DB for NoSQL connector, -we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's -schema in `hml` format. From your project's root directory, run: - -```bash title="From the root of your project, run:" -ddn connector-link update my_azure_cosmos --subgraph my_subgraph/subgraph.yaml --env-file my_subgraph/.env.my_subgraph.local -``` - -After this command runs, you can open your `my_subgraph/metadata/my_azure_cosmos.hml` file and see your metadata completely -scaffolded out for you 🎉 - -### 7. Import _all_ your indices - -You can do this with just one command. From your project's root directory, run: - -```bash title="From the root of your project, run:" -ddn connector-link update my_azure_cosmos --subgraph my_subgraph/subgraph.yaml --env-file my_subgraph/.env.my_subgraph.local --add-all-resources -``` - -### 8. Create a supergraph build - -Pass the `local` subcommand along with specifying the output directory as `./engine` in the root of the project. This -directory is used by the docker-compose file to serve the engine locally. From your project's root directory, run: - -```bash title="From the root of your project, run:" -ddn supergraph build local --output-dir engine --subgraph-env-file my_subgraph:my_subgraph/.env.my_subgraph.local -``` +After the CLI initializes the connector, you'll need to: -You can now navigate to -[`https://console.hasura.io/local/graphql?url=http://localhost:3000`](https://console.hasura.io/local/graphql?url=http://localhost:3000) -and interact with your API using the Hasura Console. +- [Introspect](https://hasura.io/docs/3.0/cli/commands/ddn_connector_introspect) the source. +- Add your [models](https://hasura.io/docs/3.0/cli/commands/ddn_model_add), + [commands](https://hasura.io/docs/3.0/cli/commands/ddn_command_add), and + [relationships](https://hasura.io/docs/3.0/cli/commands/ddn_relationship_add). +- Create a [new build](https://hasura.io/docs/3.0/cli/commands/ddn_supergraph_build_local). +- Test it by [running your project along with the connector](https://hasura.io/docs/3.0/cli/commands/ddn_run#examples). ## Contributing -We're happy to receive any contributions from the community. Please refer to our [development guide](https://github.com/hasura/ndc-azure-cosmos-connector/blob/main/docs/development.md). +We're happy to receive any contributions from the community. Please refer to our +[development guide](https://github.com/hasura/ndc-azure-cosmos-connector/blob/main/docs/development.md). ## License -The Hasura Azure Cosmos DB for NoSQL connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). +The Hasura Azure Cosmos DB for NoSQL connector is available under the +[Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/registry/hasura/bigquery/README.md b/registry/hasura/bigquery/README.md index e182c2c0..07619a99 100644 --- a/registry/hasura/bigquery/README.md +++ b/registry/hasura/bigquery/README.md @@ -6,10 +6,10 @@ [![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in -BigQuery. This connector supports BigQuery's functionalities listed in the table below, allowing for -efficient and scalable data operations. Additionally, users benefit from all the powerful features of Hasura’s Data -Delivery Network (DDN) platform, including query pushdown capabilities that delegate query operations to the database, -thereby enhancing query optimization and performance. +BigQuery. This connector supports BigQuery's functionalities listed in the table below, allowing for efficient and +scalable data operations. Additionally, users benefit from all the powerful features of Hasura’s Data Delivery Network +(DDN) platform, including query pushdown capabilities that delegate query operations to the database, thereby enhancing +query optimization and performance. This connector is built using the [Rust Data Connector SDK](https://github.com/hasura/ndc-hub#rusk-sdk) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). @@ -21,84 +21,61 @@ the [Data Connector Spec](https://github.com/hasura/ndc-spec). Below, you'll find a matrix of all supported features for the BigQuery connector: -| Feature | Supported | Notes | -|---------------------------------|-----------|--------------------------------------| -| Native Queries + Logical Models | ❌ | | -| Native Mutations | ❌ | | -| Simple Object Query | ✅ | | -| Filter / Search | ✅ | | -| Simple Aggregation | ✅ | | -| Sort | ✅ | | -| Paginate | ✅ | | -| Table Relationships | ❌ | | -| Views | ✅ | | -| Remote Relationships | ❌ | | -| Stored Procedures | ❌ | | -| Custom Fields | ❌ | | -| Mutations | ❌ | | -| Distinct | ✅ | | -| Enums | ❌ | | -| Naming Conventions | ❌ | | -| Default Values | ❌ | | -| User-defined Functions | ❌ | | - -## Before you get Started +| Feature | Supported | Notes | +| ------------------------------- | --------- | ----- | +| Native Queries + Logical Models | ❌ | | +| Native Mutations | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ❌ | | +| Views | ✅ | | +| Remote Relationships | ❌ | | +| Stored Procedures | ❌ | | +| Custom Fields | ❌ | | +| Mutations | ❌ | | +| Distinct | ✅ | | +| Enums | ❌ | | +| Naming Conventions | ❌ | | +| Default Values | ❌ | | +| User-defined Functions | ❌ | | + +## Prerequisites 1. Create a [Hasura Cloud account](https://console.hasura.io) -2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed 3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) 4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -The steps below explain how to Initialize and configure a connector for local development. You can learn how to deploy a -connector — after it's been configured — [here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). +The steps below explain how to initialize and configure a connector on your local machine (typically for development +purposes).You can learn how to deploy a connector to Hasura DDN — after it's been configured — +[here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). ## Using the BigQuery connector -### Step 1: Authenticate your CLI session +With the [context set](https://hasura.io/docs/3.0/cli/commands/ddn_context_set/) for an existing subgraph, initialize +the connector by choosing `hasura/bigquery`. When the wizard runs, you'll also be prompted to enter the following env +vars necessary for your connector to function: -```bash -ddn auth login -``` +### Environment Variables -### Step 2: Configure the connector +| Name | Description | Required | Default | +| --------------------------- | ---------------------------------------------- | -------- | ------- | +| HASURA_BIGQUERY_SERVICE_KEY | The service key of the BigQuery project | Yes | N/A | +| HASURA_BIGQUERY_PROJECT_ID | The project ID of the BigQuery databse project | Yes | N/A | +| HASURA_BIGQUERY_DATASET_ID | The dataset ID of the BigQuery databse project | Yes | N/A | -Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while -providing a name for the connector in the prompt: +After the CLI initializes the connector, you'll need to: -```bash -ddn connector init -i -``` - -#### Step 2.1: Choose the `hasura/bigquery` from the list - -#### Step 2.2: Choose a port for the connector - -The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the -default suggested port. - -#### Step 2.3: Provide the env vars for the connector - -| Name | Description | Required | Default | -|-----------------------------|--------------------------------------------------|----------|---------| -| HASURA_BIGQUERY_SERVICE_KEY | The service key of the BigQuery project | Yes | N/A | -| HASURA_BIGQUERY_PROJECT_ID | The project ID of the BigQuery databse project | Yes | N/A | -| HASURA_BIGQUERY_DATASET_ID | The dataset ID of the BigQuery databse project | Yes | N/A | - -## Step 3: Introspect the connector - -```bash -ddn connector introspect -``` - -This will generate a `configuration.json` file that will have the schema of your BigQuery database. - -## Step 4: Add your resources - -```bash -ddn model add '*' -``` - -This command will track all the containers in your BigQuery DB as [Models](https://hasura.io/docs/3.0/supergraph-modeling/models). +- [Introspect](https://hasura.io/docs/3.0/cli/commands/ddn_connector_introspect) the source. +- Add your [models](https://hasura.io/docs/3.0/cli/commands/ddn_model_add), + [commands](https://hasura.io/docs/3.0/cli/commands/ddn_command_add), and + [relationships](https://hasura.io/docs/3.0/cli/commands/ddn_relationship_add). +- Create a [new build](https://hasura.io/docs/3.0/cli/commands/ddn_supergraph_build_local). +- Test it by [running your project along with the connector](https://hasura.io/docs/3.0/cli/commands/ddn_run#examples). ## Documentation @@ -106,9 +83,9 @@ View the full documentation for the ndc-bigquery connector [here](./docs/readme. ## Contributing -We're happy to receive any contributions from the community. Please refer to our [development guide](./docs/development.md). +We're happy to receive any contributions from the community. Please refer to our +[development guide](./docs/development.md). ## License -The Hasura BigQuery connector is available under the [Apache License -2.0](https://www.apache.org/licenses/LICENSE-2.0). +The Hasura BigQuery connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/registry/hasura/clickhouse/README.md b/registry/hasura/clickhouse/README.md index a80dde6a..d53dd4bb 100644 --- a/registry/hasura/clickhouse/README.md +++ b/registry/hasura/clickhouse/README.md @@ -1,83 +1,19 @@ ## Overview -The Clickhouse Native Data Connector allows for connecting to a Clickhouse instance giving you an instant GraphQL API on top of your Clickhouse data. +The ClickHouse Native Data Connector allows for connecting to a ClickHouse instance giving you an instant GraphQL API on top of your ClickHouse data. This uses the [Rust Data Connector SDK](https://github.com/hasura/ndc-hub#rusk-sdk) from the [Data connector Hub](https://github.com/hasura/ndc-hub) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). -ClickHouse is a powerful open-source columnar database that offers a range of features designed for speed and efficiency in processing large volumes of data. ClickHouse is an excellent choice for a database when you are dealing with large volumes of data and require high-speed data retrieval, aggregation, and analysis. It's particularly well-suited for real-time analytics and handling time-series data, log data, or any scenario where read operations vastly outnumber writes. ClickHouse thrives in environments where query performance and the ability to generate reports quickly are critical, such as in financial analysis, IoT data management, and online analytical processing (OLAP). Furthermore, its column-oriented architecture makes it ideal for queries that need to scan large datasets but only access a subset of columns. +ClickHouse is a powerful open-source columnar database that offers a range of features designed for speed and efficiency in processing large volumes of data. ClickHouse is an excellent choice for a database when you are dealing with large volumes of data and require high-speed data retrieval, aggregation, and analysis. It's particularly well-suited for real-time analytics and handling time-series data, log data, or any scenario where read operations vastly outnumber writes. ClickHouse thrives in environments where query performance and the ability to generate reports quickly are critical, such as in financial analysis, IoT data management, and online analytical processing (OLAP). Furthermore, its column-oriented architecture makes it ideal for queries that need to scan large datasets but only access a subset of columns. -## Connect to Hasura +## Prerequisites -Please refer to the [Getting Started - Create an API](https://hasura.io/docs/3.0/getting-started/create-a-project) documentation if you get stuck during any of the steps outlined below. +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) +5. Create a [ClickHouse account](https://clickhouse.cloud/signUp?loc=nav-get-started) if you don't already have one. +6. Make sure to make your ClickHouse service open to the public or add Hasura's IP to the allowlist. -### Prerequisites -1. Install the [new Hasura CLI](https://hasura.io/docs/3.0/cli/installation) — to quickly and easily create and manage your Hasura projects and builds. -2. (recommended) Install the [Hasura VS Code extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) — with support for other editors coming soon! -3. Create a [Clickhouse account](https://clickhouse.cloud/signUp?loc=nav-get-started) if you don't already have one. -4. Make sure to make your Clickhouse service open to the public or add Hasura's IP to the allowlist. +## Using the ClickHouse connector -### Create Project and Connect Clickhouse - -Login to Hasura Cloud with the CLI - -``` -ddn login -``` - -Create a new project using the [create project](https://hasura.io/docs/3.0/cli/commands/create-project/) command in the CLI and change to the new directory that was generated. - -``` -ddn create project --dir ./my-first-supergraph -cd my-first-supergraph -``` - -Run the add [connector-manifest](https://hasura.io/docs/3.0/cli/commands/add-connector-manifest/) command to create a connector for Clickhouse in your project. - -``` -ddn add connector-manifest clickhouse_connector --subgraph app --hub-connector hasura/clickhouse --type cloud -``` - -Add values for your Clickhouse username, password, and connection string to corresponding definition found in: `app/clickhouse/connector/clickhouse_connector.build.hml` - -``` -kind: ConnectorManifest -version: v1 -spec: - supergraphManifests: - - base -definition: - name: clickhouse_connector - type: cloud - connector: - type: hub - name: hasura/clickhouse:v0.2.5 - deployments: - - context: . - env: - CLICKHOUSE_PASSWORD: - value: "" - CLICKHOUSE_URL: - value: "" - CLICKHOUSE_USERNAME: - value: "" -``` - -Note: You can also use environment variables for these values. Please refer to our [Getting Started - Add a connector manifest](https://hasura.io/docs/3.0/cli/commands/add-connector-manifest/) for more details. - -### Update Connector, Track Models and Build - -At this point you can either run the [dev](https://hasura.io/docs/3.0/cli/commands/dev/) mode to watch your project and create new builds as changes are made to your metadata using [Hasura’s LSP](https://hasura.io/docs/3.0/glossary/#lsp-language-server-protocol) and [VSCode extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura). - -``` -ddn dev -``` - -Alternatively, you can run the following commands to add specific models, in this example the `Trips` table and `MonthlyRevenue` view if added the view following the steps mentioned above. -``` -ddn update connector-manifest clickhouse_connector -ddn update data-connector-link clickhouse_connector -ddn add model --data-connector-link clickhouse_connector --name Trips -ddn add model --data-connector-link clickhouse_connector --name MonthlyRevenue -ddn build supergraph-manifest -``` - -You are now ready to start using your API! During the previous step the console will return some information including the Console URL. Load this link in your browser to explore the API you have created for your Clickhouse database. The UI will resemble something like this. \ No newline at end of file +Check out the [Hasura docs here](https://hasura.io/docs/3.0/getting-started/build/connect-to-data/connect-a-source/?db=ClickHouse) to get started with the ClickHouse connector. diff --git a/registry/hasura/cockroach/README.md b/registry/hasura/cockroach/README.md index fdad4553..67c957bf 100644 --- a/registry/hasura/cockroach/README.md +++ b/registry/hasura/cockroach/README.md @@ -1,28 +1,14 @@ ## Overview -`ndc-postgres` provides a Hasura Data Connector to the PostgreSQL database, -which can expose and run GraphQL queries via the Hasura v3 Project. +The Hasura PostgreSQL Connector allows for connecting Hasura to a PostgreSQL database giving you an instant GraphQL API on top of your PostgreSQL data. -- [PostgreSQL Connector information in the Hasura Connectors directory](https://hasura.io/connectors/postgres) -- [GitHub repository](https://github.com/hasura/ndc-postgres) +Data Connectors are the way to connect the Hasura Data Delivery Network (DDN) to external data sources. A data connector is an HTTP service that exposes a set of APIs that Hasura uses to communicate with the data source. Data connectors are built to conform to the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html) using one of Hasura's available SDKs. The data connector is responsible for interpreting work to be done on behalf of the Hasura Engine, using the native query language of the data source. -The connector implements the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html), -but does not currently support column relationship arguments in queries, or functions. +The connector supports the CockroachDB flavor of PostgreSQL. -Visit the -[Hasura v3 Documentation](https://hasura.io/docs/3.0/native-data-connectors/postgresql) -for more information. +## Using the PostgreSQL connector -The connector supports the [CockroachDB](https://www.cockroachlabs.com/) PostgreSQL-compatible database. - -## Deployment - -The connector is hosted by Hasura and can be used from the [Hasura v3 Console](https://console.hasura.io). - -## Usage - -Follow the [Quick Start Guide](https://hasura.io/docs/3.0/quickstart/) -To use the PostgreSQL data connector from the [Hasura v3 Console](https://console.hasura.io). +Check out the [Hasura docs here](https://hasura.io/docs/3.0/getting-started/build/connect-to-data/connect-a-source/?db=PostgreSQL) to get started with the PostgreSQL connector. ## Troubleshooting diff --git a/registry/hasura/duckdb/README.md b/registry/hasura/duckdb/README.md index 4d1a7347..00e60f11 100644 --- a/registry/hasura/duckdb/README.md +++ b/registry/hasura/duckdb/README.md @@ -1,4 +1,5 @@ # Hasura DuckDB Connector + [![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/connectors/duckdb) @@ -6,9 +7,11 @@ [![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](https://github.com/hasura/ndc-duckdb/blob/main/LICENSE.txt) [![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](https://github.com/hasura/ndc-duckdb/blob/main/README.md) -The Hasura DuckDB Connector allows for connecting to a DuckDB database or a MotherDuck hosted DuckDB database to give you an instant GraphQL API on top of your DuckDB data. +The Hasura DuckDB Connector allows for connecting to a DuckDB database or a MotherDuck hosted DuckDB database to give +you an instant GraphQL API on top of your DuckDB data. -This connector is built using the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). +This connector is built using the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and +implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). - [See the listing in the Hasura Hub](https://hasura.io/connectors/duckdb) - [Hasura V3 Documentation](https://hasura.io/docs/3.0/index/) @@ -19,113 +22,74 @@ Below, you'll find a matrix of all supported features for the DuckDB connector: | Feature | Supported | Notes | | ------------------------------- | --------- | ----- | -| Native Queries + Logical Models | ❌ | | -| Simple Object Query | ✅ | | -| Filter / Search | ✅ | | -| Simple Aggregation | ❌ | | -| Sort | ✅ | | -| Paginate | ✅ | | -| Table Relationships | ✅ | | -| Views | ❌ | | -| Distinct | ❌ | | -| Remote Relationships | ✅ | | -| Custom Fields | ❌ | | -| Mutations | ❌ | | - -## Before you get Started - -1. The [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed -2. A [supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) -3. A [subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -4. Have a [MotherDuck](https://motherduck.com/) hosted DuckDB database, or a persitent DuckDB database file — for supplying data to your API. - -The steps below explain how to Initialize and configure a connector for local development. You can learn how to deploy a -connector — after it's been configured — [here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). +| Native Queries + Logical Models | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ❌ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ✅ | | +| Views | ❌ | | +| Distinct | ❌ | | +| Remote Relationships | ✅ | | +| Custom Fields | ❌ | | +| Mutations | ❌ | | + +## Prerequisites + +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) +5. Have a [MotherDuck](https://motherduck.com/) hosted DuckDB database, or a persitent DuckDB database file — for + supplying data to your API. + +The steps below explain how to initialize and configure a connector on your local machine (typically for development +purposes).You can learn how to deploy a connector to Hasura DDN — after it's been configured — +[here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). ## Using the DuckDB connector -### Step 1: Authenticate your CLI session - -```bash -ddn auth login -``` - -### Step 2: Configure the connector - -Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while providing a name for the connector in the prompt: - -```bash -ddn connector init duckdb -i -``` - -#### Step 2.1: Choose the `hasura/duckdb` option from the list - -#### Step 2.2: Choose a port for the connector - -The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the default suggested port. - -#### Step 2.3: Provide the env var(s) for the connector - -| Name | Description | -|-|-| -| DUCKDB_URL | The connection string for the DuckDB database, or the file path to the DuckDB database file | +With the [context set](https://hasura.io/docs/3.0/cli/commands/ddn_context_set/) for an existing subgraph, initialize +the connector: -You'll find the environment variables in the `.env` file and they will be in the format: - -`__` - -Here is an example of what your `.env` file might look like: - -``` -APP_DUCKDB_AUTHORIZATION_HEADER="Bearer SPHZWfL7P3Jdc9mDMF9ZNA==" -APP_DUCKDB_DUCKDB_URL="md:?motherduck_token=ey..." -APP_DUCKDB_HASURA_SERVICE_TOKEN_SECRET="SPHZWfL7P3Jdc9mDMF9ZNA==" -APP_DUCKDB_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://local.hasura.dev:4317" -APP_DUCKDB_OTEL_SERVICE_NAME="app_duckdb" -APP_DUCKDB_READ_URL="http://local.hasura.dev:7525" -APP_DUCKDB_WRITE_URL="http://local.hasura.dev:7525" -``` - -If you are attaching to a local DuckDB file, first make sure that the file is located inside the connector directory. For example, if you had a `data.duckdb` file you could place it at `/app/connector/duckdb/data.duckdb`. Files in the connector directory get mounted to `/etc/connector/`. - -In this instance, you would set the `DUCKDB_URL=/etc/connector/data.duckdb`. Now your `.env` might look like this: - -``` -APP_DUCKDB_AUTHORIZATION_HEADER="Bearer SPHZWfL7P3Jdc9mDMF9ZNA==" -APP_DUCKDB_DUCKDB_URL="/etc/connector/data.duckdb" -APP_DUCKDB_HASURA_SERVICE_TOKEN_SECRET="SPHZWfL7P3Jdc9mDMF9ZNA==" -APP_DUCKDB_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://local.hasura.dev:4317" -APP_DUCKDB_OTEL_SERVICE_NAME="app_duckdb" -APP_DUCKDB_READ_URL="http://local.hasura.dev:7525" -APP_DUCKDB_WRITE_URL="http://local.hasura.dev:7525" +```sh +ddn connector init -i ``` -Your experience mounting files may vary, and while useful to explore a file locally, it's not recommended to attempt to deploy a connector using a locally mounted file. +When the wizard runs, you'll be prompted to enter the following env vars necessary for your connector to function: -### Step 3: Introspect the connector +| Name | Description | +| ---------- | ------------------------------------------------------------------------------------------- | +| DUCKDB_URL | The connection string for the DuckDB database, or the file path to the DuckDB database file | -Introspecting the connector will generate a `config.json` file and a `duckdb.hml` file. +If you are attaching to a local DuckDB file, first make sure that the file is located inside the connector directory. +For example, if you had a `data.duckdb` file you could place it at `/app/connector/duckdb/data.duckdb`. Files in the +connector directory get mounted to `/etc/connector/`. -```bash -ddn connector introspect duckdb -``` - -### Step 4: Add your resources +**Your experience mounting files may vary, and while useful to explore a file locally, it's not recommended to attempt +to deploy a connector using a locally mounted file.** -You can add the models, commands, and relationships to your API by tracking them which generates the HML files. +After the CLI initializes the connector, you'll need to: -```bash -ddn connector-link add-resources duckdb -``` +- [Introspect](https://hasura.io/docs/3.0/cli/commands/ddn_connector_introspect) the source. +- Add your [models](https://hasura.io/docs/3.0/cli/commands/ddn_model_add), + [commands](https://hasura.io/docs/3.0/cli/commands/ddn_command_add), and + [relationships](https://hasura.io/docs/3.0/cli/commands/ddn_relationship_add). +- Create a [new build](https://hasura.io/docs/3.0/cli/commands/ddn_supergraph_build_local). +- Test it by [running your project along with the connector](https://hasura.io/docs/3.0/cli/commands/ddn_run#examples). ## Documentation -View the full documentation for the DuckDB connector [here](https://github.com/hasura/ndc-duckdb/blob/main/docs/index.md). +View the full documentation for the DuckDB connector +[here](https://github.com/hasura/ndc-duckdb/blob/main/docs/index.md). ## Contributing -Check out our [contributing guide](https://github.com/hasura/ndc-duckdb/blob/main/docs/contributing.md) for more details. +Check out our [contributing guide](https://github.com/hasura/ndc-duckdb/blob/main/docs/contributing.md) for more +details. ## License -The DuckDB connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file +The DuckDB connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/registry/hasura/elasticsearch/README.md b/registry/hasura/elasticsearch/README.md index 7edacec6..6fc1f98f 100644 --- a/registry/hasura/elasticsearch/README.md +++ b/registry/hasura/elasticsearch/README.md @@ -4,9 +4,14 @@ [![ndc-hub](https://img.shields.io/badge/ndc--hub-elasticsearch-blue.svg?style=flat)](https://hasura.io/connectors/elasticsearch) [![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0) -With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your documents in Elasticsearch. This connector supports Elasticsearch functionalities listed in the table below, allowing for efficient and scalable data operations. Additionally, you will benefit from all the powerful features of Hasura’s Data Delivery Network (DDN) platform, including query pushdown capabilities that delegate all query operations to the Elasticsearch, thereby enhancing query optimization and performance. +With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your documents in +Elasticsearch. This connector supports Elasticsearch functionalities listed in the table below, allowing for efficient +and scalable data operations. Additionally, you will benefit from all the powerful features of Hasura’s Data Delivery +Network (DDN) platform, including query pushdown capabilities that delegate all query operations to the Elasticsearch, +thereby enhancing query optimization and performance. -This connector is built using the [Go Data Connector SDK](https://github.com/hasura/ndc-sdk-go) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). +This connector is built using the [Go Data Connector SDK](https://github.com/hasura/ndc-sdk-go) and implements the +[Data Connector Spec](https://github.com/hasura/ndc-spec). - [See the listing in the Hasura Hub](https://hasura.io/connectors/elasticsearch) - [Hasura DDN Documentation](https://hasura.io/docs/3.0) @@ -41,40 +46,28 @@ Below, you'll find a matrix of all supported features for the Elasticsearch conn | Nested Sorting | ❌ | | | Nested Relationships | ❌ | | -## Before you get Started +## Prerequisites 1. Create a [Hasura Cloud account](https://console.hasura.io) -2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed 3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) 4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -## Using the Elasticsearch connector - -### Step 1: Authenticate your CLI session - -```bash -ddn auth login -``` +The steps below explain how to initialize and configure a connector on your local machine (typically for development +purposes).You can learn how to deploy a connector to Hasura DDN — after it's been configured — +[here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). -### Step 2: Configure the connector +## Using the Elasticsearch connector -Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while -providing a name for the connector in the prompt: +With the [context set](https://hasura.io/docs/3.0/cli/commands/ddn_context_set/) for an existing subgraph, initialize +the connector: -```bash -ddn connector init -i +```sh +ddn connector init -i ``` -#### Step 2.1: Choose `hasura/elasticsearch` from the list - -#### Step 2.2: Choose a port for the connector - -The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the -default suggested port. - -#### Step 2.3: Provide the env vars required for the connector - -To configure the connector, the following environment variables need to be set: +When the wizard runs, you'll be prompted to enter the following env vars necessary for your connector to function: | Environment Variable | Description | Required | Example Value | | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------- | @@ -85,25 +78,19 @@ To configure the connector, the following environment variables need to be set: | `ELASTICSEARCH_CA_CERT_PATH` | The path to the Certificate Authority (CA) certificate for verifying the Elasticsearch server's SSL certificate | No | `/etc/connector/cacert.pem` | | `ELASTICSEARCH_INDEX_PATTERN` | The pattern for matching Elasticsearch indices, potentially including wildcards, used by the connector | No | `hasura*` | -## Step 3: Introspect the connector - -```bash -ddn connector introspect -``` - -This will generate a `configuration.json` file that will have the schema of your Elasticsearch DB. - -## Step 4: Add your resources - -```bash -ddn connector-link add-resources -``` +After the CLI initializes the connector, you'll need to: -This command will track all the indices in your Elasticsearch DB as [Models](https://hasura.io/docs/3.0/supergraph-modeling/models). +- [Introspect](https://hasura.io/docs/3.0/cli/commands/ddn_connector_introspect) the source. +- Add your [models](https://hasura.io/docs/3.0/cli/commands/ddn_model_add), + [commands](https://hasura.io/docs/3.0/cli/commands/ddn_command_add), and + [relationships](https://hasura.io/docs/3.0/cli/commands/ddn_relationship_add). +- Create a [new build](https://hasura.io/docs/3.0/cli/commands/ddn_supergraph_build_local). +- Test it by [running your project along with the connector](https://hasura.io/docs/3.0/cli/commands/ddn_run#examples). ## Contributing -Check out our [contributing guide](https://github.com/hasura/ndc-elasticsearch/blob/main/docs/contributing.md) for more details. +Check out our [contributing guide](https://github.com/hasura/ndc-elasticsearch/blob/main/docs/contributing.md) for more +details. ## License diff --git a/registry/hasura/go/README.md b/registry/hasura/go/README.md index 6434f6df..e6dc282d 100644 --- a/registry/hasura/go/README.md +++ b/registry/hasura/go/README.md @@ -1,13 +1,27 @@ ## Overview -The Go connector allows you to expose Go functions as NDC functions/procedures for use in your Hasura DDN subgraphs. -The connector provides a boilerplate with NDC Go SDK and a generation tool to generate NDC schema and DRY functions from Go code. +The Go connector allows you to expose Go functions as NDC functions/procedures for use in your Hasura DDN subgraphs. The +connector provides a boilerplate with NDC Go SDK and a generation tool to generate NDC schema and DRY functions from Go +code. - [GitHub Repository](https://github.com/hasura/ndc-sdk-go) -## How to Use +## Prerequisites -See the README file in the boilerplate which is generated from [this template](https://github.com/hasura/ndc-sdk-go/blob/main/cmd/ndc-go-sdk/templates/new/README.md.tmpl), or see [README of the generation tool on the GitHub repository](https://github.com/hasura/ndc-sdk-go/blob/main/cmd/ndc-go-sdk/README.md) for more context. +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) + +The steps below explain how to initialize and configure a connector on your local machine (typically for development +purposes).You can learn how to deploy a connector to Hasura DDN — after it's been configured — +[here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). + +## Using the Go connector + +Check out the [Hasura docs here](https://hasura.io/docs/3.0/business-logic/go#add-the-go-connector-to-a-project) to get +started with the Go connector. ## Compatibility diff --git a/registry/hasura/graphql/README.md b/registry/hasura/graphql/README.md index 42e9cdb7..cae2f659 100644 --- a/registry/hasura/graphql/README.md +++ b/registry/hasura/graphql/README.md @@ -1,24 +1,40 @@ ## Overview -The Hasura GraphQL Connector allows for connecting to a GraphQL API and bringing it into Hasura DDN supergraph as a single unified API. It can also be used to bring in your current Hasura v2 graphQL API into Hasura DDN and our recommended approach is to create a new subgraph for the v2 API. +The Hasura GraphQL Connector allows for connecting to a GraphQL API and bringing it into Hasura DDN supergraph as a +single unified API. It can also be used to bring in your current Hasura v2 graphQL API into Hasura DDN and our +recommended approach is to create a new subgraph for the v2 API. -For Hasura v2 users, this functionality is the replacement of [remote schemas](https://hasura.io/docs/latest/remote-schemas/overview/) functionality in v3 (DDN). +For Hasura v2 users, this functionality is the replacement of +[remote schemas](https://hasura.io/docs/latest/remote-schemas/overview/) functionality in v3 (DDN). -The `ndc-graphql` data connector is open source and can be found in the [ndc-graphql GitHub repository](https://github.com/hasura/ndc-graphql). +The `ndc-graphql` data connector is open source and can be found in the +[ndc-graphql GitHub repository](https://github.com/hasura/ndc-graphql). -Visit the [Hasura v3 Documentation](https://hasura.io/docs/3.0/native-data-connectors) for more information. +## Prerequisites -## Deployment - -The connector is hosted by Hasura and can be used from the [Hasura v3 CLI](https://hasura.io/docs/3.0/cli/overview/) and [Console](https://console.hasura.io). Please follow either the [Quick Start Guide](https://hasura.io/docs/3.0/getting-started/overview/) or [deploying the connector](https://hasura.io/docs/3.0/connectors/deployment). +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -## Usage +The steps below explain how to initialize and configure a connector on your local machine (typically for development +purposes).You can learn how to deploy a connector to Hasura DDN — after it's been configured — +[here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). -Please refer to the [connector readme](https://github.com/hasura/ndc-graphql/blob/main/README.md) +## Using the GraphQL connector -## Troubleshooting +Check out the +[Hasura docs here](https://hasura.io/docs/3.0/getting-started/build/connect-to-data/connect-a-source/?db=GraphQL) to get +started with the GraphQL connector. -Please [submit a Github issue](https://github.com/hasura/graphql-engine/issues/new)if you encounter any problems! +## Deployment +The connector is hosted by Hasura and can be used from the [Hasura v3 CLI](https://hasura.io/docs/3.0/cli/overview/) and +[Console](https://console.hasura.io). Please follow either the +[Quick Start Guide](https://hasura.io/docs/3.0/getting-started/overview/) or +[deploying the connector](https://hasura.io/docs/3.0/connectors/deployment). +## Troubleshooting +Please [submit a Github issue](https://github.com/hasura/graphql-engine/issues/new)if you encounter any problems! diff --git a/registry/hasura/mongodb/README.md b/registry/hasura/mongodb/README.md index 23d3ef46..3e17e1e9 100644 --- a/registry/hasura/mongodb/README.md +++ b/registry/hasura/mongodb/README.md @@ -3,20 +3,21 @@ `ndc-mongodb` provides a Hasura Data Connector to the MongoDB database, which can expose and run GraphQL queries via the Hasura v3 Project. -- [MongoDB Connector information in the Hasura Connectors directory](https://hasura.io/connectors/mongodb) - [GitHub repository](https://github.com/hasura/ndc-mongodb) The connector implements the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html), but does not currently support mutations, column relationship arguments in queries, functions or procedures. -Visit the -[Hasura v3 Documentation](https://hasura.io/docs/3.0/connectors/mongodb/) -for more information. +## Prerequisites -## Usage +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -Follow the [Quick Start Guide](https://hasura.io/docs/3.0/quickstart/) -to use the MongoDB data connector from the [Hasura v3 Console](https://console.hasura.io). +## Using the MongoDB connector + +Check out the [Hasura docs here](https://hasura.io/docs/3.0/getting-started/build/connect-to-data/connect-a-source/?db=MongoDB) to get started with the ClickHouse connector. ## Troubleshooting diff --git a/registry/hasura/mysql/README.md b/registry/hasura/mysql/README.md index 092627fb..a61c4c8e 100644 --- a/registry/hasura/mysql/README.md +++ b/registry/hasura/mysql/README.md @@ -5,11 +5,11 @@ [![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) [![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) -With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in -MySQL. This connector supports MySQL's functionalities listed in the table below, allowing for -efficient and scalable data operations. Additionally, users benefit from all the powerful features of Hasura’s Data -Delivery Network (DDN) platform, including query pushdown capabilities that delegate query operations to the database, -thereby enhancing query optimization and performance. +With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in MySQL. +This connector supports MySQL's functionalities listed in the table below, allowing for efficient and scalable data +operations. Additionally, users benefit from all the powerful features of Hasura’s Data Delivery Network (DDN) platform, +including query pushdown capabilities that delegate query operations to the database, thereby enhancing query +optimization and performance. This connector implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). @@ -22,148 +22,56 @@ Below, you'll find a matrix of all supported features for the MySQL connector: | Feature | Supported | Notes | | ------------------------------- | --------- | ----- | -| Native Queries + Logical Models | ✅ | | -| Native Mutations | ❌ | | -| Simple Object Query | ✅ | | -| Filter / Search | ✅ | | -| Simple Aggregation | ✅ | | -| Sort | ✅ | | -| Paginate | ✅ | | -| Table Relationships | ✅ | | -| Views | ✅ | | -| Remote Relationships | ✅ | | -| Custom Fields | ❌ | | -| Mutations | ❌ | | -| Distinct | ❌ | | -| Enums | ❌ | | -| Naming Conventions | ❌ | | -| Default Values | ❌ | | -| User-defined Functions | ❌ | | - -## Before you get Started +| Native Queries + Logical Models | ✅ | | +| Native Mutations | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ✅ | | +| Views | ✅ | | +| Remote Relationships | ✅ | | +| Custom Fields | ❌ | | +| Mutations | ❌ | | +| Distinct | ❌ | | +| Enums | ❌ | | +| Naming Conventions | ❌ | | +| Default Values | ❌ | | +| User-defined Functions | ❌ | | + +## Prerequisites 1. Create a [Hasura Cloud account](https://console.hasura.io) -2. Install the [CLI](https://hasura.io/docs/3.0/cli/installation/) -3. Install the [Hasura VS Code extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) -4. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) -5. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -## Using the connector +## Using the MySQL connector -To use the MySQL connector, follow these steps in a Hasura project: -(Note: for more information on the following steps, please refer to the Postgres connector -documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) +With the [context set](https://hasura.io/docs/3.0/cli/commands/ddn_context_set/) for an existing subgraph, initialize +the connector: -### 1. Init the connector - -(Note: here and following we are naming the subgraph "my_subgraph" and the connector "my_mysql") - - ```bash - ddn connector init my_mysql --subgraph my_subgraph --hub-connector hasura/mysql - ``` - -### 2. Add your MySQL credentials: - -Add your credentials to `my_subgraph/connector/my_sql/.env.local` - -```env title="my_subgraph/connector/my_mysql/.env.local" -JDBC_URL="jdbc:MySQL:thin:@//host.docker.internal:1521/XE?user=&password=" +```sh +ddn connector init -i ``` -### 3. Introspect your indices - -```bash title="From the root of your project run:" -ddn connector introspect --connector my_subgraph/connector/my_mysql/connector.yaml -``` - -If you look at the `configuration.json` for your connector, you'll see metadata describing your MySQL mappings. - -### 4. Create the Hasura metadata - -```bash title="Run the following from the root of your project:" -ddn connector-link add my_mysql --subgraph my_subgraph -``` - -The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your -subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the -connector. Ensure the port value matches what is published in your connector's docker compose file. - -```env title="my_subgraph/.env.my_subgraph" -MY_SUBGRAPH_my_mysql_READ_URL=http://local.hasura.dev:8081 -MY_SUBGRAPH_my_mysql_WRITE_URL=http://local.hasura.dev:8081 -``` - -### 5. Start the connector's docker compose - -Let's start our connector's docker compose file. - -```bash title="Run the following from the connector's subdirectory inside a subgraph:" -docker compose -f docker-compose.my_mysql.yaml up -``` - -This starts our MySQL connector on the specified port. We can navigate to the following address, with the port -modified, to see the schema of our MySQL data source: - -```bash -http://localhost:8081/schema -``` +When the wizard runs, you'll be prompted to enter the following env vars necessary for your connector to function: -### 6. Include the connector in your docker compose - -Kill the connector by pressing `CTRL+C` in the terminal tab in which the connector is running. - -Then, add the following inclusion to the docker compose `docker-compose.hasura.yaml` in your project's root directory, -taking care to modify the -subgraph's name. - -```yaml title="docker-compose.hasura.yaml" -include: - - path: my_subgraph/connector/my_mysql/docker-compose.my_mysql.yaml -``` - -Now, whenever running the following, you'll bring up the GraphQL engine, observability tools, and any connectors you've -included: - -```bash title="From the root of your project, run:" -HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yaml watch -``` - -### 7. Update the new DataConnectorLink object - -Finally, now that our `DataConnectorLink` has the correct environment variables configured for the MySQL connector, -we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's -schema in `hml` format. In a new terminal tab, run: - -```bash title="From the root of your project, run:" -ddn connector-link update my_mysql --subgraph my_subgraph -``` - -After this command runs, you can open your `my_subgraph/metadata/my_mysql.hml` file and see your metadata completely -scaffolded out for you 🎉 - -### 8. Import _all_ your indices - -You can do this in one convenience command. - -```bash title="From the root of your project, run:" -ddn connector-link update my_mysql --subgraph my_subgraph --add-all-resources -``` - -### 9. Create a supergraph build - -Pass the `local` subcommand along with specifying the output directory as `./engine` in the root of the project. This -directory is used by the docker-compose file to serve the engine locally: - -```bash title="From the root of your project, run:" -ddn supergraph build local --output-dir ./engine -``` +| Name | Description | Required | +| -------- | --------------------------------------- | -------- | +| JDBC_URL | The JDBC URL to connect to the database | Yes | -You can now navigate to -[`https://console.hasura.io/local/graphql?url=http://localhost:3000`](https://console.hasura.io/local/graphql?url=http://localhost:3000) -and interact with your API using the Hasura Console. +After the CLI initializes the connector, you'll need to: +- [Introspect](https://hasura.io/docs/3.0/cli/commands/ddn_connector_introspect) the source. +- Add your [models](https://hasura.io/docs/3.0/cli/commands/ddn_model_add), + [commands](https://hasura.io/docs/3.0/cli/commands/ddn_command_add), and + [relationships](https://hasura.io/docs/3.0/cli/commands/ddn_relationship_add). +- Create a [new build](https://hasura.io/docs/3.0/cli/commands/ddn_supergraph_build_local). +- Test it by [running your project along with the connector](https://hasura.io/docs/3.0/cli/commands/ddn_run#examples). ## License -The Hasura MySQL connector is available under the [Apache License -2.0](https://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file +The Hasura MySQL connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/registry/hasura/nodejs/README.md b/registry/hasura/nodejs/README.md index c41f7477..8ea0dbc8 100644 --- a/registry/hasura/nodejs/README.md +++ b/registry/hasura/nodejs/README.md @@ -2,39 +2,24 @@ The NodeJS Lambda connector allows you to expose TypeScript functions as Commands in your Hasura DDN Supergraph. -Here's an example function that defines and uses two object types. It is exported as a `@readonly` function so that it can be exposed from the Supergraph's GraphQL query schema. +## Prerequisites -```typescript -type FullName = { - title: string - firstName: string - surname: string -} +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -type Greeting = { - polite: string - casual: string -} +The steps below explain how to initialize and configure a connector on your local machine (typically for development +purposes).You can learn how to deploy a connector to Hasura DDN — after it's been configured — +[here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). -/** @readonly */ -export function greet(name: FullName): Greeting { - return { - polite: `Hello ${name.title} ${name.surname}`, - casual: `G'day ${name.firstName}` - } -} -``` +## Using the NodeJS Lambda connector -The NodeJS Lambda connector introspects the TypeScript types you use on your exported functions to determine the schema to use in your Supergraph. You are able to import any NodeJS npm package and use it. - -The NodeJS Lambda connector enables you to: - -* Add business logic to your Supergraph by writing normal NodeJS TypeScript code -* Expose data from any external API by writing TypeScript code that invokes the API and returns the data -* Implement complex database logic manually by connecting to your database via a native driver library imported from npm - -To learn more about this connector and how to use it, please see the [Hasura DDN Documentation](https://hasura.io/docs/3.0/connectors/typescript). +Check out the +[Hasura docs here](https://hasura.io/docs/3.0/business-logic/typescript#add-the-typescript-connector-to-a-project) to +get started with the NodeJS Lambda connector. ## More Information -* [Hasura DDN Documentation](https://hasura.io/docs/3.0/connectors/typescript) -* [ndc-nodejs-lambda GitHub Repository](https://github.com/hasura/ndc-nodejs-lambda) \ No newline at end of file + +- [ndc-nodejs-lambda GitHub Repository](https://github.com/hasura/ndc-nodejs-lambda) diff --git a/registry/hasura/openapi/README.md b/registry/hasura/openapi/README.md index 8ba92e54..d9041131 100644 --- a/registry/hasura/openapi/README.md +++ b/registry/hasura/openapi/README.md @@ -4,9 +4,13 @@ [![ndc-hub](https://img.shields.io/badge/ndc--hub-openapi-blue.svg?style=flat)](https://hasura.io/connectors/open-api-lambda) [![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0) -The OpenAPI Lambda Connector allows you to import APIs that are documented in the OpenAPI/Swagger format into the Hasura Supergraph. The connector exposes REST API endpoints as Typescript functions, which can be exposed as GraphQL queries or mutations via the [NodeJS Lambda Connector](https://github.com/hasura/ndc-nodejs-lambda). +The OpenAPI Lambda Connector allows you to import APIs that are documented in the OpenAPI/Swagger format into the Hasura +Supergraph. The connector exposes REST API endpoints as Typescript functions, which can be exposed as GraphQL queries or +mutations via the [NodeJS Lambda Connector](https://github.com/hasura/ndc-nodejs-lambda). -Functions that wrap GET requests are marked with a `@readonly` annotation, and are exposed as GraphQL Queries by the [NodeJS Lambda Connector](https://github.com/hasura/ndc-nodejs-lambda). All other request types are exposed as GraphQL Mutations. +Functions that wrap GET requests are marked with a `@readonly` annotation, and are exposed as GraphQL Queries by the +[NodeJS Lambda Connector](https://github.com/hasura/ndc-nodejs-lambda). All other request types are exposed as GraphQL +Mutations. This Connector implements the [Data Connector Spec](https://github.com/hasura/ndc-spec) @@ -35,66 +39,35 @@ Docs for the OpenAPI data connector: | PUT | ✅ | ✅ | ✅ | ✅ | | PATCH | ✅ | ✅ | ✅ | ✅ | -## Before you get Started +## Prerequisites 1. Create a [Hasura Cloud account](https://console.hasura.io) -2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed 3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) 4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -5. If you want to make changes to the generated Typescript files, please ensure you have Node.js v20+ installed -## Using the OpenAPI connector +The steps below explain how to initialize and configure a connector on your local machine (typically for development +purposes).You can learn how to deploy a connector to Hasura DDN — after it's been configured — +[here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). -### Step 1: Authenticate your CLI session +## Using the OpenAPI Lambda connector -```bash -ddn auth login -``` - -### Step 2: Configure the connector - -Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while -providing a name for the connector in the prompt: - -```bash -ddn connector init -i -``` - -#### Step 2.1: Choose `hasura/openapi` from the list - -#### Step 2.2: Choose a port for the connector - -The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the -default suggested port. - -#### Step 2.3: Provide the env vars required for the connector - -Environment variables that can be used to configure the connector are listed under [Supported Environment Variables](https://github.com/hasura/ndc-open-api-lambda/blob/main/docs/documentation.md#supported-environment-variables). - -## Step 3: Introspect the connector - -```bash -ddn connector introspect -``` - -This will generate the required metadata and TypeScript files. - -## Step 4: Add your resources - -```bash -ddn connector-link add-resources -``` - -This command will track all the API endpoints in your OpenAPI Document as [Commands](https://hasura.io/docs/3.0/supergraph-modeling/commands/). +Check out the +[Hasura docs here](https://hasura.io/docs/3.0/getting-started/build/connect-to-data/connect-a-source?db=OpenAPI) to get +started with the OpenAPI Lambda connector. ## Saving User Changes -Please refer to [Saving User Changes](https://github.com/hasura/ndc-open-api-lambda/blob/main/docs/documentation.md#saving-user-changes). +Please refer to +[Saving User Changes](https://github.com/hasura/ndc-open-api-lambda/blob/main/docs/documentation.md#saving-user-changes). -## Known Limiations +## Known Limitations -- Support for [Relaxed Types](https://github.com/hasura/ndc-nodejs-lambda/tree/main?tab=readme-ov-file#relaxed-types) is a WiP. -- [Types not supported by the NodeJS Lambda Connector](https://github.com/hasura/ndc-nodejs-lambda?tab=readme-ov-file#unsupported-types) are not supported. +- Support for [Relaxed Types](https://github.com/hasura/ndc-nodejs-lambda/tree/main?tab=readme-ov-file#relaxed-types) is + a WiP. +- [Types not supported by the NodeJS Lambda Connector](https://github.com/hasura/ndc-nodejs-lambda?tab=readme-ov-file#unsupported-types) + are not supported. ## Contributing diff --git a/registry/hasura/oracle/README.md b/registry/hasura/oracle/README.md index 604f318c..a92df5c1 100644 --- a/registry/hasura/oracle/README.md +++ b/registry/hasura/oracle/README.md @@ -5,11 +5,11 @@ [![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) [![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) -With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in -Oracle. This connector supports Oracle's functionalities listed in the table below, allowing for -efficient and scalable data operations. Additionally, users benefit from all the powerful features of Hasura’s Data -Delivery Network (DDN) platform, including query pushdown capabilities that delegate query operations to the database, -thereby enhancing query optimization and performance. +With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in Oracle. +This connector supports Oracle's functionalities listed in the table below, allowing for efficient and scalable data +operations. Additionally, users benefit from all the powerful features of Hasura’s Data Delivery Network (DDN) platform, +including query pushdown capabilities that delegate query operations to the database, thereby enhancing query +optimization and performance. This connector implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). @@ -21,149 +21,57 @@ This connector implements the [Data Connector Spec](https://github.com/hasura/nd Below, you'll find a matrix of all supported features for the Oracle connector: | Feature | Supported | Notes | -|---------------------------------|-----------|-------| -| Native Queries + Logical Models | ✅ | | -| Native Mutations | ❌ | | -| Simple Object Query | ✅ | | -| Filter / Search | ✅ | | -| Simple Aggregation | ✅ | | -| Sort | ✅ | | -| Paginate | ✅ | | -| Table Relationships | ✅ | | -| Views | ✅ | | -| Remote Relationships | ✅ | | -| Custom Fields | ❌ | | -| Mutations | ❌ | | -| Distinct | ❌ | | -| Enums | ❌ | | -| Naming Conventions | ❌ | | -| Default Values | ❌ | | -| User-defined Functions | ❌ | | - -## Before you get Started +| ------------------------------- | --------- | ----- | +| Native Queries + Logical Models | ✅ | | +| Native Mutations | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ✅ | | +| Views | ✅ | | +| Remote Relationships | ✅ | | +| Custom Fields | ❌ | | +| Mutations | ❌ | | +| Distinct | ❌ | | +| Enums | ❌ | | +| Naming Conventions | ❌ | | +| Default Values | ❌ | | +| User-defined Functions | ❌ | | + +## Prerequisites 1. Create a [Hasura Cloud account](https://console.hasura.io) -2. Install the [CLI](https://hasura.io/docs/3.0/cli/installation/) -3. Install the [Hasura VS Code extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) -4. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) -5. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -## Using the connector +## Using the Oracle connector -To use the Oracle connector, follow these steps in a Hasura project: -(Note: for more information on the following steps, please refer to the Postgres connector -documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) +With the [context set](https://hasura.io/docs/3.0/cli/commands/ddn_context_set/) for an existing subgraph, initialize +the connector: -### 1. Init the connector - -(Note: here and following we are naming the subgraph "my_subgraph" and the connector "my_oracle") - - ```bash - ddn connector init my_oracle --subgraph my_subgraph --hub-connector hasura/Oracle - ``` - -### 2. Add your Oracle credentials: - -Add your credentials to `my_subgraph/connector/my_sql/.env.local` - -```env title="my_subgraph/connector/my_oracle/.env.local" -JDBC_URL="jdbc:oracle:thin:@//host.docker.internal:1521/XE?user=&password=" +```sh +ddn connector init -i ``` -### 3. Introspect your indices - -```bash title="From the root of your project run:" -ddn connector introspect --connector my_subgraph/connector/my_oracle/connector.yaml -``` - -If you look at the `configuration.json` for your connector, you'll see metadata describing your Oracle mappings. - -### 4. Create the Hasura metadata - -```bash title="Run the following from the root of your project:" -ddn connector-link add my_oracle --subgraph my_subgraph -``` - -The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your -subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the -connector. Ensure the port value matches what is published in your connector's docker compose file. - -```env title="my_subgraph/.env.my_subgraph" -MY_SUBGRAPH_my_oracle_READ_URL=http://local.hasura.dev:8081 -MY_SUBGRAPH_my_oracle_WRITE_URL=http://local.hasura.dev:8081 -``` - -### 5. Start the connector's docker compose - -Let's start our connector's docker compose file. - -```bash title="Run the following from the connector's subdirectory inside a subgraph:" -docker compose -f docker-compose.my_oracle.yaml up -``` - -This starts our Oracle connector on the specified port. We can navigate to the following address, with the port -modified, to see the schema of our Oracle data source: - -```bash -http://localhost:8081/schema -``` +When the wizard runs, you'll be prompted to enter the following env vars necessary for your connector to function: -### 6. Include the connector in your docker compose - -Kill the connector by pressing `CTRL+C` in the terminal tab in which the connector is running. - -Then, add the following inclusion to the docker compose `docker-compose.hasura.yaml` in your project's root directory, -taking care to modify the -subgraph's name. - -```yaml title="docker-compose.hasura.yaml" -include: - - path: my_subgraph/connector/my_oracle/docker-compose.my_oracle.yaml -``` - -Now, whenever running the following, you'll bring up the GraphQL engine, observability tools, and any connectors you've -included: - -```bash title="From the root of your project, run:" -HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yaml watch -``` - -### 7. Update the new DataConnectorLink object - -Finally, now that our `DataConnectorLink` has the correct environment variables configured for the Oracle connector, -we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's -schema in `hml` format. In a new terminal tab, run: - -```bash title="From the root of your project, run:" -ddn connector-link update my_oracle --subgraph my_subgraph -``` - -After this command runs, you can open your `my_subgraph/metadata/my_oracle.hml` file and see your metadata completely -scaffolded out for you 🎉 - -### 8. Import _all_ your indices - -You can do this in one convenience command. - -```bash title="From the root of your project, run:" -ddn connector-link update my_oracle --subgraph my_subgraph --add-all-resources -``` - -### 9. Create a supergraph build - -Pass the `local` subcommand along with specifying the output directory as `./engine` in the root of the project. This -directory is used by the docker-compose file to serve the engine locally: - -```bash title="From the root of your project, run:" -ddn supergraph build local --output-dir ./engine -``` +| Name | Description | Required | +| -------- | --------------------------------------- | -------- | +| JDBC_URL | The JDBC URL to connect to the database | Yes | -You can now navigate to -[`https://console.hasura.io/local/graphql?url=http://localhost:3000`](https://console.hasura.io/local/graphql?url=http://localhost:3000) -and interact with your API using the Hasura Console. +After the CLI initializes the connector, you'll need to: +- [Introspect](https://hasura.io/docs/3.0/cli/commands/ddn_connector_introspect) the source. +- Add your [models](https://hasura.io/docs/3.0/cli/commands/ddn_model_add), + [commands](https://hasura.io/docs/3.0/cli/commands/ddn_command_add), and + [relationships](https://hasura.io/docs/3.0/cli/commands/ddn_relationship_add). +- Create a [new build](https://hasura.io/docs/3.0/cli/commands/ddn_supergraph_build_local). +- Test it by [running your project along with the connector](https://hasura.io/docs/3.0/cli/commands/ddn_run#examples). ## License -The Hasura Oracle connector is available under the [Apache License -2.0](https://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file +The Hasura Oracle connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/registry/hasura/postgres/README.md b/registry/hasura/postgres/README.md index 248ea288..ceb7944d 100644 --- a/registry/hasura/postgres/README.md +++ b/registry/hasura/postgres/README.md @@ -4,10 +4,10 @@ The Hasura PostgreSQL Connector allows for connecting Hasura to a PostgreSQL dat Data Connectors are the way to connect the Hasura Data Delivery Network (DDN) to external data sources. A data connector is an HTTP service that exposes a set of APIs that Hasura uses to communicate with the data source. Data connectors are built to conform to the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html) using one of Hasura's available SDKs. The data connector is responsible for interpreting work to be done on behalf of the Hasura Engine, using the native query language of the data source. -The `ndc-postgres` data connector is open source and can be found in the [ndc-postgres GitHub repository](https://github.com/hasura/ndc-postgres). +The `ndc-postgres` data connector is open source and can be found in the [ndc-postgres GitHub repository](https://github.com/hasura/ndc-postgres). Visit the -[Hasura DDN PostgreSQL Documentation](https://hasura.io/docs/3.0/connectors/postgresql/) +[Hasura DDN PostgreSQL Documentation](https://hasura.io/docs/3.0/connectors/postgresql/) for more information about specific features that are available for the PostgreSQL Connector. ## Deployment diff --git a/registry/hasura/postgres/aliased_connectors/aurora/README.md b/registry/hasura/postgres/aliased_connectors/aurora/README.md index ec61f75d..a07b9d09 100644 --- a/registry/hasura/postgres/aliased_connectors/aurora/README.md +++ b/registry/hasura/postgres/aliased_connectors/aurora/README.md @@ -6,19 +6,19 @@ As much as possible we attempt to provide explicit support for database projects Data Connectors are the way to connect the Hasura Data Delivery Network (DDN) to external data sources. A data connector is an HTTP service that exposes a set of APIs that Hasura uses to communicate with the data source. Data connectors are built to conform to the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html) using one of Hasura's available SDKs. The data connector is responsible for interpreting work to be done on behalf of the Hasura Engine, using the native query language of the data source. -The `ndc-postgres` data connector is open source and can be found in the [ndc-postgres GitHub repository](https://github.com/hasura/ndc-postgres). +The `ndc-postgres` data connector is open source and can be found in the [ndc-postgres GitHub repository](https://github.com/hasura/ndc-postgres). Visit the -[Hasura DDN PostgreSQL Documentation](https://hasura.io/docs/3.0/connectors/postgresql/) +[Hasura DDN PostgreSQL Documentation](https://hasura.io/docs/3.0/connectors/postgresql/) for more information about specific features that are available for the PostgreSQL Connector. ## Deployment The connector is hosted by Hasura and can be used from the [Hasura v3 Console](https://console.hasura.io). -## Usage +## Using the PostgreSQL connector -The Hasura PostgreSQL connector can be deployed using the [Hasura CLI](https://hasura.io/docs/3.0/cli/overview) by following either the [Quick Start Guide](https://hasura.io/docs/3.0/getting-started/overview/) or [deploying the connector](https://hasura.io/docs/3.0/connectors/deployment). +Check out the [Hasura docs here](https://hasura.io/docs/3.0/getting-started/build/connect-to-data/connect-a-source/?db=PostgreSQL) to get started with the PostgreSQL connector. ## Troubleshooting diff --git a/registry/hasura/postgres/aliased_connectors/citus/README.md b/registry/hasura/postgres/aliased_connectors/citus/README.md index e63f5909..9989e011 100644 --- a/registry/hasura/postgres/aliased_connectors/citus/README.md +++ b/registry/hasura/postgres/aliased_connectors/citus/README.md @@ -1,28 +1,14 @@ ## Overview -`ndc-postgres` provides a Hasura Data Connector to the PostgreSQL database, -which can expose and run GraphQL queries via the Hasura v3 Project. +The Hasura PostgreSQL Connector allows for connecting Hasura to a PostgreSQL database giving you an instant GraphQL API on top of your PostgreSQL data. -- [PostgreSQL Connector information in the Hasura Connectors directory](https://hasura.io/connectors/postgres) -- [GitHub repository](https://github.com/hasura/ndc-postgres) - -The connector implements the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html), -but does not currently support column relationship arguments in queries, or functions. - -Visit the -[Hasura v3 Documentation](https://hasura.io/docs/3.0/native-data-connectors/postgresql) -for more information. +Data Connectors are the way to connect the Hasura Data Delivery Network (DDN) to external data sources. A data connector is an HTTP service that exposes a set of APIs that Hasura uses to communicate with the data source. Data connectors are built to conform to the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html) using one of Hasura's available SDKs. The data connector is responsible for interpreting work to be done on behalf of the Hasura Engine, using the native query language of the data source. The connector supports the Citus database extensions to PostgreSQL. -## Deployment - -The connector is hosted by Hasura and can be used from the [Hasura v3 Console](https://console.hasura.io). - -## Usage +## Using the PostgreSQL connector -Follow the [Quick Start Guide](https://hasura.io/docs/3.0/quickstart/) -To use the PostgreSQL data connector from the [Hasura v3 Console](https://console.hasura.io). +Check out the [Hasura docs here](https://hasura.io/docs/3.0/getting-started/build/connect-to-data/connect-a-source/?db=PostgreSQL) to get started with the PostgreSQL connector. ## Troubleshooting diff --git a/registry/hasura/postgres/aliased_connectors/neon/README.md b/registry/hasura/postgres/aliased_connectors/neon/README.md index 9513499f..93467bbf 100644 --- a/registry/hasura/postgres/aliased_connectors/neon/README.md +++ b/registry/hasura/postgres/aliased_connectors/neon/README.md @@ -1,28 +1,14 @@ ## Overview -`ndc-postgres` provides a Hasura Data Connector to the PostgreSQL database, -which can expose and run GraphQL queries via the Hasura v3 Project. +The Hasura PostgreSQL Connector allows for connecting Hasura to a PostgreSQL database giving you an instant GraphQL API on top of your PostgreSQL data. -- [PostgreSQL Connector information in the Hasura Connectors directory](https://hasura.io/connectors/postgres) -- [GitHub repository](https://github.com/hasura/ndc-postgres) +Data Connectors are the way to connect the Hasura Data Delivery Network (DDN) to external data sources. A data connector is an HTTP service that exposes a set of APIs that Hasura uses to communicate with the data source. Data connectors are built to conform to the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html) using one of Hasura's available SDKs. The data connector is responsible for interpreting work to be done on behalf of the Hasura Engine, using the native query language of the data source. -The connector implements the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html), -but does not currently support column relationship arguments in queries, or functions. +The connector supports the [Neon](https://neon.tech) Postgres offering. -Visit the -[Hasura v3 Documentation](https://hasura.io/docs/3.0/native-data-connectors/postgresql) -for more information. +## Using the PostgreSQL connector -The connector supports the [Neon](https://neon.tech/) PostgreSQL database offering. - -## Deployment - -The connector is hosted by Hasura and can be used from the [Hasura v3 Console](https://console.hasura.io). - -## Usage - -Follow the [Quick Start Guide](https://hasura.io/docs/3.0/quickstart/) -To use the PostgreSQL data connector from the [Hasura v3 Console](https://console.hasura.io). +Check out the [Hasura docs here](https://hasura.io/docs/3.0/getting-started/build/connect-to-data/connect-a-source/?db=PostgreSQL) to get started with the PostgreSQL connector. ## Troubleshooting diff --git a/registry/hasura/postgres/aliased_connectors/postgres-alloydb/README.md b/registry/hasura/postgres/aliased_connectors/postgres-alloydb/README.md index f0504f23..002ebd8e 100644 --- a/registry/hasura/postgres/aliased_connectors/postgres-alloydb/README.md +++ b/registry/hasura/postgres/aliased_connectors/postgres-alloydb/README.md @@ -2,23 +2,13 @@ The Hasura PostgreSQL Connector allows for connecting Hasura to a PostgreSQL database giving you an instant GraphQL API on top of your PostgreSQL data. -As much as possible we attempt to provide explicit support for database projects that identify as being derived from PostgreSQL such as [Google AlloyDB PostgreSQL](https://cloud.google.com/alloydb). - Data Connectors are the way to connect the Hasura Data Delivery Network (DDN) to external data sources. A data connector is an HTTP service that exposes a set of APIs that Hasura uses to communicate with the data source. Data connectors are built to conform to the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html) using one of Hasura's available SDKs. The data connector is responsible for interpreting work to be done on behalf of the Hasura Engine, using the native query language of the data source. -The `ndc-postgres` data connector is open source and can be found in the [ndc-postgres GitHub repository](https://github.com/hasura/ndc-postgres). - -Visit the -[Hasura DDN PostgreSQL Documentation](https://hasura.io/docs/3.0/connectors/postgresql/) -for more information about specific features that are available for the PostgreSQL Connector. - -## Deployment - -The connector is hosted by Hasura and can be used from the [Hasura v3 Console](https://console.hasura.io). +The connector supports the [AlloyDB](https://cloud.google.com/alloydb) Postgres offering. -## Usage +## Using the PostgreSQL connector -The Hasura PostgreSQL connector can be deployed using the [Hasura CLI](https://hasura.io/docs/3.0/cli/overview) by following either the [Quick Start Guide](https://hasura.io/docs/3.0/getting-started/overview/) or [deploying the connector](https://hasura.io/docs/3.0/connectors/deployment). +Check out the [Hasura docs here](https://hasura.io/docs/3.0/getting-started/build/connect-to-data/connect-a-source/?db=PostgreSQL) to get started with the PostgreSQL connector. ## Troubleshooting diff --git a/registry/hasura/postgres/aliased_connectors/postgres-azure/README.md b/registry/hasura/postgres/aliased_connectors/postgres-azure/README.md index 523c3aa3..92fdc8e7 100644 --- a/registry/hasura/postgres/aliased_connectors/postgres-azure/README.md +++ b/registry/hasura/postgres/aliased_connectors/postgres-azure/README.md @@ -2,23 +2,13 @@ The Hasura PostgreSQL Connector allows for connecting Hasura to a PostgreSQL database giving you an instant GraphQL API on top of your PostgreSQL data. -As much as possible we attempt to provide explicit support for database projects that identify as being derived from PostgreSQL such as [Azure PostgreSQL](https://azure.microsoft.com/en-us/products/postgresql/). - Data Connectors are the way to connect the Hasura Data Delivery Network (DDN) to external data sources. A data connector is an HTTP service that exposes a set of APIs that Hasura uses to communicate with the data source. Data connectors are built to conform to the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html) using one of Hasura's available SDKs. The data connector is responsible for interpreting work to be done on behalf of the Hasura Engine, using the native query language of the data source. -The `ndc-postgres` data connector is open source and can be found in the [ndc-postgres GitHub repository](https://github.com/hasura/ndc-postgres). - -Visit the -[Hasura DDN PostgreSQL Documentation](https://hasura.io/docs/3.0/connectors/postgresql/) -for more information about specific features that are available for the PostgreSQL Connector. - -## Deployment - -The connector is hosted by Hasura and can be used from the [Hasura v3 Console](https://console.hasura.io). +The connector supports the [Azure](https://azure.microsoft.com/en-us/products/postgresql) Postgres offering. -## Usage +## Using the PostgreSQL connector -The Hasura PostgreSQL connector can be deployed using the [Hasura CLI](https://hasura.io/docs/3.0/cli/overview) by following either the [Quick Start Guide](https://hasura.io/docs/3.0/getting-started/overview/) or [deploying the connector](https://hasura.io/docs/3.0/connectors/deployment). +Check out the [Hasura docs here](https://hasura.io/docs/3.0/getting-started/build/connect-to-data/connect-a-source/?db=PostgreSQL) to get started with the PostgreSQL connector. ## Troubleshooting diff --git a/registry/hasura/postgres/aliased_connectors/postgres-cosmos/README.md b/registry/hasura/postgres/aliased_connectors/postgres-cosmos/README.md index 38a94876..cc26b288 100644 --- a/registry/hasura/postgres/aliased_connectors/postgres-cosmos/README.md +++ b/registry/hasura/postgres/aliased_connectors/postgres-cosmos/README.md @@ -2,23 +2,13 @@ The Hasura PostgreSQL Connector allows for connecting Hasura to a PostgreSQL database giving you an instant GraphQL API on top of your PostgreSQL data. -As much as possible we attempt to provide explicit support for database projects that identify as being derived from PostgreSQL such as [Azure Cosmos DB for PostgreSQL](https://learn.microsoft.com/en-us/azure/cosmos-db/postgresql/introduction). - Data Connectors are the way to connect the Hasura Data Delivery Network (DDN) to external data sources. A data connector is an HTTP service that exposes a set of APIs that Hasura uses to communicate with the data source. Data connectors are built to conform to the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html) using one of Hasura's available SDKs. The data connector is responsible for interpreting work to be done on behalf of the Hasura Engine, using the native query language of the data source. -The `ndc-postgres` data connector is open source and can be found in the [ndc-postgres GitHub repository](https://github.com/hasura/ndc-postgres). - -Visit the -[Hasura DDN PostgreSQL Documentation](https://hasura.io/docs/3.0/connectors/postgresql/) -for more information about specific features that are available for the PostgreSQL Connector. - -## Deployment - -The connector is hosted by Hasura and can be used from the [Hasura v3 Console](https://console.hasura.io). +The connector supports the [Azure Cosmos DB for PostgreSQL](https://azure.microsoft.com/en-us/products/postgresql) offering. -## Usage +## Using the PostgreSQL connector -The Hasura PostgreSQL connector can be deployed using the [Hasura CLI](https://hasura.io/docs/3.0/cli/overview) by following either the [Quick Start Guide](https://hasura.io/docs/3.0/getting-started/overview/) or [deploying the connector](https://hasura.io/docs/3.0/connectors/deployment). +Check out the [Hasura docs here](https://hasura.io/docs/3.0/getting-started/build/connect-to-data/connect-a-source/?db=PostgreSQL) to get started with the PostgreSQL connector. ## Troubleshooting diff --git a/registry/hasura/postgres/aliased_connectors/postgres-gcp/README.md b/registry/hasura/postgres/aliased_connectors/postgres-gcp/README.md index 207c2eb2..94a0458a 100644 --- a/registry/hasura/postgres/aliased_connectors/postgres-gcp/README.md +++ b/registry/hasura/postgres/aliased_connectors/postgres-gcp/README.md @@ -2,23 +2,13 @@ The Hasura PostgreSQL Connector allows for connecting Hasura to a PostgreSQL database giving you an instant GraphQL API on top of your PostgreSQL data. -As much as possible we attempt to provide explicit support for database projects that identify as being derived from PostgreSQL such as [Google Cloud SQL PostgreSQL database](https://cloud.google.com/sql). - Data Connectors are the way to connect the Hasura Data Delivery Network (DDN) to external data sources. A data connector is an HTTP service that exposes a set of APIs that Hasura uses to communicate with the data source. Data connectors are built to conform to the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html) using one of Hasura's available SDKs. The data connector is responsible for interpreting work to be done on behalf of the Hasura Engine, using the native query language of the data source. -The `ndc-postgres` data connector is open source and can be found in the [ndc-postgres GitHub repository](https://github.com/hasura/ndc-postgres). - -Visit the -[Hasura DDN PostgreSQL Documentation](https://hasura.io/docs/3.0/connectors/postgresql/) -for more information about specific features that are available for the PostgreSQL Connector. - -## Deployment - -The connector is hosted by Hasura and can be used from the [Hasura v3 Console](https://console.hasura.io). +The connector supports the [Cloud SQL for PostgreSQL](https://cloud.google.com/sql/docs/postgres) offering. -## Usage +## Using the PostgreSQL connector -The Hasura PostgreSQL connector can be deployed using the [Hasura CLI](https://hasura.io/docs/3.0/cli/overview) by following either the [Quick Start Guide](https://hasura.io/docs/3.0/getting-started/overview/) or [deploying the connector](https://hasura.io/docs/3.0/connectors/deployment). +Check out the [Hasura docs here](https://hasura.io/docs/3.0/getting-started/build/connect-to-data/connect-a-source/?db=PostgreSQL) to get started with the PostgreSQL connector. ## Troubleshooting diff --git a/registry/hasura/postgres/aliased_connectors/postgres-timescaledb/README.md b/registry/hasura/postgres/aliased_connectors/postgres-timescaledb/README.md index f6e6ff31..55b6d18f 100644 --- a/registry/hasura/postgres/aliased_connectors/postgres-timescaledb/README.md +++ b/registry/hasura/postgres/aliased_connectors/postgres-timescaledb/README.md @@ -2,23 +2,13 @@ The Hasura PostgreSQL Connector allows for connecting Hasura to a PostgreSQL database giving you an instant GraphQL API on top of your PostgreSQL data. -As much as possible we attempt to provide explicit support for database projects that identify as being derived from PostgreSQL such as [Timescale PostgreSQL](https://www.timescale.com/). - Data Connectors are the way to connect the Hasura Data Delivery Network (DDN) to external data sources. A data connector is an HTTP service that exposes a set of APIs that Hasura uses to communicate with the data source. Data connectors are built to conform to the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html) using one of Hasura's available SDKs. The data connector is responsible for interpreting work to be done on behalf of the Hasura Engine, using the native query language of the data source. -The `ndc-postgres` data connector is open source and can be found in the [ndc-postgres GitHub repository](https://github.com/hasura/ndc-postgres). - -Visit the -[Hasura DDN PostgreSQL Documentation](https://hasura.io/docs/3.0/connectors/postgresql/) -for more information about specific features that are available for the PostgreSQL Connector. - -## Deployment - -The connector is hosted by Hasura and can be used from the [Hasura v3 Console](https://console.hasura.io). +The connector supports the [TimescaleDB](https://www.timescale.com/) Postgres offering. -## Usage +## Using the PostgreSQL connector -The Hasura PostgreSQL connector can be deployed using the [Hasura CLI](https://hasura.io/docs/3.0/cli/overview) by following either the [Quick Start Guide](https://hasura.io/docs/3.0/getting-started/overview/) or [deploying the connector](https://hasura.io/docs/3.0/connectors/deployment). +Check out the [Hasura docs here](https://hasura.io/docs/3.0/getting-started/build/connect-to-data/connect-a-source/?db=PostgreSQL) to get started with the PostgreSQL connector. ## Troubleshooting diff --git a/registry/hasura/postgres/aliased_connectors/yugabyte/README.md b/registry/hasura/postgres/aliased_connectors/yugabyte/README.md index 07d4c795..d62e423b 100644 --- a/registry/hasura/postgres/aliased_connectors/yugabyte/README.md +++ b/registry/hasura/postgres/aliased_connectors/yugabyte/README.md @@ -1,28 +1,14 @@ ## Overview -`ndc-postgres` provides a Hasura Data Connector to the PostgreSQL database, -which can expose and run GraphQL queries via the Hasura v3 Project. +The Hasura PostgreSQL Connector allows for connecting Hasura to a PostgreSQL database giving you an instant GraphQL API on top of your PostgreSQL data. -- [PostgreSQL Connector information in the Hasura Connectors directory](https://hasura.io/connectors/postgres) -- [GitHub repository](https://github.com/hasura/ndc-postgres) +Data Connectors are the way to connect the Hasura Data Delivery Network (DDN) to external data sources. A data connector is an HTTP service that exposes a set of APIs that Hasura uses to communicate with the data source. Data connectors are built to conform to the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html) using one of Hasura's available SDKs. The data connector is responsible for interpreting work to be done on behalf of the Hasura Engine, using the native query language of the data source. -The connector implements the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html), -but does not currently support column relationship arguments in queries, or functions. +The connector supports the [Yugabyte](https://www.yugabyte.com/) Postgres offering. -Visit the -[Hasura v3 Documentation](https://hasura.io/docs/3.0/native-data-connectors/postgresql) -for more information. +## Using the PostgreSQL connector -The connector supports the [YugabyteDB](https://www.yugabyte.com) PostgreSQL database offering. - -## Deployment - -The connector is hosted by Hasura and can be used from the [Hasura v3 Console](https://console.hasura.io). - -## Usage - -Follow the [Quick Start Guide](https://hasura.io/docs/3.0/quickstart/) -To use the PostgreSQL data connector from the [Hasura v3 Console](https://console.hasura.io). +Check out the [Hasura docs here](https://hasura.io/docs/3.0/getting-started/build/connect-to-data/connect-a-source/?db=PostgreSQL) to get started with the PostgreSQL connector. ## Troubleshooting diff --git a/registry/hasura/python/README.md b/registry/hasura/python/README.md index ed0093bc..68cdac91 100644 --- a/registry/hasura/python/README.md +++ b/registry/hasura/python/README.md @@ -1,4 +1,5 @@ # Hasura Python Lambda Connector + [![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/connectors/python) @@ -10,93 +11,42 @@ This connector allows you to write Python code and call it using Hasura! With Hasura, you can integrate -- and even host -- this business logic directly with Hasura DDN and your API. -You can handle custom business logic using the Python Lambda data connector. Using this connector, you can transform or enrich data before it reaches your customers, or perform any other business logic you may need. - -You can then integrate these functions as individual commands in your metadata and API. This process enables you to simplify client applications and speed up your backend development! - -This connector is built using the [Python Data Connector SDK](https://github.com/hasura/ndc-sdk-python) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). - -## Before you get Started - -1. The [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed -2. A [supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) -3. A [subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) - -The steps below explain how to Initialize and configure a connector for local development. You can learn how to deploy a connector — after it's been configured — [here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). - -## Using the Python connector - -### Step 1: Authenticate your CLI session - -```bash -ddn auth login -``` - -### Step 2: Configure the connector - -Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while providing a name for the connector in the prompt: - -```bash -ddn connector init python -i -``` - -#### Step 2.1: Choose the `hasura/python` option from the list - -#### Step 2.2: Choose a port for the connector - -The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the default suggested port. - -### Step 3: Introspect the connector - -Introspecting the connector will generate a `config.json` file and a `python.hml` file. - -```bash -ddn connector introspect python -``` - -### Step 4: Add your resources - -You can add the models, commands, and relationships to your API by tracking them which generates the HML files. - -```bash -ddn connector-link add-resources python -``` - -### Step 5: Run your connector - -You can run your connector locally, or include it in the docker setup. - -#### Run the connector in Docker - -To include your connector in the docker setup, include its compose file at the top of your supergraph `compose.yaml` file like this: - -```yaml -include: - - path: app/connector/python/compose.yaml -``` +You can handle custom business logic using the Python Lambda data connector. Using this connector, you can transform or +enrich data before it reaches your customers, or perform any other business logic you may need. -#### Run the connector locally +You can then integrate these functions as individual commands in your metadata and API. This process enables you to +simplify client applications and speed up your backend development! -To run your connector outside of Docker first go into the connector directory: +This connector is built using the [Python Data Connector SDK](https://github.com/hasura/ndc-sdk-python) and implements +the [Data Connector Spec](https://github.com/hasura/ndc-spec). -`cd app/connector/python` +## Prerequisites -Install the requirements: +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -`pip3 install -r requirements.txt` +The steps below explain how to initialize and configure a connector on your local machine (typically for development +purposes).You can learn how to deploy a connector to Hasura DDN — after it's been configured — +[here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). -Then run the connector locally: +## Using the Python Lambda connector -```ddn connector setenv --connector connector.yaml -- python3 functions.py serve``` +Check out the [Hasura docs here](https://hasura.io/docs/3.0/business-logic/python#add-the-python-connector-to-a-project) +to get started with the Python Lambda connector. ## Documentation -View the full documentation for the Python Lambda connector [here](https://github.com/hasura/ndc-python-lambda/blob/main/docs/index.md). +View the full documentation for the Python Lambda connector +[here](https://github.com/hasura/ndc-python-lambda/blob/main/docs/index.md). ## Contributing -Check out our [contributing guide](https://github.com/hasura/ndc-python-lambda/blob/main/docs/contributing.md) for more details. +Check out our [contributing guide](https://github.com/hasura/ndc-python-lambda/blob/main/docs/contributing.md) for more +details. ## License -The Turso connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file +The Turso connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/registry/hasura/qdrant/README.md b/registry/hasura/qdrant/README.md index 02fa25cc..55b33733 100644 --- a/registry/hasura/qdrant/README.md +++ b/registry/hasura/qdrant/README.md @@ -1,4 +1,5 @@ # Hasura Qdrant Connector + [![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/connectors/qdrant) @@ -6,9 +7,11 @@ [![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](https://github.com/hasura/ndc-qdrant/blob/main/LICENSE.txt) [![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](https://github.com/hasura/ndc-qdrant/blob/main/README.md) -The Hasura Qdrant Connector allows for connecting to a Qdrant database to give you an instant GraphQL API on top of your Qdrant data. +The Hasura Qdrant Connector allows for connecting to a Qdrant database to give you an instant GraphQL API on top of your +Qdrant data. -This connector is built using the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). +This connector is built using the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and +implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). - [See the listing in the Hasura Hub](https://hasura.io/connectors/qdrant) - [Hasura V3 Documentation](https://hasura.io/docs/3.0/index/) @@ -17,102 +20,69 @@ This connector is built using the [Typescript Data Connector SDK](https://github Below, you'll find a matrix of all supported features for the Qdrant connector: -| Feature | Supported | Notes | -| ------------------------------- | --------- | ----- | -| Native Queries + Logical Models | ❌ | | -| Simple Object Query | ✅ | | -| Filter / Search | ✅ | | -| Simple Aggregation | ❌ | | -| Sort | ❌ | | -| Paginate | ✅ | Pagination offset field only works for documents with Integer ID's | -| Nested Objects | ✅ | | -| Nested Arrays | ✅ | | -| Nested Filtering | ❌ | | -| Nested Sorting | ❌ | | -| Nested Relationships | ❌ | | -| Vector Search | ✅ | | - -## Before you get Started - -[Prerequisites or recommended steps before using the connector.] - -1. The [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed -2. A [supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) -3. A [subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -4. Have a [Qdrant](https://qdrant.tech/) hosted database, or a locally running Qdrant database — for supplying data to your API. - -The steps below explain how to Initialize and configure a connector for local development. You can learn how to deploy a -connector — after it's been configured — [here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). +| Feature | Supported | Notes | +| ------------------------------- | --------- | ------------------------------------------------------------------ | +| Native Queries + Logical Models | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ❌ | | +| Sort | ❌ | | +| Paginate | ✅ | Pagination offset field only works for documents with Integer ID's | +| Nested Objects | ✅ | | +| Nested Arrays | ✅ | | +| Nested Filtering | ❌ | | +| Nested Sorting | ❌ | | +| Nested Relationships | ❌ | | +| Vector Search | ✅ | | + +## Prerequisites + +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) +5. Have a [Qdrant](https://qdrant.tech/) hosted database, or a locally running Qdrant database — for supplying data to + your API. + +The steps below explain how to initialize and configure a connector on your local machine (typically for development +purposes).You can learn how to deploy a connector to Hasura DDN — after it's been configured — +[here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). ## Using the Qdrant connector -### Step 1: Authenticate your CLI session - -```bash -ddn auth login -``` - -### Step 2: Configure the connector - -Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while providing a name for the connector in the prompt: - -```bash -ddn connector init qdrant -i -``` - -#### Step 2.1: Choose the `hasura/qdrant` option from the list - -#### Step 2.2: Choose a port for the connector - -The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the default suggested port. - -#### Step 2.3: Provide the env var(s) for the connector - -| Name | Description | -|-|-| -| QDRANT_URL | The connection string for the Qdrant database | -| QDRANT_API_KEY | The Qdrant API Key | - -You'll find the environment variables in the `.env` file and they will be in the format: - -`__` - -Here is an example of what your `.env` file might look like: +With the [context set](https://hasura.io/docs/3.0/cli/commands/ddn_context_set/) for an existing subgraph, initialize +the connector: +```sh +ddn connector init -i ``` -APP_QDRANT_AUTHORIZATION_HEADER="Bearer B9-PceSL1QrUE_Z1gJNdGQ==" -APP_QDRANT_HASURA_SERVICE_TOKEN_SECRET="B9-PceSL1QrUE_Z1gJNdGQ==" -APP_QDRANT_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://local.hasura.dev:4317" -APP_QDRANT_OTEL_SERVICE_NAME="app_qdrant" -APP_QDRANT_QDRANT_API_KEY="5PX..." -APP_QDRANT_QDRANT_URL="https://2a4ae326-fdef-473e-a13c-7dc07f2f2759.us-east4-0.gcp.cloud.qdrant.io" -APP_QDRANT_READ_URL="http://local.hasura.dev:5963" -APP_QDRANT_WRITE_URL="http://local.hasura.dev:5963" -``` - -### Step 3: Introspect the connector -Introspecting the connector will generate a `config.json` file and a `qdrant.hml` file. +When the wizard runs, you'll be prompted to enter the following env vars necessary for your connector to function: -```bash -ddn connector introspect qdrant -``` +| Name | Description | +| -------------- | --------------------------------------------- | +| QDRANT_URL | The connection string for the Qdrant database | +| QDRANT_API_KEY | The Qdrant API Key | -### Step 4: Add your resources +After the CLI initializes the connector, you'll need to: -You can add the models, commands, and relationships to your API by tracking them which generates the HML files. - -```bash -ddn connector-link add-resources qdrant -``` +- [Introspect](https://hasura.io/docs/3.0/cli/commands/ddn_connector_introspect) the source. +- Add your [models](https://hasura.io/docs/3.0/cli/commands/ddn_model_add), + [commands](https://hasura.io/docs/3.0/cli/commands/ddn_command_add), and + [relationships](https://hasura.io/docs/3.0/cli/commands/ddn_relationship_add). +- Create a [new build](https://hasura.io/docs/3.0/cli/commands/ddn_supergraph_build_local). +- Test it by [running your project along with the connector](https://hasura.io/docs/3.0/cli/commands/ddn_run#examples). ## Documentation -View the full documentation for the Qdrant connector [here](https://github.com/hasura/ndc-qdrant/blob/main/docs/index.md). +View the full documentation for the Qdrant connector +[here](https://github.com/hasura/ndc-qdrant/blob/main/docs/index.md). ## Contributing -Check out our [contributing guide](https://github.com/hasura/ndc-qdrant/blob/main/docs/contributing.md) for more details. +Check out our [contributing guide](https://github.com/hasura/ndc-qdrant/blob/main/docs/contributing.md) for more +details. ## License diff --git a/registry/hasura/singlestore/README.md b/registry/hasura/singlestore/README.md index 9a707795..e01d8f85 100644 --- a/registry/hasura/singlestore/README.md +++ b/registry/hasura/singlestore/README.md @@ -3,16 +3,20 @@ + [![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/latest/connectors/singesltore/) [![ndc-hub](https://img.shields.io/badge/ndc--hub-singlestore-blue.svg?style=flat)](https://hasura.io/connectors/singlestore) [![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE) [![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) -The Hasura SingleStore Connector ("the connector") enables you to connect to a SingleStore database and gives instant access to a GraphQL API on top of your data. +The Hasura SingleStore Connector ("the connector") enables you to connect to a SingleStore database and gives instant +access to a GraphQL API on top of your data. -This connector is built using the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and, it implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). +This connector is built using the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and, it +implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). + - [See the listing in the Hasura Hub](https://hasura.io/connectors/singlestore) - [Hasura V3 Documentation](https://hasura.io/docs/3.0) @@ -20,107 +24,78 @@ This connector is built using the [Typescript Data Connector SDK](https://github The following matrix lists the features supported by the Hasura SingleStore connector: -| Feature | Supported | Notes | -| ------------------------------- | --------- | ----- | -| Native Queries + Logical Models | ❌ | | -| Simple Object Query | ✅ | | -| Filter / Search | ✅ | | -| Simple Aggregation | ✅ | | -| Sort | ✅ | | -| Paginate | ✅ | | -| Table Relationships | ✅ | | -| Views | ✅ | | -| Distinct | ✅ | | -| Remote Relationships | ✅ | | -| Mutations | ❌ | coming soon | +| Feature | Supported | Notes | +| ------------------------------- | --------- | ----------- | +| Native Queries + Logical Models | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ✅ | | +| Views | ✅ | | +| Distinct | ✅ | | +| Remote Relationships | ✅ | | +| Mutations | ❌ | coming soon | ## Prerequisites -Ensure that the following prerequisites are met before using the connector: - -1. Install [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/). -2. Initialize a [supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph). -3. Initialize a [subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph). -4. An active [SingleStore](https://www.singlestore.com/) deployment that serves as the data source for the API. +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) +5. An active [SingleStore](https://www.singlestore.com/) deployment that serves as the data source for the API. +The steps below explain how to initialize and configure a connector on your local machine (typically for development +purposes).You can learn how to deploy a connector to Hasura DDN — after it's been configured — +[here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). ## Using the SingleStore connector -The following steps explain how to initialize and configure the connector for local development. For information on deploying a connector after it has been configured, refer to [Deploy a Connector](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). - -### Step 1: Authenticate your CLI session - -```bash -ddn auth login -``` - -### Step 2: Configure the connector - -After the supergraph and subgraph have been initialized (refer to [Prerequisites](#Prerequisites), run the initialization command in interactive mode. Specify a name for the connector in the command. +With the [context set](https://hasura.io/docs/3.0/cli/commands/ddn_context_set/) for an existing subgraph, initialize +the connector: -```bash -ddn connector init -i +```sh +ddn connector init -i ``` -#### Step 2.1: Select the SingleStore connector - -From the list of connectors, select `singlestore`. - -#### Step 2.2: Select a port for the connector -The CLI prompts you to specify a port for running the connector. Either select the default port suggested or choose a port that is not currently in use. - -#### Step 2.3: Provide the environment variable(s) for the connector - -Specify the connection string used to connect to the SingleStore database using the `SINGLESTORE_URL` variable. The connection string must be in the `mysql://[[:]][@:[]]/[][?=[&=]]` format. - -For example: - -```env -SINGLESTORE_URL=singlestore://username:password@hostname/database -``` -The connector uses [MySQL2](https://sidorares.github.io/node-mysql2/docs) library to establish a connection. -For more information, refer to [Connection options](https://www.npmjs.com/package/mysql#connection-options) and [Pool options](https://www.npmjs.com/package/mysql#pool-options). +When the wizard runs, you'll be prompted to enter the following env vars necessary for your connector to function: + +| Name | Default | Description | +| ----------------------------------- | --------- | --------------------------------------------------------------------------------------------------- | +| SINGLESTORE_HOST | localhost | Hostname of the SingleStore database to connect with. | +| SINGLESTORE_PORT | 3306 | Port number of the SingleStore database. | +| SINGLESTORE_PASSWORD | | Password of the SingleStore database user. | +| SINGLESTORE_DATABASE | | Name of the SingleStore database to connect with. | +| SINGLESTORE_SSL_CA | | Path to the trusted CA certificate file. | +| SINGLESTORE_SSL_CERT | | Path to the certificate chain file in PEM format. | +| SINGLESTORE_SSL_KEY | | Path to the private key file in PEM format. | +| SINGLESTORE_SSL_CIPHERS | | Cipher suite specification. If specified, it replaces the default value. | +| SINGLESTORE_SSL_PASSPHRASE | | Cipher suite specification. If specified, it replaces the default value. | +| SINGLESTORE_SSL_REJECT_UNAUTHORIZED | true | If enabled, the server rejects any connection that is not authorized with the list of supplied CAs. | + +The connector uses [MySQL2](https://sidorares.github.io/node-mysql2/docs) library to establish a connection. For more +information, refer to [Connection options](https://www.npmjs.com/package/mysql#connection-options) and +[Pool options](https://www.npmjs.com/package/mysql#pool-options). + +After the CLI initializes the connector, you'll need to: + +- [Introspect](https://hasura.io/docs/3.0/cli/commands/ddn_connector_introspect) the source. +- Add your [models](https://hasura.io/docs/3.0/cli/commands/ddn_model_add), + [commands](https://hasura.io/docs/3.0/cli/commands/ddn_command_add), and + [relationships](https://hasura.io/docs/3.0/cli/commands/ddn_relationship_add). +- Create a [new build](https://hasura.io/docs/3.0/cli/commands/ddn_supergraph_build_local). +- Test it by [running your project along with the connector](https://hasura.io/docs/3.0/cli/commands/ddn_run#examples). + +### Note + +SingleStore does not support foreign keys. Relationships between tables must be added manually. You can define +relationships by appending relationship information to the `.hml` files generated in the previous step. For information +on defining relationships, refer to [Relationships](https://hasura.io/docs/3.0/supergraph-modeling/relationships/). For +example, to add a relationship from a `message` table to the `user` table, append following text to the `DbMessage.hml` +file: -Alternatively, you can also set following environment variables instead of the `SINGLELSTORE_URL` variable: - -| Name | Default | Description | -|-------------------------------------|-------------|-------------| -| SINGLESTORE_HOST | localhost | Hostname of the SingleStore database to connect with. | -| SINGLESTORE_PORT | 3306 | Port number of the SingleStore database. | -| SINGLESTORE_PASSWORD | | Password of the SingleStore database user. | -| SINGLESTORE_DATABASE | | Name of the SingleStore database to connect with. | -| SINGLESTORE_SSL_CA | | Path to the trusted CA certificate file. | -| SINGLESTORE_SSL_CERT | | Path to the certificate chain file in PEM format. | -| SINGLESTORE_SSL_KEY | | Path to the private key file in PEM format. | -| SINGLESTORE_SSL_CIPHERS | | Cipher suite specification. If specified, it replaces the default value. | -| SINGLESTORE_SSL_PASSPHRASE | | Cipher suite specification. If specified, it replaces the default value. | -| SINGLESTORE_SSL_REJECT_UNAUTHORIZED | true | If enabled, the server rejects any connection that is not authorized with the list of supplied CAs. | - -If `SINGLELSTORE_URL` is set these variables are ignored. - -### Step 3: Introspect your data source - -After configuring the connector, use the CLI to introspect the SingleStore database and create a source-specific configuration file for the connector (`configuration.json`). - -```bash -ddn connector introspect -``` - -## Step 4: Add your resources - -This command will create `.hml` files for each table and view in your database -and an `.hml` file with information about SingleStore data types. - -```bash -ddn connector-link add-resources -``` - -## Step 5. Add relationships - -SingleStore does not support foreign keys. Relationships between tables must be added manually. You can define relationships by appending relationship information to the `.hml` files generated in the previous step. -For information on defining relationships, refer to [Relationships](https://hasura.io/docs/3.0/supergraph-modeling/relationships/). -For example, to add a relationship from a `message` table to the `user` table, append following text to the -`DbMessage.hml` file: ```hml --- kind: Relationship @@ -142,6 +117,7 @@ definition: - fieldName: id description: The user details for a message ``` + ## License The SingleStore connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/registry/hasura/snowflake/README.md b/registry/hasura/snowflake/README.md index b967a94d..03bd3dad 100644 --- a/registry/hasura/snowflake/README.md +++ b/registry/hasura/snowflake/README.md @@ -6,10 +6,10 @@ [![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in -Snowflake. This connector supports Snowflake's functionalities listed in the table below, allowing for -efficient and scalable data operations. Additionally, users benefit from all the powerful features of Hasura’s Data -Delivery Network (DDN) platform, including query pushdown capabilities that delegate query operations to the database, -thereby enhancing query optimization and performance. +Snowflake. This connector supports Snowflake's functionalities listed in the table below, allowing for efficient and +scalable data operations. Additionally, users benefit from all the powerful features of Hasura’s Data Delivery Network +(DDN) platform, including query pushdown capabilities that delegate query operations to the database, thereby enhancing +query optimization and performance. This connector implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). @@ -22,149 +22,61 @@ Below, you'll find a matrix of all supported features for the Snowflake connecto | Feature | Supported | Notes | | ------------------------------- | --------- | ----- | -| Native Queries + Logical Models | ✅ | | -| Native Mutations | ❌ | | -| Simple Object Query | ✅ | | -| Filter / Search | ✅ | | -| Simple Aggregation | ✅ | | -| Sort | ✅ | | -| Paginate | ✅ | | -| Table Relationships | ✅ | | -| Views | ✅ | | -| Remote Relationships | ✅ | | -| Custom Fields | ❌ | | -| Mutations | ❌ | | -| Distinct | ❌ | | -| Enums | ❌ | | -| Naming Conventions | ❌ | | -| Default Values | ❌ | | -| User-defined Functions | ❌ | | - -## Before you get Started +| Native Queries + Logical Models | ✅ | | +| Native Mutations | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ✅ | | +| Views | ✅ | | +| Remote Relationships | ✅ | | +| Custom Fields | ❌ | | +| Mutations | ❌ | | +| Distinct | ❌ | | +| Enums | ❌ | | +| Naming Conventions | ❌ | | +| Default Values | ❌ | | +| User-defined Functions | ❌ | | + +## Prerequisites 1. Create a [Hasura Cloud account](https://console.hasura.io) -2. Install the [CLI](https://hasura.io/docs/3.0/cli/installation/) -3. Install the [Hasura VS Code extension](https://marketplace.visualstudio.com/items?itemName=HasuraHQ.hasura) -4. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) -5. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -## Using the connector +The steps below explain how to initialize and configure a connector on your local machine (typically for development +purposes).You can learn how to deploy a connector to Hasura DDN — after it's been configured — +[here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). -To use the Snowflake connector, follow these steps in a Hasura project: -(Note: for more information on the following steps, please refer to the Postgres connector -documentation [here](https://hasura.io/docs/3.0/getting-started/connect-to-data/connect-a-source)) +## Using the Snowflake connector -### 1. Init the connector +With the [context set](https://hasura.io/docs/3.0/cli/commands/ddn_context_set/) for an existing subgraph, initialize +the connector: -(Note: here and following we are naming the subgraph "my_subgraph" and the connector "my_snowflake") - - ```bash - ddn connector init my_snowflake --subgraph my_subgraph --hub-connector hasura/snowflake - ``` - -### 2. Add your Snowflake credentials: - -Add your credentials to `my_subgraph/connector/my_sql/.env.local` - -```env title="my_subgraph/connector/my_snowflake/.env.local" -JDBC_URL="jdbc:snowflake://ak1234.us-east-2.aws.snowflakecomputing.com/?user=&password=&db=CHINOOK&schema=PUBLIC&warehouse=COMPUTE_WH&role=ACCOUNTADMIN" -JDBC_SCHEMAS=PUBLIC -``` - -### 3. Introspect your indices - -```bash title="From the root of your project run:" -ddn connector introspect --connector my_subgraph/connector/my_snowflake/connector.yaml -``` - -If you look at the `configuration.json` for your connector, you'll see metadata describing your Snowflake mappings. - -### 4. Create the Hasura metadata - -```bash title="Run the following from the root of your project:" -ddn connector-link add my_snowflake --subgraph my_subgraph -``` - -The generated file has two environment variables — one for reads and one for writes — that you'll need to add to your -subgraph's `.env.my_subgraph` file. Each key is prefixed by the subgraph name, an underscore, and the name of the -connector. Ensure the port value matches what is published in your connector's docker compose file. - -```env title="my_subgraph/.env.my_subgraph" -MY_SUBGRAPH_MY_SNOWFLAKE_READ_URL=http://local.hasura.dev:8081 -MY_SUBGRAPH_MY_SNOWFLAKE_WRITE_URL=http://local.hasura.dev:8081 -``` - -### 5. Start the connector's docker compose - -Let's start our connector's docker compose file. - -```bash title="Run the following from the connector's subdirectory inside a subgraph:" -docker compose -f docker-compose.my_snowflake.yaml up -``` - -This starts our Snowflake connector on the specified port. We can navigate to the following address, with the port -modified, to see the schema of our Snowflake data source: - -```bash -http://localhost:8081/schema -``` - -### 6. Include the connector in your docker compose - -Kill the connector by pressing `CTRL+C` in the terminal tab in which the connector is running. - -Then, add the following inclusion to the docker compose `docker-compose.hasura.yaml` in your project's root directory, -taking care to modify the -subgraph's name. - -```yaml title="docker-compose.hasura.yaml" -include: - - path: my_subgraph/connector/my_snowflake/docker-compose.my_snowflake.yaml -``` - -Now, whenever running the following, you'll bring up the GraphQL engine, observability tools, and any connectors you've -included: - -```bash title="From the root of your project, run:" -HASURA_DDN_PAT=$(ddn auth print-pat) docker compose -f docker-compose.hasura.yaml watch -``` - -### 7. Update the new DataConnectorLink object - -Finally, now that our `DataConnectorLink` has the correct environment variables configured for the Snowflake connector, -we can run the update command to have the CLI look at the configuration JSON and transform it to reflect our database's -schema in `hml` format. In a new terminal tab, run: - -```bash title="From the root of your project, run:" -ddn connector-link update my_snowflake --subgraph my_subgraph -``` - -After this command runs, you can open your `my_subgraph/metadata/my_snowflake.hml` file and see your metadata completely -scaffolded out for you 🎉 - -### 8. Import _all_ your indices - -You can do this in one convenience command. - -```bash title="From the root of your project, run:" -ddn connector-link update my_snowflake --subgraph my_subgraph --add-all-resources +```sh +ddn connector init -i ``` -### 9. Create a supergraph build +When the wizard runs, you'll be prompted to enter the following env vars necessary for your connector to function: -Pass the `local` subcommand along with specifying the output directory as `./engine` in the root of the project. This -directory is used by the docker-compose file to serve the engine locally: - -```bash title="From the root of your project, run:" -ddn supergraph build local --output-dir ./engine -``` +| Name | Description | Required | +| ------------ | ------------------------------------------------------------ | -------- | +| JDBC_URL | The JDBC URL to connect to the database | Yes | +| JDBC_SCHEMAS | A comma-separated list of schemas to include in the metadata | Yes | -You can now navigate to -[`https://console.hasura.io/local/graphql?url=http://localhost:3000`](https://console.hasura.io/local/graphql?url=http://localhost:3000) -and interact with your API using the Hasura Console. +After the CLI initializes the connector, you'll need to: +- [Introspect](https://hasura.io/docs/3.0/cli/commands/ddn_connector_introspect) the source. +- Add your [models](https://hasura.io/docs/3.0/cli/commands/ddn_model_add), + [commands](https://hasura.io/docs/3.0/cli/commands/ddn_command_add), and + [relationships](https://hasura.io/docs/3.0/cli/commands/ddn_relationship_add). +- Create a [new build](https://hasura.io/docs/3.0/cli/commands/ddn_supergraph_build_local). +- Test it by [running your project along with the connector](https://hasura.io/docs/3.0/cli/commands/ddn_run#examples). ## License -The Hasura Snowflake connector is available under the [Apache License -2.0](https://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file +The Hasura Snowflake connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/registry/hasura/sqlserver/README.md b/registry/hasura/sqlserver/README.md index 791e90b7..f1f1c3cb 100644 --- a/registry/hasura/sqlserver/README.md +++ b/registry/hasura/sqlserver/README.md @@ -22,7 +22,7 @@ the [Data Connector Spec](https://github.com/hasura/ndc-spec). Below, you'll find a matrix of all supported features for the SQL Server connector: | Feature | Supported | Notes | -|---------------------------------|-----------|--------------------------------------| +| ------------------------------- | --------- | ------------------------------------ | | Native Queries + Logical Models | ✅ | | | Native Mutations | ✅ | | | Simple Object Query | ✅ | | @@ -42,61 +42,41 @@ Below, you'll find a matrix of all supported features for the SQL Server connect | Default Values | ❌ | | | User-defined Functions | ❌ | | -## Before you get Started +## Prerequisites 1. Create a [Hasura Cloud account](https://console.hasura.io) -2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed 3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) 4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -The steps below explain how to Initialize and configure a connector for local development. You can learn how to deploy a -connector — after it's been configured — [here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). +The steps below explain how to initialize and configure a connector on your local machine (typically for development +purposes).You can learn how to deploy a connector to Hasura DDN — after it's been configured — +[here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). -## Using the SQL Server connector +## Using the SQLServer connector -### Step 1: Authenticate your CLI session +With the [context set](https://hasura.io/docs/3.0/cli/commands/ddn_context_set/) for an existing subgraph, initialize +the connector: -```bash -ddn auth login +```sh +ddn connector init -i ``` -### Step 2: Configure the connector - -Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while -providing a name for the connector in the prompt: - -```bash -ddn connector init -i -``` - -#### Step 2.1: Choose the `hasura/sqlserver` from the list - -#### Step 2.2: Choose a port for the connector - -The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the -default suggested port. - -#### Step 2.3: Provide the env vars for the connector +When the wizard runs, you'll be prompted to enter the following env vars necessary for your connector to function: | Name | Description | Required | Default | -|----------------|--------------------------------------------------|----------|---------| +| -------------- | ------------------------------------------------ | -------- | ------- | | CONNECTION_URI | The connection string of the SQL Server database | Yes | N/A | -## Step 3: Introspect the connector - -```bash -ddn connector introspect -``` - -This will generate a `configuration.json` file that will have the schema of your SQL Server database. - -## Step 4: Add your resources - -```bash -ddn connector-link add-resources -``` +After the CLI initializes the connector, you'll need to: -This command will track all the containers in your SQL Server DB as [Models](https://hasura.io/docs/3.0/supergraph-modeling/models). +- [Introspect](https://hasura.io/docs/3.0/cli/commands/ddn_connector_introspect) the source. +- Add your [models](https://hasura.io/docs/3.0/cli/commands/ddn_model_add), + [commands](https://hasura.io/docs/3.0/cli/commands/ddn_command_add), and + [relationships](https://hasura.io/docs/3.0/cli/commands/ddn_relationship_add). +- Create a [new build](https://hasura.io/docs/3.0/cli/commands/ddn_supergraph_build_local). +- Test it by [running your project along with the connector](https://hasura.io/docs/3.0/cli/commands/ddn_run#examples). ## Documentation @@ -104,9 +84,10 @@ View the full documentation for the ndc-sqlserver connector [here](./docs/readme ## Contributing -We're happy to receive any contributions from the community. Please refer to our [development guide](./docs/development.md). +We're happy to receive any contributions from the community. Please refer to our +[development guide](./docs/development.md). ## License -The Hasura SQL Server connector is available under the [Apache License -2.0](https://www.apache.org/licenses/LICENSE-2.0). +The Hasura SQL Server connector is available under the +[Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/registry/hasura/turso/README.md b/registry/hasura/turso/README.md index 2d3977b0..77ac483a 100644 --- a/registry/hasura/turso/README.md +++ b/registry/hasura/turso/README.md @@ -1,15 +1,17 @@ # Hasura Turso Connector - + [![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/connectors/turso) [![ndc-hub](https://img.shields.io/badge/ndc--hub-turso-blue.svg?style=flat)](https://hasura.io/connectors/turso) [![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](https://github.com/hasura/ndc-turso/blob/main/LICENSE.txt) [![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](https://github.com/hasura/ndc-turso/blob/main/README.md) -The Hasura Turso Connector allows for connecting to a LibSQL/SQLite database or a Turso hosted LibSQL database to give you an instant GraphQL API on top of your Turso data. +The Hasura Turso Connector allows for connecting to a LibSQL/SQLite database or a Turso hosted LibSQL database to give +you an instant GraphQL API on top of your Turso data. -This connector is built using the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). +This connector is built using the [Typescript Data Connector SDK](https://github.com/hasura/ndc-sdk-typescript) and +implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). - [See the listing in the Hasura Hub](https://hasura.io/connectors/turso) - [Hasura V3 Documentation](https://hasura.io/docs/3.0/index/) @@ -20,106 +22,65 @@ Below, you'll find a matrix of all supported features for the Turso connector: | Feature | Supported | Notes | | ------------------------------- | --------- | ----- | -| Native Queries + Logical Models | ❌ | | -| Simple Object Query | ✅ | | -| Filter / Search | ✅ | | -| Simple Aggregation | ❌ | | -| Sort | ✅ | | -| Paginate | ✅ | | -| Table Relationships | ✅ | | -| Views | ❌ | | -| Distinct | ❌ | | -| Remote Relationships | ✅ | | -| Custom Fields | ❌ | | -| Mutations | ✅ | | - -## Before you get Started - -1. The [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and [Docker](https://docs.docker.com/engine/install/) installed -2. A [supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) -3. A [subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -4. Have a [Turso](https://turso.tech/) hosted database, or a persistent Turso SQLite database file — for supplying data to your API. - -The steps below explain how to Initialize and configure a connector for local development. You can learn how to deploy a -connector — after it's been configured — [here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). +| Native Queries + Logical Models | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ❌ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ✅ | | +| Views | ❌ | | +| Distinct | ❌ | | +| Remote Relationships | ✅ | | +| Custom Fields | ❌ | | +| Mutations | ✅ | | + +## Prerequisites + +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) + +The steps below explain how to initialize and configure a connector on your local machine (typically for development +purposes).You can learn how to deploy a connector to Hasura DDN — after it's been configured — +[here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). ## Using the Turso connector -### Step 1: Authenticate your CLI session - -```bash -ddn auth login -``` - -### Step 2: Configure the connector - -Once you have an initialized supergraph and subgraph, run the initialization command in interactive mode while providing a name for the connector in the prompt: +With the [context set](https://hasura.io/docs/3.0/cli/commands/ddn_context_set/) for an existing subgraph, initialize +the connector: -```bash -ddn connector init turso -i +```sh +ddn connector init -i ``` -#### Step 2.1: Choose the `hasura/turso` option from the list +When the wizard runs, you'll be prompted to enter the following env vars necessary for your connector to function: -#### Step 2.2: Choose a port for the connector - -The CLI will ask for a specific port to run the connector on. Choose a port that is not already in use or use the default suggested port. - -#### Step 2.3: Provide the env var(s) for the connector - -| Name | Description | -|-|-| +| Name | Description | +| ---------------- | --------------------------------------------------------------------------------- | | TURSO_URL | The connection string for the Turso database, or the file path to the SQLite file | -| TURSO_AUTH_TOKEN | The turso auth token | - -You'll find the environment variables in the `.env` file and they will be in the format: - -`__` - -Here is an example of what your `.env` file might look like: +| TURSO_AUTH_TOKEN | The turso auth token | -``` -APP_TURSO_AUTHORIZATION_HEADER="Bearer QTJ7rl19SvKa0rwOZjYILQ==" -APP_TURSO_HASURA_SERVICE_TOKEN_SECRET="QTJ7rl19SvKa0rwOZjYILQ==" -APP_TURSO_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://local.hasura.dev:4317" -APP_TURSO_OTEL_SERVICE_NAME="app_turso" -APP_TURSO_READ_URL="http://local.hasura.dev:4362" -APP_TURSO_TURSO_AUTH_TOKEN="eyJ..." -APP_TURSO_TURSO_URL="libsql://chinook-tristenharr.turso.io" -APP_TURSO_WRITE_URL="http://local.hasura.dev:4362" -``` - -If you are attaching to a local SQLite file, first make sure that the file is located inside the connector directory. For example, if you had a `data.sqlite` file you could place it at `/app/connector/turso/data.sqlite`. Files in the connector directory get mounted to `/etc/connector/`. - -In this instance, you would set the `TURSO_URL=file:/etc/connector/data.sqlite` and leave the `TURSO_AUTH_TOKEN` as blank/null. Now your `.env` might look like this: - -``` -APP_TURSO_AUTHORIZATION_HEADER="Bearer QTJ7rl19SvKa0rwOZjYILQ==" -APP_TURSO_HASURA_SERVICE_TOKEN_SECRET="QTJ7rl19SvKa0rwOZjYILQ==" -APP_TURSO_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://local.hasura.dev:4317" -APP_TURSO_OTEL_SERVICE_NAME="app_turso" -APP_TURSO_READ_URL="http://local.hasura.dev:4362" -APP_TURSO_TURSO_URL="file:/etc/connector/data.sqlite" -APP_TURSO_WRITE_URL="http://local.hasura.dev:4362" -``` - -Your experience mounting files may vary, and while useful to explore a file locally, it's not recommended to attempt to deploy a connector using a locally mounted file. - -### Step 3: Introspect the connector +If you are attaching to a local SQLite file, first make sure that the file is located inside the connector directory. +For example, if you had a `data.sqlite` file you could place it at `/app/connector/turso/data.sqlite`. Files in the +connector directory get mounted to `/etc/connector/`. -Introspecting the connector will generate a `config.json` file and a `turso.hml` file. +In this instance, you would set the `TURSO_URL=file:/etc/connector/data.sqlite` and leave the `TURSO_AUTH_TOKEN` as +blank/null. -```bash -ddn connector introspect turso -``` - -### Step 4: Add your resources +**Your experience mounting files may vary, and while useful to explore a file locally, it's not recommended to attempt +to deploy a connector using a locally mounted file.** -You can add the models, commands, and relationships to your API by tracking them which generates the HML files. +After the CLI initializes the connector, you'll need to: -```bash -ddn connector-link add-resources turso -``` +- [Introspect](https://hasura.io/docs/3.0/cli/commands/ddn_connector_introspect) the source. +- Add your [models](https://hasura.io/docs/3.0/cli/commands/ddn_model_add), + [commands](https://hasura.io/docs/3.0/cli/commands/ddn_command_add), and + [relationships](https://hasura.io/docs/3.0/cli/commands/ddn_relationship_add). +- Create a [new build](https://hasura.io/docs/3.0/cli/commands/ddn_supergraph_build_local). +- Test it by [running your project along with the connector](https://hasura.io/docs/3.0/cli/commands/ddn_run#examples). ## Documentation @@ -131,4 +92,4 @@ Check out our [contributing guide](https://github.com/hasura/ndc-turso/blob/main ## License -The Turso connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file +The Turso connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). From 08cb7363c176bb00aad429354f37dffd4a87b38c Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Fri, 27 Sep 2024 14:25:29 -0400 Subject: [PATCH 109/135] Release graphql v0.2.0 (#316) --- registry/hasura/graphql/metadata.json | 53 +++---------------- .../releases/v0.2.0/connector-packaging.json | 11 ++++ 2 files changed, 17 insertions(+), 47 deletions(-) create mode 100644 registry/hasura/graphql/releases/v0.2.0/connector-packaging.json diff --git a/registry/hasura/graphql/metadata.json b/registry/hasura/graphql/metadata.json index aa468a3b..85c69f13 100644 --- a/registry/hasura/graphql/metadata.json +++ b/registry/hasura/graphql/metadata.json @@ -5,7 +5,7 @@ "title": "GraphQL Native Data Connector", "logo": "logo.svg", "tags": [], - "latest_version": "v0.1.3" + "latest_version": "v0.2.0" }, "author": { "support_email": "support@hasura.io", @@ -14,56 +14,15 @@ }, "is_verified": true, "is_hosted_by_hasura": false, - "packages": [ - { - "version": "0.1.3", - "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.3/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "4045cfd23f6ed4bf747241f967a7717dd391b5fe8285ec486584427698cf9881" - }, - "source": { - "hash": "4262e34d57255c622a47daa408eba8c25fb279f7" - } - }, - { - "version": "0.1.2", - "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.2/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "85aa0294a4a13da85c2932254878814f60f8e9b61621232675b5dfa551248a77" - }, - "source": { - "hash": "1cfb5d3e52d914acf4e5e96edd54d7fc744ec304" - } - }, - { - "version": "0.1.1", - "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.1/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "8a5acec98e28953b22932d7a3734f7e7e535ac9478058b4d06ad9da5dc21ce1d" - }, - "source": { - "hash": "85b80185e28eb7f6721fc50ecd2552f96633e5db" - } - }, - { - "version": "0.1.0", - "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "30d6883c57b146812fb141feb3b4680a9ffe214cb13e04b0618a8da069d1286c" - }, - "source": { - "hash": "8fb41a151b3852fadcfadbe17695605f77aaa240" - } - } - ], "source_code": { "is_open_source": true, "repository": "https://github.com/hasura/ndc-graphql/", "version": [ + { + "tag": "v0.2.0", + "hash": "6296807daffb437a2f4dd158cab4c58d51ecd37c", + "is_verified": true + }, { "tag": "v0.1.3", "hash": "4262e34d57255c622a47daa408eba8c25fb279f7", diff --git a/registry/hasura/graphql/releases/v0.2.0/connector-packaging.json b/registry/hasura/graphql/releases/v0.2.0/connector-packaging.json new file mode 100644 index 00000000..adbb3f88 --- /dev/null +++ b/registry/hasura/graphql/releases/v0.2.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.2.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "5cfa92fe3b713312d24060b81677616e96b0454e5e719d7f416d162f3a9c07f1" + }, + "source": { + "hash": "6296807daffb437a2f4dd158cab4c58d51ecd37c" + } +} \ No newline at end of file From aa3eae2bfa0f95cf6ea7d5d7dcf9eb5aaeadd77d Mon Sep 17 00:00:00 2001 From: Akshaya Acharya Date: Mon, 30 Sep 2024 14:06:41 +0530 Subject: [PATCH 110/135] Connector upgrades DX (#296) Introduces a new plugin command `upgradeConfiguration` to upgrade connector configuration in place. [Rendered](https://github.com/hasura/ndc-hub/blob/ak/connector-upgrade-dx/rfcs/0010-connector-upgrades-dx.md) --- rfcs/0010-connector-upgrades-dx.md | 104 +++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 rfcs/0010-connector-upgrades-dx.md diff --git a/rfcs/0010-connector-upgrades-dx.md b/rfcs/0010-connector-upgrades-dx.md new file mode 100644 index 00000000..ae13376f --- /dev/null +++ b/rfcs/0010-connector-upgrades-dx.md @@ -0,0 +1,104 @@ +# RFC: connector upgrades DX + +How does a user upgrade across connector versions? For example: from postgres v0.7.0 to v1.1.1 ? + +## Solution + +DDN CLI will upgrade parts of the users project that it owns (such as the connector.yaml definition and docker compose.yaml). A new plugin command `upgradeConfiguration` is introduced for the connector to upgrade connector configuration. + +`ddn connector upgrade --connector [--version ]` will +- upgrade the connector to the specified version or to the latest version +- upgrade the connector.yaml and compose.yaml files in place +- atomically replace the .hasura-connector folder +- call the plugin command `upgradeConfiguration` on the *target version* of the connector + +The target version must be greater than the current version. + +The plugin command is expected to perform any connector specific upgrades to the connector configuration. + +If the plugin command is not defined, the CLI will WARN that the connector does not natively support configuration upgrades and that manual upgrades may be necessary. + +Connector authors should always include a upgradeConfiguration command, even if it a noop. + +## `upgradeConfiguration` command + +Should upgrade the context directory in place. The user is expected to use a version control system to handle changes. + +Note: connectors should capture the configuration version as a part of the configuration. + +Do not rely on or modify the following files: connector.yaml, compose.yaml. Connectors must read and modify only files that the connector itself owns. + +## `connector-metadata.yaml` types + +```diff +type ConnectorMetadataDefinition = { + packagingDefinition: PackagingDefinition + nativeToolchainDefinition?: NativeToolchainDefinition + supportedEnvironmentVariables: EnvironmentVariableDefinition[] + commands: Commands + cliPlugin?: CliPluginDefinition + dockerComposeWatch: DockerComposeWatch +} + +type PackagingDefinition = PrebuiltDockerImagePackaging | ManagedDockerBuildPackaging + +type PrebuiltDockerImagePackaging = { + type: "PrebuiltDockerImage" + dockerImage: string +} + +type ManagedDockerBuildPackaging = { + type: "ManagedDockerBuild" +} + +type NativeToolchainDefinition = { + commands: NativeToolchainCommands +} + + +type NativeToolchainCommands = { + start: string | DockerizedCommand | ShellScriptCommand + update?: string | DockerizedCommand | ShellScriptCommand + watch: string | DockerizedCommand | ShellScriptCommand +} + +type EnvironmentVariableDefinition = { + name: string + description: string + defaultValue?: string +} + +type Commands = { + update?: string | DockerizedCommand | ShellScriptCommand + watch?: string | DockerizedCommand | ShellScriptCommand + printSchemaAndCapabilities?: string | DockerizedCommand | ShellScriptCommand ++ upgradeConfiguration?: string | DockerizedCommand | ShellScriptCommand +} + + +type DockerizedCommand = { + type: "Dockerized" + dockerImage: string + commandArgs: string[] +} + +type ShellScriptCommand = { + type: "ShellScript" + bash: string + powershell: string +} + +type CliPluginDefinition = { + name: string + version: string +} + +type DockerComposeWatch = DockerComposeWatchItem[] + +type DockerComposeWatchItem = { + path: string + action: "rebuild" | "sync" | "sync+restart" + target?: string + ignore?: string[] +} +``` From 31e57a0e988c1e68cb3f4b114049d91727783f38 Mon Sep 17 00:00:00 2001 From: Toan Nguyen Date: Mon, 30 Sep 2024 17:53:45 +0700 Subject: [PATCH 111/135] ndc-prometheus v0.1.0 (#317) Release Prometheus connector v0.1.0 --- registry/hasura/prometheus/metadata.json | 7 ++++++- .../releases/v0.1.0/connector-packaging.json | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 registry/hasura/prometheus/releases/v0.1.0/connector-packaging.json diff --git a/registry/hasura/prometheus/metadata.json b/registry/hasura/prometheus/metadata.json index 3a70b4b9..846bf844 100644 --- a/registry/hasura/prometheus/metadata.json +++ b/registry/hasura/prometheus/metadata.json @@ -5,7 +5,7 @@ "title": "Prometheus Data Connector", "logo": "logo.svg", "tags": ["database"], - "latest_version": "v0.0.4" + "latest_version": "v0.1.0" }, "author": { "support_email": "support@hasura.io", @@ -22,6 +22,11 @@ "tag": "v0.0.4", "hash": "69915e6c9736f38a0952c5ce8ad9a2d180783a43", "is_verified": true + }, + { + "tag": "v0.1.0", + "hash": "3d45dd1628d268906c8b56ecf235d6c280c29ca9", + "is_verified": true } ] } diff --git a/registry/hasura/prometheus/releases/v0.1.0/connector-packaging.json b/registry/hasura/prometheus/releases/v0.1.0/connector-packaging.json new file mode 100644 index 00000000..f38a8aaa --- /dev/null +++ b/registry/hasura/prometheus/releases/v0.1.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.1.0", + "uri": "https://github.com/hasura/ndc-prometheus/releases/download/v0.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "efe31157e7a2a580239b18f964c1ad2720e67f65e8ecbad29b8346b76fb3ae22" + }, + "source": { + "hash": "3d45dd1628d268906c8b56ecf235d6c280c29ca9" + } +} From 8294af6577fd3f014c808eb0656a3d216c2a6d36 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Tue, 1 Oct 2024 18:44:01 -0400 Subject: [PATCH 112/135] Release Clickhouse v1.0.3 (#319) --- registry/hasura/clickhouse/metadata.json | 7 ++++++- .../releases/v1.0.3/connector-packaging.json | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 registry/hasura/clickhouse/releases/v1.0.3/connector-packaging.json diff --git a/registry/hasura/clickhouse/metadata.json b/registry/hasura/clickhouse/metadata.json index 34c0808e..f3c69b2c 100644 --- a/registry/hasura/clickhouse/metadata.json +++ b/registry/hasura/clickhouse/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.2" + "latest_version": "v1.0.3" }, "author": { "support_email": "support@hasura.io", @@ -20,6 +20,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-clickhouse/", "version": [ + { + "tag": "v1.0.3", + "hash": "e359aed45779b3c249c164f76cd6450c272739ce", + "is_verified": true + }, { "tag": "v1.0.2", "hash": "ec2463375b9244e008005d44a2b82288867c2d4e", diff --git a/registry/hasura/clickhouse/releases/v1.0.3/connector-packaging.json b/registry/hasura/clickhouse/releases/v1.0.3/connector-packaging.json new file mode 100644 index 00000000..97cd7953 --- /dev/null +++ b/registry/hasura/clickhouse/releases/v1.0.3/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.3", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v1.0.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "e8dfc5d3a0706ebe9391fa7a1735d42395211bd462ad7f3cfe135b17036ec9e5" + }, + "source": { + "hash": "e359aed45779b3c249c164f76cd6450c272739ce" + } +} \ No newline at end of file From ea14b37d0e6a4eede1228bfaa82dc74aab1320cc Mon Sep 17 00:00:00 2001 From: Brandon Martin Date: Wed, 2 Oct 2024 04:56:48 -0600 Subject: [PATCH 113/135] Release MongoDB version 1.3.0 (#320) --- registry/hasura/mongodb/metadata.json | 113 ++---------------- .../releases/v1.3.0/connector-packaging.json | 11 ++ 2 files changed, 22 insertions(+), 102 deletions(-) create mode 100644 registry/hasura/mongodb/releases/v1.3.0/connector-packaging.json diff --git a/registry/hasura/mongodb/metadata.json b/registry/hasura/mongodb/metadata.json index 43923c03..39eab698 100644 --- a/registry/hasura/mongodb/metadata.json +++ b/registry/hasura/mongodb/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.1.0" + "latest_version": "v1.3.0" }, "author": { "support_email": "support@hasura.io", @@ -16,111 +16,20 @@ }, "is_verified": true, "is_hosted_by_hasura": false, - "packages": [ - { - "version": "1.1.0", - "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v1.1.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "e0b616454261c1d07b058578f26ba928c832b11805ade1474e274c945e12e088" - }, - "source": { - "hash": "eab726516ecfcee76abeab1b92f3b5d6cba10976" - } - }, - { - "version": "1.0.0", - "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v1.0.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "0dc038620f40911a2c5662b61d8e2ac9605876c80b3eb3cbae5cc1ebcd5b611f" - }, - "source": { - "hash": "4beb7ddabddc3035ca5cc7bd85493a71a2e34147" - } - }, - { - "version": "0.1.0", - "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.1.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "adb5ce24e053117ba33c16ecf54bdc5a678790f3b31801645911fdf7091a58e0" - }, - "source": { - "hash": "175272912b86a11359a9b6b7fd72c7a6e2326bf1" - } - }, - { - "version": "0.0.6", - "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.6/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "24370c44a8ff92dce488569717956069f2a50de7a8f54547b140d85a17b52875" - }, - "source": { - "hash": "6e842c308eeee38d3bc393e6b99157961ca3ed03" - } - }, - { - "version": "0.0.5", - "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.5/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "2064a98d223240b912720f0528c6b9a7107a42e4452407c2b75e77dcfdbd4227" - }, - "source": { - "hash": "055154b5d84f05ff0049aa75a29b85caf89822f6" - } - }, - { - "version": "0.0.4", - "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.4/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "7b826a79686b48e58819751091fac62071df75ca9fd617b80709fe098a054f26" - }, - "source": { - "hash": "38a4a56134a909001b645c659062ae393c2cebe0" - } - }, - { - "version": "0.0.3", - "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.3/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "0019dfc4b32d63c1392aa264aed2253c1e0c2fb09216f8e2cc269bbfb8bb49b5" - }, - "source": { - "hash": "b50094a368f8fbab7c37e4b83ef5dc1249a4a5d5" - } - }, - { - "version": "0.0.2", - "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.2/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "f014459e9dbcce8bafe1c33c74b1fa1720d544bc283cc819c81d719028219846" - }, - "source": { - "hash": "90c336c4d1d949d62dd25b04742e650fb6d458e0" - } - }, - { - "version": "0.0.1", - "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.1/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "2cd3584557be7e2870f3488a30cac6219924b3f7accd9f5f473285323843a0f4" - }, - "source": { - "hash": "c32adbde478147518f65ff465c40a0703239288a" - } - } - ], "source_code": { "is_open_source": true, "repository": "https://github.com/hasura/ndc-mongodb/", "version": [ + { + "tag": "v1.3.0", + "hash": "47fc3c301203d0118940a317e7c634e768b8898a", + "is_verified": true + }, + { + "tag": "v1.2.0", + "hash": "2e0696e8bd587c18f067e683ec367f6ba350537f", + "is_verified": true + }, { "tag": "v1.1.0", "hash": "eab726516ecfcee76abeab1b92f3b5d6cba10976", diff --git a/registry/hasura/mongodb/releases/v1.3.0/connector-packaging.json b/registry/hasura/mongodb/releases/v1.3.0/connector-packaging.json new file mode 100644 index 00000000..4dd4d385 --- /dev/null +++ b/registry/hasura/mongodb/releases/v1.3.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.3.0", + "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v1.3.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "f67bcd8ad5a39e1d93e73e5259c5fd8e4f8a55f9ab4d897980c1d7d43d01f2b9" + }, + "source": { + "hash": "47fc3c301203d0118940a317e7c634e768b8898a" + } +} From 3328674e6829235be6aee12f0bc45d183516a20e Mon Sep 17 00:00:00 2001 From: AdalbertMemSQL Date: Thu, 3 Oct 2024 01:07:19 +0300 Subject: [PATCH 114/135] release singlestore version 0.0.4 (#321) --- registry/hasura/singlestore/README.md | 9 +++++---- registry/hasura/singlestore/metadata.json | 12 +++++++++++- .../releases/v0.0.4/connector-packaging.json | 11 +++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 registry/hasura/singlestore/releases/v0.0.4/connector-packaging.json diff --git a/registry/hasura/singlestore/README.md b/registry/hasura/singlestore/README.md index e01d8f85..3acb622f 100644 --- a/registry/hasura/singlestore/README.md +++ b/registry/hasura/singlestore/README.md @@ -66,13 +66,14 @@ When the wizard runs, you'll be prompted to enter the following env vars necessa | ----------------------------------- | --------- | --------------------------------------------------------------------------------------------------- | | SINGLESTORE_HOST | localhost | Hostname of the SingleStore database to connect with. | | SINGLESTORE_PORT | 3306 | Port number of the SingleStore database. | +| SINGLESTORE_USER | | SingleStore user to authenticate as. | | SINGLESTORE_PASSWORD | | Password of the SingleStore database user. | | SINGLESTORE_DATABASE | | Name of the SingleStore database to connect with. | -| SINGLESTORE_SSL_CA | | Path to the trusted CA certificate file. | -| SINGLESTORE_SSL_CERT | | Path to the certificate chain file in PEM format. | -| SINGLESTORE_SSL_KEY | | Path to the private key file in PEM format. | +| SINGLESTORE_SSL_CA | | CA certificate. | +| SINGLESTORE_SSL_CERT | | Certificate chain in PEM format. | +| SINGLESTORE_SSL_KEY | | Private key in PEM format. | | SINGLESTORE_SSL_CIPHERS | | Cipher suite specification. If specified, it replaces the default value. | -| SINGLESTORE_SSL_PASSPHRASE | | Cipher suite specification. If specified, it replaces the default value. | +| SINGLESTORE_SSL_PASSPHRASE | | Shared passphrase used for a single private key. | | SINGLESTORE_SSL_REJECT_UNAUTHORIZED | true | If enabled, the server rejects any connection that is not authorized with the list of supplied CAs. | The connector uses [MySQL2](https://sidorares.github.io/node-mysql2/docs) library to establish a connection. For more diff --git a/registry/hasura/singlestore/metadata.json b/registry/hasura/singlestore/metadata.json index 46c26690..f7e8f6ab 100644 --- a/registry/hasura/singlestore/metadata.json +++ b/registry/hasura/singlestore/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v0.0.3" + "latest_version": "v0.0.4" }, "author": { "support_email": "integrations@singlestore.com", @@ -34,6 +34,16 @@ "tag": "v0.0.3", "hash": "72ed900d5cc6819614fa27bba7bdba8977eedc6d", "is_verified": false + }, + { + "tag": "v0.0.4", + "hash": "4a7e713a767d9899c6b81d455ba76b7b75602d06", + "is_verified": false + }, + { + "tag": "v0.0.4", + "hash": "f26ee20fedf4578a29ff3199561b2882d70f915a", + "is_verified": false } ] } diff --git a/registry/hasura/singlestore/releases/v0.0.4/connector-packaging.json b/registry/hasura/singlestore/releases/v0.0.4/connector-packaging.json new file mode 100644 index 00000000..ca96ac57 --- /dev/null +++ b/registry/hasura/singlestore/releases/v0.0.4/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.4", + "uri": "https://github.com/singlestore-labs/singlestore-hasura-connector/releases/download/v0.0.4/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "1532508dfff96f003adc16ad9b440b779733ee8fdfe9d1b07c4f8d8edea05188" + }, + "source": { + "hash": "f26ee20fedf4578a29ff3199561b2882d70f915a" + } +} From 3bf98db0b90b678dcb56629420b5dc83b9dd0ae3 Mon Sep 17 00:00:00 2001 From: pranshi06 <85474619+pranshi06@users.noreply.github.com> Date: Fri, 4 Oct 2024 13:48:03 +0530 Subject: [PATCH 115/135] Release SQLServer v0.2.2 (#323) --- registry/hasura/sqlserver/metadata.json | 2 +- .../releases/v0.2.2/connector-packaging.json | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 registry/hasura/sqlserver/releases/v0.2.2/connector-packaging.json diff --git a/registry/hasura/sqlserver/metadata.json b/registry/hasura/sqlserver/metadata.json index 4607df8d..1bba9bf7 100644 --- a/registry/hasura/sqlserver/metadata.json +++ b/registry/hasura/sqlserver/metadata.json @@ -5,7 +5,7 @@ "title": "SQL Server Connector", "logo": "logo.png", "tags": ["database"], - "latest_version": "v0.2.1" + "latest_version": "v0.2.2" }, "author": { "support_email": "support@hasura.io", diff --git a/registry/hasura/sqlserver/releases/v0.2.2/connector-packaging.json b/registry/hasura/sqlserver/releases/v0.2.2/connector-packaging.json new file mode 100644 index 00000000..7c1ccefa --- /dev/null +++ b/registry/hasura/sqlserver/releases/v0.2.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.2", + "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.2.2/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "2dbe5251872bf39d3a08261f7042307bae2ea8c831eec1982177b765c1e7013d" + }, + "source": { + "hash": "c33ff7efdcdef2c337aa40e2e776a4c2fdaca68b" + } +} From bfcb124c6a4f61be5beb66418080e6f06658bd22 Mon Sep 17 00:00:00 2001 From: Toan Nguyen Date: Mon, 7 Oct 2024 17:14:51 +0700 Subject: [PATCH 116/135] add ndc-go v1.5.1 (#325) --- registry/hasura/go/metadata.json | 7 ++++++- .../go/releases/v1.5.1/connector-packaging.json | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 registry/hasura/go/releases/v1.5.1/connector-packaging.json diff --git a/registry/hasura/go/metadata.json b/registry/hasura/go/metadata.json index 87f4b21f..cf73be01 100644 --- a/registry/hasura/go/metadata.json +++ b/registry/hasura/go/metadata.json @@ -5,7 +5,7 @@ "title": "Go Connector", "logo": "logo.svg", "tags": [], - "latest_version": "v1.4.0" + "latest_version": "v1.5.1" }, "author": { "support_email": "support@hasura.io", @@ -18,6 +18,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-sdk-go", "version": [ + { + "tag": "v1.5.1", + "hash": "e6a7fd89d13f0a8b12732ee88ae5bbe775ec60ba", + "is_verified": true + }, { "tag": "v1.4.0", "hash": "c31575e0eb0c55e0f326c859f7c1a830dc09c424", diff --git a/registry/hasura/go/releases/v1.5.1/connector-packaging.json b/registry/hasura/go/releases/v1.5.1/connector-packaging.json new file mode 100644 index 00000000..f529df56 --- /dev/null +++ b/registry/hasura/go/releases/v1.5.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v1.5.1", + "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.5.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "4d55c4f60793b23446d0d88eaa1f591cb34197115f65a626728da01556e2b53b" + }, + "source": { + "hash": "e6a7fd89d13f0a8b12732ee88ae5bbe775ec60ba" + } +} From cae4d041ca9a321bb30c866763760cfe281adad9 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Mon, 7 Oct 2024 09:38:09 -0400 Subject: [PATCH 117/135] Release ClickHouse v1.0.4 (#324) --- registry/hasura/clickhouse/metadata.json | 7 ++++++- .../releases/v1.0.4/connector-packaging.json | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 registry/hasura/clickhouse/releases/v1.0.4/connector-packaging.json diff --git a/registry/hasura/clickhouse/metadata.json b/registry/hasura/clickhouse/metadata.json index f3c69b2c..05e18ab7 100644 --- a/registry/hasura/clickhouse/metadata.json +++ b/registry/hasura/clickhouse/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.3" + "latest_version": "v1.0.4" }, "author": { "support_email": "support@hasura.io", @@ -20,6 +20,11 @@ "is_open_source": true, "repository": "https://github.com/hasura/ndc-clickhouse/", "version": [ + { + "tag": "v1.0.4", + "hash": "2702f3f3cd1b399a42d451f9fcfe75d641b1cfeb", + "is_verified": true + }, { "tag": "v1.0.3", "hash": "e359aed45779b3c249c164f76cd6450c272739ce", diff --git a/registry/hasura/clickhouse/releases/v1.0.4/connector-packaging.json b/registry/hasura/clickhouse/releases/v1.0.4/connector-packaging.json new file mode 100644 index 00000000..639787d0 --- /dev/null +++ b/registry/hasura/clickhouse/releases/v1.0.4/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.4", + "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v1.0.4/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "e1528c4e7453839547c43fb831f5733cbbb3254da49e7df6226e1f83fc467f3f" + }, + "source": { + "hash": "2702f3f3cd1b399a42d451f9fcfe75d641b1cfeb" + } +} \ No newline at end of file From f18504de738fb1d1c739a24119fbd0c45c942f69 Mon Sep 17 00:00:00 2001 From: Vishnu Bharathi Date: Mon, 7 Oct 2024 22:22:09 +0530 Subject: [PATCH 118/135] make cockroach to be an aliased connector of postgres (#327) I guess we missed including this one in our previous attempt to create alias connectors for postgres. --- .../aliased_connectors}/cockroach/README.md | 0 .../aliased_connectors}/cockroach/logo.png | Bin .../aliased_connectors}/cockroach/metadata.json | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename registry/hasura/{ => postgres/aliased_connectors}/cockroach/README.md (100%) rename registry/hasura/{ => postgres/aliased_connectors}/cockroach/logo.png (100%) rename registry/hasura/{ => postgres/aliased_connectors}/cockroach/metadata.json (100%) diff --git a/registry/hasura/cockroach/README.md b/registry/hasura/postgres/aliased_connectors/cockroach/README.md similarity index 100% rename from registry/hasura/cockroach/README.md rename to registry/hasura/postgres/aliased_connectors/cockroach/README.md diff --git a/registry/hasura/cockroach/logo.png b/registry/hasura/postgres/aliased_connectors/cockroach/logo.png similarity index 100% rename from registry/hasura/cockroach/logo.png rename to registry/hasura/postgres/aliased_connectors/cockroach/logo.png diff --git a/registry/hasura/cockroach/metadata.json b/registry/hasura/postgres/aliased_connectors/cockroach/metadata.json similarity index 100% rename from registry/hasura/cockroach/metadata.json rename to registry/hasura/postgres/aliased_connectors/cockroach/metadata.json From 7677be6a57a9794442ad46eaf06009ac11d269a3 Mon Sep 17 00:00:00 2001 From: pranshi06 <85474619+pranshi06@users.noreply.github.com> Date: Tue, 8 Oct 2024 20:12:28 +0530 Subject: [PATCH 119/135] update BigQuery logo file (#330) Co-authored-by: py --- registry/hasura/bigquery/logo.png | Bin 3065 -> 13394 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/registry/hasura/bigquery/logo.png b/registry/hasura/bigquery/logo.png index 997915e29ffe55c2b2825eb51a998abcdc3bcdc5..fa2a54e96e45bfaea4aa602fc1fd33aa8669354c 100644 GIT binary patch literal 13394 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 AoB#j- literal 3065 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 Date: Wed, 9 Oct 2024 16:46:43 +0530 Subject: [PATCH 120/135] fix sha256 checksum for some connectors (#328) --- .../clickhouse/releases/v0.2.9/connector-packaging.json | 2 +- registry/hasura/go/releases/v0.5.2/connector-packaging.json | 4 ++-- registry/hasura/go/releases/v0.6.3/connector-packaging.json | 2 +- registry/hasura/go/releases/v1.1.2/connector-packaging.json | 4 ++-- registry/hasura/go/releases/v1.2.3/connector-packaging.json | 2 +- registry/hasura/go/releases/v1.3.1/connector-packaging.json | 2 +- registry/hasura/go/releases/v1.4.0/connector-packaging.json | 2 +- registry/hasura/go/releases/v1.5.1/connector-packaging.json | 2 +- .../hasura/mongodb/releases/v0.0.3/connector-packaging.json | 4 ++-- .../hasura/mysql/releases/v0.1.0/connector-packaging.json | 2 +- .../hasura/oracle/releases/v0.1.0/connector-packaging.json | 2 +- .../hasura/phoenix/releases/v1.0.0/connector-packaging.json | 2 +- .../hasura/snowflake/releases/v0.1.0/connector-packaging.json | 2 +- 13 files changed, 16 insertions(+), 16 deletions(-) diff --git a/registry/hasura/clickhouse/releases/v0.2.9/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.9/connector-packaging.json index dc6c0452..fd1946e1 100644 --- a/registry/hasura/clickhouse/releases/v0.2.9/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v0.2.9/connector-packaging.json @@ -3,7 +3,7 @@ "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.9/connector-definition.tgz", "checksum": { "type": "sha256", - "value": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + "value": "7c1f2915336dfcea291e3dc50b7cfd7df72216346b8f4d6a4073e13d55c53b90" }, "source": { "hash": "93752f433f4e7c91f0c13d92ea9369deb97d1970" diff --git a/registry/hasura/go/releases/v0.5.2/connector-packaging.json b/registry/hasura/go/releases/v0.5.2/connector-packaging.json index 90a5ffc1..898ed0eb 100644 --- a/registry/hasura/go/releases/v0.5.2/connector-packaging.json +++ b/registry/hasura/go/releases/v0.5.2/connector-packaging.json @@ -3,9 +3,9 @@ "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v0.5.2/connector-definition.tgz", "checksum": { "type": "sha256", - "value": "dfb2ea7499744a1ad00673703eed28bccaf38b4866721f5b0aacb546d788a659" + "value": "820018ed9e9f19fd969a87ce7c5da1e6d8408a271290c5fa63a5730ad391f26d" }, "source": { "hash": "79788195359a5e3cf0fc8896b61eb8f4d9196427" } -} \ No newline at end of file +} diff --git a/registry/hasura/go/releases/v0.6.3/connector-packaging.json b/registry/hasura/go/releases/v0.6.3/connector-packaging.json index 61753179..d9d102f5 100644 --- a/registry/hasura/go/releases/v0.6.3/connector-packaging.json +++ b/registry/hasura/go/releases/v0.6.3/connector-packaging.json @@ -3,7 +3,7 @@ "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v0.6.3/connector-definition.tgz", "checksum": { "type": "sha256", - "value": "e6ebd14bc1a75ab384da80eae7a823dd6883af6a574b42d720358d873491f96e" + "value": "e991b20f53c2d0bfd6fc11468c177154b38eb23ad5b708c0cd408b533b8404e8" }, "source": { "hash": "726b3fbb442fae62d18840905545f1d663baf87b" diff --git a/registry/hasura/go/releases/v1.1.2/connector-packaging.json b/registry/hasura/go/releases/v1.1.2/connector-packaging.json index f24a3e90..f16c490e 100644 --- a/registry/hasura/go/releases/v1.1.2/connector-packaging.json +++ b/registry/hasura/go/releases/v1.1.2/connector-packaging.json @@ -3,9 +3,9 @@ "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.1.2/connector-definition.tgz", "checksum": { "type": "sha256", - "value": "2e037c86fd4da3f07417a7216a7921b885a4e13b8da15210e1cd13cc4ee728f1" + "value": "2691a5a266da6a17c1d6681c7524ef85ce35842d391769decccd6ba4f05e3ac4" }, "source": { "hash": "32e28e549f11b790c320b6a79ad33ad8e6df5bd7" } -} \ No newline at end of file +} diff --git a/registry/hasura/go/releases/v1.2.3/connector-packaging.json b/registry/hasura/go/releases/v1.2.3/connector-packaging.json index b70abe80..cf31e4f5 100644 --- a/registry/hasura/go/releases/v1.2.3/connector-packaging.json +++ b/registry/hasura/go/releases/v1.2.3/connector-packaging.json @@ -3,7 +3,7 @@ "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.2.3/connector-definition.tgz", "checksum": { "type": "sha256", - "value": "9573485be49d633ab3a7b39e8777da2d3524702fafac1739e42217caf5b3ad9a" + "value": "c8baf7a8eead7fa705871269f4fe552cb0c3e8d7cc98bace6448a8a63f96fa89" }, "source": { "hash": "1fdc72d31dccae129d6d626dea6e31b5cd3b0b18" diff --git a/registry/hasura/go/releases/v1.3.1/connector-packaging.json b/registry/hasura/go/releases/v1.3.1/connector-packaging.json index 3628891b..347fc613 100644 --- a/registry/hasura/go/releases/v1.3.1/connector-packaging.json +++ b/registry/hasura/go/releases/v1.3.1/connector-packaging.json @@ -3,7 +3,7 @@ "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.3.1/connector-definition.tgz", "checksum": { "type": "sha256", - "value": "be6e634b8c989e4e13d68959e1daed9b76d64ae1337c52e0a0295f3bc5873d2e" + "value": "36b14d6475c749bbb1d29c0371bb7091a0cd5db54d2f83caae3f3a15505dedb9" }, "source": { "hash": "f6093ca96fe64063df786159a2bb061c01d9197d" diff --git a/registry/hasura/go/releases/v1.4.0/connector-packaging.json b/registry/hasura/go/releases/v1.4.0/connector-packaging.json index a0c4264b..efd405c8 100644 --- a/registry/hasura/go/releases/v1.4.0/connector-packaging.json +++ b/registry/hasura/go/releases/v1.4.0/connector-packaging.json @@ -3,7 +3,7 @@ "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.4.0/connector-definition.tgz", "checksum": { "type": "sha256", - "value": "d599976b66b18c241eb6bef9baf8c77d15d32c41db4392d198887ef848893e6f" + "value": "a24b5a8a6cc58280868f31f1e8bb39b420d4829efe68bcbeb6992be1a2c2fee5" }, "source": { "hash": "c31575e0eb0c55e0f326c859f7c1a830dc09c424" diff --git a/registry/hasura/go/releases/v1.5.1/connector-packaging.json b/registry/hasura/go/releases/v1.5.1/connector-packaging.json index f529df56..8cdb3efc 100644 --- a/registry/hasura/go/releases/v1.5.1/connector-packaging.json +++ b/registry/hasura/go/releases/v1.5.1/connector-packaging.json @@ -3,7 +3,7 @@ "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.5.1/connector-definition.tgz", "checksum": { "type": "sha256", - "value": "4d55c4f60793b23446d0d88eaa1f591cb34197115f65a626728da01556e2b53b" + "value": "153379fbbedfe4e6682dc882bdf60bb5285c884328c3b29dfe0e36db8c80fe86" }, "source": { "hash": "e6a7fd89d13f0a8b12732ee88ae5bbe775ec60ba" diff --git a/registry/hasura/mongodb/releases/v0.0.3/connector-packaging.json b/registry/hasura/mongodb/releases/v0.0.3/connector-packaging.json index 69037da8..2e40d789 100644 --- a/registry/hasura/mongodb/releases/v0.0.3/connector-packaging.json +++ b/registry/hasura/mongodb/releases/v0.0.3/connector-packaging.json @@ -3,9 +3,9 @@ "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.3/connector-definition.tgz", "checksum": { "type": "sha256", - "value": "0019dfc4b32d63c1392aa264aed2253c1e0c2fb09216f8e2cc269bbfb8bb49b5" + "value": "04e4d3bb29bdb96766fa3cf0b9c9d4173550dced5c6c36b1a1d32545b5c0bd30" }, "source": { "hash": "b50094a368f8fbab7c37e4b83ef5dc1249a4a5d5" } -} \ No newline at end of file +} diff --git a/registry/hasura/mysql/releases/v0.1.0/connector-packaging.json b/registry/hasura/mysql/releases/v0.1.0/connector-packaging.json index ef79399f..3c76e1fe 100644 --- a/registry/hasura/mysql/releases/v0.1.0/connector-packaging.json +++ b/registry/hasura/mysql/releases/v0.1.0/connector-packaging.json @@ -3,7 +3,7 @@ "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/mysql%2Fv0.1.0/package.tar.gz", "checksum": { "type": "sha256", - "value": "09b51f9be725099345159880d21efb712776bfd09291a0daa81d7e7b1418ca2c" + "value": "9807b4467dae194f558af17970cb3ba4f7faf4f3a0c14f2a114a7296498cf025" }, "source": { "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" diff --git a/registry/hasura/oracle/releases/v0.1.0/connector-packaging.json b/registry/hasura/oracle/releases/v0.1.0/connector-packaging.json index 535615bc..9de59411 100644 --- a/registry/hasura/oracle/releases/v0.1.0/connector-packaging.json +++ b/registry/hasura/oracle/releases/v0.1.0/connector-packaging.json @@ -3,7 +3,7 @@ "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/oracle%2Fv0.1.0/package.tar.gz", "checksum": { "type": "sha256", - "value": "0d837408a213f55df34062b96a2ac7fabcf8c61891918b6b2754d90fc61dd24c" + "value": "33a52fa0070ee4c956fbae37212b2012ff5f637dc90e2b47ee1899a39b3d34a6" }, "source": { "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" diff --git a/registry/hasura/phoenix/releases/v1.0.0/connector-packaging.json b/registry/hasura/phoenix/releases/v1.0.0/connector-packaging.json index e2778153..10028942 100644 --- a/registry/hasura/phoenix/releases/v1.0.0/connector-packaging.json +++ b/registry/hasura/phoenix/releases/v1.0.0/connector-packaging.json @@ -3,7 +3,7 @@ "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/phoenix%2Fv1.0.0/package.tar.gz", "checksum": { "type": "sha256", - "value": "6875748c433e772da7603e3b4fd0798b4c2321a4" + "value": "dea7bcd0784bce3a2b8f7a573f793f24f511f793c2b117636235ff883c351e68" }, "source": { "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" diff --git a/registry/hasura/snowflake/releases/v0.1.0/connector-packaging.json b/registry/hasura/snowflake/releases/v0.1.0/connector-packaging.json index 55a37c1c..0783e356 100644 --- a/registry/hasura/snowflake/releases/v0.1.0/connector-packaging.json +++ b/registry/hasura/snowflake/releases/v0.1.0/connector-packaging.json @@ -3,7 +3,7 @@ "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/snowflake%2Fv0.1.0/package.tar.gz", "checksum": { "type": "sha256", - "value": "564757bc44bebe56560fe21a1306507d160caf084d69556bded4a7ed392e1b41" + "value": "662391f5d3821bf41662d25266bfa9ff6e9d5a162a31b74959487d12deb89d3e" }, "source": { "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" From fdb98e110c5a86148e39be23e31a997a6c150620 Mon Sep 17 00:00:00 2001 From: Vishnu Bharathi Date: Wed, 9 Oct 2024 19:03:56 +0530 Subject: [PATCH 121/135] ci: turn off connector publication (#332) Fixing some discrepancies in the hub. So turning off the automation for a bit. We will revert this after fixing all the discrepancies. --- .github/workflows/registry-updates-prod.yaml | 36 ++++++++++---------- .github/workflows/registry-updates.yaml | 34 +++++++++--------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/.github/workflows/registry-updates-prod.yaml b/.github/workflows/registry-updates-prod.yaml index 32e8d71e..78bc2aca 100644 --- a/.github/workflows/registry-updates-prod.yaml +++ b/.github/workflows/registry-updates-prod.yaml @@ -40,21 +40,21 @@ jobs: run: | cat changed_files.json - - name: Setup Go - uses: actions/setup-go@v4 - with: - go-version: 1.21.x - - - name: Run registry automation program - env: - CHANGED_FILES_PATH: "changed_files.json" - PUBLICATION_ENV: "production" - CONNECTOR_REGISTRY_GQL_URL: ${{ secrets.CONNECTOR_REGISTRY_GQL_URL }} - GCP_BUCKET_NAME: ${{ secrets.GCP_BUCKET_NAME }} - GCP_SERVICE_ACCOUNT_DETAILS: ${{ secrets.GCP_SERVICE_ACCOUNT_DETAILS }} - CONNECTOR_PUBLICATION_KEY: ${{ secrets.CONNECTOR_PUBLICATION_KEY }} - CLOUDINARY_URL: ${{ secrets.CLOUDINARY_URL }} - run: | - mv changed_files.json registry-automation/changed_files.json - cd registry-automation - go run main.go ci + # - name: Setup Go + # uses: actions/setup-go@v4 + # with: + # go-version: 1.21.x + + # - name: Run registry automation program + # env: + # CHANGED_FILES_PATH: "changed_files.json" + # PUBLICATION_ENV: "production" + # CONNECTOR_REGISTRY_GQL_URL: ${{ secrets.CONNECTOR_REGISTRY_GQL_URL }} + # GCP_BUCKET_NAME: ${{ secrets.GCP_BUCKET_NAME }} + # GCP_SERVICE_ACCOUNT_DETAILS: ${{ secrets.GCP_SERVICE_ACCOUNT_DETAILS }} + # CONNECTOR_PUBLICATION_KEY: ${{ secrets.CONNECTOR_PUBLICATION_KEY }} + # CLOUDINARY_URL: ${{ secrets.CLOUDINARY_URL }} + # run: | + # mv changed_files.json registry-automation/changed_files.json + # cd registry-automation + # go run main.go ci diff --git a/.github/workflows/registry-updates.yaml b/.github/workflows/registry-updates.yaml index fd0a6afe..64029cdb 100644 --- a/.github/workflows/registry-updates.yaml +++ b/.github/workflows/registry-updates.yaml @@ -63,21 +63,21 @@ jobs: run: | cat changed_files.json - - name: Setup Go - uses: actions/setup-go@v4 - with: - go-version: 1.21.x + # - name: Setup Go + # uses: actions/setup-go@v4 + # with: + # go-version: 1.21.x - - name: Run registry automation program - env: - CHANGED_FILES_PATH: "changed_files.json" - PUBLICATION_ENV: "staging" - CONNECTOR_REGISTRY_GQL_URL: ${{ secrets.CONNECTOR_REGISTRY_GQL_URL }} - GCP_BUCKET_NAME: ${{ secrets.GCP_BUCKET_NAME }} - GCP_SERVICE_ACCOUNT_DETAILS: ${{ secrets.GCP_SERVICE_ACCOUNT_DETAILS }} - CONNECTOR_PUBLICATION_KEY: ${{ secrets.CONNECTOR_PUBLICATION_KEY }} - CLOUDINARY_URL: ${{ secrets.CLOUDINARY_URL }} - run: | - mv changed_files.json registry-automation/changed_files.json - cd registry-automation - go run main.go ci + # - name: Run registry automation program + # env: + # CHANGED_FILES_PATH: "changed_files.json" + # PUBLICATION_ENV: "staging" + # CONNECTOR_REGISTRY_GQL_URL: ${{ secrets.CONNECTOR_REGISTRY_GQL_URL }} + # GCP_BUCKET_NAME: ${{ secrets.GCP_BUCKET_NAME }} + # GCP_SERVICE_ACCOUNT_DETAILS: ${{ secrets.GCP_SERVICE_ACCOUNT_DETAILS }} + # CONNECTOR_PUBLICATION_KEY: ${{ secrets.CONNECTOR_PUBLICATION_KEY }} + # CLOUDINARY_URL: ${{ secrets.CLOUDINARY_URL }} + # run: | + # mv changed_files.json registry-automation/changed_files.json + # cd registry-automation + # go run main.go ci From c90ea86797feead0034896e865760235c4142ecf Mon Sep 17 00:00:00 2001 From: Vishnu Bharathi Date: Wed, 9 Oct 2024 19:06:16 +0530 Subject: [PATCH 122/135] hasura/qdrant: add missing releases (#331) --- .../qdrant/releases/v0.1.7/connector-packaging.json | 11 +++++++++++ .../qdrant/releases/v0.1.9/connector-packaging.json | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 registry/hasura/qdrant/releases/v0.1.7/connector-packaging.json create mode 100644 registry/hasura/qdrant/releases/v0.1.9/connector-packaging.json diff --git a/registry/hasura/qdrant/releases/v0.1.7/connector-packaging.json b/registry/hasura/qdrant/releases/v0.1.7/connector-packaging.json new file mode 100644 index 00000000..6df9f8c6 --- /dev/null +++ b/registry/hasura/qdrant/releases/v0.1.7/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.1.7", + "uri": "https://github.com/hasura/ndc-qdrant/releases/download/v0.1.7/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "6ed4b6252e9f3f91d68deb4195a11b70fe14691b155af792ec91f8aee743b587" + }, + "source": { + "hash": "848a9022df832b4595473f8bae4b3a66564f0bda" + } +} diff --git a/registry/hasura/qdrant/releases/v0.1.9/connector-packaging.json b/registry/hasura/qdrant/releases/v0.1.9/connector-packaging.json new file mode 100644 index 00000000..285b79ea --- /dev/null +++ b/registry/hasura/qdrant/releases/v0.1.9/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.1.9", + "uri": "https://github.com/hasura/ndc-qdrant/releases/download/v0.1.9/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "38a83f9851a6600e23eeda5e2c07f2aba492b6298a7a0c434a70af9d143ec4f4" + }, + "source": { + "hash": "c07dbcfbf00a1c4549eaf2860afad018910c830a" + } +} From e7a41f45d614b5112ec62c710ec02c88d1e45856 Mon Sep 17 00:00:00 2001 From: Vishnu Bharathi Date: Wed, 9 Oct 2024 20:33:48 +0530 Subject: [PATCH 123/135] hasura/go: add missing releases (#333) --- .../go/releases/v0.6.5/connector-packaging.json | 11 +++++++++++ .../go/releases/v1.2.5/connector-packaging.json | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 registry/hasura/go/releases/v0.6.5/connector-packaging.json create mode 100644 registry/hasura/go/releases/v1.2.5/connector-packaging.json diff --git a/registry/hasura/go/releases/v0.6.5/connector-packaging.json b/registry/hasura/go/releases/v0.6.5/connector-packaging.json new file mode 100644 index 00000000..c9074751 --- /dev/null +++ b/registry/hasura/go/releases/v0.6.5/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.6.5", + "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v0.6.5/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "83aa8fb301c562af143c18faaa51d1ba849e960196ff3abe3407275916f6ad71" + }, + "source": { + "hash": "c9e64bdf5972aca5f9c350ff6e6b05eff32af7c9" + } +} diff --git a/registry/hasura/go/releases/v1.2.5/connector-packaging.json b/registry/hasura/go/releases/v1.2.5/connector-packaging.json new file mode 100644 index 00000000..6d6c27ec --- /dev/null +++ b/registry/hasura/go/releases/v1.2.5/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v1.2.5", + "uri": "https://github.com/hasura/ndc-sdk-go/releases/download/v1.2.5/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "06cb73837c36969c0d9249816ff5061854f2eced0ea3f24c7c8b7867e9f5653c" + }, + "source": { + "hash": "53706fbf16bab34ee7a375b8f502016725a4928c" + } +} From 0461f247440b288131200feadac2f1b32a4b2801 Mon Sep 17 00:00:00 2001 From: Vishnu Bharathi Date: Wed, 9 Oct 2024 20:35:15 +0530 Subject: [PATCH 124/135] hasura/python: add missing releases (#335) --- .../python/releases/v0.0.29/connector-packaging.json | 11 +++++++++++ .../python/releases/v0.0.30/connector-packaging.json | 11 +++++++++++ .../python/releases/v0.0.32/connector-packaging.json | 11 +++++++++++ .../python/releases/v0.0.33/connector-packaging.json | 11 +++++++++++ .../python/releases/v0.0.41/connector-packaging.json | 11 +++++++++++ 5 files changed, 55 insertions(+) create mode 100644 registry/hasura/python/releases/v0.0.29/connector-packaging.json create mode 100644 registry/hasura/python/releases/v0.0.30/connector-packaging.json create mode 100644 registry/hasura/python/releases/v0.0.32/connector-packaging.json create mode 100644 registry/hasura/python/releases/v0.0.33/connector-packaging.json create mode 100644 registry/hasura/python/releases/v0.0.41/connector-packaging.json diff --git a/registry/hasura/python/releases/v0.0.29/connector-packaging.json b/registry/hasura/python/releases/v0.0.29/connector-packaging.json new file mode 100644 index 00000000..56708a02 --- /dev/null +++ b/registry/hasura/python/releases/v0.0.29/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.0.29", + "uri": "https://github.com/hasura/ndc-python-lambda/releases/download/v0.0.29/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "913c7f91535ddabc6d49bbfbe4ba3a5f42bc812ae6dc3849419314c772933b28" + }, + "source": { + "hash": "d3257fb98e7e4ed41f7a6482c523c66d03efc374" + } +} diff --git a/registry/hasura/python/releases/v0.0.30/connector-packaging.json b/registry/hasura/python/releases/v0.0.30/connector-packaging.json new file mode 100644 index 00000000..29030db0 --- /dev/null +++ b/registry/hasura/python/releases/v0.0.30/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.0.30", + "uri": "https://github.com/hasura/ndc-python-lambda/releases/download/v0.0.30/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "dbd59f1da60cee002c5fbbd9e48798578aa7fcdf4b65d2fe06d157869837d6df" + }, + "source": { + "hash": "eb1c3d90eea1ff09c04914b60d9254eb85cc489f" + } +} diff --git a/registry/hasura/python/releases/v0.0.32/connector-packaging.json b/registry/hasura/python/releases/v0.0.32/connector-packaging.json new file mode 100644 index 00000000..c8038641 --- /dev/null +++ b/registry/hasura/python/releases/v0.0.32/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.0.32", + "uri": "https://github.com/hasura/ndc-python-lambda/releases/download/v0.0.32/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "18d2c5e1449b3b23499093b4282fe27d6667df20685c1be4deac73daf31fbc1d" + }, + "source": { + "hash": "c65fb03c8f756340cf9b85885ef98bdf1712321b" + } +} diff --git a/registry/hasura/python/releases/v0.0.33/connector-packaging.json b/registry/hasura/python/releases/v0.0.33/connector-packaging.json new file mode 100644 index 00000000..e27afef0 --- /dev/null +++ b/registry/hasura/python/releases/v0.0.33/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.0.33", + "uri": "https://github.com/hasura/ndc-python-lambda/releases/download/v0.0.33/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "11cd4be00dbfa3fa33b4067acb8b8b6086d0f935ead19e823d91ce7e6df7a0fb" + }, + "source": { + "hash": "c8b46112a6ae4da231c07f4edf478cd2c336772e" + } +} diff --git a/registry/hasura/python/releases/v0.0.41/connector-packaging.json b/registry/hasura/python/releases/v0.0.41/connector-packaging.json new file mode 100644 index 00000000..7994b281 --- /dev/null +++ b/registry/hasura/python/releases/v0.0.41/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.0.41", + "uri": "https://github.com/hasura/ndc-python-lambda/releases/download/v0.0.41/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "0e9d93ed0bc48328dc78a7f428308988d09a18acbde64ce94d7c973fc555a07b" + }, + "source": { + "hash": "02344cb606f2a851ecb1545ce894a697bc533e13" + } +} From 64b7f73ace97df5064a9984934a7936d92dd95e3 Mon Sep 17 00:00:00 2001 From: Vishnu Bharathi Date: Wed, 9 Oct 2024 20:36:02 +0530 Subject: [PATCH 125/135] hasura/duckdb: add missing releases (#336) --- .../duckdb/releases/v0.0.9/connector-packaging.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 registry/hasura/duckdb/releases/v0.0.9/connector-packaging.json diff --git a/registry/hasura/duckdb/releases/v0.0.9/connector-packaging.json b/registry/hasura/duckdb/releases/v0.0.9/connector-packaging.json new file mode 100644 index 00000000..120e0e0d --- /dev/null +++ b/registry/hasura/duckdb/releases/v0.0.9/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.0.9", + "uri": "https://github.com/hasura/ndc-duckdb/releases/download/v0.0.9/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "1117ed3274a7cdab4ab61082cf860ad045d242e5e7ffb1ac8f76bb1053e63094" + }, + "source": { + "hash": "5da63b6d05a87529967346b24f80d25bcf16f103" + } +} From 2ea771e708e36b1385c2c252839dbf69c13f48e9 Mon Sep 17 00:00:00 2001 From: Vishnu Bharathi Date: Wed, 9 Oct 2024 20:37:32 +0530 Subject: [PATCH 126/135] hasura/turso: add missing releases (#337) --- .../turso/releases/v0.0.10/connector-packaging.json | 11 +++++++++++ .../turso/releases/v0.0.14/connector-packaging.json | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 registry/hasura/turso/releases/v0.0.10/connector-packaging.json create mode 100644 registry/hasura/turso/releases/v0.0.14/connector-packaging.json diff --git a/registry/hasura/turso/releases/v0.0.10/connector-packaging.json b/registry/hasura/turso/releases/v0.0.10/connector-packaging.json new file mode 100644 index 00000000..0c79ae81 --- /dev/null +++ b/registry/hasura/turso/releases/v0.0.10/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.0.10", + "uri": "https://github.com/hasura/ndc-turso/releases/download/v0.0.10/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "fcf43584074d917905f5c9ed56612a02536cfe9378e09498e55d97bce0ed1545" + }, + "source": { + "hash": "ca77c247f448a15b6821df32d716ec2f7f58fa21" + } +} diff --git a/registry/hasura/turso/releases/v0.0.14/connector-packaging.json b/registry/hasura/turso/releases/v0.0.14/connector-packaging.json new file mode 100644 index 00000000..d0b3cefa --- /dev/null +++ b/registry/hasura/turso/releases/v0.0.14/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.0.14", + "uri": "https://github.com/hasura/ndc-turso/releases/download/v0.0.14/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "8ac58c78f836c89ea97e2bc3dab636c23dbd6976f9183c00cd2d3cd5b99a6efe" + }, + "source": { + "hash": "6087a7aa26fea73421bdbc74fb7820e8ca9c3bf7" + } +} From 409cacd8ef0ec571800693fb46d5ad941bedaaae Mon Sep 17 00:00:00 2001 From: Vishnu Bharathi Date: Wed, 9 Oct 2024 20:38:40 +0530 Subject: [PATCH 127/135] hasura/openapi: add missing releases (#338) --- .../releases/v0.0.2-alpha/connector-packaging.json | 11 +++++++++++ .../openapi/releases/v0.1.0/connector-packaging.json | 11 +++++++++++ .../openapi/releases/v0.1.1/connector-packaging.json | 11 +++++++++++ 3 files changed, 33 insertions(+) create mode 100644 registry/hasura/openapi/releases/v0.0.2-alpha/connector-packaging.json create mode 100644 registry/hasura/openapi/releases/v0.1.0/connector-packaging.json create mode 100644 registry/hasura/openapi/releases/v0.1.1/connector-packaging.json diff --git a/registry/hasura/openapi/releases/v0.0.2-alpha/connector-packaging.json b/registry/hasura/openapi/releases/v0.0.2-alpha/connector-packaging.json new file mode 100644 index 00000000..c2d0b86c --- /dev/null +++ b/registry/hasura/openapi/releases/v0.0.2-alpha/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.0.2-alpha", + "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.0.2-alpha/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "25ec7152d795871e1d2944665ef48012520181afaf6f7c66a030c3a443edbeb3" + }, + "source": { + "hash": "35ba5da05dba1602fea40a3a8fba3652fd1c3e12" + } +} diff --git a/registry/hasura/openapi/releases/v0.1.0/connector-packaging.json b/registry/hasura/openapi/releases/v0.1.0/connector-packaging.json new file mode 100644 index 00000000..7029b11a --- /dev/null +++ b/registry/hasura/openapi/releases/v0.1.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.1.0", + "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "f371014bc0f8a873644bd0127531aa6354b9fca1e5680b12c567c3a3fc4204a5" + }, + "source": { + "hash": "d0c628e9206d397373f42faaf3733f6ada94b56c" + } +} diff --git a/registry/hasura/openapi/releases/v0.1.1/connector-packaging.json b/registry/hasura/openapi/releases/v0.1.1/connector-packaging.json new file mode 100644 index 00000000..e3e02875 --- /dev/null +++ b/registry/hasura/openapi/releases/v0.1.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.1.1", + "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.1.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "a7365a6f7780dcfae85cc787e2de83ea22d416a1d4a9fc597b68227bf978e264" + }, + "source": { + "hash": "4b70712933de7a7ed475407ccd0be7bed1611ae8" + } +} From 005a2ba7b1e83ea209e50d0b00e55c90181d4309 Mon Sep 17 00:00:00 2001 From: Vishnu Bharathi Date: Wed, 9 Oct 2024 20:40:26 +0530 Subject: [PATCH 128/135] hasura/azure-cosmos: add missing releases (#339) --- .../releases/v0.1.7/connector-packaging.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 registry/hasura/azure-cosmos/releases/v0.1.7/connector-packaging.json diff --git a/registry/hasura/azure-cosmos/releases/v0.1.7/connector-packaging.json b/registry/hasura/azure-cosmos/releases/v0.1.7/connector-packaging.json new file mode 100644 index 00000000..21d4a4bc --- /dev/null +++ b/registry/hasura/azure-cosmos/releases/v0.1.7/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.1.7", + "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.1.7/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "7871b676682fc72054166bde70384957bf744f04ed7a8352867cda04fbede904" + }, + "source": { + "hash": "eb6beadf7d6102c647820a8ebb957b6f99b68f59" + } +} From e3b8c091e86ef34e30086b21acc46da3b2bdab13 Mon Sep 17 00:00:00 2001 From: Vishnu Bharathi Date: Wed, 9 Oct 2024 20:41:55 +0530 Subject: [PATCH 129/135] hasura/postgres: add missing releases (#334) --- .../postgres/releases/v0.5.1/connector-packaging.json | 11 +++++++++++ .../postgres/releases/v0.5.2/connector-packaging.json | 11 +++++++++++ .../postgres/releases/v0.6.0/connector-packaging.json | 11 +++++++++++ .../postgres/releases/v0.7.0/connector-packaging.json | 11 +++++++++++ .../postgres/releases/v0.7.1/connector-packaging.json | 11 +++++++++++ .../postgres/releases/v0.8.0/connector-packaging.json | 11 +++++++++++ .../postgres/releases/v1.0.0/connector-packaging.json | 11 +++++++++++ .../postgres/releases/v1.0.1/connector-packaging.json | 11 +++++++++++ .../postgres/releases/v1.1.1/connector-packaging.json | 11 +++++++++++ 9 files changed, 99 insertions(+) create mode 100644 registry/hasura/postgres/releases/v0.5.1/connector-packaging.json create mode 100644 registry/hasura/postgres/releases/v0.5.2/connector-packaging.json create mode 100644 registry/hasura/postgres/releases/v0.6.0/connector-packaging.json create mode 100644 registry/hasura/postgres/releases/v0.7.0/connector-packaging.json create mode 100644 registry/hasura/postgres/releases/v0.7.1/connector-packaging.json create mode 100644 registry/hasura/postgres/releases/v0.8.0/connector-packaging.json create mode 100644 registry/hasura/postgres/releases/v1.0.0/connector-packaging.json create mode 100644 registry/hasura/postgres/releases/v1.0.1/connector-packaging.json create mode 100644 registry/hasura/postgres/releases/v1.1.1/connector-packaging.json diff --git a/registry/hasura/postgres/releases/v0.5.1/connector-packaging.json b/registry/hasura/postgres/releases/v0.5.1/connector-packaging.json new file mode 100644 index 00000000..71869c6d --- /dev/null +++ b/registry/hasura/postgres/releases/v0.5.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.5.1", + "uri": "https://github.com/hasura/ndc-postgres/releases/download/v0.5.1/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "e219c7511e1ba994f3089db6bde5c0fd80a9744d12f04e4a13fdca41cf234433" + }, + "source": { + "hash": "bdb270288188d0e32e564ea369e27da6d73833c5" + } +} diff --git a/registry/hasura/postgres/releases/v0.5.2/connector-packaging.json b/registry/hasura/postgres/releases/v0.5.2/connector-packaging.json new file mode 100644 index 00000000..fd7f4e85 --- /dev/null +++ b/registry/hasura/postgres/releases/v0.5.2/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.5.2", + "uri": "https://github.com/hasura/ndc-postgres/releases/download/v0.5.2/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "e577b0f90d4611f293064478ddc647f9a14004307852efa6a87973622889faad" + }, + "source": { + "hash": "805bc53209b9c8f7ca184b5a76bf86da5f47a1a3" + } +} diff --git a/registry/hasura/postgres/releases/v0.6.0/connector-packaging.json b/registry/hasura/postgres/releases/v0.6.0/connector-packaging.json new file mode 100644 index 00000000..33e89824 --- /dev/null +++ b/registry/hasura/postgres/releases/v0.6.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.6.0", + "uri": "https://github.com/hasura/ndc-postgres/releases/download/v0.6.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "49b491928898f5ed251ea67dccb4eeca99fbdcc0855ce6331d7e5cb2a2cf339e" + }, + "source": { + "hash": "582c771c06b0ee5b4a5541ebc75dd483a6376c48" + } +} diff --git a/registry/hasura/postgres/releases/v0.7.0/connector-packaging.json b/registry/hasura/postgres/releases/v0.7.0/connector-packaging.json new file mode 100644 index 00000000..960f98e7 --- /dev/null +++ b/registry/hasura/postgres/releases/v0.7.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.7.0", + "uri": "https://github.com/hasura/ndc-postgres/releases/download/v0.7.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "ca0ff962cd836c4cb19ad89590896c02e9538b5b6fabc99f93b96b5db9ddd988" + }, + "source": { + "hash": "0c6fbadcaceb08791fe98f3e68294c739decfbec" + } +} diff --git a/registry/hasura/postgres/releases/v0.7.1/connector-packaging.json b/registry/hasura/postgres/releases/v0.7.1/connector-packaging.json new file mode 100644 index 00000000..d9e124c2 --- /dev/null +++ b/registry/hasura/postgres/releases/v0.7.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.7.1", + "uri": "https://github.com/hasura/ndc-postgres/releases/download/v0.7.1/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "881fe5d046665d16eeb11410813335b0f3fc54ea6f948a7b5683fdc8eceeb281" + }, + "source": { + "hash": "53565d6b4d342f98eed5cb2a91bebac745aa1d13" + } +} diff --git a/registry/hasura/postgres/releases/v0.8.0/connector-packaging.json b/registry/hasura/postgres/releases/v0.8.0/connector-packaging.json new file mode 100644 index 00000000..f1c698ee --- /dev/null +++ b/registry/hasura/postgres/releases/v0.8.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.8.0", + "uri": "https://github.com/hasura/ndc-postgres/releases/download/v0.8.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "828dcbc1c1951c6dd4324cbaf41410076507094be88e278b8710aaccbf87af32" + }, + "source": { + "hash": "45131122d3f153cfee3df1e1b8077dd21a37e386" + } +} diff --git a/registry/hasura/postgres/releases/v1.0.0/connector-packaging.json b/registry/hasura/postgres/releases/v1.0.0/connector-packaging.json new file mode 100644 index 00000000..0b279c87 --- /dev/null +++ b/registry/hasura/postgres/releases/v1.0.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v1.0.0", + "uri": "https://github.com/hasura/ndc-postgres/releases/download/v1.0.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "e9d4b11b29f5bc721b3cd596cdfcf4de7e8463c5510ea104b673215e876a9139" + }, + "source": { + "hash": "4af168d5638545f0e5c9e864ad4b4b28b7e860eb" + } +} diff --git a/registry/hasura/postgres/releases/v1.0.1/connector-packaging.json b/registry/hasura/postgres/releases/v1.0.1/connector-packaging.json new file mode 100644 index 00000000..92e04f7c --- /dev/null +++ b/registry/hasura/postgres/releases/v1.0.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v1.0.1", + "uri": "https://github.com/hasura/ndc-postgres/releases/download/v1.0.1/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "c88e3199aa42b5a758941b0d0c6ed98396b7a1be3076c25daacd1ad7d92aa8f5" + }, + "source": { + "hash": "e2fd65143411400ec612a20100e7ed3a7ed8f298" + } +} diff --git a/registry/hasura/postgres/releases/v1.1.1/connector-packaging.json b/registry/hasura/postgres/releases/v1.1.1/connector-packaging.json new file mode 100644 index 00000000..d8025f12 --- /dev/null +++ b/registry/hasura/postgres/releases/v1.1.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v1.1.1", + "uri": "https://github.com/hasura/ndc-postgres/releases/download/v1.1.1/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "bb03bd400417e61884f2f7bafe5054b24a1377adcd22e749e4e3d0cc3b3d70bf" + }, + "source": { + "hash": "fc6a7a742a0adb3b2923316e678003322fbd821b" + } +} From ec3d3605b3afb91b72f0318d957227a91369a0fe Mon Sep 17 00:00:00 2001 From: Vishnu Bharathi Date: Wed, 9 Oct 2024 21:19:26 +0530 Subject: [PATCH 130/135] fix: add missing version prefix (#340) --- .../releases/v0.1.2/connector-packaging.json | 20 +++++++++---------- .../releases/v0.1.3/connector-packaging.json | 20 +++++++++---------- .../releases/v0.1.6/connector-packaging.json | 20 +++++++++---------- .../releases/v0.2.0/connector-packaging.json | 20 +++++++++---------- .../releases/v0.1.1/connector-packaging.json | 4 ++-- .../releases/v0.2.1/connector-packaging.json | 2 +- .../releases/v0.2.10/connector-packaging.json | 2 +- .../releases/v0.2.11/connector-packaging.json | 2 +- .../releases/v0.2.2/connector-packaging.json | 2 +- .../releases/v0.2.3/connector-packaging.json | 2 +- .../releases/v0.2.4/connector-packaging.json | 2 +- .../releases/v0.2.5/connector-packaging.json | 2 +- .../releases/v0.2.6/connector-packaging.json | 2 +- .../releases/v0.2.7/connector-packaging.json | 2 +- .../releases/v0.2.8/connector-packaging.json | 2 +- .../releases/v0.2.9/connector-packaging.json | 2 +- .../releases/v1.0.0/connector-packaging.json | 2 +- .../releases/v1.0.1/connector-packaging.json | 2 +- .../releases/v1.0.2/connector-packaging.json | 2 +- .../releases/v1.0.3/connector-packaging.json | 2 +- .../releases/v1.0.4/connector-packaging.json | 2 +- .../releases/v0.0.17/connector-packaging.json | 19 +++++++++--------- .../releases/v0.1.0/connector-packaging.json | 4 ++-- .../releases/v0.1.0/connector-packaging.json | 4 ++-- .../releases/v0.1.1/connector-packaging.json | 4 ++-- .../releases/v0.2.0/connector-packaging.json | 4 ++-- .../releases/v1.0.0/connector-packaging.json | 4 ++-- .../releases/v1.0.1/connector-packaging.json | 4 ++-- .../releases/v1.0.2/connector-packaging.json | 4 ++-- .../releases/v1.0.3/connector-packaging.json | 4 ++-- .../releases/v0.1.0/connector-packaging.json | 2 +- .../releases/v0.1.1/connector-packaging.json | 2 +- .../releases/v0.1.2/connector-packaging.json | 2 +- .../releases/v0.1.3/connector-packaging.json | 2 +- .../releases/v0.2.0/connector-packaging.json | 2 +- .../releases/v0.0.1/connector-packaging.json | 2 +- .../releases/v0.0.2/connector-packaging.json | 2 +- .../releases/v0.0.3/connector-packaging.json | 4 ++-- .../releases/v0.0.4/connector-packaging.json | 2 +- .../releases/v0.0.5/connector-packaging.json | 2 +- .../releases/v0.0.6/connector-packaging.json | 2 +- .../releases/v0.1.0/connector-packaging.json | 2 +- .../releases/v1.0.0/connector-packaging.json | 2 +- .../releases/v1.1.0/connector-packaging.json | 2 +- .../releases/v1.2.0/connector-packaging.json | 4 ++-- .../releases/v1.3.0/connector-packaging.json | 4 ++-- .../releases/v0.1.0/connector-packaging.json | 20 +++++++++---------- .../releases/v1.0.1/connector-packaging.json | 20 +++++++++---------- .../releases/v1.0.2/connector-packaging.json | 20 +++++++++---------- .../releases/v1.0.0/connector-packaging.json | 4 ++-- .../releases/v1.1.0/connector-packaging.json | 4 ++-- .../releases/v1.2.0/connector-packaging.json | 4 ++-- .../releases/v1.3.0/connector-packaging.json | 4 ++-- .../releases/v1.4.0/connector-packaging.json | 4 ++-- .../releases/v1.4.1/connector-packaging.json | 4 ++-- .../releases/v1.5.0/connector-packaging.json | 4 ++-- .../releases/v1.6.0/connector-packaging.json | 4 ++-- .../releases/v1.7.0/connector-packaging.json | 4 ++-- .../releases/v1.8.0/connector-packaging.json | 4 ++-- .../releases/v0.1.2/connector-packaging.json | 4 ++-- .../releases/v0.1.3/connector-packaging.json | 4 ++-- .../releases/v0.1.4/connector-packaging.json | 4 ++-- .../releases/v0.1.5/connector-packaging.json | 4 ++-- .../releases/v0.2.0/connector-packaging.json | 19 +++++++++--------- .../releases/v0.1.0/connector-packaging.json | 20 +++++++++---------- .../releases/v1.0.1/connector-packaging.json | 20 +++++++++---------- .../releases/v1.0.2/connector-packaging.json | 20 +++++++++---------- .../releases/v1.0.0/connector-packaging.json | 20 +++++++++---------- .../releases/v1.0.2/connector-packaging.json | 4 ++-- .../releases/v1.1.0/connector-packaging.json | 4 ++-- .../releases/v0.0.45/connector-packaging.json | 18 ++++++++--------- .../releases/v0.1.0/connector-packaging.json | 18 ++++++++--------- .../releases/v0.2.1/connector-packaging.json | 19 +++++++++--------- .../releases/v0.3.0/connector-packaging.json | 4 ++-- .../releases/v0.0.1/connector-packaging.json | 18 ++++++++--------- .../releases/v0.0.2/connector-packaging.json | 4 ++-- .../releases/v0.0.3/connector-packaging.json | 4 ++-- .../releases/v0.0.4/connector-packaging.json | 4 ++-- .../releases/v0.1.0/connector-packaging.json | 4 ++-- .../releases/v1.0.1/connector-packaging.json | 4 ++-- .../releases/v0.1.0/connector-packaging.json | 4 ++-- .../releases/v0.1.1/connector-packaging.json | 4 ++-- .../releases/v0.1.2/connector-packaging.json | 4 ++-- .../releases/v0.2.0/connector-packaging.json | 20 +++++++++---------- .../releases/v0.2.1/connector-packaging.json | 20 +++++++++---------- .../releases/v0.2.2/connector-packaging.json | 20 +++++++++---------- .../releases/v0.0.15/connector-packaging.json | 19 +++++++++--------- .../releases/v0.1.0/connector-packaging.json | 4 ++-- 88 files changed, 308 insertions(+), 312 deletions(-) diff --git a/registry/hasura/azure-cosmos/releases/v0.1.2/connector-packaging.json b/registry/hasura/azure-cosmos/releases/v0.1.2/connector-packaging.json index 4feb205e..d60eb2e7 100644 --- a/registry/hasura/azure-cosmos/releases/v0.1.2/connector-packaging.json +++ b/registry/hasura/azure-cosmos/releases/v0.1.2/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "0.1.2", - "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.1.2/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "09ce246a9039d2aaf799a7e0402b243fb3763ba802535348a9fee243de1bf1b7" - }, - "source": { - "hash": "f67b2f80d64175a055a9489d4e59f30d5d3870a0" - } -} + "version": "v0.1.2", + "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.1.2/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "09ce246a9039d2aaf799a7e0402b243fb3763ba802535348a9fee243de1bf1b7" + }, + "source": { + "hash": "f67b2f80d64175a055a9489d4e59f30d5d3870a0" + } +} \ No newline at end of file diff --git a/registry/hasura/azure-cosmos/releases/v0.1.3/connector-packaging.json b/registry/hasura/azure-cosmos/releases/v0.1.3/connector-packaging.json index 3d4242c9..3a268c01 100644 --- a/registry/hasura/azure-cosmos/releases/v0.1.3/connector-packaging.json +++ b/registry/hasura/azure-cosmos/releases/v0.1.3/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "0.1.3", - "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.1.3/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "34655ff615be0d5738ffe1811972776808e9880a6fa3ec673123844c648154d7" - }, - "source": { - "hash": "97032d1a41fd932d637b5ba24ca6611d9e1f4905" - } -} + "version": "v0.1.3", + "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.1.3/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "34655ff615be0d5738ffe1811972776808e9880a6fa3ec673123844c648154d7" + }, + "source": { + "hash": "97032d1a41fd932d637b5ba24ca6611d9e1f4905" + } +} \ No newline at end of file diff --git a/registry/hasura/azure-cosmos/releases/v0.1.6/connector-packaging.json b/registry/hasura/azure-cosmos/releases/v0.1.6/connector-packaging.json index 3b23bbb9..6b00fbfc 100644 --- a/registry/hasura/azure-cosmos/releases/v0.1.6/connector-packaging.json +++ b/registry/hasura/azure-cosmos/releases/v0.1.6/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "0.1.6", - "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.1.6/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "c95285f38d38b213c1163ce60be87d868645d065c36ed4bac6b99ed89f5e5184" - }, - "source": { - "hash": "eb6beadf7d6102c647820a8ebb957b6f99b68f59" - } -} + "version": "v0.1.6", + "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.1.6/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "c95285f38d38b213c1163ce60be87d868645d065c36ed4bac6b99ed89f5e5184" + }, + "source": { + "hash": "eb6beadf7d6102c647820a8ebb957b6f99b68f59" + } +} \ No newline at end of file diff --git a/registry/hasura/azure-cosmos/releases/v0.2.0/connector-packaging.json b/registry/hasura/azure-cosmos/releases/v0.2.0/connector-packaging.json index 0e557006..5819d034 100644 --- a/registry/hasura/azure-cosmos/releases/v0.2.0/connector-packaging.json +++ b/registry/hasura/azure-cosmos/releases/v0.2.0/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "0.2.0", - "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.2.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "4457e122a608f055fae0cc312b6850c0213ddbbfbce1b0af8356b5c00f2f322f" - }, - "source": { - "hash": "5478d2a3b282d7a61961a8de8f7df3ebbb29c5c4" - } -} + "version": "v0.2.0", + "uri": "https://github.com/hasura/ndc-azure-cosmos-connector/releases/download/v0.2.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "4457e122a608f055fae0cc312b6850c0213ddbbfbce1b0af8356b5c00f2f322f" + }, + "source": { + "hash": "5478d2a3b282d7a61961a8de8f7df3ebbb29c5c4" + } +} \ No newline at end of file diff --git a/registry/hasura/bigquery/releases/v0.1.1/connector-packaging.json b/registry/hasura/bigquery/releases/v0.1.1/connector-packaging.json index c92ea036..e29a4a6d 100644 --- a/registry/hasura/bigquery/releases/v0.1.1/connector-packaging.json +++ b/registry/hasura/bigquery/releases/v0.1.1/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.1", + "version": "v0.1.1", "uri": "https://github.com/hasura/ndc-bigquery/releases/download/v0.1.1/package.tar.gz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "10ac176c590840971354a611c156aef6bc9915c4" } -} +} \ No newline at end of file diff --git a/registry/hasura/clickhouse/releases/v0.2.1/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.1/connector-packaging.json index ca4da984..4b2af140 100644 --- a/registry/hasura/clickhouse/releases/v0.2.1/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v0.2.1/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.2.1", + "version": "v0.2.1", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.1/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/clickhouse/releases/v0.2.10/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.10/connector-packaging.json index 4588d858..7c6cddfa 100644 --- a/registry/hasura/clickhouse/releases/v0.2.10/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v0.2.10/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.2.10", + "version": "v0.2.10", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.10/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/clickhouse/releases/v0.2.11/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.11/connector-packaging.json index 4df2fe21..98affcb8 100644 --- a/registry/hasura/clickhouse/releases/v0.2.11/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v0.2.11/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.2.11", + "version": "v0.2.11", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.11/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/clickhouse/releases/v0.2.2/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.2/connector-packaging.json index da7f9a11..c4c74542 100644 --- a/registry/hasura/clickhouse/releases/v0.2.2/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v0.2.2/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.2.2", + "version": "v0.2.2", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.2/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/clickhouse/releases/v0.2.3/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.3/connector-packaging.json index c321dba6..e8c0c7b1 100644 --- a/registry/hasura/clickhouse/releases/v0.2.3/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v0.2.3/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.2.3", + "version": "v0.2.3", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.3/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/clickhouse/releases/v0.2.4/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.4/connector-packaging.json index 758f847d..e71969cf 100644 --- a/registry/hasura/clickhouse/releases/v0.2.4/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v0.2.4/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.2.4", + "version": "v0.2.4", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.4/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/clickhouse/releases/v0.2.5/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.5/connector-packaging.json index 2cdea3c6..85909a0a 100644 --- a/registry/hasura/clickhouse/releases/v0.2.5/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v0.2.5/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.2.5", + "version": "v0.2.5", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.5/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/clickhouse/releases/v0.2.6/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.6/connector-packaging.json index 29ab3b91..69684a34 100644 --- a/registry/hasura/clickhouse/releases/v0.2.6/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v0.2.6/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.2.6", + "version": "v0.2.6", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.6/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/clickhouse/releases/v0.2.7/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.7/connector-packaging.json index fa17cc7c..c1513463 100644 --- a/registry/hasura/clickhouse/releases/v0.2.7/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v0.2.7/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.2.7", + "version": "v0.2.7", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.7/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/clickhouse/releases/v0.2.8/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.8/connector-packaging.json index ceb0ce8f..66c3d5bb 100644 --- a/registry/hasura/clickhouse/releases/v0.2.8/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v0.2.8/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.2.8", + "version": "v0.2.8", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.8/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/clickhouse/releases/v0.2.9/connector-packaging.json b/registry/hasura/clickhouse/releases/v0.2.9/connector-packaging.json index fd1946e1..f89da44f 100644 --- a/registry/hasura/clickhouse/releases/v0.2.9/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v0.2.9/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.2.9", + "version": "v0.2.9", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v0.2.9/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/clickhouse/releases/v1.0.0/connector-packaging.json b/registry/hasura/clickhouse/releases/v1.0.0/connector-packaging.json index 56f19e77..dbfbd5ac 100644 --- a/registry/hasura/clickhouse/releases/v1.0.0/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v1.0.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.0.0", + "version": "v1.0.0", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v1.0.0/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/clickhouse/releases/v1.0.1/connector-packaging.json b/registry/hasura/clickhouse/releases/v1.0.1/connector-packaging.json index ea1d3a58..2e0fe051 100644 --- a/registry/hasura/clickhouse/releases/v1.0.1/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v1.0.1/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.0.1", + "version": "v1.0.1", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v1.0.1/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/clickhouse/releases/v1.0.2/connector-packaging.json b/registry/hasura/clickhouse/releases/v1.0.2/connector-packaging.json index 492c2f09..30627125 100644 --- a/registry/hasura/clickhouse/releases/v1.0.2/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v1.0.2/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.0.2", + "version": "v1.0.2", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v1.0.2/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/clickhouse/releases/v1.0.3/connector-packaging.json b/registry/hasura/clickhouse/releases/v1.0.3/connector-packaging.json index 97cd7953..6be655ac 100644 --- a/registry/hasura/clickhouse/releases/v1.0.3/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v1.0.3/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.0.3", + "version": "v1.0.3", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v1.0.3/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/clickhouse/releases/v1.0.4/connector-packaging.json b/registry/hasura/clickhouse/releases/v1.0.4/connector-packaging.json index 639787d0..b9178453 100644 --- a/registry/hasura/clickhouse/releases/v1.0.4/connector-packaging.json +++ b/registry/hasura/clickhouse/releases/v1.0.4/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.0.4", + "version": "v1.0.4", "uri": "https://github.com/hasura/ndc-clickhouse/releases/download/v1.0.4/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/duckdb/releases/v0.0.17/connector-packaging.json b/registry/hasura/duckdb/releases/v0.0.17/connector-packaging.json index 1665ecbf..001fa1af 100644 --- a/registry/hasura/duckdb/releases/v0.0.17/connector-packaging.json +++ b/registry/hasura/duckdb/releases/v0.0.17/connector-packaging.json @@ -1,12 +1,11 @@ { - "version": "0.0.17", - "uri": "https://github.com/hasura/ndc-duckdb/releases/download/v0.0.17/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "3449766fff1794f0866f19505355b37d151d91682e1f784aef664b91abd57570" - }, - "source": { - "hash": "875c5fb4539febea0e5dad569fd8b64557870c1c" - } + "version": "v0.0.17", + "uri": "https://github.com/hasura/ndc-duckdb/releases/download/v0.0.17/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "3449766fff1794f0866f19505355b37d151d91682e1f784aef664b91abd57570" + }, + "source": { + "hash": "875c5fb4539febea0e5dad569fd8b64557870c1c" } - \ No newline at end of file +} \ No newline at end of file diff --git a/registry/hasura/duckdb/releases/v0.1.0/connector-packaging.json b/registry/hasura/duckdb/releases/v0.1.0/connector-packaging.json index 60793934..117716c7 100644 --- a/registry/hasura/duckdb/releases/v0.1.0/connector-packaging.json +++ b/registry/hasura/duckdb/releases/v0.1.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.0", + "version": "v0.1.0", "uri": "https://github.com/hasura/ndc-duckdb/releases/download/v0.1.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "580d059cf6250da21e7fdb9bcfc78f6803c626f5" } -} +} \ No newline at end of file diff --git a/registry/hasura/elasticsearch/releases/v0.1.0/connector-packaging.json b/registry/hasura/elasticsearch/releases/v0.1.0/connector-packaging.json index e0a3d864..32c4dfcf 100644 --- a/registry/hasura/elasticsearch/releases/v0.1.0/connector-packaging.json +++ b/registry/hasura/elasticsearch/releases/v0.1.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.0", + "version": "v0.1.0", "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v0.1.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "4c6fabedaf3a28cdd6c55a18a37e1db974a83262" } -} +} \ No newline at end of file diff --git a/registry/hasura/elasticsearch/releases/v0.1.1/connector-packaging.json b/registry/hasura/elasticsearch/releases/v0.1.1/connector-packaging.json index 000cd437..601a6f3e 100644 --- a/registry/hasura/elasticsearch/releases/v0.1.1/connector-packaging.json +++ b/registry/hasura/elasticsearch/releases/v0.1.1/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.1", + "version": "v0.1.1", "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v0.1.1/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "413a2a4ddfd1910757c40c38e9a18148bc3b3bdc" } -} +} \ No newline at end of file diff --git a/registry/hasura/elasticsearch/releases/v0.2.0/connector-packaging.json b/registry/hasura/elasticsearch/releases/v0.2.0/connector-packaging.json index d794b284..03fddc85 100644 --- a/registry/hasura/elasticsearch/releases/v0.2.0/connector-packaging.json +++ b/registry/hasura/elasticsearch/releases/v0.2.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.2.0", + "version": "v0.2.0", "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v0.2.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "f5938f8c76829de7f16cf291c95a06f590b16d9a" } -} +} \ No newline at end of file diff --git a/registry/hasura/elasticsearch/releases/v1.0.0/connector-packaging.json b/registry/hasura/elasticsearch/releases/v1.0.0/connector-packaging.json index adf38221..915b6fd6 100644 --- a/registry/hasura/elasticsearch/releases/v1.0.0/connector-packaging.json +++ b/registry/hasura/elasticsearch/releases/v1.0.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.0.0", + "version": "v1.0.0", "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v1.0.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "9f1f508f551b4a9dec02c49e3312f38c24bb16c4" } -} +} \ No newline at end of file diff --git a/registry/hasura/elasticsearch/releases/v1.0.1/connector-packaging.json b/registry/hasura/elasticsearch/releases/v1.0.1/connector-packaging.json index 79c1cbd2..9e59d405 100644 --- a/registry/hasura/elasticsearch/releases/v1.0.1/connector-packaging.json +++ b/registry/hasura/elasticsearch/releases/v1.0.1/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.0.1", + "version": "v1.0.1", "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v1.0.1/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "72fad205f57e88781da6acafe1e03a7d220467c7" } -} +} \ No newline at end of file diff --git a/registry/hasura/elasticsearch/releases/v1.0.2/connector-packaging.json b/registry/hasura/elasticsearch/releases/v1.0.2/connector-packaging.json index e907f61f..b9a1987a 100644 --- a/registry/hasura/elasticsearch/releases/v1.0.2/connector-packaging.json +++ b/registry/hasura/elasticsearch/releases/v1.0.2/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.0.2", + "version": "v1.0.2", "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v1.0.2/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "19c1dfbce44db9fb9a71e9ca68c93de2d5fade6c" } -} +} \ No newline at end of file diff --git a/registry/hasura/elasticsearch/releases/v1.0.3/connector-packaging.json b/registry/hasura/elasticsearch/releases/v1.0.3/connector-packaging.json index 9044dc58..832d6b92 100644 --- a/registry/hasura/elasticsearch/releases/v1.0.3/connector-packaging.json +++ b/registry/hasura/elasticsearch/releases/v1.0.3/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.0.3", + "version": "v1.0.3", "uri": "https://github.com/hasura/ndc-elasticsearch/releases/download/v1.0.3/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "4993fed05687b9464c64d44140cd801471ef32b9" } -} +} \ No newline at end of file diff --git a/registry/hasura/graphql/releases/v0.1.0/connector-packaging.json b/registry/hasura/graphql/releases/v0.1.0/connector-packaging.json index f3bebe33..7ccd6462 100644 --- a/registry/hasura/graphql/releases/v0.1.0/connector-packaging.json +++ b/registry/hasura/graphql/releases/v0.1.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.0", + "version": "v0.1.0", "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.0/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/graphql/releases/v0.1.1/connector-packaging.json b/registry/hasura/graphql/releases/v0.1.1/connector-packaging.json index 8e7f0769..ed5c99c4 100644 --- a/registry/hasura/graphql/releases/v0.1.1/connector-packaging.json +++ b/registry/hasura/graphql/releases/v0.1.1/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.1", + "version": "v0.1.1", "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.1/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/graphql/releases/v0.1.2/connector-packaging.json b/registry/hasura/graphql/releases/v0.1.2/connector-packaging.json index ffea7300..2b0e2fa3 100644 --- a/registry/hasura/graphql/releases/v0.1.2/connector-packaging.json +++ b/registry/hasura/graphql/releases/v0.1.2/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.2", + "version": "v0.1.2", "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.2/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/graphql/releases/v0.1.3/connector-packaging.json b/registry/hasura/graphql/releases/v0.1.3/connector-packaging.json index 37aee93b..93e7fea1 100644 --- a/registry/hasura/graphql/releases/v0.1.3/connector-packaging.json +++ b/registry/hasura/graphql/releases/v0.1.3/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.3", + "version": "v0.1.3", "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.1.3/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/graphql/releases/v0.2.0/connector-packaging.json b/registry/hasura/graphql/releases/v0.2.0/connector-packaging.json index adbb3f88..cab549d5 100644 --- a/registry/hasura/graphql/releases/v0.2.0/connector-packaging.json +++ b/registry/hasura/graphql/releases/v0.2.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.2.0", + "version": "v0.2.0", "uri": "https://github.com/hasura/ndc-graphql/releases/download/v0.2.0/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/mongodb/releases/v0.0.1/connector-packaging.json b/registry/hasura/mongodb/releases/v0.0.1/connector-packaging.json index 68e8ce45..f5136044 100644 --- a/registry/hasura/mongodb/releases/v0.0.1/connector-packaging.json +++ b/registry/hasura/mongodb/releases/v0.0.1/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.0.1", + "version": "v0.0.1", "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.1/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/mongodb/releases/v0.0.2/connector-packaging.json b/registry/hasura/mongodb/releases/v0.0.2/connector-packaging.json index 9b5acaed..c977f037 100644 --- a/registry/hasura/mongodb/releases/v0.0.2/connector-packaging.json +++ b/registry/hasura/mongodb/releases/v0.0.2/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.0.2", + "version": "v0.0.2", "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.2/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/mongodb/releases/v0.0.3/connector-packaging.json b/registry/hasura/mongodb/releases/v0.0.3/connector-packaging.json index 2e40d789..123edb61 100644 --- a/registry/hasura/mongodb/releases/v0.0.3/connector-packaging.json +++ b/registry/hasura/mongodb/releases/v0.0.3/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.0.3", + "version": "v0.0.3", "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.3/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "b50094a368f8fbab7c37e4b83ef5dc1249a4a5d5" } -} +} \ No newline at end of file diff --git a/registry/hasura/mongodb/releases/v0.0.4/connector-packaging.json b/registry/hasura/mongodb/releases/v0.0.4/connector-packaging.json index 32d838ee..193e0111 100644 --- a/registry/hasura/mongodb/releases/v0.0.4/connector-packaging.json +++ b/registry/hasura/mongodb/releases/v0.0.4/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.0.4", + "version": "v0.0.4", "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.4/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/mongodb/releases/v0.0.5/connector-packaging.json b/registry/hasura/mongodb/releases/v0.0.5/connector-packaging.json index c5804ba4..c42cbeb7 100644 --- a/registry/hasura/mongodb/releases/v0.0.5/connector-packaging.json +++ b/registry/hasura/mongodb/releases/v0.0.5/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.0.5", + "version": "v0.0.5", "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.5/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/mongodb/releases/v0.0.6/connector-packaging.json b/registry/hasura/mongodb/releases/v0.0.6/connector-packaging.json index f7915551..a3bcfd00 100644 --- a/registry/hasura/mongodb/releases/v0.0.6/connector-packaging.json +++ b/registry/hasura/mongodb/releases/v0.0.6/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.0.6", + "version": "v0.0.6", "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.0.6/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/mongodb/releases/v0.1.0/connector-packaging.json b/registry/hasura/mongodb/releases/v0.1.0/connector-packaging.json index 899794ce..acfe5550 100644 --- a/registry/hasura/mongodb/releases/v0.1.0/connector-packaging.json +++ b/registry/hasura/mongodb/releases/v0.1.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.0", + "version": "v0.1.0", "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v0.1.0/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/mongodb/releases/v1.0.0/connector-packaging.json b/registry/hasura/mongodb/releases/v1.0.0/connector-packaging.json index 4e4ab11c..3824bbef 100644 --- a/registry/hasura/mongodb/releases/v1.0.0/connector-packaging.json +++ b/registry/hasura/mongodb/releases/v1.0.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.0.0", + "version": "v1.0.0", "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v1.0.0/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/mongodb/releases/v1.1.0/connector-packaging.json b/registry/hasura/mongodb/releases/v1.1.0/connector-packaging.json index 047f7ec3..6d1a9268 100644 --- a/registry/hasura/mongodb/releases/v1.1.0/connector-packaging.json +++ b/registry/hasura/mongodb/releases/v1.1.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.1.0", + "version": "v1.1.0", "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v1.1.0/connector-definition.tgz", "checksum": { "type": "sha256", diff --git a/registry/hasura/mongodb/releases/v1.2.0/connector-packaging.json b/registry/hasura/mongodb/releases/v1.2.0/connector-packaging.json index 28c279f4..0425d36b 100644 --- a/registry/hasura/mongodb/releases/v1.2.0/connector-packaging.json +++ b/registry/hasura/mongodb/releases/v1.2.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.2.0", + "version": "v1.2.0", "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v1.2.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "2e0696e8bd587c18f067e683ec367f6ba350537f" } -} +} \ No newline at end of file diff --git a/registry/hasura/mongodb/releases/v1.3.0/connector-packaging.json b/registry/hasura/mongodb/releases/v1.3.0/connector-packaging.json index 4dd4d385..4cd462ed 100644 --- a/registry/hasura/mongodb/releases/v1.3.0/connector-packaging.json +++ b/registry/hasura/mongodb/releases/v1.3.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.3.0", + "version": "v1.3.0", "uri": "https://github.com/hasura/ndc-mongodb/releases/download/v1.3.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "47fc3c301203d0118940a317e7c634e768b8898a" } -} +} \ No newline at end of file diff --git a/registry/hasura/mysql/releases/v0.1.0/connector-packaging.json b/registry/hasura/mysql/releases/v0.1.0/connector-packaging.json index 3c76e1fe..1901a5e4 100644 --- a/registry/hasura/mysql/releases/v0.1.0/connector-packaging.json +++ b/registry/hasura/mysql/releases/v0.1.0/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "0.1.0", - "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/mysql%2Fv0.1.0/package.tar.gz", - "checksum": { - "type": "sha256", - "value": "9807b4467dae194f558af17970cb3ba4f7faf4f3a0c14f2a114a7296498cf025" - }, - "source": { - "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" - } -} + "version": "v0.1.0", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/mysql%2Fv0.1.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "9807b4467dae194f558af17970cb3ba4f7faf4f3a0c14f2a114a7296498cf025" + }, + "source": { + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" + } +} \ No newline at end of file diff --git a/registry/hasura/mysql/releases/v1.0.1/connector-packaging.json b/registry/hasura/mysql/releases/v1.0.1/connector-packaging.json index b4b7a4fc..df47ea20 100644 --- a/registry/hasura/mysql/releases/v1.0.1/connector-packaging.json +++ b/registry/hasura/mysql/releases/v1.0.1/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "1.0.1", - "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/mysql%2Fv1.0.1/package.tar.gz", - "checksum": { - "type": "sha256", - "value": "4503cb8961e3c2c8aede3183187fb69862ac1442a89085d35cf1d4a4989d6db9" - }, - "source": { - "hash": "fbeb926e1d5550bec78a042a36d5ac2a8fba4c9f" - } -} + "version": "v1.0.1", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/mysql%2Fv1.0.1/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "4503cb8961e3c2c8aede3183187fb69862ac1442a89085d35cf1d4a4989d6db9" + }, + "source": { + "hash": "fbeb926e1d5550bec78a042a36d5ac2a8fba4c9f" + } +} \ No newline at end of file diff --git a/registry/hasura/mysql/releases/v1.0.2/connector-packaging.json b/registry/hasura/mysql/releases/v1.0.2/connector-packaging.json index 5d6f1b75..4f3e2972 100644 --- a/registry/hasura/mysql/releases/v1.0.2/connector-packaging.json +++ b/registry/hasura/mysql/releases/v1.0.2/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "1.0.2", - "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/mysql%2Fv1.0.2/package.tar.gz", - "checksum": { - "type": "sha256", - "value": "86be6695432bef7cfcdccfc376c18f3c89ffefe6d139869ab4739709dd980141" - }, - "source": { - "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" - } -} + "version": "v1.0.2", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/mysql%2Fv1.0.2/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "86be6695432bef7cfcdccfc376c18f3c89ffefe6d139869ab4739709dd980141" + }, + "source": { + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" + } +} \ No newline at end of file diff --git a/registry/hasura/nodejs/releases/v1.0.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.0.0/connector-packaging.json index c8428361..001fa49c 100644 --- a/registry/hasura/nodejs/releases/v1.0.0/connector-packaging.json +++ b/registry/hasura/nodejs/releases/v1.0.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.0.0", + "version": "v1.0.0", "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.0.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "c7ef1aa899e1f83cc2935c2f91f4b9010411d716" } -} +} \ No newline at end of file diff --git a/registry/hasura/nodejs/releases/v1.1.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.1.0/connector-packaging.json index 96db88f4..1d960db1 100644 --- a/registry/hasura/nodejs/releases/v1.1.0/connector-packaging.json +++ b/registry/hasura/nodejs/releases/v1.1.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.1.0", + "version": "v1.1.0", "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.1.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "32e33529d5cfc5c1dbc4245e384f22099654d02d" } -} +} \ No newline at end of file diff --git a/registry/hasura/nodejs/releases/v1.2.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.2.0/connector-packaging.json index 2e946362..1e523cef 100644 --- a/registry/hasura/nodejs/releases/v1.2.0/connector-packaging.json +++ b/registry/hasura/nodejs/releases/v1.2.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.2.0", + "version": "v1.2.0", "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.2.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "a13236051b836e4506463ff8c7e152f69c787680" } -} +} \ No newline at end of file diff --git a/registry/hasura/nodejs/releases/v1.3.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.3.0/connector-packaging.json index 4ec46b4d..e9ea8aed 100644 --- a/registry/hasura/nodejs/releases/v1.3.0/connector-packaging.json +++ b/registry/hasura/nodejs/releases/v1.3.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.3.0", + "version": "v1.3.0", "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.3.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "faf8cc78db442e53ca0cf6cdf79c9feb0cfc8052" } -} +} \ No newline at end of file diff --git a/registry/hasura/nodejs/releases/v1.4.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.4.0/connector-packaging.json index 9a4923fd..c2286e5a 100644 --- a/registry/hasura/nodejs/releases/v1.4.0/connector-packaging.json +++ b/registry/hasura/nodejs/releases/v1.4.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.4.0", + "version": "v1.4.0", "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.4.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "53ae3870e4f332310a7b6e359188371aa16714cf" } -} +} \ No newline at end of file diff --git a/registry/hasura/nodejs/releases/v1.4.1/connector-packaging.json b/registry/hasura/nodejs/releases/v1.4.1/connector-packaging.json index e39a6ebd..df479378 100644 --- a/registry/hasura/nodejs/releases/v1.4.1/connector-packaging.json +++ b/registry/hasura/nodejs/releases/v1.4.1/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.4.1", + "version": "v1.4.1", "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.4.1/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "9b5f795aca98854205ba5646162d1df7f060d642" } -} +} \ No newline at end of file diff --git a/registry/hasura/nodejs/releases/v1.5.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.5.0/connector-packaging.json index 00e593dc..051e09f0 100644 --- a/registry/hasura/nodejs/releases/v1.5.0/connector-packaging.json +++ b/registry/hasura/nodejs/releases/v1.5.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.5.0", + "version": "v1.5.0", "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.5.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "2a9a04d0a1c8116d9b864a83d81817ccddae355d" } -} +} \ No newline at end of file diff --git a/registry/hasura/nodejs/releases/v1.6.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.6.0/connector-packaging.json index cc6c7616..1a5ddf3f 100644 --- a/registry/hasura/nodejs/releases/v1.6.0/connector-packaging.json +++ b/registry/hasura/nodejs/releases/v1.6.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.6.0", + "version": "v1.6.0", "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.6.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "2fb76722db449b5525d1dcce33cf48ee0cf44ad8" } -} +} \ No newline at end of file diff --git a/registry/hasura/nodejs/releases/v1.7.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.7.0/connector-packaging.json index 77926b29..6736397d 100644 --- a/registry/hasura/nodejs/releases/v1.7.0/connector-packaging.json +++ b/registry/hasura/nodejs/releases/v1.7.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.7.0", + "version": "v1.7.0", "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.7.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "1adf00b7c36dd811d5e15894c1a141149db6325f" } -} +} \ No newline at end of file diff --git a/registry/hasura/nodejs/releases/v1.8.0/connector-packaging.json b/registry/hasura/nodejs/releases/v1.8.0/connector-packaging.json index a5c8a627..9909fc09 100644 --- a/registry/hasura/nodejs/releases/v1.8.0/connector-packaging.json +++ b/registry/hasura/nodejs/releases/v1.8.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.8.0", + "version": "v1.8.0", "uri": "https://github.com/hasura/ndc-nodejs-lambda/releases/download/v1.8.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "c1442716e822f7748e06aa25dd4f348e536d60cd" } -} +} \ No newline at end of file diff --git a/registry/hasura/openapi/releases/v0.1.2/connector-packaging.json b/registry/hasura/openapi/releases/v0.1.2/connector-packaging.json index 81aec720..0e2d5082 100644 --- a/registry/hasura/openapi/releases/v0.1.2/connector-packaging.json +++ b/registry/hasura/openapi/releases/v0.1.2/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.2", + "version": "v0.1.2", "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.1.2/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "a1fd7e016fc24107d35374a09fad24b4fc9c09d7" } -} +} \ No newline at end of file diff --git a/registry/hasura/openapi/releases/v0.1.3/connector-packaging.json b/registry/hasura/openapi/releases/v0.1.3/connector-packaging.json index 254d8023..c7147b90 100644 --- a/registry/hasura/openapi/releases/v0.1.3/connector-packaging.json +++ b/registry/hasura/openapi/releases/v0.1.3/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.3", + "version": "v0.1.3", "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.1.3/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "7a0177198da5e0691e01ba4378b90d7ad1e42044" } -} +} \ No newline at end of file diff --git a/registry/hasura/openapi/releases/v0.1.4/connector-packaging.json b/registry/hasura/openapi/releases/v0.1.4/connector-packaging.json index 7b9d28a0..9a1e2551 100644 --- a/registry/hasura/openapi/releases/v0.1.4/connector-packaging.json +++ b/registry/hasura/openapi/releases/v0.1.4/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.4", + "version": "v0.1.4", "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.1.4/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "95b64da4484b7cf547e0436ab4dd56f5ff4991a7" } -} +} \ No newline at end of file diff --git a/registry/hasura/openapi/releases/v0.1.5/connector-packaging.json b/registry/hasura/openapi/releases/v0.1.5/connector-packaging.json index 82565a90..539ae78b 100644 --- a/registry/hasura/openapi/releases/v0.1.5/connector-packaging.json +++ b/registry/hasura/openapi/releases/v0.1.5/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.5", + "version": "v0.1.5", "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.1.5/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "934491f158736401449c8144186330a1eeac78b7" } -} +} \ No newline at end of file diff --git a/registry/hasura/openapi/releases/v0.2.0/connector-packaging.json b/registry/hasura/openapi/releases/v0.2.0/connector-packaging.json index 59202d50..4887904b 100644 --- a/registry/hasura/openapi/releases/v0.2.0/connector-packaging.json +++ b/registry/hasura/openapi/releases/v0.2.0/connector-packaging.json @@ -1,12 +1,11 @@ { - "version": "0.2.0", - "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.2.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "6b766e1e2c7c21eddc8d6b7aa024c791a51716f8cdccdf8b8ae2e77f5b3b70e2" - }, - "source": { - "hash": "fa033ba34c5a40e5907a6c6277ecbe941a08edfc" - } + "version": "v0.2.0", + "uri": "https://github.com/hasura/ndc-open-api-lambda/releases/download/v0.2.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "6b766e1e2c7c21eddc8d6b7aa024c791a51716f8cdccdf8b8ae2e77f5b3b70e2" + }, + "source": { + "hash": "fa033ba34c5a40e5907a6c6277ecbe941a08edfc" } - \ No newline at end of file +} \ No newline at end of file diff --git a/registry/hasura/oracle/releases/v0.1.0/connector-packaging.json b/registry/hasura/oracle/releases/v0.1.0/connector-packaging.json index 9de59411..c973add8 100644 --- a/registry/hasura/oracle/releases/v0.1.0/connector-packaging.json +++ b/registry/hasura/oracle/releases/v0.1.0/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "0.1.0", - "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/oracle%2Fv0.1.0/package.tar.gz", - "checksum": { - "type": "sha256", - "value": "33a52fa0070ee4c956fbae37212b2012ff5f637dc90e2b47ee1899a39b3d34a6" - }, - "source": { - "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" - } -} + "version": "v0.1.0", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/oracle%2Fv0.1.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "33a52fa0070ee4c956fbae37212b2012ff5f637dc90e2b47ee1899a39b3d34a6" + }, + "source": { + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" + } +} \ No newline at end of file diff --git a/registry/hasura/oracle/releases/v1.0.1/connector-packaging.json b/registry/hasura/oracle/releases/v1.0.1/connector-packaging.json index 56b25785..457b60c1 100644 --- a/registry/hasura/oracle/releases/v1.0.1/connector-packaging.json +++ b/registry/hasura/oracle/releases/v1.0.1/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "1.0.1", - "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/oracle%2Fv1.0.1/package.tar.gz", - "checksum": { - "type": "sha256", - "value": "58ed43d43e0afc74d24c6ec1552ab3fbcc48cf108420f1f6dd6f7bd960b2d126" - }, - "source": { - "hash": "fbeb926e1d5550bec78a042a36d5ac2a8fba4c9f" - } -} + "version": "v1.0.1", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/oracle%2Fv1.0.1/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "58ed43d43e0afc74d24c6ec1552ab3fbcc48cf108420f1f6dd6f7bd960b2d126" + }, + "source": { + "hash": "fbeb926e1d5550bec78a042a36d5ac2a8fba4c9f" + } +} \ No newline at end of file diff --git a/registry/hasura/oracle/releases/v1.0.2/connector-packaging.json b/registry/hasura/oracle/releases/v1.0.2/connector-packaging.json index e83d968d..3b78ba32 100644 --- a/registry/hasura/oracle/releases/v1.0.2/connector-packaging.json +++ b/registry/hasura/oracle/releases/v1.0.2/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "1.0.2", - "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/oracle%2Fv1.0.2/package.tar.gz", - "checksum": { - "type": "sha256", - "value": "14891c40124d06c7732f0ca6559c62f3f8bdb1a0d802d4079868aae8a6013935" - }, - "source": { - "hash": "ef3dd9d851e62c18fc1fbee5d049b61065f37f72" - } -} + "version": "v1.0.2", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/oracle%2Fv1.0.2/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "14891c40124d06c7732f0ca6559c62f3f8bdb1a0d802d4079868aae8a6013935" + }, + "source": { + "hash": "ef3dd9d851e62c18fc1fbee5d049b61065f37f72" + } +} \ No newline at end of file diff --git a/registry/hasura/phoenix/releases/v1.0.0/connector-packaging.json b/registry/hasura/phoenix/releases/v1.0.0/connector-packaging.json index 10028942..06f25bf8 100644 --- a/registry/hasura/phoenix/releases/v1.0.0/connector-packaging.json +++ b/registry/hasura/phoenix/releases/v1.0.0/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "1.0.0", - "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/phoenix%2Fv1.0.0/package.tar.gz", - "checksum": { - "type": "sha256", - "value": "dea7bcd0784bce3a2b8f7a573f793f24f511f793c2b117636235ff883c351e68" - }, - "source": { - "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" - } -} + "version": "v1.0.0", + "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/phoenix%2Fv1.0.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "dea7bcd0784bce3a2b8f7a573f793f24f511f793c2b117636235ff883c351e68" + }, + "source": { + "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" + } +} \ No newline at end of file diff --git a/registry/hasura/postgres/releases/v1.0.2/connector-packaging.json b/registry/hasura/postgres/releases/v1.0.2/connector-packaging.json index 6ecbb324..782ab69d 100644 --- a/registry/hasura/postgres/releases/v1.0.2/connector-packaging.json +++ b/registry/hasura/postgres/releases/v1.0.2/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.0.2", + "version": "v1.0.2", "uri": "https://github.com/hasura/ndc-postgres/releases/download/v1.0.2/package.tar.gz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "1378805c72a16934788d3ab6a5bc767f8f0b9741" } -} +} \ No newline at end of file diff --git a/registry/hasura/postgres/releases/v1.1.0/connector-packaging.json b/registry/hasura/postgres/releases/v1.1.0/connector-packaging.json index 8bce4e87..d679124a 100644 --- a/registry/hasura/postgres/releases/v1.1.0/connector-packaging.json +++ b/registry/hasura/postgres/releases/v1.1.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.1.0", + "version": "v1.1.0", "uri": "https://github.com/hasura/ndc-postgres/releases/download/v1.1.0/package.tar.gz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "a57c0b5c76f98ea1da33d5aa649b6e8d071c3d4a" } -} +} \ No newline at end of file diff --git a/registry/hasura/python/releases/v0.0.45/connector-packaging.json b/registry/hasura/python/releases/v0.0.45/connector-packaging.json index fcd49dc9..bc4c332d 100644 --- a/registry/hasura/python/releases/v0.0.45/connector-packaging.json +++ b/registry/hasura/python/releases/v0.0.45/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "0.0.45", - "uri": "https://github.com/hasura/ndc-python-lambda/releases/download/v0.0.45/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "e9ba6388e4d3fad8c09dd3b696df5c97666f4551d47062b8dd7f311f1918269d" - }, - "source": { - "hash": "76a3d43d8ccf990b14812d9c0c354c4320b810f6" - } + "version": "v0.0.45", + "uri": "https://github.com/hasura/ndc-python-lambda/releases/download/v0.0.45/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "e9ba6388e4d3fad8c09dd3b696df5c97666f4551d47062b8dd7f311f1918269d" + }, + "source": { + "hash": "76a3d43d8ccf990b14812d9c0c354c4320b810f6" + } } \ No newline at end of file diff --git a/registry/hasura/python/releases/v0.1.0/connector-packaging.json b/registry/hasura/python/releases/v0.1.0/connector-packaging.json index c9ee9e54..fe0cc94d 100644 --- a/registry/hasura/python/releases/v0.1.0/connector-packaging.json +++ b/registry/hasura/python/releases/v0.1.0/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "0.1.0", - "uri": "https://github.com/hasura/ndc-python-lambda/releases/download/v0.1.0/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "4bd56df0920b1f889292a1ef12a0735a9883c47edef7a3cfbdc4c7db37dcf644" - }, - "source": { - "hash": "6f83afe355a60bd9677536e1bb13b212dca5460a" - } + "version": "v0.1.0", + "uri": "https://github.com/hasura/ndc-python-lambda/releases/download/v0.1.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "4bd56df0920b1f889292a1ef12a0735a9883c47edef7a3cfbdc4c7db37dcf644" + }, + "source": { + "hash": "6f83afe355a60bd9677536e1bb13b212dca5460a" + } } \ No newline at end of file diff --git a/registry/hasura/qdrant/releases/v0.2.1/connector-packaging.json b/registry/hasura/qdrant/releases/v0.2.1/connector-packaging.json index dd888aee..4264026b 100644 --- a/registry/hasura/qdrant/releases/v0.2.1/connector-packaging.json +++ b/registry/hasura/qdrant/releases/v0.2.1/connector-packaging.json @@ -1,12 +1,11 @@ { - "version": "0.2.1", - "uri": "https://github.com/hasura/ndc-qdrant/releases/download/v0.2.1/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "007cfaa76e45d3df2c2f50e1fdf0d4a3122a48895088958eaa972aee5ce49ac8" - }, - "source": { - "hash": "2effed689bd2f97c9649d1b8f9966533ed1d82a0" - } + "version": "v0.2.1", + "uri": "https://github.com/hasura/ndc-qdrant/releases/download/v0.2.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "007cfaa76e45d3df2c2f50e1fdf0d4a3122a48895088958eaa972aee5ce49ac8" + }, + "source": { + "hash": "2effed689bd2f97c9649d1b8f9966533ed1d82a0" } - \ No newline at end of file +} \ No newline at end of file diff --git a/registry/hasura/qdrant/releases/v0.3.0/connector-packaging.json b/registry/hasura/qdrant/releases/v0.3.0/connector-packaging.json index 30849afa..7cf389ad 100644 --- a/registry/hasura/qdrant/releases/v0.3.0/connector-packaging.json +++ b/registry/hasura/qdrant/releases/v0.3.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.3.0", + "version": "v0.3.0", "uri": "https://github.com/hasura/ndc-qdrant/releases/download/v0.3.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "5eda2128fcbe710741f07a404a6eb69214da2731" } -} +} \ No newline at end of file diff --git a/registry/hasura/singlestore/releases/v0.0.1/connector-packaging.json b/registry/hasura/singlestore/releases/v0.0.1/connector-packaging.json index ba22dd94..a233f2eb 100644 --- a/registry/hasura/singlestore/releases/v0.0.1/connector-packaging.json +++ b/registry/hasura/singlestore/releases/v0.0.1/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "0.0.1", - "uri": "https://github.com/singlestore-labs/singlestore-hasura-connector/releases/download/v0.0.1/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "7cc9f73cb966c2b69ef54d5f0e346407d3555ed1ac08f361f16157540bb80041" - }, - "source": { - "hash": "a9caa889c13a251040003c0934c7e67fccfd7de4" - } + "version": "v0.0.1", + "uri": "https://github.com/singlestore-labs/singlestore-hasura-connector/releases/download/v0.0.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "7cc9f73cb966c2b69ef54d5f0e346407d3555ed1ac08f361f16157540bb80041" + }, + "source": { + "hash": "a9caa889c13a251040003c0934c7e67fccfd7de4" + } } \ No newline at end of file diff --git a/registry/hasura/singlestore/releases/v0.0.2/connector-packaging.json b/registry/hasura/singlestore/releases/v0.0.2/connector-packaging.json index f795e617..d12b6c7a 100644 --- a/registry/hasura/singlestore/releases/v0.0.2/connector-packaging.json +++ b/registry/hasura/singlestore/releases/v0.0.2/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.0.2", + "version": "v0.0.2", "uri": "https://github.com/singlestore-labs/singlestore-hasura-connector/releases/download/v0.0.2/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "2afe3150215fbd6bf8a93ee6f853ad232e5d101d" } -} +} \ No newline at end of file diff --git a/registry/hasura/singlestore/releases/v0.0.3/connector-packaging.json b/registry/hasura/singlestore/releases/v0.0.3/connector-packaging.json index 36603350..73016048 100644 --- a/registry/hasura/singlestore/releases/v0.0.3/connector-packaging.json +++ b/registry/hasura/singlestore/releases/v0.0.3/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.0.3", + "version": "v0.0.3", "uri": "https://github.com/singlestore-labs/singlestore-hasura-connector/releases/download/v0.0.3/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "72ed900d5cc6819614fa27bba7bdba8977eedc6d" } -} +} \ No newline at end of file diff --git a/registry/hasura/singlestore/releases/v0.0.4/connector-packaging.json b/registry/hasura/singlestore/releases/v0.0.4/connector-packaging.json index ca96ac57..1fae3aae 100644 --- a/registry/hasura/singlestore/releases/v0.0.4/connector-packaging.json +++ b/registry/hasura/singlestore/releases/v0.0.4/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.0.4", + "version": "v0.0.4", "uri": "https://github.com/singlestore-labs/singlestore-hasura-connector/releases/download/v0.0.4/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "f26ee20fedf4578a29ff3199561b2882d70f915a" } -} +} \ No newline at end of file diff --git a/registry/hasura/snowflake/releases/v0.1.0/connector-packaging.json b/registry/hasura/snowflake/releases/v0.1.0/connector-packaging.json index 0783e356..07a586cf 100644 --- a/registry/hasura/snowflake/releases/v0.1.0/connector-packaging.json +++ b/registry/hasura/snowflake/releases/v0.1.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.0", + "version": "v0.1.0", "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/snowflake%2Fv0.1.0/package.tar.gz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "145792746281b606bcef2dfe20d1f0ad69efe01e" } -} +} \ No newline at end of file diff --git a/registry/hasura/snowflake/releases/v1.0.1/connector-packaging.json b/registry/hasura/snowflake/releases/v1.0.1/connector-packaging.json index 1df80206..b6e1dcd6 100644 --- a/registry/hasura/snowflake/releases/v1.0.1/connector-packaging.json +++ b/registry/hasura/snowflake/releases/v1.0.1/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "1.0.1", + "version": "v1.0.1", "uri": "https://github.com/hasura/ndc-jvm-mono/releases/download/snowflake%2Fv1.0.1/package.tar.gz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "fbeb926e1d5550bec78a042a36d5ac2a8fba4c9f" } -} +} \ No newline at end of file diff --git a/registry/hasura/sqlserver/releases/v0.1.0/connector-packaging.json b/registry/hasura/sqlserver/releases/v0.1.0/connector-packaging.json index f0200516..531f6325 100644 --- a/registry/hasura/sqlserver/releases/v0.1.0/connector-packaging.json +++ b/registry/hasura/sqlserver/releases/v0.1.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.0", + "version": "v0.1.0", "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.1.0/package.tar.gz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "e26d6bd1a22540dcf5c5b29460260c2d23ff2657" } -} +} \ No newline at end of file diff --git a/registry/hasura/sqlserver/releases/v0.1.1/connector-packaging.json b/registry/hasura/sqlserver/releases/v0.1.1/connector-packaging.json index d1836ef5..3aa7053d 100644 --- a/registry/hasura/sqlserver/releases/v0.1.1/connector-packaging.json +++ b/registry/hasura/sqlserver/releases/v0.1.1/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.1", + "version": "v0.1.1", "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.1.1/package.tar.gz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "638a2b608f7a9c4625de7df35c61c909d2ce16b1" } -} +} \ No newline at end of file diff --git a/registry/hasura/sqlserver/releases/v0.1.2/connector-packaging.json b/registry/hasura/sqlserver/releases/v0.1.2/connector-packaging.json index 7757b0bd..2ac187ba 100644 --- a/registry/hasura/sqlserver/releases/v0.1.2/connector-packaging.json +++ b/registry/hasura/sqlserver/releases/v0.1.2/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.2", + "version": "v0.1.2", "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.1.2/package.tar.gz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "bc0fd3d126f6c142587e014aa900fc6bc90cd59d" } -} +} \ No newline at end of file diff --git a/registry/hasura/sqlserver/releases/v0.2.0/connector-packaging.json b/registry/hasura/sqlserver/releases/v0.2.0/connector-packaging.json index 0c6a545a..98d43812 100644 --- a/registry/hasura/sqlserver/releases/v0.2.0/connector-packaging.json +++ b/registry/hasura/sqlserver/releases/v0.2.0/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "0.2.0", - "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.2.0/package.tar.gz", - "checksum": { - "type": "sha256", - "value": "5fe8c9461acc6eeb8290d3e41e4f4d77f2b3ecc30898194746e469b1c45e2365" - }, - "source": { - "hash": "368b38f" - } -} + "version": "v0.2.0", + "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.2.0/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "5fe8c9461acc6eeb8290d3e41e4f4d77f2b3ecc30898194746e469b1c45e2365" + }, + "source": { + "hash": "368b38f" + } +} \ No newline at end of file diff --git a/registry/hasura/sqlserver/releases/v0.2.1/connector-packaging.json b/registry/hasura/sqlserver/releases/v0.2.1/connector-packaging.json index 22dde26a..f11cf563 100644 --- a/registry/hasura/sqlserver/releases/v0.2.1/connector-packaging.json +++ b/registry/hasura/sqlserver/releases/v0.2.1/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "0.2.1", - "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.2.1/package.tar.gz", - "checksum": { - "type": "sha256", - "value": "ab32dcdbf66df75a7ca6a319d433b6057afe89bec203378abad857a13608f285" - }, - "source": { - "hash": "35dd850de629234553b3338f4c1ab976b20d77b6" - } -} + "version": "v0.2.1", + "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.2.1/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "ab32dcdbf66df75a7ca6a319d433b6057afe89bec203378abad857a13608f285" + }, + "source": { + "hash": "35dd850de629234553b3338f4c1ab976b20d77b6" + } +} \ No newline at end of file diff --git a/registry/hasura/sqlserver/releases/v0.2.2/connector-packaging.json b/registry/hasura/sqlserver/releases/v0.2.2/connector-packaging.json index 7c1ccefa..f05762ee 100644 --- a/registry/hasura/sqlserver/releases/v0.2.2/connector-packaging.json +++ b/registry/hasura/sqlserver/releases/v0.2.2/connector-packaging.json @@ -1,11 +1,11 @@ { - "version": "0.2.2", - "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.2.2/package.tar.gz", - "checksum": { - "type": "sha256", - "value": "2dbe5251872bf39d3a08261f7042307bae2ea8c831eec1982177b765c1e7013d" - }, - "source": { - "hash": "c33ff7efdcdef2c337aa40e2e776a4c2fdaca68b" - } -} + "version": "v0.2.2", + "uri": "https://github.com/hasura/ndc-sqlserver/releases/download/v0.2.2/package.tar.gz", + "checksum": { + "type": "sha256", + "value": "2dbe5251872bf39d3a08261f7042307bae2ea8c831eec1982177b765c1e7013d" + }, + "source": { + "hash": "c33ff7efdcdef2c337aa40e2e776a4c2fdaca68b" + } +} \ No newline at end of file diff --git a/registry/hasura/turso/releases/v0.0.15/connector-packaging.json b/registry/hasura/turso/releases/v0.0.15/connector-packaging.json index 74e749a8..70c87dc4 100644 --- a/registry/hasura/turso/releases/v0.0.15/connector-packaging.json +++ b/registry/hasura/turso/releases/v0.0.15/connector-packaging.json @@ -1,12 +1,11 @@ { - "version": "0.0.15", - "uri": "https://github.com/hasura/ndc-turso/releases/download/v0.0.15/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "a2c8426c443bf8c94b0f706d8438bd06eeeef30c0d2b40389c0e37be4be920a6" - }, - "source": { - "hash": "6bae967daf7b9aa718d62103e077a739c41d5a6d" - } + "version": "v0.0.15", + "uri": "https://github.com/hasura/ndc-turso/releases/download/v0.0.15/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "a2c8426c443bf8c94b0f706d8438bd06eeeef30c0d2b40389c0e37be4be920a6" + }, + "source": { + "hash": "6bae967daf7b9aa718d62103e077a739c41d5a6d" } - \ No newline at end of file +} \ No newline at end of file diff --git a/registry/hasura/turso/releases/v0.1.0/connector-packaging.json b/registry/hasura/turso/releases/v0.1.0/connector-packaging.json index 969af0c3..3ef5ca68 100644 --- a/registry/hasura/turso/releases/v0.1.0/connector-packaging.json +++ b/registry/hasura/turso/releases/v0.1.0/connector-packaging.json @@ -1,5 +1,5 @@ { - "version": "0.1.0", + "version": "v0.1.0", "uri": "https://github.com/hasura/ndc-turso/releases/download/v0.1.0/connector-definition.tgz", "checksum": { "type": "sha256", @@ -8,4 +8,4 @@ "source": { "hash": "ef4b124ea384a13f3d051e30ce33623fcc6847c5" } -} +} \ No newline at end of file From c6b0c041254402059d53255dc3b6d5880c55ce8f Mon Sep 17 00:00:00 2001 From: Vishnu Bharathi Date: Wed, 9 Oct 2024 21:38:07 +0530 Subject: [PATCH 131/135] ci: turn on connector publication (#341) This reverts commit fdb98e110c5a86148e39be23e31a997a6c150620. --- .github/workflows/registry-updates-prod.yaml | 36 ++++++++++---------- .github/workflows/registry-updates.yaml | 34 +++++++++--------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/.github/workflows/registry-updates-prod.yaml b/.github/workflows/registry-updates-prod.yaml index 78bc2aca..32e8d71e 100644 --- a/.github/workflows/registry-updates-prod.yaml +++ b/.github/workflows/registry-updates-prod.yaml @@ -40,21 +40,21 @@ jobs: run: | cat changed_files.json - # - name: Setup Go - # uses: actions/setup-go@v4 - # with: - # go-version: 1.21.x - - # - name: Run registry automation program - # env: - # CHANGED_FILES_PATH: "changed_files.json" - # PUBLICATION_ENV: "production" - # CONNECTOR_REGISTRY_GQL_URL: ${{ secrets.CONNECTOR_REGISTRY_GQL_URL }} - # GCP_BUCKET_NAME: ${{ secrets.GCP_BUCKET_NAME }} - # GCP_SERVICE_ACCOUNT_DETAILS: ${{ secrets.GCP_SERVICE_ACCOUNT_DETAILS }} - # CONNECTOR_PUBLICATION_KEY: ${{ secrets.CONNECTOR_PUBLICATION_KEY }} - # CLOUDINARY_URL: ${{ secrets.CLOUDINARY_URL }} - # run: | - # mv changed_files.json registry-automation/changed_files.json - # cd registry-automation - # go run main.go ci + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: 1.21.x + + - name: Run registry automation program + env: + CHANGED_FILES_PATH: "changed_files.json" + PUBLICATION_ENV: "production" + CONNECTOR_REGISTRY_GQL_URL: ${{ secrets.CONNECTOR_REGISTRY_GQL_URL }} + GCP_BUCKET_NAME: ${{ secrets.GCP_BUCKET_NAME }} + GCP_SERVICE_ACCOUNT_DETAILS: ${{ secrets.GCP_SERVICE_ACCOUNT_DETAILS }} + CONNECTOR_PUBLICATION_KEY: ${{ secrets.CONNECTOR_PUBLICATION_KEY }} + CLOUDINARY_URL: ${{ secrets.CLOUDINARY_URL }} + run: | + mv changed_files.json registry-automation/changed_files.json + cd registry-automation + go run main.go ci diff --git a/.github/workflows/registry-updates.yaml b/.github/workflows/registry-updates.yaml index 64029cdb..fd0a6afe 100644 --- a/.github/workflows/registry-updates.yaml +++ b/.github/workflows/registry-updates.yaml @@ -63,21 +63,21 @@ jobs: run: | cat changed_files.json - # - name: Setup Go - # uses: actions/setup-go@v4 - # with: - # go-version: 1.21.x + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: 1.21.x - # - name: Run registry automation program - # env: - # CHANGED_FILES_PATH: "changed_files.json" - # PUBLICATION_ENV: "staging" - # CONNECTOR_REGISTRY_GQL_URL: ${{ secrets.CONNECTOR_REGISTRY_GQL_URL }} - # GCP_BUCKET_NAME: ${{ secrets.GCP_BUCKET_NAME }} - # GCP_SERVICE_ACCOUNT_DETAILS: ${{ secrets.GCP_SERVICE_ACCOUNT_DETAILS }} - # CONNECTOR_PUBLICATION_KEY: ${{ secrets.CONNECTOR_PUBLICATION_KEY }} - # CLOUDINARY_URL: ${{ secrets.CLOUDINARY_URL }} - # run: | - # mv changed_files.json registry-automation/changed_files.json - # cd registry-automation - # go run main.go ci + - name: Run registry automation program + env: + CHANGED_FILES_PATH: "changed_files.json" + PUBLICATION_ENV: "staging" + CONNECTOR_REGISTRY_GQL_URL: ${{ secrets.CONNECTOR_REGISTRY_GQL_URL }} + GCP_BUCKET_NAME: ${{ secrets.GCP_BUCKET_NAME }} + GCP_SERVICE_ACCOUNT_DETAILS: ${{ secrets.GCP_SERVICE_ACCOUNT_DETAILS }} + CONNECTOR_PUBLICATION_KEY: ${{ secrets.CONNECTOR_PUBLICATION_KEY }} + CLOUDINARY_URL: ${{ secrets.CLOUDINARY_URL }} + run: | + mv changed_files.json registry-automation/changed_files.json + cd registry-automation + go run main.go ci From c004b7b1f4f71bddc7c14474d5f9090a5ce70d96 Mon Sep 17 00:00:00 2001 From: "David A. Ventimiglia" <100613027+dventimihasura@users.noreply.github.com> Date: Fri, 11 Oct 2024 13:48:45 -0700 Subject: [PATCH 132/135] Dventimihasura/add cassandra v1.0.6 (#343) --- registry/hasura/cassandra/README.md | 24 ++++++++ registry/hasura/cassandra/logo.png | Bin 0 -> 28790 bytes registry/hasura/cassandra/metadata.json | 55 ++++++++++++++++++ .../releases/v1.0.5/connector-packaging.json | 11 ++++ .../releases/v1.0.6/connector-packaging.json | 11 ++++ 5 files changed, 101 insertions(+) create mode 100644 registry/hasura/cassandra/README.md create mode 100644 registry/hasura/cassandra/logo.png create mode 100644 registry/hasura/cassandra/metadata.json create mode 100644 registry/hasura/cassandra/releases/v1.0.5/connector-packaging.json create mode 100644 registry/hasura/cassandra/releases/v1.0.6/connector-packaging.json diff --git a/registry/hasura/cassandra/README.md b/registry/hasura/cassandra/README.md new file mode 100644 index 00000000..46304d91 --- /dev/null +++ b/registry/hasura/cassandra/README.md @@ -0,0 +1,24 @@ +## Overview + +`ndc-cassandra` provides a Hasura Data Connector to the Cassandra database, +which can expose and run GraphQL queries via the Hasura v3 Project. + +- [Cassandra Connector information in the Hasura Connectors directory](https://hasura.io/connectors/cassandra) +- [GitHub repository](https://github.com/hasura/ndc-cassandra) + +The connector implements the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html), +but does not currently support mutations, column relationship arguments in queries, functions or procedures. + +Visit the +[Hasura v3 Documentation](https://hasura.io/docs/3.0/native-data-connectors/cassandra) +for more information. + +## Usage + +Follow the [Quick Start Guide](https://hasura.io/docs/3.0/quickstart/) +to use the Cassandra data connector from the [Hasura v3 Console](https://console.hasura.io). + +## Troubleshooting + +Please [submit a Github issue](https://github.com/hasura/graphql-engine/issues/new) +if you encounter any problems! diff --git a/registry/hasura/cassandra/logo.png b/registry/hasura/cassandra/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..cb003c2d8437c087cb9b348c6fbf08a51e4d2e1e GIT binary patch literal 28790 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 literal 0 HcmV?d00001 diff --git a/registry/hasura/cassandra/metadata.json b/registry/hasura/cassandra/metadata.json new file mode 100644 index 00000000..45e19994 --- /dev/null +++ b/registry/hasura/cassandra/metadata.json @@ -0,0 +1,55 @@ +{ + "overview": { + "namespace": "hasura", + "description": "The Cassandra Native Data Connector allows for connecting to a Cassandra instance giving you an instant GraphQL API on top of your Cassandra data.", + "title": "Cassandra Native Data Connector", + "logo": "logo.png", + "tags": [ + "database" + ], + "latest_version": "v1.0.6" + }, + "author": { + "support_email": "support@hasura.io", + "homepage": "https://hasura.io", + "name": "Hasura" + }, + "is_verified": true, + "is_hosted_by_hasura": false, + "source_code": { + "is_open_source": true, + "repository": "https://github.com/hasura/ndc-cassandra/", + "version": [ + { + "tag": "v1.0.1", + "hash": "c12a7356e20d01559e5824f7956234a9c6f43b1e", + "is_verified": true + }, + { + "tag": "v1.0.2", + "hash": "c12a7356e20d01559e5824f7956234a9c6f43b1e", + "is_verified": true + }, + { + "tag": "v1.0.3", + "hash": "f44814dff668c51f036568299fc485fac948668e", + "is_verified": true + }, + { + "tag": "v1.0.4", + "hash": "1167fb8fb9c93fedc3ef5d9fd455338068ce0041", + "is_verified": true + }, + { + "tag": "v1.0.5", + "hash": "541027b278c7ec2a7b1f14724fc73e5f150be1cf", + "is_verified": true + }, + { + "tag": "v1.0.6", + "hash": "79d7ef00c57f5b58e5e4f27e8ec89ffc2a685ec7", + "is_verified": true + } + ] + } +} diff --git a/registry/hasura/cassandra/releases/v1.0.5/connector-packaging.json b/registry/hasura/cassandra/releases/v1.0.5/connector-packaging.json new file mode 100644 index 00000000..5a4ff274 --- /dev/null +++ b/registry/hasura/cassandra/releases/v1.0.5/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.5", + "uri": "https://github.com/hasura/ndc-cassandra/releases/download/v1.0.5/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "397c56552c46344615962763c0813d64af806a7a45df114a8ae19de80113776f" + }, + "source": { + "hash": "541027b278c7ec2a7b1f14724fc73e5f150be1cf" + } +} diff --git a/registry/hasura/cassandra/releases/v1.0.6/connector-packaging.json b/registry/hasura/cassandra/releases/v1.0.6/connector-packaging.json new file mode 100644 index 00000000..f97e1b65 --- /dev/null +++ b/registry/hasura/cassandra/releases/v1.0.6/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.6", + "uri": "https://github.com/hasura/ndc-cassandra/releases/download/v1.0.6/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "2a58cd03094fb6cdd9032c6cd3383e31177c77234c05db411b8fa4d7e32d52ec" + }, + "source": { + "hash": "541027b278c7ec2a7b1f14724fc73e5f150be1cf" + } +} From c87b839cb35808d965eaf951c6fc379e53ad650a Mon Sep 17 00:00:00 2001 From: Daniel Chambers Date: Mon, 14 Oct 2024 12:20:34 +1100 Subject: [PATCH 133/135] Add SendGrid releases and update readme (#342) --- registry/hasura/sendgrid/README.md | 68 +++++------- registry/hasura/sendgrid/metadata.json | 101 ++++++++++-------- .../releases/v0.5.0/connector-packaging.json | 11 ++ .../releases/v0.6.0/connector-packaging.json | 11 ++ 4 files changed, 107 insertions(+), 84 deletions(-) create mode 100644 registry/hasura/sendgrid/releases/v0.5.0/connector-packaging.json create mode 100644 registry/hasura/sendgrid/releases/v0.6.0/connector-packaging.json diff --git a/registry/hasura/sendgrid/README.md b/registry/hasura/sendgrid/README.md index 97d22e0e..fd120b7f 100644 --- a/registry/hasura/sendgrid/README.md +++ b/registry/hasura/sendgrid/README.md @@ -5,62 +5,46 @@ This connector uses the SendGrid v3 API to: * List email templates * Send emails -https://github.com/hasura/ndc-sendgrid/tree/main#sendgrid-connector +## Prerequisites -* [Create a SendGrid API account](https://signup.sendgrid.com/) -* [Create an API key](https://app.sendgrid.com/settings/api_keys) -* Create a share service token +1. [Create a SendGrid API account](https://signup.sendgrid.com/) +2. [Create a SendGrid API key](https://app.sendgrid.com/settings/api_keys) +2. Create a [Hasura Cloud account](https://console.hasura.io) +3. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed +4. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +5. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) -You will need the Hasura -[V3 CLI](https://github.com/hasura/v3-cli) -and -[Connector Plugin](https://hasura.io/docs/latest/hasura-cli/connector-plugin/) -installed to use this connector. +The steps below explain how to initialize and configure a connector on your local machine (typically for development +purposes).You can learn how to deploy a connector to Hasura DDN — after it's been configured — +[here](https://hasura.io/docs/3.0/getting-started/deployment/deploy-a-connector). +## Using the SendGrid Connector -## Deployment - -You will need to have a configuration file available with your sendgrid credentials in the following format: +Add the SendGrid connector to your DDN project by running ``` -> cat sendgrid.connector.configuration.json -{"version": 1, "sendgrid_api_key": "YOUR-API-KEY-HERE" } +> ddn connector init -i ``` -Deploy and name the connector with the following command referencing your config: - -> hasura3 connector create sendgrid:v1 --github-repo-url https://github.com/hasura/ndc-sendgrid/tree/main --volume ./sendgrid.connector.configuration.json:/config.json --env SERVICE_TOKEN_SECRET=MY-SERVICE-TOKEN - -Monitor the deployment status by name: - -> hasura connector status sendgrid:v1 - -List your connector with its deployed URL: +Select the SendGrid connector from the list and provide a name for the connector and your SendGrid API key. -> hasura connector list +Then you need to introspect the connector to get its schema: ``` -sendgrid:v1 https://connector-9XXX7-hyc5v23h6a-ue.a.run.app active +> ddn connector introspect ``` +And then you can add all the SendGrid commands to your supergraph: -## Usage - -Include the connector URL in your Hasura V3 project metadata: - -```json -[ - { - "kind": "dataSource", - "name": "sendgrid", - "dataConnectorUrl": "https://connector-9XXX7-hyc5v23h6a-ue.a.run.app", - "schema": {} - } - ... -] +``` +> ddn command add "*" ``` -## Troubleshooting +You can now build your supergraph, run it locally, and open the Hasura Console to try it out: -Please [https://github.com/hasura/ndc-sendgrid/issues/new](submit a Github issue) -if you encounter any problems! +``` +> ddn supergraph build local +> ddn run docker-start +> ddn console --local +``` diff --git a/registry/hasura/sendgrid/metadata.json b/registry/hasura/sendgrid/metadata.json index c9d089c6..da67679d 100644 --- a/registry/hasura/sendgrid/metadata.json +++ b/registry/hasura/sendgrid/metadata.json @@ -1,43 +1,60 @@ { - "overview":{ - "namespace":"hasura", - "description":"Connect to SendGrid v3 API and expose it to Hasura Cloud v3 project", - "title":"SendGrid Native Data Connector", - "logo":"logo.png", - "tags":["email"], - "latest_version":"v0.3" - }, - "author":{ - "support_email":"support@hasura.io", - "homepage":"https://hasura.io", - "name":"Hasura" - }, - "is_verified":true, - "is_hosted_by_hasura":false, - "source_code":{ - "is_open_source":true, - "repository":"https://github.com/hasura/ndc-sendgrid/", - "version":[ - { - "tag": "v0.3", - "hash": "4d129449d3faa295fb145bc99b1f69db73314cce", - "is_verified": true - }, - { - "tag": "v0.2.1", - "hash": "e06860bb3ceedf7ec76e5b8559238bca527422b4", - "is_verified": true - }, - { - "tag": "v0.2", - "hash": "c0b3f13893e24a41df084985908af7ced0265498", - "is_verified": true - }, - { - "tag":"v0.1", - "hash":"8dc16c427e4e0136ebf0cfba1de3831c7939befb", - "is_verified": true - } - ] - } -} + "overview": { + "namespace": "hasura", + "description": "Connect to SendGrid v3 API and expose it to Hasura DDN project", + "title": "SendGrid Connector", + "logo": "logo.png", + "tags": [ + "email" + ], + "latest_version": "v0.6.0" + }, + "author": { + "support_email": "support@hasura.io", + "homepage": "https://hasura.io", + "name": "Hasura" + }, + "is_verified": true, + "is_hosted_by_hasura": false, + "source_code": { + "is_open_source": true, + "repository": "https://github.com/hasura/ndc-sendgrid/", + "version": [ + { + "tag": "v0.6.0", + "hash": "dcd4ca3025783ca732077fd71b094db3902785dd", + "is_verified": true + }, + { + "tag": "v0.5.0", + "hash": "b373cbc42968e9619d2ecfda8ef08f1d0f970619", + "is_verified": true + }, + { + "tag": "v0.4", + "hash": "4eba05262ceb31e2af885717b93d7d487b27275c", + "is_verified": true + }, + { + "tag": "v0.3", + "hash": "4d129449d3faa295fb145bc99b1f69db73314cce", + "is_verified": true + }, + { + "tag": "v0.2.1", + "hash": "e06860bb3ceedf7ec76e5b8559238bca527422b4", + "is_verified": true + }, + { + "tag": "v0.2", + "hash": "c0b3f13893e24a41df084985908af7ced0265498", + "is_verified": true + }, + { + "tag": "v0.1", + "hash": "8dc16c427e4e0136ebf0cfba1de3831c7939befb", + "is_verified": true + } + ] + } +} \ No newline at end of file diff --git a/registry/hasura/sendgrid/releases/v0.5.0/connector-packaging.json b/registry/hasura/sendgrid/releases/v0.5.0/connector-packaging.json new file mode 100644 index 00000000..d8124845 --- /dev/null +++ b/registry/hasura/sendgrid/releases/v0.5.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.5.0", + "uri": "https://github.com/hasura/ndc-sendgrid/releases/download/v0.5.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "ef9b4beb8c3db01856e04524c8debab3b8495421416d20c40faa63cdac73f07e" + }, + "source": { + "hash": "b373cbc42968e9619d2ecfda8ef08f1d0f970619" + } +} \ No newline at end of file diff --git a/registry/hasura/sendgrid/releases/v0.6.0/connector-packaging.json b/registry/hasura/sendgrid/releases/v0.6.0/connector-packaging.json new file mode 100644 index 00000000..5ff03c5a --- /dev/null +++ b/registry/hasura/sendgrid/releases/v0.6.0/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.6.0", + "uri": "https://github.com/hasura/ndc-sendgrid/releases/download/v0.6.0/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "e4277682dd5b1705d863966177af3c597693494d7bc109fb1b9fbdf978637d8e" + }, + "source": { + "hash": "dcd4ca3025783ca732077fd71b094db3902785dd" + } +} \ No newline at end of file From eb7c408510be1460f1b8e7e3c274496cd6375120 Mon Sep 17 00:00:00 2001 From: Toan Nguyen Date: Mon, 14 Oct 2024 19:44:51 +0700 Subject: [PATCH 134/135] Add ndc-prometheus v0.3.1 (#326) --- registry/hasura/prometheus/metadata.json | 7 ++++++- .../releases/v0.3.1/connector-packaging.json | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 registry/hasura/prometheus/releases/v0.3.1/connector-packaging.json diff --git a/registry/hasura/prometheus/metadata.json b/registry/hasura/prometheus/metadata.json index 846bf844..3eb06950 100644 --- a/registry/hasura/prometheus/metadata.json +++ b/registry/hasura/prometheus/metadata.json @@ -5,7 +5,7 @@ "title": "Prometheus Data Connector", "logo": "logo.svg", "tags": ["database"], - "latest_version": "v0.1.0" + "latest_version": "v0.3.1" }, "author": { "support_email": "support@hasura.io", @@ -27,6 +27,11 @@ "tag": "v0.1.0", "hash": "3d45dd1628d268906c8b56ecf235d6c280c29ca9", "is_verified": true + }, + { + "tag": "v0.3.1", + "hash": "7a1911709873636e821af8313492e747ea717c14", + "is_verified": true } ] } diff --git a/registry/hasura/prometheus/releases/v0.3.1/connector-packaging.json b/registry/hasura/prometheus/releases/v0.3.1/connector-packaging.json new file mode 100644 index 00000000..a499af39 --- /dev/null +++ b/registry/hasura/prometheus/releases/v0.3.1/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "v0.3.1", + "uri": "https://github.com/hasura/ndc-prometheus/releases/download/v0.3.1/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "218dea726017cc865b9ba746e5150427df5519bb52eb09fbcce38cde1d681598" + }, + "source": { + "hash": "7a1911709873636e821af8313492e747ea717c14" + } +} From 0acae134b120e447be2e635125b71a92c118a763 Mon Sep 17 00:00:00 2001 From: "David A. Ventimiglia" <100613027+dventimihasura@users.noreply.github.com> Date: Mon, 14 Oct 2024 17:01:37 -0700 Subject: [PATCH 135/135] dventimihasura/add cassandra v1.0.7 (#344) 1. Added the `registry/hasura/cassandra/releases/v1.0.7 folder with `connector-packaging.json`. 2. Set `connector-packaging.json` to reflect verion `1.0.7` and to have the right SHA and hash. 3. Set `metadata.json` to make the `latest_version` set to `v1.0.7`. 4. Maintained references to `v1.0.7` elsewhere in `metadata.json`. 5. Purged directories for earlier, bogus versions. 6. Purged references to those earlier, bogus version. 7. Copied the content from the MySQL connector's `README.md` file, but adapted it for Cassandra. --- registry/hasura/cassandra/README.md | 94 +++++++++++++++---- registry/hasura/cassandra/metadata.json | 29 +----- .../releases/v1.0.5/connector-packaging.json | 11 --- .../releases/v1.0.6/connector-packaging.json | 11 --- .../releases/v1.0.7/connector-packaging.json | 11 +++ 5 files changed, 91 insertions(+), 65 deletions(-) delete mode 100644 registry/hasura/cassandra/releases/v1.0.5/connector-packaging.json delete mode 100644 registry/hasura/cassandra/releases/v1.0.6/connector-packaging.json create mode 100644 registry/hasura/cassandra/releases/v1.0.7/connector-packaging.json diff --git a/registry/hasura/cassandra/README.md b/registry/hasura/cassandra/README.md index 46304d91..f8bb5b6c 100644 --- a/registry/hasura/cassandra/README.md +++ b/registry/hasura/cassandra/README.md @@ -1,24 +1,86 @@ -## Overview +# Cassandra Connector -`ndc-cassandra` provides a Hasura Data Connector to the Cassandra database, -which can expose and run GraphQL queries via the Hasura v3 Project. +[![Docs](https://img.shields.io/badge/docs-v3.x-brightgreen.svg?style=flat)](https://hasura.io/docs/3.0/getting-started/overview/) +[![ndc-hub](https://img.shields.io/badge/ndc--hub-sqlserver-blue.svg?style=flat)](https://hasura.io/connectors/sqlserver) +[![License](https://img.shields.io/badge/license-Apache--2.0-purple.svg?style=flat)](LICENSE.txt) +[![Status](https://img.shields.io/badge/status-alpha-yellow.svg?style=flat)](./readme.md) -- [Cassandra Connector information in the Hasura Connectors directory](https://hasura.io/connectors/cassandra) -- [GitHub repository](https://github.com/hasura/ndc-cassandra) +With this connector, Hasura allows you to instantly create a real-time GraphQL API on top of your data models in Cassandra. +This connector supports Cassandra's functionalities listed in the table below, allowing for efficient and scalable data +operations. Additionally, users benefit from all the powerful features of Hasura’s Data Delivery Network (DDN) platform, +including query pushdown capabilities that delegate query operations to the database, thereby enhancing query +optimization and performance. -The connector implements the [NDC Specification](https://hasura.github.io/ndc-spec/overview.html), -but does not currently support mutations, column relationship arguments in queries, functions or procedures. +This connector implements the [Data Connector Spec](https://github.com/hasura/ndc-spec). -Visit the -[Hasura v3 Documentation](https://hasura.io/docs/3.0/native-data-connectors/cassandra) -for more information. +- [Connector information in the Hasura Hub](https://hasura.io/connectors/cassandra) +- [Hasura V3 Documentation](https://hasura.io/docs/3.0) -## Usage +## Features -Follow the [Quick Start Guide](https://hasura.io/docs/3.0/quickstart/) -to use the Cassandra data connector from the [Hasura v3 Console](https://console.hasura.io). +Below, you'll find a matrix of all supported features for the Cassandra connector: -## Troubleshooting +| Feature | Supported | Notes | +| ------------------------------- | --------- | ----- | +| Native Queries + Logical Models | ✅ | | +| Native Mutations | ❌ | | +| Simple Object Query | ✅ | | +| Filter / Search | ✅ | | +| Simple Aggregation | ✅ | | +| Sort | ✅ | | +| Paginate | ✅ | | +| Table Relationships | ✅ | | +| Views | ✅ | | +| Remote Relationships | ✅ | | +| Custom Fields | ❌ | | +| Mutations | ❌ | | +| Distinct | ❌ | | +| Enums | ❌ | | +| Naming Conventions | ❌ | | +| Default Values | ❌ | | +| User-defined Functions | ❌ | | -Please [submit a Github issue](https://github.com/hasura/graphql-engine/issues/new) -if you encounter any problems! +## Prerequisites + +1. Create a [Hasura Cloud account](https://console.hasura.io) +2. Please ensure you have the [DDN CLI](https://hasura.io/docs/3.0/cli/installation) and + [Docker](https://docs.docker.com/engine/install/) installed +3. [Create a supergraph](https://hasura.io/docs/3.0/getting-started/init-supergraph) +4. [Create a subgraph](https://hasura.io/docs/3.0/getting-started/init-subgraph) + +## Using the Cassandra connector + +With the [context set](https://hasura.io/docs/3.0/cli/commands/ddn_context_set/) for an existing subgraph, initialize +the connector: + +```sh +ddn connector init -i +``` + +When the wizard runs, you'll be prompted to enter the following env vars necessary for your connector to function: + +| Name | Description | Required | +|-----------------------|-----------------------------------------|----------| +| CASSANDRA_HOST | Cassandra Host | true | +| CASSANDRA_KEYSPACE | Cassandra KeySpace | true | +| CASSANDRA_USERNAME | Cassandra username | true | +| CASSANDRA_PASSWORD | Cassandra password | true | +| CASSANDRA_PORT | Cassandra port | false | +| CASSANDRA_DC | Cassandra Data Center | false | +| CASSANDRA_SSL_CA_PATH | Cassandra self-signed root cert path | false | +| CASSANDRA_SSL | Cassandra SSL | false | + + + +After the CLI initializes the connector, you'll need to: + +- [Introspect](https://hasura.io/docs/3.0/cli/commands/ddn_connector_introspect) the source. +- Add your [models](https://hasura.io/docs/3.0/cli/commands/ddn_model_add), + [commands](https://hasura.io/docs/3.0/cli/commands/ddn_command_add), and + [relationships](https://hasura.io/docs/3.0/cli/commands/ddn_relationship_add). +- Create a [new build](https://hasura.io/docs/3.0/cli/commands/ddn_supergraph_build_local). +- Test it by [running your project along with the connector](https://hasura.io/docs/3.0/cli/commands/ddn_run#examples). + +## License + +The Hasura Cassandra connector is available under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/registry/hasura/cassandra/metadata.json b/registry/hasura/cassandra/metadata.json index 45e19994..d13e3484 100644 --- a/registry/hasura/cassandra/metadata.json +++ b/registry/hasura/cassandra/metadata.json @@ -7,7 +7,7 @@ "tags": [ "database" ], - "latest_version": "v1.0.6" + "latest_version": "v1.0.7" }, "author": { "support_email": "support@hasura.io", @@ -21,32 +21,7 @@ "repository": "https://github.com/hasura/ndc-cassandra/", "version": [ { - "tag": "v1.0.1", - "hash": "c12a7356e20d01559e5824f7956234a9c6f43b1e", - "is_verified": true - }, - { - "tag": "v1.0.2", - "hash": "c12a7356e20d01559e5824f7956234a9c6f43b1e", - "is_verified": true - }, - { - "tag": "v1.0.3", - "hash": "f44814dff668c51f036568299fc485fac948668e", - "is_verified": true - }, - { - "tag": "v1.0.4", - "hash": "1167fb8fb9c93fedc3ef5d9fd455338068ce0041", - "is_verified": true - }, - { - "tag": "v1.0.5", - "hash": "541027b278c7ec2a7b1f14724fc73e5f150be1cf", - "is_verified": true - }, - { - "tag": "v1.0.6", + "tag": "v1.0.7", "hash": "79d7ef00c57f5b58e5e4f27e8ec89ffc2a685ec7", "is_verified": true } diff --git a/registry/hasura/cassandra/releases/v1.0.5/connector-packaging.json b/registry/hasura/cassandra/releases/v1.0.5/connector-packaging.json deleted file mode 100644 index 5a4ff274..00000000 --- a/registry/hasura/cassandra/releases/v1.0.5/connector-packaging.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": "1.0.5", - "uri": "https://github.com/hasura/ndc-cassandra/releases/download/v1.0.5/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "397c56552c46344615962763c0813d64af806a7a45df114a8ae19de80113776f" - }, - "source": { - "hash": "541027b278c7ec2a7b1f14724fc73e5f150be1cf" - } -} diff --git a/registry/hasura/cassandra/releases/v1.0.6/connector-packaging.json b/registry/hasura/cassandra/releases/v1.0.6/connector-packaging.json deleted file mode 100644 index f97e1b65..00000000 --- a/registry/hasura/cassandra/releases/v1.0.6/connector-packaging.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": "1.0.6", - "uri": "https://github.com/hasura/ndc-cassandra/releases/download/v1.0.6/connector-definition.tgz", - "checksum": { - "type": "sha256", - "value": "2a58cd03094fb6cdd9032c6cd3383e31177c77234c05db411b8fa4d7e32d52ec" - }, - "source": { - "hash": "541027b278c7ec2a7b1f14724fc73e5f150be1cf" - } -} diff --git a/registry/hasura/cassandra/releases/v1.0.7/connector-packaging.json b/registry/hasura/cassandra/releases/v1.0.7/connector-packaging.json new file mode 100644 index 00000000..4d10f659 --- /dev/null +++ b/registry/hasura/cassandra/releases/v1.0.7/connector-packaging.json @@ -0,0 +1,11 @@ +{ + "version": "1.0.7", + "uri": "https://github.com/hasura/ndc-cassandra/releases/download/v1.0.7/connector-definition.tgz", + "checksum": { + "type": "sha256", + "value": "6f10cb6e2fd436e61e81328f27df03f262154ecf03238cd030ec49c75b0f97a9" + }, + "source": { + "hash": "79d7ef00c57f5b58e5e4f27e8ec89ffc2a685ec7" + } +}