From 9ba5743227590a8bffe0a24b542e598d9b313b85 Mon Sep 17 00:00:00 2001 From: Ryan Tan Date: Fri, 8 Nov 2024 16:37:20 +0000 Subject: [PATCH] feat(ci): add stainless generation to ci --- .github/workflows/generate-node-client.yml | 19 +++ crates/jstz_node/openapi.json | 6 +- crates/jstz_node/stainless.yml | 133 +++++++++++++++++++++ crates/jstz_proto/src/operation.rs | 17 ++- crates/jstz_proto/src/receipt.rs | 2 +- 5 files changed, 169 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/generate-node-client.yml create mode 100644 crates/jstz_node/stainless.yml diff --git a/.github/workflows/generate-node-client.yml b/.github/workflows/generate-node-client.yml new file mode 100644 index 000000000..0bfaba7d7 --- /dev/null +++ b/.github/workflows/generate-node-client.yml @@ -0,0 +1,19 @@ +name: Upload OpenAPI spec to Stainless + +on: + pull_request: # testing only + push: + branches: [main] + +jobs: + stainless: + concurrency: upload-openapi-spec-action + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: stainless-api/upload-openapi-spec-action@main + with: + stainless_api_key: ${{ secrets.STAINLESS_API_KEY }} + input_path: "crates/jstz_node/openapi.json" + config_path: "crates/jstz_node/stainless.yml" + project_name: "jstz-client" diff --git a/crates/jstz_node/openapi.json b/crates/jstz_node/openapi.json index 02d381f6e..e522e7c25 100644 --- a/crates/jstz_node/openapi.json +++ b/crates/jstz_node/openapi.json @@ -872,7 +872,8 @@ }, "headers": { "type": "object", - "description": "Any valid HTTP headers" + "description": "Any valid HTTP headers", + "additionalProperties": true }, "method": { "type": "string", @@ -916,7 +917,8 @@ }, "headers": { "type": "object", - "description": "Any valid HTTP headers" + "description": "Any valid HTTP headers", + "additionalProperties": true }, "status_code": { "type": "integer", diff --git a/crates/jstz_node/stainless.yml b/crates/jstz_node/stainless.yml new file mode 100644 index 000000000..db37d7396 --- /dev/null +++ b/crates/jstz_node/stainless.yml @@ -0,0 +1,133 @@ +# yaml-language-server: $schema=https://app.stainlessapi.com/config.schema.json + +organization: + # Name of your organization or company, used to determine the name of the client + # and headings. + name: jstz client # Strangely, the organisation name is used as the name of the root class + docs: https://jstz-dev.github.io/jstz/ + contact: contact@trili.tech + +# `targets` define the output targets and their customization options, such as +# whether to emit the Node SDK and what it's package name should be. +targets: + node: + readme_title: Jstz Client + package_name: "@jstz-dev/client" + production_repo: null + publish: + npm: false + +# `client_settings` define settings for the API client, such as extra constructor +# arguments (used for authentication), retry behavior, idempotency, etc. +client_settings: + opts: {} + +# `environments` are a map of the name of the environment (e.g. "sandbox", +# "production") to the corresponding url to use. +environments: + production: https://localhost:8933 + +# `pagination` defines [pagination schemes] which provides a template to match +# endpoints and generate next-page and auto-pagination helpers in the SDKs. +pagination: [] + +# `resources` define the structure and organziation for your API, such as how +# methods and models are grouped together and accessed. See the [configuration +# guide] for more information. +# +# [configuration guide]: +# https://app.stainlessapi.com/docs/guides/configure#resources +resources: + accounts: + # Subresources define resources that are nested within another for more powerful + # logical groupings, e.g. `cards.payments`. + subresources: + balance: + # Configure the methods defined in this resource. Each key in the object is the + # name of the method and the value is either an endpoint (for example, `get /foo`) + # or an object with more detail. + # + # [reference]: https://app.stainlessapi.com/docs/reference/config#method + methods: + retrieve: get /accounts/{address}/balance + code: + # Configure the models--named types--defined in the resource. Each key in the + # object is the name of the model and the value is either the name of a schema in + # `#/components/schemas` or an object with more detail. + # + # [reference]: https://app.stainlessapi.com/docs/reference/config#model + models: + parsedCode: ParsedCode + methods: + retrieve: get /accounts/{address}/code + kv: + models: + kvValue: KvValue + methods: + retrieve: get /accounts/{address}/kv + subresources: + subkeys: + methods: + list: + type: http + endpoint: get /accounts/{address}/kv/subkeys + paginated: false + nonce: + models: + nonce: Nonce + methods: + retrieve: get /accounts/{address}/nonce + + logs: + models: + logRecord: LogRecord + methods: + stream: get /logs/{address}/stream + subresources: + persistent_requests: + methods: + list: + type: http + endpoint: get /logs/{address}/persistent/requests + paginated: false + retrieve: get /logs/{address}/persistent/requests/{request_id} + + operations: + methods: + inject: post /operations + subresources: + receipt: + models: + receipt: Receipt + methods: + retrieve: get /operations/{operation_hash}/receipt + + crypto: + models: + publicKey: PublicKey + publicKeyHash: PublicKeyHash + signature: Signature + +settings: + license: Apache-2.0 + +# `readme` is used to configure the code snippets that will be rendered in the +# README.md of various SDKs. In particular, you can change the `headline` +# snippet's endpoint and the arguments to call it with. +readme: + example_requests: + default: + type: request + endpoint: get /accounts/{address}/code + params: &ref_0 + address: REPLACE_ME + headline: + type: request + endpoint: get /accounts/{address}/code + params: *ref_0 + pagination: + type: request + endpoint: get /accounts/{address}/kv/subkeys + params: + address: REPLACE_ME + include_stainless_attribution: false diff --git a/crates/jstz_proto/src/operation.rs b/crates/jstz_proto/src/operation.rs index 6f96994e6..98f319efa 100644 --- a/crates/jstz_proto/src/operation.rs +++ b/crates/jstz_proto/src/operation.rs @@ -111,10 +111,7 @@ pub struct RunFunction { pub method: Method, /// Any valid HTTP headers #[serde(with = "http_serde::header_map")] - #[schema( - value_type = Object, - additional_properties, - )] + #[schema(schema_with= openapi::http_headers)] pub headers: HeaderMap, #[schema(schema_with = openapi::http_body_schema)] pub body: HttpBody, @@ -219,9 +216,19 @@ pub enum ExternalOperation { } pub mod openapi { - use utoipa::{openapi::Array, schema}; + use utoipa::{ + openapi::{schema::AdditionalProperties, Array, Object, ObjectBuilder}, + schema, + }; pub fn http_body_schema() -> Array { schema!(Option>).build() } + + pub fn http_headers() -> Object { + ObjectBuilder::new() + .additional_properties(Some(AdditionalProperties::FreeForm(true))) + .description(Some("Any valid HTTP headers")) + .build() + } } diff --git a/crates/jstz_proto/src/receipt.rs b/crates/jstz_proto/src/receipt.rs index c810c1113..8e637bc52 100644 --- a/crates/jstz_proto/src/receipt.rs +++ b/crates/jstz_proto/src/receipt.rs @@ -62,7 +62,7 @@ pub struct RunFunctionReceipt { pub status_code: StatusCode, /// Any valid HTTP headers #[serde(with = "http_serde::header_map")] - #[schema(value_type = Object, additional_properties)] + #[schema(schema_with = crate::operation::openapi::http_headers)] pub headers: HeaderMap, }