Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 152 additions & 24 deletions bun.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ run = "bun run release:smoke"

[tasks.test]
description = "Run tests"
run = "bun test"
run = "bun run test"

[tasks."spec:fetch"]
description = "Fetch the production OpenAPI spec snapshot"
Expand Down
16 changes: 9 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,25 @@
"release:package": "bun scripts/release.ts package --version $npm_package_version --output dist/release",
"release:verify": "bun scripts/release.ts verify --version $npm_package_version --output dist/release",
"release:smoke": "bun scripts/release.ts smoke --version $npm_package_version --output dist/release",
"test": "bun test"
"test": "vitest run"
},
"devDependencies": {
"@effect/openapi-generator": "4.0.0-beta.106",
"@effect/platform-node": "4.0.0-beta.106",
"@effect/openapi-generator": "4.0.0-rc.109",
"@effect/platform-node": "4.0.0-rc.109",
"@effect/vitest": "4.0.0-rc.109",
"@types/bun": "^1.3.0",
"typescript": "^5.9.0"
"typescript": "^5.9.0",
"vitest": "^4.1.0"
},
"engines": {
"bun": ">=1.3.7"
},
"dependencies": {
"@akua-dev/sdk": "^0.9.4",
"effect": "4.0.0-beta.106"
"effect": "4.0.0-rc.109"
},
"patchedDependencies": {
"effect@4.0.0-beta.106": "patches/effect@4.0.0-beta.106.patch",
"@effect/openapi-generator@4.0.0-beta.106": "patches/@effect%2Fopenapi-generator@4.0.0-beta.106.patch"
"@effect/openapi-generator@4.0.0-rc.109": "patches/@effect%2Fopenapi-generator@4.0.0-rc.109.patch",
"effect@4.0.0-rc.109": "patches/effect@4.0.0-rc.109.patch"
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
diff --git a/dist/HttpApiTransformer.js b/dist/HttpApiTransformer.js
index aad332ba5abf58db21178942761dee147b382235..49c363e2070a2e8ab21b42f83706fc6241e5c683 100644
index aad332ba5abf58db21178942761dee147b382235..4c062f5928cc75c85de4186d60c32d221242668d 100644
--- a/dist/HttpApiTransformer.js
+++ b/dist/HttpApiTransformer.js
@@ -149,7 +149,7 @@ const renderPayload = operation => {
return;
}
if (operation.requestBody?.required === false) {
- payloads.unshift("HttpApiSchema.NoContent");
+ payloads.push("HttpApiSchema.NoContent");
}
return joinSchemas(payloads);
};
@@ -165,11 +165,11 @@ const renderResponseSet = (responses, target) => {
continue;
}
Expand Down Expand Up @@ -29,6 +38,15 @@ index aad332ba5abf58db21178942761dee147b382235..49c363e2070a2e8ab21b42f83706fc62
return `HttpApiSchema.StreamSse(${options})`;
}
if (media.effectStream === "uint8array") {
@@ -359,7 +361,7 @@ const renderSecurityScheme = securityScheme => {
return source;
};
const toOperationKey = operation => `${operation.method}:${operation.path}`;
-const toHttpApiPath = path => path.replace(/{([^}]+)}/g, ":$1");
+const toHttpApiPath = path => path.replace(/:/g, "%3A").replace(/{([^}]+)}/g, ":$1");
const toStatus = status => {
if (!/^\d{3}$/.test(status)) {
return;
diff --git a/dist/OpenApiGenerator.js b/dist/OpenApiGenerator.js
index a1c2dce0a23131373824e1a0f11fdfb361faabb5..4207d1022f8b6741ddcd47ed95b875dc20ec3529 100644
--- a/dist/OpenApiGenerator.js
Expand Down Expand Up @@ -123,23 +141,35 @@ index a1c2dce0a23131373824e1a0f11fdfb361faabb5..4207d1022f8b6741ddcd47ed95b875dc
return true;
}
continue;
diff --git a/dist/HttpApiTransformer.js b/dist/HttpApiTransformer.js
--- a/dist/HttpApiTransformer.js
+++ b/dist/HttpApiTransformer.js
@@ -149,7 +149,7 @@ const renderPayload = operation => {
return;
}
if (operation.requestBody?.required === false) {
- payloads.unshift("HttpApiSchema.NoContent");
+ payloads.push("HttpApiSchema.NoContent");
}
return joinSchemas(payloads);
};
diff --git a/src/HttpApiTransformer.ts b/src/HttpApiTransformer.ts
index 02be5759b1bcbc48da4a3e72cb2a852c9143558e..b71826d7f02e66659737d726327656d032cd2203 100644
--- a/src/HttpApiTransformer.ts
+++ b/src/HttpApiTransformer.ts
@@ -252,3 +252,3 @@ const renderPayload = (operation: ParsedOperation): string | undefined => {
@@ -250,7 +250,7 @@ const renderPayload = (operation: ParsedOperation): string | undefined => {
}

if (operation.requestBody?.required === false) {
- payloads.unshift("HttpApiSchema.NoContent")
+ payloads.push("HttpApiSchema.NoContent")
}

return joinSchemas(payloads)
@@ -513,7 +513,17 @@ const renderSecurityScheme = (securityScheme: ParsedOpenApiSecurityScheme): stri

const toOperationKey = (operation: ParsedOperation): string => `${operation.method}:${operation.path}`

-const toHttpApiPath = (path: string): string => path.replace(/{([^}]+)}/g, ":$1")
+// REST-RPC-style OpenAPI paths (e.g. `/clusters/{id}:resume`) embed a literal
+// `:action` suffix alongside the `{param}` placeholder. Effect's HttpApiClient
+// path compiler treats every `:word` occurrence in a compiled endpoint path as
+// an Express-style path parameter, with no way to distinguish a literal colon
+// from a parameter marker. Percent-encoding literal colons before rewriting
+// `{param}` to `:param` keeps the parameter rewrite unambiguous: only colons
+// we just introduced remain unescaped, so the client compiler no longer
+// mistakes the literal action suffix for a second path parameter. The server
+// (and any RFC 3986-compliant router) decodes `%3A` back to `:` before route
+// matching, so the request is unchanged on the wire.
+const toHttpApiPath = (path: string): string => path.replace(/:/g, "%3A").replace(/{([^}]+)}/g, ":$1")

