diff --git a/modules/handlers.ts b/modules/handlers.ts index 2d525c3..b92400d 100644 --- a/modules/handlers.ts +++ b/modules/handlers.ts @@ -42,7 +42,7 @@ export async function createMockResponse(request, context) { } else if (contentType.startsWith("multipart/form-data")) { isOpenApi = true; // Handle OpenAPI mock - binId += "_oas"; + binId += "-oas"; responseData = await handleOpenApiMock( request, context, @@ -130,7 +130,7 @@ async function handleOpenApiMock(request, context, binId, storage, url) { let originalYamlUrl: string | undefined; if (isYaml) { // Save the original YAML file - const yamlBinId = `${binId}_YAML_original`; + const yamlBinId = `${binId}-YAML-original`; await storage.uploadObject(`${yamlBinId}.yaml`, body); const yamlUrl = getInvokeBinUrl(url, yamlBinId); originalYamlUrl = yamlUrl.href; diff --git a/modules/utils.ts b/modules/utils.ts index f4fddc1..c96397f 100644 --- a/modules/utils.ts +++ b/modules/utils.ts @@ -45,7 +45,7 @@ export function getInvokeBinUrl(url: URL, binId: string) { return mockUrl; } -const binRegEx = /^[0-9a-fA-F]{32}(_oas)?$/; +const binRegEx = /^[0-9a-fA-F]{32}([-_]oas)?$/; export function validateBinId(binId: string) { return binRegEx.test(binId); @@ -83,5 +83,5 @@ export function validateOpenApiDocument(document: any): void { } export function isOasBin(binId: string) { - return binId.indexOf("_oas") > 0; + return binId.indexOf("_oas") > 0 || binId.indexOf("-oas") > 0; } diff --git a/tests/openapi-bin-creation.test.ts b/tests/openapi-bin-creation.test.ts new file mode 100644 index 0000000..e528e40 --- /dev/null +++ b/tests/openapi-bin-creation.test.ts @@ -0,0 +1,23 @@ +import { describe, test, assert } from "vitest"; + +describe("OpenAPI Bin ID Format Tests", () => { + test("Should use hyphen format for new OpenAPI bins", () => { + // This test verifies that when creating new OpenAPI bins, + // they use the hyphen format which is DNS-compatible + + // Simulate the bin ID creation logic from handlers.ts + let binId = "12345678901234567890123456789012"; // 32 hex chars + binId += "-oas"; // This is the new format we're implementing + + // Verify the format + assert.isTrue(binId.endsWith("-oas"), "Should use hyphen format"); + assert.isFalse(binId.includes("_"), "Should not contain underscores"); + assert.strictEqual(binId.length, 36, "Should be 32 chars + 4 chars for -oas"); + + // Verify it's DNS-compatible + const isDnsCompatible = /^[a-zA-Z0-9-]+$/.test(binId) && + !binId.startsWith("-") && + !binId.endsWith("-"); + assert.isTrue(isDnsCompatible, "Should be DNS hostname compatible"); + }); +}); \ No newline at end of file diff --git a/tests/openapi-bin-domain.test.ts b/tests/openapi-bin-domain.test.ts new file mode 100644 index 0000000..c0e0d31 --- /dev/null +++ b/tests/openapi-bin-domain.test.ts @@ -0,0 +1,90 @@ +import { describe, test, assert } from "vitest"; +import { validateBinId, isOasBin, getInvokeBinUrl } from "../modules/utils"; + +describe("OpenAPI Bin Domain Validation Tests", () => { + test("Should validate new hyphen-based OpenAPI bin IDs", () => { + const binId = "12345678901234567890123456789012-oas"; + assert.isTrue(validateBinId(binId)); + }); + + test("Should still validate legacy underscore-based OpenAPI bin IDs for backward compatibility", () => { + const binId = "12345678901234567890123456789012_oas"; + assert.isTrue(validateBinId(binId)); + }); + + test("Should validate regular bin IDs without suffix", () => { + const binId = "12345678901234567890123456789012"; + assert.isTrue(validateBinId(binId)); + }); + + test("Should reject invalid bin IDs", () => { + const invalidBinId = "12345"; + assert.isFalse(validateBinId(invalidBinId)); + }); + + test("Should detect hyphen-based OpenAPI bins", () => { + const binId = "12345678901234567890123456789012-oas"; + assert.isTrue(isOasBin(binId)); + }); + + test("Should still detect legacy underscore-based OpenAPI bins", () => { + const binId = "12345678901234567890123456789012_oas"; + assert.isTrue(isOasBin(binId)); + }); + + test("Should not detect regular bins as OpenAPI bins", () => { + const binId = "12345678901234567890123456789012"; + assert.isFalse(isOasBin(binId)); + }); + + test("Should generate valid subdomain with hyphen-based OpenAPI bin ID", () => { + const binId = "12345678901234567890123456789012-oas"; + const url = new URL("https://api.mockbin.io"); + + // Mock USE_WILDCARD_SUBDOMAIN as true for this test + const originalEnv = process.env.USE_WILDCARD_SUBDOMAIN; + process.env.USE_WILDCARD_SUBDOMAIN = "true"; + + // Since we can't directly test getInvokeBinUrl with the environment variable, + // let's verify the subdomain manually + const expectedSubdomain = binId; + + // Check that the binId doesn't contain underscores (which are invalid in DNS) + assert.isFalse(expectedSubdomain.includes("_"), "Bin ID should not contain underscores for DNS compatibility"); + + // Check that it contains hyphens (which are valid in DNS) + assert.isTrue(expectedSubdomain.includes("-"), "Bin ID should contain hyphens for OpenAPI bins"); + + // Restore original environment + if (originalEnv !== undefined) { + process.env.USE_WILDCARD_SUBDOMAIN = originalEnv; + } else { + delete process.env.USE_WILDCARD_SUBDOMAIN; + } + }); + + test("Should validate DNS hostname rules for new format", () => { + const binId = "12345678901234567890123456789012-oas"; + + // DNS hostname rules: + // - Can contain letters, digits, and hyphens + // - Cannot start or end with hyphen + // - Cannot contain underscores + + const isValidDnsHostname = (hostname: string): boolean => { + // Check for invalid characters (anything other than alphanumeric and hyphens) + if (!/^[a-zA-Z0-9-]+$/.test(hostname)) { + return false; + } + + // Check that it doesn't start or end with hyphen + if (hostname.startsWith("-") || hostname.endsWith("-")) { + return false; + } + + return true; + }; + + assert.isTrue(isValidDnsHostname(binId), "New bin ID format should be valid for DNS hostnames"); + }); +}); \ No newline at end of file