Skip to content

Latest commit

 

History

History
582 lines (558 loc) · 15.8 KB

README.md

File metadata and controls

582 lines (558 loc) · 15.8 KB

ruk-cuk

yarn global add ruk-cuk

Generate Moleculer-compliant TypeScript typings from any 3.x OpenAPI document.

ruk-cuk generate [documents..]

generate Moleculer-compliant TypeScript signatures from 3.x OpenAPI documents

Positionals:
  documents  Location of 3.x OpenAPI documents.            [array] [default: []]

Options:
      --version              Show version number                       [boolean]
      --help                 Show help                                 [boolean]
  -o, --output               The name of the file or full file path to store def
                             initions as        [string] [default: "types.d.ts"]
      --prettify             Use Prettier to format the output code
                                                       [boolean] [default: true]
  -q, --quiet                Print nothing but errors [boolean] [default: false]
      --ts-namespace-prefix  Prefix used within the TypeScript declaration name
                                                          [string] [default: ""]
      --ts-skip-events       Exclude events definitions
                                                      [boolean] [default: false]
  -w, --watch                Watch document and rebuild on changes
                                                      [boolean] [default: false]

Example

Given the following OpenAPI Document

openapi.v1.json
{
  "openapi": "3.1.0",
  "info": {
    "title": "Activity",
    "version": "1.0",
    "description": "Operations for managing activity logs."
  },
  "paths": {
    "/v1/workspaces/{workspace_id}/activity": {
      "get": {
        "summary": "List Workspace Activity",
        "tags": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Activity"
                  }
                }
              }
            },
            "headers": {
              "Link": {
                "schema": {
                  "type": "string"
                },
                "description": "Provides links to the next and previous results per https://datatracker.ietf.org/doc/html/rfc5988"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "operationId": "v1.activity.byWorkspace",
        "security": [
          {
            "Authorization": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "example": "2021-08-02T14:59:01.433Z",
              "format": "date-time"
            },
            "in": "query",
            "name": "before",
            "description": "Filter list before a specific created date. Useful for pagination."
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "example": "2021-08-02T14:59:01.433Z"
            },
            "in": "query",
            "name": "after",
            "description": "Filter list after a specific created date. Useful for pagination."
          },
          {
            "schema": {
              "type": "number",
              "default": 50,
              "minimum": 1,
              "maximum": 100
            },
            "in": "query",
            "name": "limit",
            "description": "Limit the size of the list returned"
          },
          {
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/ActivityType"
              }
            },
            "in": "query",
            "name": "type",
            "description": "Filter to a specific activity types"
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "group",
            "description": "Filter to a specific group ID"
          }
        ]
      },
      "parameters": [
        {
          "schema": {
            "type": "string",
            "example": "d2s6MQ"
          },
          "name": "workspace_id",
          "in": "path",
          "required": true,
          "description": "Base64 encoded \"wk:\" + workspace ID"
        }
      ]
    },
    "/v1/activity/hasura-event-handler": {
      "post": {
        "summary": "Hasura Activity Log Event Handler",
        "operationId": "v1.activity.hasuraEventHandler",
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "x-internal": true,
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "event": {
                    "type": "object",
                    "required": ["session_variables", "op", "data"],
                    "properties": {
                      "session_variables": {
                        "type": ["object", "null"]
                      },
                      "op": {
                        "type": "string",
                        "enum": ["INSERT", "UPDATE", "DELETE", "MANUAL"]
                      },
                      "data": {
                        "type": "object",
                        "required": ["old", "new"],
                        "properties": {
                          "old": {
                            "type": ["object", "null"]
                          },
                          "new": {
                            "type": ["object", "null"]
                          }
                        }
                      }
                    }
                  },
                  "created_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "id": {
                    "type": "string"
                  },
                  "trigger": {
                    "type": "object",
                    "required": ["name"],
                    "properties": {
                      "name": {
                        "type": "string"
                      }
                    }
                  },
                  "table": {
                    "type": "object",
                    "required": ["schema", "name"],
                    "properties": {
                      "schema": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      }
                    }
                  }
                },
                "required": ["event", "created_at", "id", "trigger", "table"]
              }
            }
          }
        },
        "description": ""
      },
      "parameters": []
    }
  },
  "components": {
    "schemas": {
      "Activity": {
        "title": "Activity",
        "type": "object",
        "examples": [],
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "$ref": "#/components/schemas/ActivityType"
          },
          "metadata": {
            "type": "object",
            "description": "Additional information specific to the activity type"
          },
          "created_at": {
            "type": "string",
            "description": "Timestamp when the activity was performed",
            "format": "date-time"
          },
          "ip_address": {
            "type": ["string", "null"],
            "description": "IP address of client where the activity was performed",
            "format": "ipv4"
          },
          "actor": {
            "type": ["object", "null"],
            "description": "User who performed the activity",
            "required": ["name", "email"],
            "properties": {
              "name": {
                "type": "string"
              },
              "email": {
                "type": "string"
              }
            }
          }
        },
        "required": [
          "id",
          "type",
          "metadata",
          "created_at",
          "ip_address",
          "actor"
        ]
      },
      "Error": {
        "title": "Error",
        "type": "object",
        "description": "Represents generic error",
        "examples": [
          {
            "message": "Name is required.",
            "code": 400,
            "type": "VALIDATION_ERROR"
          }
        ],
        "properties": {
          "message": {
            "type": "string",
            "description": "Detailed error message"
          },
          "code": {
            "type": "number",
            "enum": [400, 401, 403, 404, 409, 500],
            "description": "HTTP Status Code"
          },
          "type": {
            "type": "string",
            "description": "Error type"
          }
        },
        "required": ["message", "code"]
      },
      "ActivityType": {
        "type": "string",
        "title": "ActivityType",
        "enum": ["create", "move", "read", "delete", "update"]
      }
    },
    "securitySchemes": {
      "Authorization": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "responses": {
      "BadRequestError": {
        "description": "The server could not understand the request due to invalid syntax.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "Missing required field": {
                "value": {
                  "message": "Name is required.",
                  "code": 400,
                  "type": "VALIDATION_ERROR"
                }
              }
            }
          },
          "application/xml": {
            "schema": {
              "type": "object",
              "properties": {}
            }
          },
          "multipart/form-data": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFoundError": {
        "description": "The server can not find the requested resource.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "Entity not found": {
                "value": {
                  "message": "Group is not found",
                  "code": 404,
                  "type": "GROUP_NOT_FOUND"
                }
              }
            }
          }
        }
      },
      "UnauthorizedError": {
        "description": "The client must authenticate itself to get the requested response.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "Missing authorization header": {
                "value": {
                  "message": "Missing authorization",
                  "code": 401,
                  "type": "UNAUTHORIZED"
                }
              }
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "The client must be on the correct billing plan to access the content.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "Payment Required": {
                "value": {
                  "code": 402,
                  "type": "PAYMENT_REQUIRED",
                  "message": "This feature is not enabled for your workspace billing plan, or your workspace billing is out of standing."
                }
              }
            }
          }
        }
      },
      "ForbiddenError": {
        "description": "The client does not have permissions to access the content.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "No permissions": {
                "value": {
                  "message": "You do not have permissions to delete this group.",
                  "code": 403,
                  "type": "FORBIDDEN"
                }
              }
            }
          }
        }
      },
      "InternalServerError": {
        "description": "The server has encountered a situation it doesn't know how to handle.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "Transporter receives unknown data": {
                "value": {
                  "message": "Internal Server Error",
                  "code": 500,
                  "type": "INVALID_PACKET_DATA"
                }
              }
            }
          }
        }
      }
    },
    "parameters": {}
  }
}