const toStatus = (status: string): number | undefined => {
if (!/^\d{3}$/.test(status)) {
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
diff --git a/dist/internal/schema/toCodeDocument.js b/dist/internal/schema/toCodeDocument.js
index 59399d367e3b0755e2394e384e3b1586e5032363..c3d282057f7d7d4c788b5495b7f96d41005da418 100644
index 9600dfc7693953a58a79b2f13abe4f414859022d..0dd9af5ddd95dff7dede3344cf93af31a9f29e4c 100644
--- a/dist/internal/schema/toCodeDocument.js
+++ b/dist/internal/schema/toCodeDocument.js
@@ -418,7 +418,8 @@
@@ -418,7 +418,8 @@ export function toCodeDocument(document) {
return makeCode(`Schema.Record(${signature.parameter.runtime}, ${signature.type.runtime})`, `{ readonly [x: ${signature.parameter.Type}]: ${signature.type.Type} }`);
}
const indexRuntimes = indexSignatures.map(signature => `Schema.Record(${signature.parameter.runtime}, ${signature.type.runtime})`).join(", ");
Expand All @@ -11,8 +11,22 @@ index 59399d367e3b0755e2394e384e3b1586e5032363..c3d282057f7d7d4c788b5495b7f96d41
+ const indexTypes = indexSignatures.map(signature => `readonly [x: ${signature.parameter.Type}]: ${signature.type.Type}${indexValueType}`).join(", ");
return makeCode(`Schema.StructWithRest(Schema.Struct({ ${propertyRuntimes} }), [${indexRuntimes}])`, `{ ${propertyTypes}${properties.length > 0 ? ", " : ""}${indexTypes} }`);
}
case "Union":
case "Union":
diff --git a/dist/unstable/cli/CliOutput.js b/dist/unstable/cli/CliOutput.js
index 874e19f9968cd1f1a072803730ef3e46ffbb808c..7230a334b76f5c201d6f6fd7225ab6338eafd146 100644
--- a/dist/unstable/cli/CliOutput.js
+++ b/dist/unstable/cli/CliOutput.js
@@ -195,7 +195,7 @@ const renderTable = (rows, widthCap) => {
return rows.map(({
left,
right
- }) => ` ${pad(left, col)}${right}`).join("\n");
+ }) => ` ${pad(left, Math.max(col, visualLength(left) + 2))}${right}`).join("\n");
};
const formatSubcommandName = (name, alias) => alias ? `${name}, ${alias}` : name;
/**
diff --git a/dist/unstable/httpapi/HttpApiEndpoint.d.ts b/dist/unstable/httpapi/HttpApiEndpoint.d.ts
index e95cfc448c7fd374d1781c59b601dec9703fd9a1..e2047691b17e9a16fbaa86b752161f8c6e89b000 100644
--- a/dist/unstable/httpapi/HttpApiEndpoint.d.ts
+++ b/dist/unstable/httpapi/HttpApiEndpoint.d.ts
@@ -283,12 +283,10 @@ export type ClientRequest<Params extends Schema.Constraint, Query extends Schema
Expand All @@ -30,7 +44,23 @@ diff --git a/dist/unstable/httpapi/HttpApiEndpoint.d.ts b/dist/unstable/httpapi/
})) extends infer Req ? keyof Req extends never ? (void | {
readonly responseMode?: ResponseMode;
}) : Req & {
diff --git a/src/unstable/cli/CliOutput.ts b/src/unstable/cli/CliOutput.ts
index 13cc142d69796ce24d5155fdd263f53772be972a..98455abaec5b9fdfce25867578e674b7315b4789 100644
--- a/src/unstable/cli/CliOutput.ts
+++ b/src/unstable/cli/CliOutput.ts
@@ -411,7 +411,9 @@ interface Row {
const renderTable = (rows: ReadonlyArray<Row>, widthCap?: number) => {
const maxColumn = Math.max(...rows.map((r) => visualLength(r.left))) + 4
const col = widthCap === undefined ? maxColumn : Math.min(maxColumn, widthCap)
- return rows.map(({ left, right }) => ` ${pad(left, col)}${right}`).join("\n")
+ return rows
+ .map(({ left, right }) => ` ${pad(left, Math.max(col, visualLength(left) + 2))}${right}`)
+ .join("\n")
}

const formatSubcommandName = (name: string, alias: string | undefined): string => alias ? `${name}, ${alias}` : name
diff --git a/src/unstable/httpapi/HttpApiEndpoint.ts b/src/unstable/httpapi/HttpApiEndpoint.ts
index 331b4ff84e85e70193eda8371ce63ebed659b9b9..c30c0fc94cb3751b8b6a43f551e3999c7d10d04d 100644
--- a/src/unstable/httpapi/HttpApiEndpoint.ts
+++ b/src/unstable/httpapi/HttpApiEndpoint.ts
@@ -502,11 +502,18 @@ export type ClientRequest<
Expand All @@ -57,28 +87,3 @@ diff --git a/src/unstable/httpapi/HttpApiEndpoint.ts b/src/unstable/httpapi/Http
) extends infer Req ? keyof Req extends never ? (void | { readonly responseMode?: ResponseMode }) :
Req & { readonly responseMode?: ResponseMode } :
void
diff --git a/dist/unstable/cli/CliOutput.js b/dist/unstable/cli/CliOutput.js
--- a/dist/unstable/cli/CliOutput.js
+++ b/dist/unstable/cli/CliOutput.js
@@ -192,8 +192,8 @@ const renderTable = (rows, widthCap) => {
const renderTable = (rows, widthCap) => {
const maxColumn = Math.max(...rows.map(r => visualLength(r.left))) + 4;
const col = widthCap === undefined ? maxColumn : Math.min(maxColumn, widthCap);
return rows.map(({
left,
right
- }) => ` ${pad(left, col)}${right}`).join("\n");
+ }) => ` ${pad(left, Math.max(col, visualLength(left) + 2))}${right}`).join("\n");
};
diff --git a/src/unstable/cli/CliOutput.ts b/src/unstable/cli/CliOutput.ts
--- a/src/unstable/cli/CliOutput.ts
+++ b/src/unstable/cli/CliOutput.ts
@@ -411,5 +411,7 @@ const renderTable = (rows: ReadonlyArray<Row>, widthCap?: number) => {
const renderTable = (rows: ReadonlyArray<Row>, widthCap?: number) => {
const maxColumn = Math.max(...rows.map((r) => visualLength(r.left))) + 4
const col = widthCap === undefined ? maxColumn : Math.min(maxColumn, widthCap)
- return rows.map(({ left, right }) => ` ${pad(left, col)}${right}`).join("\n")
+ return rows
+ .map(({ left, right }) => ` ${pad(left, Math.max(col, visualLength(left) + 2))}${right}`)
+ .join("\n")
}
Loading
Loading