From 37434a15481b28cd325758ea2a646bafb89433c6 Mon Sep 17 00:00:00 2001 From: Jeroen Rinzema Date: Thu, 12 Feb 2026 20:24:37 +0100 Subject: [PATCH] feat: include openapi typescript generator in makefile and workflow --- .github/workflows/ci.yml | 11 + Makefile | 1 + console/package.json | 1 + console/src/oapi/webhooks.generated.ts | 432 +++++++++++++++++++++++++ 4 files changed, 445 insertions(+) create mode 100644 console/src/oapi/webhooks.generated.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc51af14..18939e57 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,6 +92,15 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: ${{ vars.PNPM_VERSION }} + - name: Set-up Node + uses: actions/setup-node@v5 + with: + node-version: ${{ vars.NODEJS_VERSION }} + cache: "pnpm" + cache-dependency-path: console/pnpm-lock.yaml - name: Set up Go uses: actions/setup-go@v5 with: @@ -105,6 +114,8 @@ jobs: with: path: bin key: ${{ runner.os }}-bin-${{ hashFiles('**/go.sum') }} + - name: Install Console Dependencies + run: cd console && pnpm install - name: Auto generate files run: make generate - name: Check for file changes diff --git a/Makefile b/Makefile index 2ba1b600..a8fd302b 100644 --- a/Makefile +++ b/Makefile @@ -93,6 +93,7 @@ fmt: | $(EMBEDDED) ; $(info $(M) running go fmt…) @ ## Run gofmt on all source .PHONY: generate generate: | $(EMBEDDED) $(TOOLCHAIN) ; $(info $(M) updating generated files…) @ ## Update all generated files $Q $(GO) generate $(PKGS) + $Q cd console && $(PNPM) run generate $Q $(MAKE) fmt .PHONY: clean diff --git a/console/package.json b/console/package.json index 1a947e13..ca75c327 100644 --- a/console/package.json +++ b/console/package.json @@ -73,6 +73,7 @@ "test:coverage": "vitest run --coverage --watch=false", "lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"", "analyze:bundle": "pnpm build && npx source-map-explorer './dist/assets/*.js'", + "generate": "pnpm run /^generate:/", "generate:openapi": "openapi-typescript ../oapi/webhooks.yml -o ./src/oapi/webhooks.generated.ts" }, "types": "./lib/cjs/mod.d.ts", diff --git a/console/src/oapi/webhooks.generated.ts b/console/src/oapi/webhooks.generated.ts new file mode 100644 index 00000000..c253af4a --- /dev/null +++ b/console/src/oapi/webhooks.generated.ts @@ -0,0 +1,432 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export interface paths { + "/webhooks/providers/bootstrap": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Bootstrap default integrations for a new project + * @description Called by Lunogram when a new project is created. + * The endpoint should return one or more default providers and/or an `external_id` + * that can be used by Lunogram to send or fetch configuration. + */ + post: operations["bootstrapProviders"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/webhooks/provider/send": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Send a message through an external provider + * @description Called by Lunogram to send a message through the external provider identified by `external_id`. + * The request body can represent an **email**, **SMS**, or **push** notification. + */ + post: operations["sendMessage"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/webhooks/journey/templates": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List available journey step templates + * @description Returns a list of available journey step templates that define how users can get started + * with Journeys. Each template includes an identifier and a brief description. + */ + get: operations["journeyTemplates"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/webhooks/journey/template": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Retrieve a journey step template + * @description Returns a predefined journey step template that defines how users can get started + * with Journeys. The template contains a map of step definitions, including `entrance`, + * `action`, and `sticky` types. + */ + get: operations["journeyTemplate"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; +} +export type webhooks = Record; +export interface components { + schemas: { + Providers: { + /** @description List of providers to create */ + providers: components["schemas"]["Provider"][]; + }; + Provider: { + /** @description Provider type (e.g., "twilio", "sendgrid", "slack") */ + type: string; + /** @description Display name of the provider */ + name: string; + /** + * @description Group of the provider + * @enum {string} + */ + group: "email" | "text" | "push" | "webhook" | "analytics"; + /** @description Provider-specific configuration data */ + data: { + [key: string]: unknown; + }; + /** @description Whether this provider is marked as default */ + is_default: boolean; + /** + * @description Rate limit interval + * @enum {string} + */ + rate_interval?: "second" | "minute" | "hour" | "day"; + /** @description Maximum number of requests allowed in the specified interval */ + rate_limit?: number; + /** @description External identifier to fetch or send through */ + external_id: string; + }; + /** + * @description Represents a journey step template map, where each key is a unique step ID (UUID) + * and the value defines the step configuration. + * @example { + * "819fbabf-c3c0-4fe3-b41f-7f6bbe068379": { + * "type": "entrance", + * "data": {}, + * "name": "", + * "data_key": null, + * "x": 0, + * "y": 0, + * "children": [ + * { + * "external_id": "a9b91772-f555-4d0b-999e-bae513202821", + * "path": "", + * "data": {} + * } + * ] + * }, + * "e6eed3fb-9d7f-4295-947e-6fceb546ad40": { + * "type": "sticky", + * "data": { + * "text": "Journeys define how users progress through your automated steps and actions over time." + * }, + * "name": "Getting Started! 🎉", + * "data_key": null, + * "x": 303.37, + * "y": -10.8, + * "children": [] + * }, + * "a9b91772-f555-4d0b-999e-bae513202821": { + * "type": "action", + * "data": { + * "campaign_id": "00000000-0000-0000-0000-000000000000" + * }, + * "name": "", + * "data_key": null, + * "x": -40.62, + * "y": 289.19, + * "children": [] + * }, + * "a197e316-c2aa-4290-9231-31a56218e5a8": { + * "type": "sticky", + * "data": { + * "text": "Use actions to send emails, SMS, push notifications, or trigger webhooks." + * }, + * "name": "Deliver your Message 📣", + * "data_key": null, + * "x": 302.03, + * "y": 385.81, + * "children": [] + * } + * } + */ + Journey: { + [key: string]: components["schemas"]["JourneyStep"]; + }; + JourneyStep: { + /** @enum {string} */ + type: "entrance" | "action" | "sticky"; + name?: string | null; + data?: { + [key: string]: unknown; + } | null; + data_key?: string | null; + x: number; + y: number; + children?: components["schemas"]["JourneyStepChild"][] | null; + }; + JourneyStepChild: { + external_id: string; + path?: string | null; + data?: { + [key: string]: unknown; + } | null; + }; + Email: { + /** + * @description discriminator enum property added by openapi-typescript + * @enum {string} + */ + type: "email"; + to: string; + from: string | components["schemas"]["NamedEmail"]; + cc?: string; + bcc?: string; + reply_to?: string; + subject: string; + text?: string; + html?: string; + headers?: { + [key: string]: string; + }; + list?: { + unsubscribe?: string; + }; + }; + TextMessage: { + /** + * @description discriminator enum property added by openapi-typescript + * @enum {string} + */ + type: "text"; + to: string; + text: string; + }; + Push: { + /** + * @description discriminator enum property added by openapi-typescript + * @enum {string} + */ + type: "push"; + tokens: string | string[]; + title: string; + body: string; + custom?: { + [key: string]: unknown; + }; + }; + NamedEmail: { + name: string; + email: string; + }; + }; + responses: never; + parameters: never; + requestBodies: never; + headers: never; + pathItems: never; +} +export type $defs = Record; +export interface operations { + bootstrapProviders: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": { + /** + * Format: uuid + * @description Unique identifier of the project + */ + project_id: string; + /** + * Format: uuid + * @description Organization to which the project belongs + */ + organization_id?: string; + }; + }; + }; + responses: { + /** @description Default providers and/or external reference */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["Providers"]; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Server error in external system */ + 500: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + sendMessage: { + parameters: { + query: { + /** @description External identifier of the provider */ + external_id: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["Email"] | components["schemas"]["TextMessage"] | components["schemas"]["Push"]; + }; + }; + responses: { + /** @description Message accepted by the external system */ + 201: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Invalid payload or unsupported message type */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Provider not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Server error in external system */ + 500: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + journeyTemplates: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description List of journey templates retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": { + /** @description Identifier of the journey template */ + template_id: string; + /** @description Name of the journey template */ + name: string; + /** @description Brief description of the journey template */ + description?: string; + }[]; + }; + }; + /** @description Server error in external system */ + 500: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + journeyTemplate: { + parameters: { + query: { + /** @description Identifier of the journey template */ + template_id: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Journey template retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["Journey"]; + }; + }; + /** @description Invalid template_id or malformed request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Template not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Server error in external system */ + 500: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; +}