Executing

ruk-cuk generate "openapi.v1.json"

would generate types.d.ts file with the following content:

declare namespace Activity {
  type Actions = {
    'v1.activity': {
      byWorkspace: (params: ByWorkspaceParams) => Promise<ByWorkspaceResponse>;
      hasuraEventHandler: (params: HasuraEventHandlerParams) => Promise<void>;
    };
  };
  type Events = never;
  type ByWorkspaceParams = {
    workspace_id: string;
    before?: string;
    after?: string;

    /**
     * @defaultValue `50`
     */
    limit?: number;
    type?: ActivityType[];
    group?: string;
  };
  type ByWorkspaceResponse = Activity[];
  type HasuraEventHandlerParams = {
    event: {
      session_variables: Record<string, unknown> | null;
      op: 'INSERT' | 'UPDATE' | 'DELETE' | 'MANUAL';
      data: {
        old: Record<string, unknown> | null;
        new: Record<string, unknown> | null;
        [k: string]: unknown;
      };
      [k: string]: unknown;
    };
    created_at: string;
    id: string;
    trigger: {
      name: string;
      [k: string]: unknown;
    };
    table: {
      schema: string;
      name: string;
      [k: string]: unknown;
    };
    [k: string]: unknown;
  };
  type Activity = {
    id: string;
    type: ActivityType;

    /**
     * Additional information specific to the activity type
     */
    metadata: Record<string, unknown>;

    /**
     * Timestamp when the activity was performed
     */
    created_at: string;

    /**
     * IP address of client where the activity was performed
     */
    ip_address: string | null;

    /**
     * User who performed the activity
     */
    actor: {
      name: string;
      email: string;
      [k: string]: unknown;
    } | null;
    [k: string]: unknown;
  };
  type Error = {
    /**
     * Detailed error message
     */
    message: string;

    /**
     * HTTP Status Code
     */
    code: 400 | 401 | 403 | 404 | 409 | 500;

    /**
     * Error type
     */
    type?: string;
    [k: string]: unknown;
  };
  type ActivityType = 'create' | 'move' | 'read' | 'delete' | 'update';
  type BadRequestError = Error | Record<string, unknown>;
  type NotFoundError = Error;
  type UnauthorizedError = Error;
  type PaymentRequired = Error;
  type ForbiddenError = Error;
  type InternalServerError = Error;
}

LICENSE

Apache License 2.0