Skip to content

Commit a7da064

Browse files
razor-xclaude
andauthored
Migrate Ruby SDK route generation to Metalsmith-based codegen (#524)
Replace the @seamapi/nextlove-sdk-generator pipeline with the Metalsmith + Handlebars + @seamapi/blueprint architecture used by seamapi/javascript-http and seamapi/docs. The blueprint drives route/endpoint/namespace iteration; the raw OpenAPI spec is still consulted wherever the previous generator derived output from data the blueprint normalizes differently. Those spots, and the verbatim helper ports that back them, are marked with TODO/TEMPORARY banners so they can migrate to blueprint once the generated output is allowed to change. Generated output under lib/seam/routes is byte-identical after `rake format`. - Add codegen/ (smith entry, Metalsmith plugin, layout context builders, Handlebars templates/partials, and TEMPORARY parity helpers) - Pin @seamapi/blueprint 0.55.0, add @seamapi/smith and change-case; drop @seamapi/nextlove-sdk-generator and del - Add tsconfig.json, eslint.config.ts, .prettierignore; wire typecheck/lint scripts; gitignore the generated root CODEGEN.md - Remove generate-routes.js Claude-Session: https://claude.ai/code/session_016XEpBuyVgLx5jvB4zygya6 Co-authored-by: Claude <noreply@anthropic.com>
1 parent d08e8d4 commit a7da064

33 files changed

Lines changed: 7075 additions & 1164 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
# For more details, visit the project page:
66
# https://github.com/github/gitignore
77

8+
# Codegen
9+
CODEGEN.md
10+
811
# rspec failure tracking
912
.rspec_status
1013

.prettierignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Prettier exceptions
2+
3+
*.hbs
4+
CODEGEN.md

codegen/content/CODEGEN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Codegen

codegen/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default null

codegen/layouts/client.hbs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
{{#if importActionAttempt}}
3+
4+
require "seam/helpers/action_attempt"
5+
{{/if}}
6+
7+
module Seam
8+
module Clients
9+
class {{className}}
10+
def initialize(client:, defaults:)
11+
@client = client
12+
@defaults = defaults
13+
end
14+
{{#each childClients}}
15+
16+
def {{namespace}}
17+
@{{namespace}} ||= Seam::Clients::{{clientName}}.new(client: @client, defaults: @defaults)
18+
end
19+
{{/each}}
20+
{{#each methods}}
21+
22+
{{> client-method}}
23+
{{/each}}
24+
end
25+
end
26+
end

codegen/layouts/default.hbs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{contents}}

codegen/layouts/imports.hbs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# frozen_string_literal: true
2+
3+
{{#each customImports}}
4+
{{this}}
5+
{{/each}}
6+
{{#each requires}}
7+
require_relative "{{this}}"
8+
{{/each}}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
def {{name}}{{#if hasSignature}}({{signatureParams}}){{/if}}
2+
{{#if usesRes}}res = {{/if}}@client.post("{{path}}"{{#if hasParams}}, {{bodyParams}}.compact{{/if}})
3+
{{#if isResource}}
4+
5+
Seam::Resources::{{returnResource}}.load_from_response(res.body["{{returnPath}}"])
6+
{{/if}}
7+
{{#if isPoll}}
8+
9+
wait_for_action_attempt = wait_for_action_attempt.nil? ? @defaults.wait_for_action_attempt : wait_for_action_attempt
10+
11+
Helpers::ActionAttempt.decide_and_wait(Seam::Resources::ActionAttempt.load_from_response(res.body["{{returnPath}}"]), @client, wait_for_action_attempt)
12+
{{/if}}
13+
{{#if isNil}}
14+
15+
nil
16+
{{/if}}
17+
end

codegen/layouts/resource.hbs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# frozen_string_literal: true
2+
3+
module Seam
4+
module Resources
5+
class {{className}} < BaseResource
6+
attr_accessor {{attrAccessors}}
7+
{{#if hasDateAccessors}}
8+
9+
date_accessor {{dateAccessors}}
10+
{{/if}}
11+
{{#if hasSupportModules}}
12+
13+
{{#if includeErrorsSupport}}
14+
include Seam::Resources::ResourceErrorsSupport
15+
{{/if}}
16+
{{#if includeWarningsSupport}}
17+
include Seam::Resources::ResourceWarningsSupport
18+
{{/if}}
19+
{{/if}}
20+
end
21+
end
22+
end

codegen/layouts/routes.hbs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# frozen_string_literal: true
2+
3+
module Seam
4+
module Routes
5+
{{#each routeClients}}
6+
def {{name}}
7+
@{{name}} ||= Seam::Clients::{{className}}.new(client: @client, defaults: @defaults)
8+
end
9+
10+
{{/each}}
11+
# @deprecated Please use {#devices.unmanaged} instead.
12+
def unmanaged_devices
13+
warn "[DEPRECATION] 'unmanaged_devices' is deprecated. Please use 'devices.unmanaged' instead."
14+
15+
@unmanaged_devices ||= Seam::Clients::DevicesUnmanaged.new(client: @client, defaults: @defaults)
16+
end
17+
18+
# @deprecated Please use {#access_codes.unmanaged} instead.
19+
def unmanaged_access_codes
20+
warn "[DEPRECATION] 'unmanaged_access_codes' is deprecated. Please use 'access_codes.unmanaged' instead."
21+
22+
@unmanaged_access_codes ||= Seam::Clients::AccessCodesUnmanaged.new(client: @client, defaults: @defaults)
23+
end
24+
25+
private
26+
27+
def initialize_routes(client:, defaults:)
28+
@client = client
29+
@defaults = defaults
30+
end
31+
end
32+
end

0 commit comments

Comments
 (0)