diff --git a/packages/cli/cli/changes/5.23.6/fix-docs-dev-hot-reload.yml b/packages/cli/cli/changes/5.23.6/fix-docs-dev-hot-reload.yml new file mode 100644 index 000000000000..ae5146fa479e --- /dev/null +++ b/packages/cli/cli/changes/5.23.6/fix-docs-dev-hot-reload.yml @@ -0,0 +1,6 @@ +- summary: | + Fix `fern docs dev` hot reload not working for .mdx file changes. The backend + now updates the docs definition before notifying the browser to refresh, and + the reload handler properly recovers from errors instead of silently blocking + all future reloads. + type: fix diff --git a/packages/cli/cli/changes/5.24.0/seed-verify-pipeline.yml b/packages/cli/cli/changes/5.24.0/seed-verify-pipeline.yml new file mode 100644 index 000000000000..2479860da7a1 --- /dev/null +++ b/packages/cli/cli/changes/5.24.0/seed-verify-pipeline.yml @@ -0,0 +1,10 @@ +# yaml-language-server: $schema=../../../../../fern-changes-yml.schema.json + +- summary: | + Plumb `verify`, `verifyRunner`, and `verifyValidatorVersion` flags through + `GenerationRunner.RunArgs` so the seed runner can invoke + `PostGenerationPipeline` with `VerificationStep` and exercise the same + validator-container code path that `fern generate --local --verify` uses. + No customer-facing CLI behavior change — the flags are opt-in and used only + by the seed test runner today. + type: internal diff --git a/packages/cli/cli/versions.yml b/packages/cli/cli/versions.yml index b88d629a617c..e25af3872110 100644 --- a/packages/cli/cli/versions.yml +++ b/packages/cli/cli/versions.yml @@ -1,4 +1,26 @@ # yaml-language-server: $schema=../../../fern-versions-yml.schema.json +- version: 5.24.0 + changelogEntry: + - summary: | + Plumb `verify`, `verifyRunner`, and `verifyValidatorVersion` flags through + `GenerationRunner.RunArgs` so the seed runner can invoke + `PostGenerationPipeline` with `VerificationStep` and exercise the same + validator-container code path that `fern generate --local --verify` uses. + No customer-facing CLI behavior change — the flags are opt-in and used only + by the seed test runner today. + type: internal + createdAt: "2026-05-13" + irVersion: 66 +- version: 5.23.6 + changelogEntry: + - summary: | + Fix `fern docs dev` hot reload not working for .mdx file changes. The backend + now updates the docs definition before notifying the browser to refresh, and + the reload handler properly recovers from errors instead of silently blocking + all future reloads. + type: fix + createdAt: "2026-05-13" + irVersion: 66 - version: 5.23.5 changelogEntry: - summary: | diff --git a/packages/cli/docs-preview/src/runAppPreviewServer.ts b/packages/cli/docs-preview/src/runAppPreviewServer.ts index 9201cc456971..985801028b00 100644 --- a/packages/cli/docs-preview/src/runAppPreviewServer.ts +++ b/packages/cli/docs-preview/src/runAppPreviewServer.ts @@ -1240,57 +1240,71 @@ export async function runAppPreviewServer({ void (async () => { isReloading = true; - // Expand the list of files to include pages that depend on changed snippets - const filesToReload = snippetTracker.getFilesToReload(editedAbsoluteFilepaths); - const hasSnippetDependencies = snippetTracker.hasSnippetDependencies(editedAbsoluteFilepaths); - - if (hasSnippetDependencies) { - context.logger.info( - `Snippet dependencies detected. Reloading ${filesToReload.length} files (${editedAbsoluteFilepaths.length} changed, ${filesToReload.length - editedAbsoluteFilepaths.length} dependent pages)` - ); - } - sendData({ version: 1, type: "startReload" }); - const reloadedPreviewResult = await reloadDocsDefinition(filesToReload); + try { + // Expand the list of files to include pages that depend on changed snippets + const filesToReload = snippetTracker.getFilesToReload(editedAbsoluteFilepaths); + const hasSnippetDependencies = snippetTracker.hasSnippetDependencies(editedAbsoluteFilepaths); - editedAbsoluteFilepaths.length = 0; + if (hasSnippetDependencies) { + context.logger.info( + `Snippet dependencies detected. Reloading ${filesToReload.length} files (${editedAbsoluteFilepaths.length} changed, ${filesToReload.length - editedAbsoluteFilepaths.length} dependent pages)` + ); + } - isReloading = false; + const reloadedPreviewResult = await reloadDocsDefinition(filesToReload); - sendData({ - version: 1, - type: "finishReload" - }); + // Update the docs definition BEFORE notifying the browser, + // so the backend serves fresh data when the browser refreshes. + if (reloadedPreviewResult != null) { + // Detect slug changes before updating the docs definition + const slugChanges = slugTracker.updateAndDetectChanges(reloadedPreviewResult.docsDefinition); - if (reloadedPreviewResult != null) { - // Detect slug changes before updating the docs definition - const slugChanges = slugTracker.updateAndDetectChanges(reloadedPreviewResult.docsDefinition); + previewResult = reloadedPreviewResult; - previewResult = reloadedPreviewResult; + // Recompute translated definitions + translatedDefinitions = await computeTranslatedDefinitions(reloadedPreviewResult); + if (translatedDefinitions.size > 0) { + context.logger.debug(`Recomputed translations for ${translatedDefinitions.size} locale(s)`); + } - // Recompute translated definitions - translatedDefinitions = await computeTranslatedDefinitions(reloadedPreviewResult); - if (translatedDefinitions.size > 0) { - context.logger.debug(`Recomputed translations for ${translatedDefinitions.size} locale(s)`); - } + sendData({ + version: 1, + type: "finishReload" + }); - // Send navigateToSlug events for any slug changes - if (slugChanges.length > 0) { - slugChanges.forEach((change) => { - const eventData = { - version: 1, - type: "navigateToSlug", - oldSlug: change.oldSlug, - newSlug: change.newSlug - }; - - sendData(eventData); + // Send navigateToSlug events for any slug changes + if (slugChanges.length > 0) { + slugChanges.forEach((change) => { + const eventData = { + version: 1, + type: "navigateToSlug", + oldSlug: change.oldSlug, + newSlug: change.newSlug + }; + + sendData(eventData); + }); + } + } else { + sendData({ + version: 1, + type: "finishReload" }); } + } catch (err) { + context.logger.error(`Reload failed: ${extractErrorMessage(err)}`); + sendData({ + version: 1, + type: "finishReload" + }); + } finally { + editedAbsoluteFilepaths.length = 0; + isReloading = false; } })(); }, RELOAD_DEBOUNCE_MS); diff --git a/packages/cli/generation/local-generation/local-workspace-runner/src/GenerationRunner.ts b/packages/cli/generation/local-generation/local-workspace-runner/src/GenerationRunner.ts index 07747dae0d3a..e277eb278dbd 100644 --- a/packages/cli/generation/local-generation/local-workspace-runner/src/GenerationRunner.ts +++ b/packages/cli/generation/local-generation/local-workspace-runner/src/GenerationRunner.ts @@ -7,12 +7,15 @@ import { } from "@fern-api/api-workspace-commons"; import { SourceResolverImpl } from "@fern-api/cli-source-resolver"; import { generatorsYml, SNIPPET_JSON_FILENAME } from "@fern-api/configuration"; +import { ContainerRunner } from "@fern-api/core-utils"; import { AbsoluteFilePath, join, RelativeFilePath } from "@fern-api/fs-utils"; +import { type PipelineLogger, PostGenerationPipeline } from "@fern-api/generator-cli/pipeline"; import { generateIntermediateRepresentation } from "@fern-api/ir-generator"; import { IntermediateRepresentation } from "@fern-api/ir-sdk"; import { CliError, TaskAbortSignal, TaskContext } from "@fern-api/task-context"; import { FernGeneratorExec } from "@fern-fern/generator-exec-sdk"; import chalk from "chalk"; +import { assertVerifyPipelineSucceeded } from "./assertVerifyPipelineSucceeded.js"; import { generateDynamicSnippetTests } from "./dynamic-snippets/generateDynamicSnippetTests.js"; import { ExecutionEnvironment } from "./ExecutionEnvironment.js"; import { writeFilesToDiskAndRunGenerator } from "./runGenerator.js"; @@ -33,6 +36,33 @@ export declare namespace GenerationRunner { ai: generatorsYml.AiServicesSchema | undefined; skipFernignore?: boolean; skipAutogenerationIfManualExamplesExist?: boolean; + /** + * When true, run `PostGenerationPipeline` with `VerificationStep` after the + * generator finishes writing files. Exercises the same validator-container + * code path that `fern generate --local --verify` (and Fiddle) use today, so + * seed CI catches regressions in the verify.sh + validator-image plumbing + * end-to-end. + * + * Currently wired only for the TypeScript SDK generator, because it is the + * only generator emitting `.fern/verify.sh` today (FER-9681 will extend + * emission to the remaining language generators). + */ + verify?: boolean; + /** + * Container runtime to use when `verify` is true. Defaults to "docker". + * Ignored when `verify` is false. + */ + verifyRunner?: ContainerRunner; + /** + * Optional override for the validator-image tag. `VerificationStep` derives + * the image as `{generatorName}-validator:{version}` from + * `generatorVersions[generatorName]`. Seed sets this to `"latest"` because + * the generator runs at the `:local` tag locally but no `:local` validator + * image is built today — the published `:latest` is the closest analog. + * When undefined, the generator invocation's own version is used (the + * behavior `runLocalGenerationForWorkspace` relies on). + */ + verifyValidatorVersion?: string; } } @@ -54,7 +84,10 @@ export class GenerationRunner { skipUnstableDynamicSnippetTests, inspect, skipFernignore, - skipAutogenerationIfManualExamplesExist + skipAutogenerationIfManualExamplesExist, + verify, + verifyRunner, + verifyValidatorVersion }: GenerationRunner.RunArgs): Promise { const results = await Promise.all( generatorGroup.generators.map(async (generatorInvocation) => { @@ -106,6 +139,17 @@ export class GenerationRunner { `Skipping dynamic snippet tests; shouldGenerateDynamicSnippetTests: ${shouldGenerateDynamicSnippetTests}, language: ${generatorInvocation.language}` ); } + + if (verify === true) { + await runVerifyPipeline({ + outputDir: generatorInvocation.absolutePathToLocalOutput, + generatorName: generatorInvocation.name, + generatorVersion: verifyValidatorVersion ?? generatorInvocation.version, + cliVersion: workspace.cliVersion, + runner: verifyRunner ?? "docker", + context: interactiveTaskContext + }); + } } catch (error) { if (error instanceof TaskAbortSignal) { // already logged by failAndThrow, nothing to do @@ -228,3 +272,50 @@ export class GenerationRunner { }); } } + +/** + * Mirrors the `verifyOnlyPipelineEnabled` branch of `runLocalGenerationForWorkspace`: + * instantiates `PostGenerationPipeline` with only `VerificationStep` enabled so the + * same validator-container + image-derivation + `execInContainer` flow used by + * `fern generate --local --verify` is exercised end-to-end by the seed runner. + * + * `VerificationStep` no-ops when `.fern/verify.sh` is absent, so wiring a generator + * that does not emit the script (today: anything other than the TypeScript SDK) + * is a safe no-op rather than a hard failure. + */ +async function runVerifyPipeline({ + outputDir, + generatorName, + generatorVersion, + cliVersion, + runner, + context +}: { + outputDir: AbsoluteFilePath; + generatorName: string; + generatorVersion: string; + cliVersion: string | undefined; + runner: ContainerRunner; + context: TaskContext; +}): Promise { + const pipelineLogger: PipelineLogger = { + debug: (msg) => context.logger.debug(msg), + info: (msg) => context.logger.info(msg), + warn: (msg) => context.logger.warn(msg), + error: (msg) => context.logger.error(msg) + }; + + const pipeline = new PostGenerationPipeline( + { + outputDir, + verify: { enabled: true, runner }, + cliVersion: cliVersion ?? "unknown", + generatorVersions: { [generatorName]: generatorVersion }, + generatorName + }, + pipelineLogger + ); + + const pipelineResult = await pipeline.run(); + assertVerifyPipelineSucceeded(pipelineResult, generatorName); +} diff --git a/packages/cli/generation/local-generation/local-workspace-runner/src/__test__/assertVerifyPipelineSucceeded.test.ts b/packages/cli/generation/local-generation/local-workspace-runner/src/__test__/assertVerifyPipelineSucceeded.test.ts new file mode 100644 index 000000000000..ae9de8b0f350 --- /dev/null +++ b/packages/cli/generation/local-generation/local-workspace-runner/src/__test__/assertVerifyPipelineSucceeded.test.ts @@ -0,0 +1,139 @@ +import type { PipelineResult, VerificationStepResult } from "@fern-api/generator-cli/pipeline"; +import { CliError } from "@fern-api/task-context"; +import { describe, expect, it } from "vitest"; +import { assertVerifyPipelineSucceeded } from "../assertVerifyPipelineSucceeded.js"; + +const GENERATOR_NAME = "fernapi/fern-typescript-sdk"; + +function makeVerifyResult(overrides: Partial = {}): VerificationStepResult { + return { + executed: true, + success: true, + skipped: false, + ...overrides + }; +} + +describe("assertVerifyPipelineSucceeded", () => { + it("no-ops on a successful pipeline result", () => { + const result: PipelineResult = { + success: true, + steps: { verify: makeVerifyResult() } + }; + + expect(() => assertVerifyPipelineSucceeded(result, GENERATOR_NAME)).not.toThrow(); + }); + + it("no-ops when verify.sh is absent (step skipped, pipeline still succeeded)", () => { + // VerificationStep returns `skipped: true, success: true` when `.fern/verify.sh` + // is missing, so the orchestrator leaves `pipelineResult.success === true`. + // The helper must not throw — otherwise non-TS generators (no verify.sh today) + // would fail seed CI as soon as we flipped them into the allow-list. + const result: PipelineResult = { + success: true, + steps: { verify: makeVerifyResult({ skipped: true }) } + }; + + expect(() => assertVerifyPipelineSucceeded(result, GENERATOR_NAME)).not.toThrow(); + }); + + it("throws an InternalError CliError with validator stderr when verify ran and failed", () => { + const result: PipelineResult = { + success: false, + steps: { + verify: makeVerifyResult({ + success: false, + stderr: "tsc: src/index.ts(1,1): error TS1005: ';' expected." + }) + }, + errors: ["tsc: src/index.ts(1,1): error TS1005: ';' expected."] + }; + + expect(() => assertVerifyPipelineSucceeded(result, GENERATOR_NAME)).toThrowError(CliError); + + try { + assertVerifyPipelineSucceeded(result, GENERATOR_NAME); + } catch (error) { + expect(error).toBeInstanceOf(CliError); + const cliError = error as CliError; + expect(cliError.code).toBe(CliError.Code.InternalError); + expect(cliError.message).toContain(GENERATOR_NAME); + expect(cliError.message).toContain("error TS1005"); + } + }); + + it("throws when the pipeline failed before VerificationStep recorded a result", () => { + // Models the validator-image-pull-failure / container-start-failure branch: + // `VerificationStep.execute()` throws, the orchestrator catches and flips + // `result.success = false` without ever assigning `result.steps.verify`. + // Checking only `steps.verify.success` would silently no-op here — this test + // pins down the harder failure mode the user called out. + const result: PipelineResult = { + success: false, + steps: {}, + errors: ["verify step error: Unable to find image 'fernapi/fern-typescript-sdk-validator:latest' locally"] + }; + + expect(() => assertVerifyPipelineSucceeded(result, GENERATOR_NAME)).toThrowError(CliError); + + try { + assertVerifyPipelineSucceeded(result, GENERATOR_NAME); + } catch (error) { + expect(error).toBeInstanceOf(CliError); + const cliError = error as CliError; + expect(cliError.code).toBe(CliError.Code.InternalError); + expect(cliError.message).toContain("Unable to find image"); + } + }); + + it("falls back to errorMessage when no stderr and no pipeline-level errors are present", () => { + const result: PipelineResult = { + success: false, + steps: { + verify: makeVerifyResult({ + success: false, + errorMessage: "non-zero exit code from validator container" + }) + } + }; + + expect(() => assertVerifyPipelineSucceeded(result, GENERATOR_NAME)).toThrowError( + /non-zero exit code from validator container/ + ); + }); + + it("falls back to a generic message when no other detail is available", () => { + const result: PipelineResult = { + success: false, + steps: {} + }; + + expect(() => assertVerifyPipelineSucceeded(result, GENERATOR_NAME)).toThrowError( + /verification pipeline failed/ + ); + }); + + it("prefers validator stderr over generic pipeline errors so the most actionable signal wins", () => { + const result: PipelineResult = { + success: false, + steps: { + verify: makeVerifyResult({ + success: false, + stderr: "actionable validator stderr", + errorMessage: "less specific error message" + }) + }, + errors: ["generic pipeline error"] + }; + + try { + assertVerifyPipelineSucceeded(result, GENERATOR_NAME); + } catch (error) { + expect(error).toBeInstanceOf(CliError); + const cliError = error as CliError; + expect(cliError.message).toContain("actionable validator stderr"); + expect(cliError.message).not.toContain("generic pipeline error"); + expect(cliError.message).not.toContain("less specific error message"); + } + }); +}); diff --git a/packages/cli/generation/local-generation/local-workspace-runner/src/assertVerifyPipelineSucceeded.ts b/packages/cli/generation/local-generation/local-workspace-runner/src/assertVerifyPipelineSucceeded.ts new file mode 100644 index 000000000000..4ffc6442c66d --- /dev/null +++ b/packages/cli/generation/local-generation/local-workspace-runner/src/assertVerifyPipelineSucceeded.ts @@ -0,0 +1,44 @@ +import type { PipelineResult } from "@fern-api/generator-cli/pipeline"; +import { CliError } from "@fern-api/task-context"; + +/** + * Throws a `CliError` when `PostGenerationPipeline` reports failure, exported so it + * can be unit-tested without spinning up the real pipeline. + * + * `pipelineResult.success` is the canonical signal: it's `true` only when every step + * (including `VerificationStep`) returned `success: true` and nothing threw. We key + * off it instead of `pipelineResult.steps.verify.success` because the orchestrator + * only populates `steps.verify` after the step returns cleanly — if the validator + * image fails to pull or the container fails to start, the step throws, the + * orchestrator catches and sets `success: false` without ever assigning + * `steps.verify`. Checking only `steps.verify.success` would silently no-op in that + * case and mask a real verify-pipeline failure in seed CI. + * + * Detail message preference: validator stderr (most actionable), then accumulated + * pipeline errors (covers the thrown-before-result branch), then `errorMessage`, + * then a generic fallback so the user always gets *something*. + */ +export function assertVerifyPipelineSucceeded(pipelineResult: PipelineResult, generatorName: string): void { + if (pipelineResult.success) { + return; + } + + const verifyResult = pipelineResult.steps.verify; + const errors = pipelineResult.errors ?? []; + + let detail: string; + if (verifyResult?.stderr != null && verifyResult.stderr.length > 0) { + detail = verifyResult.stderr; + } else if (errors.length > 0) { + detail = errors.join("\n"); + } else if (verifyResult?.errorMessage != null) { + detail = verifyResult.errorMessage; + } else { + detail = "verification pipeline failed"; + } + + throw new CliError({ + message: `Verification failed for ${generatorName}: ${detail}`, + code: CliError.Code.InternalError + }); +} diff --git a/packages/seed/src/commands/test/test-runner/ContainerTestRunner.ts b/packages/seed/src/commands/test/test-runner/ContainerTestRunner.ts index c4b15f553cbd..8a5dc3380451 100644 --- a/packages/seed/src/commands/test/test-runner/ContainerTestRunner.ts +++ b/packages/seed/src/commands/test/test-runner/ContainerTestRunner.ts @@ -10,6 +10,7 @@ import path from "path"; import { runScript } from "../../../runScript.js"; import { ALL_AUDIENCES, DUMMY_ORGANIZATION } from "../../../utils/constants.js"; +import { generatorEmitsVerifyScript } from "../../../utils/generatorEmitsVerifyScript.js"; import { getGeneratorInvocation } from "../../../utils/getGeneratorInvocation.js"; import { getWorktreeSuffix } from "../../../utils/getWorktreeSuffix.js"; import { ParsedDockerName, parseDockerOrThrow } from "../../../utils/parseDockerOrThrow.js"; @@ -175,6 +176,9 @@ export class ContainerTestRunner extends TestRunner { }) ] }; + const generatorName = this.getParsedDockerImageName().name; + const verifyEnabled = generatorEmitsVerifyScript(generatorName); + await runContainerizedGenerationForSeed({ organization: organization ?? DUMMY_ORGANIZATION, absolutePathToFernConfig: absolutePathToFernConfig ?? absolutePathToFernDefinition, @@ -191,7 +195,13 @@ export class ContainerTestRunner extends TestRunner { runner: this.runner, executionEnvironment: this.reusableContainer, ai: undefined, - skipAutogenerationIfManualExamplesExist + skipAutogenerationIfManualExamplesExist, + verify: verifyEnabled, + verifyRunner: this.runner, + // Generator runs at :local but the validator image isn't built locally; + // pull the published :latest validator. This mirrors what a customer's + // `fern generate --local --verify` would do against a published generator. + verifyValidatorVersion: verifyEnabled ? "latest" : undefined }); } diff --git a/packages/seed/src/commands/test/test-runner/LocalTestRunner.ts b/packages/seed/src/commands/test/test-runner/LocalTestRunner.ts index 4594622938fa..7bd062af7133 100644 --- a/packages/seed/src/commands/test/test-runner/LocalTestRunner.ts +++ b/packages/seed/src/commands/test/test-runner/LocalTestRunner.ts @@ -7,6 +7,7 @@ import path from "path"; import { LocalBuildInfo } from "../../../config/api/index.js"; import { runScript } from "../../../runScript.js"; import { ALL_AUDIENCES, DUMMY_ORGANIZATION } from "../../../utils/constants.js"; +import { generatorEmitsVerifyScript } from "../../../utils/generatorEmitsVerifyScript.js"; import { getGeneratorInvocation } from "../../../utils/getGeneratorInvocation.js"; import { TestRunner } from "./TestRunner.js"; @@ -84,6 +85,9 @@ export class LocalTestRunner extends TestRunner { ] }; + const generatorName = this.getParsedDockerImageName().name; + const verifyEnabled = generatorEmitsVerifyScript(generatorName); + await runNativeGenerationForSeed( { organization: organization ?? DUMMY_ORGANIZATION, @@ -97,7 +101,12 @@ export class LocalTestRunner extends TestRunner { skipUnstableDynamicSnippetTests: true, inspect, ai: undefined, - skipAutogenerationIfManualExamplesExist + skipAutogenerationIfManualExamplesExist, + verify: verifyEnabled, + // Generator runs at :local but the validator image isn't built locally; + // pull the published :latest validator. This mirrors what a customer's + // `fern generate --local --verify` would do against a published generator. + verifyValidatorVersion: verifyEnabled ? "latest" : undefined }, commands, this.generator.workspaceConfig.test.local?.workingDirectory, diff --git a/packages/seed/src/commands/test/test-runner/TestRunner.ts b/packages/seed/src/commands/test/test-runner/TestRunner.ts index f134e72c42af..7db794c4779e 100644 --- a/packages/seed/src/commands/test/test-runner/TestRunner.ts +++ b/packages/seed/src/commands/test/test-runner/TestRunner.ts @@ -10,6 +10,7 @@ import { GeneratorWorkspace } from "../../../loadGeneratorWorkspaces.js"; import { Semaphore } from "../../../Semaphore.js"; import { Stopwatch } from "../../../Stopwatch.js"; import { convertGeneratorWorkspaceToFernWorkspace } from "../../../utils/convertSeedWorkspaceToFernWorkspace.js"; +import { generatorEmitsVerifyScript } from "../../../utils/generatorEmitsVerifyScript.js"; import { ParsedDockerName, parseDockerOrThrow } from "../../../utils/parseDockerOrThrow.js"; import { workspaceShouldGenerateDynamicSnippetTests } from "../../../workspaceShouldGenerateDynamicSnippetTests.js"; import { ScriptRunner } from "../index.js"; @@ -345,6 +346,24 @@ export abstract class TestRunner { }; } + // For generators that emit `.fern/verify.sh`, `runGenerator` above already + // ran `PostGenerationPipeline` + `VerificationStep` against the output + // directory — the exact same code path that `fern generate --local --verify` + // and Fiddle execute in production. Re-running the seed.yml `scripts` block + // would just duplicate that work with a different (less-faithful) runner, + // so we skip it here. The `scripts` block stays in seed.yml as a fallback + // for any fixture that fails to emit `verify.sh` and as the canonical + // build/test recipe until FER-9681 extends self-verification to every + // language SDK generator. + if (generatorEmitsVerifyScript(this.getParsedDockerImageName().name)) { + return { + type: "success", + id: fixture, + outputFolder, + metrics + }; + } + const scriptResponse = await this.scriptRunner?.run({ taskContext, outputDir, diff --git a/packages/seed/src/utils/generatorEmitsVerifyScript.ts b/packages/seed/src/utils/generatorEmitsVerifyScript.ts new file mode 100644 index 000000000000..ff2e97e6ecd0 --- /dev/null +++ b/packages/seed/src/utils/generatorEmitsVerifyScript.ts @@ -0,0 +1,23 @@ +/** + * Generators that emit `.fern/verify.sh` after generation. The seed runner wires + * `PostGenerationPipeline` + `VerificationStep` only for these generators so seed + * CI exercises the same validator-container code path that + * `fern generate --local --verify` (and Fiddle) use end-to-end. + * + * Today only the TypeScript SDK generator emits the script (see PR #15718). + * FER-9681 tracks extending self-verification to the remaining language SDK + * generators - add each one to this set as they ship. + */ +const GENERATORS_EMITTING_VERIFY_SCRIPT = new Set([ + "fernapi/fern-typescript-sdk", + "fernapi/fern-typescript-node-sdk" +]); + +/** + * Returns true when the generator identified by `dockerImageName` is known to + * emit `.fern/verify.sh` after generation. `dockerImageName` is the repository + * portion of the docker reference (no tag), e.g. `"fernapi/fern-typescript-sdk"`. + */ +export function generatorEmitsVerifyScript(dockerImageName: string): boolean { + return GENERATORS_EMITTING_VERIFY_SCRIPT.has(dockerImageName); +} diff --git a/seed/java-sdk/allof-inline/README.md b/seed/java-sdk/allof-inline/README.md index 77758a0def3c..1b36ba06093d 100644 --- a/seed/java-sdk/allof-inline/README.md +++ b/seed/java-sdk/allof-inline/README.md @@ -58,7 +58,7 @@ package com.example.usage; import com.seed.api.SeedApiClient; import com.seed.api.requests.RuleCreateRequest; -import com.seed.api.types.RuleExecutionContext; +import com.seed.api.types.RuleCreateRequestExecutionContext; public class Example { public static void main(String[] args) { @@ -70,7 +70,7 @@ public class Example { RuleCreateRequest .builder() .name("name") - .executionContext(RuleExecutionContext.PROD) + .executionContext(RuleCreateRequestExecutionContext.PROD) .build() ); } diff --git a/seed/java-sdk/allof-inline/reference.md b/seed/java-sdk/allof-inline/reference.md index c37cf3e44a84..3ffb31766886 100644 --- a/seed/java-sdk/allof-inline/reference.md +++ b/seed/java-sdk/allof-inline/reference.md @@ -60,7 +60,7 @@ client.createRule( RuleCreateRequest .builder() .name("name") - .executionContext(RuleExecutionContext.PROD) + .executionContext(RuleCreateRequestExecutionContext.PROD) .build() ); ``` @@ -85,7 +85,7 @@ client.createRule(
-**executionContext:** `RuleExecutionContext` +**executionContext:** `RuleCreateRequestExecutionContext` — Execution context for the rule, excluding the prod environment.
diff --git a/seed/java-sdk/allof-inline/snippet.json b/seed/java-sdk/allof-inline/snippet.json index da207fd21348..affeed349f90 100644 --- a/seed/java-sdk/allof-inline/snippet.json +++ b/seed/java-sdk/allof-inline/snippet.json @@ -22,8 +22,8 @@ }, "snippet": { "type": "java", - "sync_client": "package com.example.usage;\n\nimport com.seed.api.SeedApiClient;\nimport com.seed.api.requests.RuleCreateRequest;\nimport com.seed.api.types.RuleExecutionContext;\n\npublic class Example {\n public static void main(String[] args) {\n SeedApiClient client = SeedApiClient\n .builder()\n .build();\n\n client.createRule(\n RuleCreateRequest\n .builder()\n .name(\"name\")\n .executionContext(RuleExecutionContext.PROD)\n .build()\n );\n }\n}\n", - "async_client": "package com.example.usage;\n\nimport com.seed.api.SeedApiClient;\nimport com.seed.api.requests.RuleCreateRequest;\nimport com.seed.api.types.RuleExecutionContext;\n\npublic class Example {\n public static void main(String[] args) {\n SeedApiClient client = SeedApiClient\n .builder()\n .build();\n\n client.createRule(\n RuleCreateRequest\n .builder()\n .name(\"name\")\n .executionContext(RuleExecutionContext.PROD)\n .build()\n );\n }\n}\n" + "sync_client": "package com.example.usage;\n\nimport com.seed.api.SeedApiClient;\nimport com.seed.api.requests.RuleCreateRequest;\nimport com.seed.api.types.RuleCreateRequestExecutionContext;\n\npublic class Example {\n public static void main(String[] args) {\n SeedApiClient client = SeedApiClient\n .builder()\n .build();\n\n client.createRule(\n RuleCreateRequest\n .builder()\n .name(\"name\")\n .executionContext(RuleCreateRequestExecutionContext.PROD)\n .build()\n );\n }\n}\n", + "async_client": "package com.example.usage;\n\nimport com.seed.api.SeedApiClient;\nimport com.seed.api.requests.RuleCreateRequest;\nimport com.seed.api.types.RuleCreateRequestExecutionContext;\n\npublic class Example {\n public static void main(String[] args) {\n SeedApiClient client = SeedApiClient\n .builder()\n .build();\n\n client.createRule(\n RuleCreateRequest\n .builder()\n .name(\"name\")\n .executionContext(RuleCreateRequestExecutionContext.PROD)\n .build()\n );\n }\n}\n" } }, { diff --git a/seed/java-sdk/allof-inline/src/main/java/com/seed/api/requests/RuleCreateRequest.java b/seed/java-sdk/allof-inline/src/main/java/com/seed/api/requests/RuleCreateRequest.java index 0f39ad2d3cf4..743a6644a35f 100644 --- a/seed/java-sdk/allof-inline/src/main/java/com/seed/api/requests/RuleCreateRequest.java +++ b/seed/java-sdk/allof-inline/src/main/java/com/seed/api/requests/RuleCreateRequest.java @@ -11,7 +11,7 @@ import com.fasterxml.jackson.annotation.JsonSetter; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.seed.api.core.ObjectMappers; -import com.seed.api.types.RuleExecutionContext; +import com.seed.api.types.RuleCreateRequestExecutionContext; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -22,12 +22,12 @@ public final class RuleCreateRequest { private final String name; - private final RuleExecutionContext executionContext; + private final RuleCreateRequestExecutionContext executionContext; private final Map additionalProperties; private RuleCreateRequest( - String name, RuleExecutionContext executionContext, Map additionalProperties) { + String name, RuleCreateRequestExecutionContext executionContext, Map additionalProperties) { this.name = name; this.executionContext = executionContext; this.additionalProperties = additionalProperties; @@ -38,8 +38,11 @@ public String getName() { return name; } + /** + * @return Execution context for the rule, excluding the prod environment. + */ @JsonProperty("executionContext") - public RuleExecutionContext getExecutionContext() { + public RuleCreateRequestExecutionContext getExecutionContext() { return executionContext; } @@ -79,7 +82,10 @@ public interface NameStage { } public interface ExecutionContextStage { - _FinalStage executionContext(@NotNull RuleExecutionContext executionContext); + /** + *

Execution context for the rule, excluding the prod environment.

+ */ + _FinalStage executionContext(@NotNull RuleCreateRequestExecutionContext executionContext); } public interface _FinalStage { @@ -94,7 +100,7 @@ public interface _FinalStage { public static final class Builder implements NameStage, ExecutionContextStage, _FinalStage { private String name; - private RuleExecutionContext executionContext; + private RuleCreateRequestExecutionContext executionContext; @JsonAnySetter private Map additionalProperties = new HashMap<>(); @@ -115,9 +121,14 @@ public ExecutionContextStage name(@NotNull String name) { return this; } + /** + *

Execution context for the rule, excluding the prod environment.

+ *

Execution context for the rule, excluding the prod environment.

+ * @return Reference to {@code this} so that method calls can be chained together. + */ @java.lang.Override @JsonSetter("executionContext") - public _FinalStage executionContext(@NotNull RuleExecutionContext executionContext) { + public _FinalStage executionContext(@NotNull RuleCreateRequestExecutionContext executionContext) { this.executionContext = Objects.requireNonNull(executionContext, "executionContext must not be null"); return this; } diff --git a/seed/java-sdk/allof-inline/src/main/java/com/seed/api/types/RuleCreateRequestExecutionContext.java b/seed/java-sdk/allof-inline/src/main/java/com/seed/api/types/RuleCreateRequestExecutionContext.java new file mode 100644 index 000000000000..4ad978ce3bba --- /dev/null +++ b/seed/java-sdk/allof-inline/src/main/java/com/seed/api/types/RuleCreateRequestExecutionContext.java @@ -0,0 +1,96 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.seed.api.types; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public final class RuleCreateRequestExecutionContext { + public static final RuleCreateRequestExecutionContext PROD = + new RuleCreateRequestExecutionContext(Value.PROD, "prod"); + + public static final RuleCreateRequestExecutionContext DEV = new RuleCreateRequestExecutionContext(Value.DEV, "dev"); + + public static final RuleCreateRequestExecutionContext STAGING = + new RuleCreateRequestExecutionContext(Value.STAGING, "staging"); + + private final Value value; + + private final String string; + + RuleCreateRequestExecutionContext(Value value, String string) { + this.value = value; + this.string = string; + } + + public Value getEnumValue() { + return value; + } + + @java.lang.Override + @JsonValue + public String toString() { + return this.string; + } + + @java.lang.Override + public boolean equals(Object other) { + return (this == other) + || (other instanceof RuleCreateRequestExecutionContext + && this.string.equals(((RuleCreateRequestExecutionContext) other).string)); + } + + @java.lang.Override + public int hashCode() { + return this.string.hashCode(); + } + + public T visit(Visitor visitor) { + switch (value) { + case PROD: + return visitor.visitProd(); + case DEV: + return visitor.visitDev(); + case STAGING: + return visitor.visitStaging(); + case UNKNOWN: + default: + return visitor.visitUnknown(string); + } + } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static RuleCreateRequestExecutionContext valueOf(String value) { + switch (value) { + case "prod": + return PROD; + case "dev": + return DEV; + case "staging": + return STAGING; + default: + return new RuleCreateRequestExecutionContext(Value.UNKNOWN, value); + } + } + + public enum Value { + PROD, + + STAGING, + + DEV, + + UNKNOWN + } + + public interface Visitor { + T visitProd(); + + T visitStaging(); + + T visitDev(); + + T visitUnknown(String unknownType); + } +} diff --git a/seed/java-sdk/allof-inline/src/main/java/com/snippets/Example2.java b/seed/java-sdk/allof-inline/src/main/java/com/snippets/Example2.java index e0f6cdddaea0..25c637e47b94 100644 --- a/seed/java-sdk/allof-inline/src/main/java/com/snippets/Example2.java +++ b/seed/java-sdk/allof-inline/src/main/java/com/snippets/Example2.java @@ -2,7 +2,7 @@ import com.seed.api.SeedApiClient; import com.seed.api.requests.RuleCreateRequest; -import com.seed.api.types.RuleExecutionContext; +import com.seed.api.types.RuleCreateRequestExecutionContext; public class Example2 { public static void main(String[] args) { @@ -11,7 +11,7 @@ public static void main(String[] args) { client.createRule(RuleCreateRequest.builder() .name("name") - .executionContext(RuleExecutionContext.PROD) + .executionContext(RuleCreateRequestExecutionContext.PROD) .build()); } } diff --git a/seed/java-sdk/allof-inline/src/main/java/com/snippets/Example3.java b/seed/java-sdk/allof-inline/src/main/java/com/snippets/Example3.java index 7f1d77d08358..10117a5c8ff0 100644 --- a/seed/java-sdk/allof-inline/src/main/java/com/snippets/Example3.java +++ b/seed/java-sdk/allof-inline/src/main/java/com/snippets/Example3.java @@ -2,7 +2,7 @@ import com.seed.api.SeedApiClient; import com.seed.api.requests.RuleCreateRequest; -import com.seed.api.types.RuleExecutionContext; +import com.seed.api.types.RuleCreateRequestExecutionContext; public class Example3 { public static void main(String[] args) { @@ -11,7 +11,7 @@ public static void main(String[] args) { client.createRule(RuleCreateRequest.builder() .name("name") - .executionContext(RuleExecutionContext.PROD) + .executionContext(RuleCreateRequestExecutionContext.PROD) .build()); } } diff --git a/seed/java-sdk/allof/README.md b/seed/java-sdk/allof/README.md index 7ac816f96126..efd496c38183 100644 --- a/seed/java-sdk/allof/README.md +++ b/seed/java-sdk/allof/README.md @@ -58,7 +58,7 @@ package com.example.usage; import com.seed.api.SeedApiClient; import com.seed.api.requests.RuleCreateRequest; -import com.seed.api.types.RuleExecutionContext; +import com.seed.api.types.RuleCreateRequestExecutionContext; public class Example { public static void main(String[] args) { @@ -70,7 +70,7 @@ public class Example { RuleCreateRequest .builder() .name("name") - .executionContext(RuleExecutionContext.PROD) + .executionContext(RuleCreateRequestExecutionContext.PROD) .build() ); } diff --git a/seed/java-sdk/allof/reference.md b/seed/java-sdk/allof/reference.md index c37cf3e44a84..3ffb31766886 100644 --- a/seed/java-sdk/allof/reference.md +++ b/seed/java-sdk/allof/reference.md @@ -60,7 +60,7 @@ client.createRule( RuleCreateRequest .builder() .name("name") - .executionContext(RuleExecutionContext.PROD) + .executionContext(RuleCreateRequestExecutionContext.PROD) .build() ); ``` @@ -85,7 +85,7 @@ client.createRule(
-**executionContext:** `RuleExecutionContext` +**executionContext:** `RuleCreateRequestExecutionContext` — Execution context for the rule, excluding the prod environment.
diff --git a/seed/java-sdk/allof/snippet.json b/seed/java-sdk/allof/snippet.json index 7f041f8b8f9b..27798905f781 100644 --- a/seed/java-sdk/allof/snippet.json +++ b/seed/java-sdk/allof/snippet.json @@ -22,8 +22,8 @@ }, "snippet": { "type": "java", - "sync_client": "package com.example.usage;\n\nimport com.seed.api.SeedApiClient;\nimport com.seed.api.requests.RuleCreateRequest;\nimport com.seed.api.types.RuleExecutionContext;\n\npublic class Example {\n public static void main(String[] args) {\n SeedApiClient client = SeedApiClient\n .builder()\n .build();\n\n client.createRule(\n RuleCreateRequest\n .builder()\n .name(\"name\")\n .executionContext(RuleExecutionContext.PROD)\n .build()\n );\n }\n}\n", - "async_client": "package com.example.usage;\n\nimport com.seed.api.SeedApiClient;\nimport com.seed.api.requests.RuleCreateRequest;\nimport com.seed.api.types.RuleExecutionContext;\n\npublic class Example {\n public static void main(String[] args) {\n SeedApiClient client = SeedApiClient\n .builder()\n .build();\n\n client.createRule(\n RuleCreateRequest\n .builder()\n .name(\"name\")\n .executionContext(RuleExecutionContext.PROD)\n .build()\n );\n }\n}\n" + "sync_client": "package com.example.usage;\n\nimport com.seed.api.SeedApiClient;\nimport com.seed.api.requests.RuleCreateRequest;\nimport com.seed.api.types.RuleCreateRequestExecutionContext;\n\npublic class Example {\n public static void main(String[] args) {\n SeedApiClient client = SeedApiClient\n .builder()\n .build();\n\n client.createRule(\n RuleCreateRequest\n .builder()\n .name(\"name\")\n .executionContext(RuleCreateRequestExecutionContext.PROD)\n .build()\n );\n }\n}\n", + "async_client": "package com.example.usage;\n\nimport com.seed.api.SeedApiClient;\nimport com.seed.api.requests.RuleCreateRequest;\nimport com.seed.api.types.RuleCreateRequestExecutionContext;\n\npublic class Example {\n public static void main(String[] args) {\n SeedApiClient client = SeedApiClient\n .builder()\n .build();\n\n client.createRule(\n RuleCreateRequest\n .builder()\n .name(\"name\")\n .executionContext(RuleCreateRequestExecutionContext.PROD)\n .build()\n );\n }\n}\n" } }, { diff --git a/seed/java-sdk/allof/src/main/java/com/seed/api/requests/RuleCreateRequest.java b/seed/java-sdk/allof/src/main/java/com/seed/api/requests/RuleCreateRequest.java index 0f39ad2d3cf4..743a6644a35f 100644 --- a/seed/java-sdk/allof/src/main/java/com/seed/api/requests/RuleCreateRequest.java +++ b/seed/java-sdk/allof/src/main/java/com/seed/api/requests/RuleCreateRequest.java @@ -11,7 +11,7 @@ import com.fasterxml.jackson.annotation.JsonSetter; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.seed.api.core.ObjectMappers; -import com.seed.api.types.RuleExecutionContext; +import com.seed.api.types.RuleCreateRequestExecutionContext; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -22,12 +22,12 @@ public final class RuleCreateRequest { private final String name; - private final RuleExecutionContext executionContext; + private final RuleCreateRequestExecutionContext executionContext; private final Map additionalProperties; private RuleCreateRequest( - String name, RuleExecutionContext executionContext, Map additionalProperties) { + String name, RuleCreateRequestExecutionContext executionContext, Map additionalProperties) { this.name = name; this.executionContext = executionContext; this.additionalProperties = additionalProperties; @@ -38,8 +38,11 @@ public String getName() { return name; } + /** + * @return Execution context for the rule, excluding the prod environment. + */ @JsonProperty("executionContext") - public RuleExecutionContext getExecutionContext() { + public RuleCreateRequestExecutionContext getExecutionContext() { return executionContext; } @@ -79,7 +82,10 @@ public interface NameStage { } public interface ExecutionContextStage { - _FinalStage executionContext(@NotNull RuleExecutionContext executionContext); + /** + *

Execution context for the rule, excluding the prod environment.

+ */ + _FinalStage executionContext(@NotNull RuleCreateRequestExecutionContext executionContext); } public interface _FinalStage { @@ -94,7 +100,7 @@ public interface _FinalStage { public static final class Builder implements NameStage, ExecutionContextStage, _FinalStage { private String name; - private RuleExecutionContext executionContext; + private RuleCreateRequestExecutionContext executionContext; @JsonAnySetter private Map additionalProperties = new HashMap<>(); @@ -115,9 +121,14 @@ public ExecutionContextStage name(@NotNull String name) { return this; } + /** + *

Execution context for the rule, excluding the prod environment.

+ *

Execution context for the rule, excluding the prod environment.

+ * @return Reference to {@code this} so that method calls can be chained together. + */ @java.lang.Override @JsonSetter("executionContext") - public _FinalStage executionContext(@NotNull RuleExecutionContext executionContext) { + public _FinalStage executionContext(@NotNull RuleCreateRequestExecutionContext executionContext) { this.executionContext = Objects.requireNonNull(executionContext, "executionContext must not be null"); return this; } diff --git a/seed/java-sdk/allof/src/main/java/com/seed/api/types/RuleCreateRequestExecutionContext.java b/seed/java-sdk/allof/src/main/java/com/seed/api/types/RuleCreateRequestExecutionContext.java new file mode 100644 index 000000000000..4ad978ce3bba --- /dev/null +++ b/seed/java-sdk/allof/src/main/java/com/seed/api/types/RuleCreateRequestExecutionContext.java @@ -0,0 +1,96 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.seed.api.types; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public final class RuleCreateRequestExecutionContext { + public static final RuleCreateRequestExecutionContext PROD = + new RuleCreateRequestExecutionContext(Value.PROD, "prod"); + + public static final RuleCreateRequestExecutionContext DEV = new RuleCreateRequestExecutionContext(Value.DEV, "dev"); + + public static final RuleCreateRequestExecutionContext STAGING = + new RuleCreateRequestExecutionContext(Value.STAGING, "staging"); + + private final Value value; + + private final String string; + + RuleCreateRequestExecutionContext(Value value, String string) { + this.value = value; + this.string = string; + } + + public Value getEnumValue() { + return value; + } + + @java.lang.Override + @JsonValue + public String toString() { + return this.string; + } + + @java.lang.Override + public boolean equals(Object other) { + return (this == other) + || (other instanceof RuleCreateRequestExecutionContext + && this.string.equals(((RuleCreateRequestExecutionContext) other).string)); + } + + @java.lang.Override + public int hashCode() { + return this.string.hashCode(); + } + + public T visit(Visitor visitor) { + switch (value) { + case PROD: + return visitor.visitProd(); + case DEV: + return visitor.visitDev(); + case STAGING: + return visitor.visitStaging(); + case UNKNOWN: + default: + return visitor.visitUnknown(string); + } + } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static RuleCreateRequestExecutionContext valueOf(String value) { + switch (value) { + case "prod": + return PROD; + case "dev": + return DEV; + case "staging": + return STAGING; + default: + return new RuleCreateRequestExecutionContext(Value.UNKNOWN, value); + } + } + + public enum Value { + PROD, + + STAGING, + + DEV, + + UNKNOWN + } + + public interface Visitor { + T visitProd(); + + T visitStaging(); + + T visitDev(); + + T visitUnknown(String unknownType); + } +} diff --git a/seed/java-sdk/allof/src/main/java/com/snippets/Example2.java b/seed/java-sdk/allof/src/main/java/com/snippets/Example2.java index e0f6cdddaea0..25c637e47b94 100644 --- a/seed/java-sdk/allof/src/main/java/com/snippets/Example2.java +++ b/seed/java-sdk/allof/src/main/java/com/snippets/Example2.java @@ -2,7 +2,7 @@ import com.seed.api.SeedApiClient; import com.seed.api.requests.RuleCreateRequest; -import com.seed.api.types.RuleExecutionContext; +import com.seed.api.types.RuleCreateRequestExecutionContext; public class Example2 { public static void main(String[] args) { @@ -11,7 +11,7 @@ public static void main(String[] args) { client.createRule(RuleCreateRequest.builder() .name("name") - .executionContext(RuleExecutionContext.PROD) + .executionContext(RuleCreateRequestExecutionContext.PROD) .build()); } } diff --git a/seed/java-sdk/allof/src/main/java/com/snippets/Example3.java b/seed/java-sdk/allof/src/main/java/com/snippets/Example3.java index 7f1d77d08358..10117a5c8ff0 100644 --- a/seed/java-sdk/allof/src/main/java/com/snippets/Example3.java +++ b/seed/java-sdk/allof/src/main/java/com/snippets/Example3.java @@ -2,7 +2,7 @@ import com.seed.api.SeedApiClient; import com.seed.api.requests.RuleCreateRequest; -import com.seed.api.types.RuleExecutionContext; +import com.seed.api.types.RuleCreateRequestExecutionContext; public class Example3 { public static void main(String[] args) { @@ -11,7 +11,7 @@ public static void main(String[] args) { client.createRule(RuleCreateRequest.builder() .name("name") - .executionContext(RuleExecutionContext.PROD) + .executionContext(RuleCreateRequestExecutionContext.PROD) .build()); } } diff --git a/seed/openapi/allof-inline/openapi.yml b/seed/openapi/allof-inline/openapi.yml index 50370d5d0760..d4b725927f85 100644 --- a/seed/openapi/allof-inline/openapi.yml +++ b/seed/openapi/allof-inline/openapi.yml @@ -71,7 +71,10 @@ paths: examples: - name executionContext: - $ref: '#/components/schemas/RuleExecutionContext' + $ref: '#/components/schemas/RuleCreateRequestExecutionContext' + description: >- + Execution context for the rule, excluding the prod + environment. required: - name - executionContext @@ -148,6 +151,14 @@ paths: summary: Get an organization with merged object-typed properties components: schemas: + RuleCreateRequestExecutionContext: + title: RuleCreateRequestExecutionContext + type: string + enum: + - prod + - staging + - dev + description: Execution context for the rule, excluding the prod environment. PaginatedResult: title: PaginatedResult type: object diff --git a/seed/openapi/allof/openapi.yml b/seed/openapi/allof/openapi.yml index 1975805a28f3..971c82c6b12f 100644 --- a/seed/openapi/allof/openapi.yml +++ b/seed/openapi/allof/openapi.yml @@ -71,7 +71,10 @@ paths: examples: - name executionContext: - $ref: '#/components/schemas/RuleExecutionContext' + $ref: '#/components/schemas/RuleCreateRequestExecutionContext' + description: >- + Execution context for the rule, excluding the prod + environment. required: - name - executionContext @@ -148,6 +151,14 @@ paths: summary: Get an organization with merged object-typed properties components: schemas: + RuleCreateRequestExecutionContext: + title: RuleCreateRequestExecutionContext + type: string + enum: + - prod + - staging + - dev + description: Execution context for the rule, excluding the prod environment. PaginatedResult: title: PaginatedResult type: object diff --git a/seed/python-sdk/allof-inline/no-custom-config/poetry.lock b/seed/python-sdk/allof-inline/no-custom-config/poetry.lock index ca6327856cec..05af2c1be9cb 100644 --- a/seed/python-sdk/allof-inline/no-custom-config/poetry.lock +++ b/seed/python-sdk/allof-inline/no-custom-config/poetry.lock @@ -1281,13 +1281,13 @@ six = ">=1.5" [[package]] name = "requests" -version = "2.34.0" +version = "2.34.1" description = "Python HTTP for Humans." optional = false python-versions = ">=3.10" files = [ - {file = "requests-2.34.0-py3-none-any.whl", hash = "sha256:917520a21b767485ce7c588f4ebb917c436b24a31231b44228715eaeb5a52c60"}, - {file = "requests-2.34.0.tar.gz", hash = "sha256:7d62fe92f50eb82c529b0916bb445afa1531a566fc8f35ffdc64446e771b856a"}, + {file = "requests-2.34.1-py3-none-any.whl", hash = "sha256:bf38a3ff993960d3dd819c08862c40b3c703306eb7c744fcd9f4ddbb95b548f0"}, + {file = "requests-2.34.1.tar.gz", hash = "sha256:0fc5669f2b69704449fe1552360bd2a73a54512dfd03e65529157f1513322beb"}, ] [package.dependencies] diff --git a/seed/python-sdk/allof/no-custom-config/poetry.lock b/seed/python-sdk/allof/no-custom-config/poetry.lock index ca6327856cec..05af2c1be9cb 100644 --- a/seed/python-sdk/allof/no-custom-config/poetry.lock +++ b/seed/python-sdk/allof/no-custom-config/poetry.lock @@ -1281,13 +1281,13 @@ six = ">=1.5" [[package]] name = "requests" -version = "2.34.0" +version = "2.34.1" description = "Python HTTP for Humans." optional = false python-versions = ">=3.10" files = [ - {file = "requests-2.34.0-py3-none-any.whl", hash = "sha256:917520a21b767485ce7c588f4ebb917c436b24a31231b44228715eaeb5a52c60"}, - {file = "requests-2.34.0.tar.gz", hash = "sha256:7d62fe92f50eb82c529b0916bb445afa1531a566fc8f35ffdc64446e771b856a"}, + {file = "requests-2.34.1-py3-none-any.whl", hash = "sha256:bf38a3ff993960d3dd819c08862c40b3c703306eb7c744fcd9f4ddbb95b548f0"}, + {file = "requests-2.34.1.tar.gz", hash = "sha256:0fc5669f2b69704449fe1552360bd2a73a54512dfd03e65529157f1513322beb"}, ] [package.dependencies] diff --git a/seed/python-sdk/basic-auth-pw-omitted/with-wire-tests/poetry.lock b/seed/python-sdk/basic-auth-pw-omitted/with-wire-tests/poetry.lock index ca6327856cec..05af2c1be9cb 100644 --- a/seed/python-sdk/basic-auth-pw-omitted/with-wire-tests/poetry.lock +++ b/seed/python-sdk/basic-auth-pw-omitted/with-wire-tests/poetry.lock @@ -1281,13 +1281,13 @@ six = ">=1.5" [[package]] name = "requests" -version = "2.34.0" +version = "2.34.1" description = "Python HTTP for Humans." optional = false python-versions = ">=3.10" files = [ - {file = "requests-2.34.0-py3-none-any.whl", hash = "sha256:917520a21b767485ce7c588f4ebb917c436b24a31231b44228715eaeb5a52c60"}, - {file = "requests-2.34.0.tar.gz", hash = "sha256:7d62fe92f50eb82c529b0916bb445afa1531a566fc8f35ffdc64446e771b856a"}, + {file = "requests-2.34.1-py3-none-any.whl", hash = "sha256:bf38a3ff993960d3dd819c08862c40b3c703306eb7c744fcd9f4ddbb95b548f0"}, + {file = "requests-2.34.1.tar.gz", hash = "sha256:0fc5669f2b69704449fe1552360bd2a73a54512dfd03e65529157f1513322beb"}, ] [package.dependencies] diff --git a/seed/python-sdk/exhaustive/deps_with_min_python_version/poetry.lock b/seed/python-sdk/exhaustive/deps_with_min_python_version/poetry.lock index bd8647f9a6fd..16e681b4609d 100644 --- a/seed/python-sdk/exhaustive/deps_with_min_python_version/poetry.lock +++ b/seed/python-sdk/exhaustive/deps_with_min_python_version/poetry.lock @@ -2058,13 +2058,13 @@ files = [ [[package]] name = "requests" -version = "2.34.0" +version = "2.34.1" description = "Python HTTP for Humans." optional = false python-versions = ">=3.10" files = [ - {file = "requests-2.34.0-py3-none-any.whl", hash = "sha256:917520a21b767485ce7c588f4ebb917c436b24a31231b44228715eaeb5a52c60"}, - {file = "requests-2.34.0.tar.gz", hash = "sha256:7d62fe92f50eb82c529b0916bb445afa1531a566fc8f35ffdc64446e771b856a"}, + {file = "requests-2.34.1-py3-none-any.whl", hash = "sha256:bf38a3ff993960d3dd819c08862c40b3c703306eb7c744fcd9f4ddbb95b548f0"}, + {file = "requests-2.34.1.tar.gz", hash = "sha256:0fc5669f2b69704449fe1552360bd2a73a54512dfd03e65529157f1513322beb"}, ] [package.dependencies] diff --git a/seed/python-sdk/exhaustive/extra_dev_dependencies/poetry.lock b/seed/python-sdk/exhaustive/extra_dev_dependencies/poetry.lock index ff4a92114bf5..6d9c8ac24171 100644 --- a/seed/python-sdk/exhaustive/extra_dev_dependencies/poetry.lock +++ b/seed/python-sdk/exhaustive/extra_dev_dependencies/poetry.lock @@ -1330,13 +1330,13 @@ six = ">=1.5" [[package]] name = "requests" -version = "2.34.0" +version = "2.34.1" description = "Python HTTP for Humans." optional = false python-versions = ">=3.10" files = [ - {file = "requests-2.34.0-py3-none-any.whl", hash = "sha256:917520a21b767485ce7c588f4ebb917c436b24a31231b44228715eaeb5a52c60"}, - {file = "requests-2.34.0.tar.gz", hash = "sha256:7d62fe92f50eb82c529b0916bb445afa1531a566fc8f35ffdc64446e771b856a"}, + {file = "requests-2.34.1-py3-none-any.whl", hash = "sha256:bf38a3ff993960d3dd819c08862c40b3c703306eb7c744fcd9f4ddbb95b548f0"}, + {file = "requests-2.34.1.tar.gz", hash = "sha256:0fc5669f2b69704449fe1552360bd2a73a54512dfd03e65529157f1513322beb"}, ] [package.dependencies] diff --git a/seed/python-sdk/exhaustive/no-custom-config/poetry.lock b/seed/python-sdk/exhaustive/no-custom-config/poetry.lock index ca6327856cec..05af2c1be9cb 100644 --- a/seed/python-sdk/exhaustive/no-custom-config/poetry.lock +++ b/seed/python-sdk/exhaustive/no-custom-config/poetry.lock @@ -1281,13 +1281,13 @@ six = ">=1.5" [[package]] name = "requests" -version = "2.34.0" +version = "2.34.1" description = "Python HTTP for Humans." optional = false python-versions = ">=3.10" files = [ - {file = "requests-2.34.0-py3-none-any.whl", hash = "sha256:917520a21b767485ce7c588f4ebb917c436b24a31231b44228715eaeb5a52c60"}, - {file = "requests-2.34.0.tar.gz", hash = "sha256:7d62fe92f50eb82c529b0916bb445afa1531a566fc8f35ffdc64446e771b856a"}, + {file = "requests-2.34.1-py3-none-any.whl", hash = "sha256:bf38a3ff993960d3dd819c08862c40b3c703306eb7c744fcd9f4ddbb95b548f0"}, + {file = "requests-2.34.1.tar.gz", hash = "sha256:0fc5669f2b69704449fe1552360bd2a73a54512dfd03e65529157f1513322beb"}, ] [package.dependencies] diff --git a/seed/python-sdk/exhaustive/wire-tests-custom-client-name/poetry.lock b/seed/python-sdk/exhaustive/wire-tests-custom-client-name/poetry.lock index ca6327856cec..05af2c1be9cb 100644 --- a/seed/python-sdk/exhaustive/wire-tests-custom-client-name/poetry.lock +++ b/seed/python-sdk/exhaustive/wire-tests-custom-client-name/poetry.lock @@ -1281,13 +1281,13 @@ six = ">=1.5" [[package]] name = "requests" -version = "2.34.0" +version = "2.34.1" description = "Python HTTP for Humans." optional = false python-versions = ">=3.10" files = [ - {file = "requests-2.34.0-py3-none-any.whl", hash = "sha256:917520a21b767485ce7c588f4ebb917c436b24a31231b44228715eaeb5a52c60"}, - {file = "requests-2.34.0.tar.gz", hash = "sha256:7d62fe92f50eb82c529b0916bb445afa1531a566fc8f35ffdc64446e771b856a"}, + {file = "requests-2.34.1-py3-none-any.whl", hash = "sha256:bf38a3ff993960d3dd819c08862c40b3c703306eb7c744fcd9f4ddbb95b548f0"}, + {file = "requests-2.34.1.tar.gz", hash = "sha256:0fc5669f2b69704449fe1552360bd2a73a54512dfd03e65529157f1513322beb"}, ] [package.dependencies] diff --git a/seed/python-sdk/python-streaming-parameter-openapi/with-wire-tests/poetry.lock b/seed/python-sdk/python-streaming-parameter-openapi/with-wire-tests/poetry.lock index ca6327856cec..05af2c1be9cb 100644 --- a/seed/python-sdk/python-streaming-parameter-openapi/with-wire-tests/poetry.lock +++ b/seed/python-sdk/python-streaming-parameter-openapi/with-wire-tests/poetry.lock @@ -1281,13 +1281,13 @@ six = ">=1.5" [[package]] name = "requests" -version = "2.34.0" +version = "2.34.1" description = "Python HTTP for Humans." optional = false python-versions = ">=3.10" files = [ - {file = "requests-2.34.0-py3-none-any.whl", hash = "sha256:917520a21b767485ce7c588f4ebb917c436b24a31231b44228715eaeb5a52c60"}, - {file = "requests-2.34.0.tar.gz", hash = "sha256:7d62fe92f50eb82c529b0916bb445afa1531a566fc8f35ffdc64446e771b856a"}, + {file = "requests-2.34.1-py3-none-any.whl", hash = "sha256:bf38a3ff993960d3dd819c08862c40b3c703306eb7c744fcd9f4ddbb95b548f0"}, + {file = "requests-2.34.1.tar.gz", hash = "sha256:0fc5669f2b69704449fe1552360bd2a73a54512dfd03e65529157f1513322beb"}, ] [package.dependencies] diff --git a/seed/python-sdk/server-sent-events-openapi/with-wire-tests/poetry.lock b/seed/python-sdk/server-sent-events-openapi/with-wire-tests/poetry.lock index ca6327856cec..05af2c1be9cb 100644 --- a/seed/python-sdk/server-sent-events-openapi/with-wire-tests/poetry.lock +++ b/seed/python-sdk/server-sent-events-openapi/with-wire-tests/poetry.lock @@ -1281,13 +1281,13 @@ six = ">=1.5" [[package]] name = "requests" -version = "2.34.0" +version = "2.34.1" description = "Python HTTP for Humans." optional = false python-versions = ">=3.10" files = [ - {file = "requests-2.34.0-py3-none-any.whl", hash = "sha256:917520a21b767485ce7c588f4ebb917c436b24a31231b44228715eaeb5a52c60"}, - {file = "requests-2.34.0.tar.gz", hash = "sha256:7d62fe92f50eb82c529b0916bb445afa1531a566fc8f35ffdc64446e771b856a"}, + {file = "requests-2.34.1-py3-none-any.whl", hash = "sha256:bf38a3ff993960d3dd819c08862c40b3c703306eb7c744fcd9f4ddbb95b548f0"}, + {file = "requests-2.34.1.tar.gz", hash = "sha256:0fc5669f2b69704449fe1552360bd2a73a54512dfd03e65529157f1513322beb"}, ] [package.dependencies] diff --git a/seed/python-sdk/server-sent-events/with-wire-tests/poetry.lock b/seed/python-sdk/server-sent-events/with-wire-tests/poetry.lock index ca6327856cec..05af2c1be9cb 100644 --- a/seed/python-sdk/server-sent-events/with-wire-tests/poetry.lock +++ b/seed/python-sdk/server-sent-events/with-wire-tests/poetry.lock @@ -1281,13 +1281,13 @@ six = ">=1.5" [[package]] name = "requests" -version = "2.34.0" +version = "2.34.1" description = "Python HTTP for Humans." optional = false python-versions = ">=3.10" files = [ - {file = "requests-2.34.0-py3-none-any.whl", hash = "sha256:917520a21b767485ce7c588f4ebb917c436b24a31231b44228715eaeb5a52c60"}, - {file = "requests-2.34.0.tar.gz", hash = "sha256:7d62fe92f50eb82c529b0916bb445afa1531a566fc8f35ffdc64446e771b856a"}, + {file = "requests-2.34.1-py3-none-any.whl", hash = "sha256:bf38a3ff993960d3dd819c08862c40b3c703306eb7c744fcd9f4ddbb95b548f0"}, + {file = "requests-2.34.1.tar.gz", hash = "sha256:0fc5669f2b69704449fe1552360bd2a73a54512dfd03e65529157f1513322beb"}, ] [package.dependencies] diff --git a/seed/python-sdk/unions/union-naming-v1-wire-tests/poetry.lock b/seed/python-sdk/unions/union-naming-v1-wire-tests/poetry.lock index ca6327856cec..05af2c1be9cb 100644 --- a/seed/python-sdk/unions/union-naming-v1-wire-tests/poetry.lock +++ b/seed/python-sdk/unions/union-naming-v1-wire-tests/poetry.lock @@ -1281,13 +1281,13 @@ six = ">=1.5" [[package]] name = "requests" -version = "2.34.0" +version = "2.34.1" description = "Python HTTP for Humans." optional = false python-versions = ">=3.10" files = [ - {file = "requests-2.34.0-py3-none-any.whl", hash = "sha256:917520a21b767485ce7c588f4ebb917c436b24a31231b44228715eaeb5a52c60"}, - {file = "requests-2.34.0.tar.gz", hash = "sha256:7d62fe92f50eb82c529b0916bb445afa1531a566fc8f35ffdc64446e771b856a"}, + {file = "requests-2.34.1-py3-none-any.whl", hash = "sha256:bf38a3ff993960d3dd819c08862c40b3c703306eb7c744fcd9f4ddbb95b548f0"}, + {file = "requests-2.34.1.tar.gz", hash = "sha256:0fc5669f2b69704449fe1552360bd2a73a54512dfd03e65529157f1513322beb"}, ] [package.dependencies] diff --git a/seed/swift-sdk/allof-inline/Sources/Requests/Requests+RuleCreateRequest.swift b/seed/swift-sdk/allof-inline/Sources/Requests/Requests+RuleCreateRequest.swift index 652324b903b1..bdff74ebaecd 100644 --- a/seed/swift-sdk/allof-inline/Sources/Requests/Requests+RuleCreateRequest.swift +++ b/seed/swift-sdk/allof-inline/Sources/Requests/Requests+RuleCreateRequest.swift @@ -3,13 +3,14 @@ import Foundation extension Requests { public struct RuleCreateRequest: Codable, Hashable, Sendable { public let name: String - public let executionContext: RuleExecutionContext + /// Execution context for the rule, excluding the prod environment. + public let executionContext: RuleCreateRequestExecutionContext /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( name: String, - executionContext: RuleExecutionContext, + executionContext: RuleCreateRequestExecutionContext, additionalProperties: [String: JSONValue] = .init() ) { self.name = name @@ -20,7 +21,7 @@ extension Requests { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.name = try container.decode(String.self, forKey: .name) - self.executionContext = try container.decode(RuleExecutionContext.self, forKey: .executionContext) + self.executionContext = try container.decode(RuleCreateRequestExecutionContext.self, forKey: .executionContext) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/allof-inline/Sources/Schemas/RuleCreateRequestExecutionContext.swift b/seed/swift-sdk/allof-inline/Sources/Schemas/RuleCreateRequestExecutionContext.swift new file mode 100644 index 000000000000..7a0ffae58a0c --- /dev/null +++ b/seed/swift-sdk/allof-inline/Sources/Schemas/RuleCreateRequestExecutionContext.swift @@ -0,0 +1,8 @@ +import Foundation + +/// Execution context for the rule, excluding the prod environment. +public enum RuleCreateRequestExecutionContext: String, Codable, Hashable, CaseIterable, Sendable { + case prod + case staging + case dev +} \ No newline at end of file diff --git a/seed/swift-sdk/allof/Sources/Requests/Requests+RuleCreateRequest.swift b/seed/swift-sdk/allof/Sources/Requests/Requests+RuleCreateRequest.swift index 652324b903b1..bdff74ebaecd 100644 --- a/seed/swift-sdk/allof/Sources/Requests/Requests+RuleCreateRequest.swift +++ b/seed/swift-sdk/allof/Sources/Requests/Requests+RuleCreateRequest.swift @@ -3,13 +3,14 @@ import Foundation extension Requests { public struct RuleCreateRequest: Codable, Hashable, Sendable { public let name: String - public let executionContext: RuleExecutionContext + /// Execution context for the rule, excluding the prod environment. + public let executionContext: RuleCreateRequestExecutionContext /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( name: String, - executionContext: RuleExecutionContext, + executionContext: RuleCreateRequestExecutionContext, additionalProperties: [String: JSONValue] = .init() ) { self.name = name @@ -20,7 +21,7 @@ extension Requests { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.name = try container.decode(String.self, forKey: .name) - self.executionContext = try container.decode(RuleExecutionContext.self, forKey: .executionContext) + self.executionContext = try container.decode(RuleCreateRequestExecutionContext.self, forKey: .executionContext) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/allof/Sources/Schemas/RuleCreateRequestExecutionContext.swift b/seed/swift-sdk/allof/Sources/Schemas/RuleCreateRequestExecutionContext.swift new file mode 100644 index 000000000000..7a0ffae58a0c --- /dev/null +++ b/seed/swift-sdk/allof/Sources/Schemas/RuleCreateRequestExecutionContext.swift @@ -0,0 +1,8 @@ +import Foundation + +/// Execution context for the rule, excluding the prod environment. +public enum RuleCreateRequestExecutionContext: String, Codable, Hashable, CaseIterable, Sendable { + case prod + case staging + case dev +} \ No newline at end of file diff --git a/seed/ts-sdk/allof-inline/src/api/client/requests/RuleCreateRequest.ts b/seed/ts-sdk/allof-inline/src/api/client/requests/RuleCreateRequest.ts index bb42c4d24ac9..2c25b033514f 100644 --- a/seed/ts-sdk/allof-inline/src/api/client/requests/RuleCreateRequest.ts +++ b/seed/ts-sdk/allof-inline/src/api/client/requests/RuleCreateRequest.ts @@ -1,7 +1,5 @@ // This file was auto-generated by Fern from our API Definition. -import type * as SeedApi from "../../index.js"; - /** * @example * { @@ -11,5 +9,16 @@ import type * as SeedApi from "../../index.js"; */ export interface RuleCreateRequest { name: string; - executionContext: SeedApi.RuleExecutionContext; + /** Execution context for the rule, excluding the prod environment. */ + executionContext: RuleCreateRequest.ExecutionContext; +} + +export namespace RuleCreateRequest { + /** Execution context for the rule, excluding the prod environment. */ + export const ExecutionContext = { + Prod: "prod", + Staging: "staging", + Dev: "dev", + } as const; + export type ExecutionContext = (typeof ExecutionContext)[keyof typeof ExecutionContext]; } diff --git a/seed/ts-sdk/allof-inline/src/api/client/requests/index.ts b/seed/ts-sdk/allof-inline/src/api/client/requests/index.ts index 07aecd81dd45..c8c22b703233 100644 --- a/seed/ts-sdk/allof-inline/src/api/client/requests/index.ts +++ b/seed/ts-sdk/allof-inline/src/api/client/requests/index.ts @@ -1,2 +1,2 @@ -export type { RuleCreateRequest } from "./RuleCreateRequest.js"; +export { RuleCreateRequest } from "./RuleCreateRequest.js"; export type { SearchRuleTypesRequest } from "./SearchRuleTypesRequest.js"; diff --git a/seed/ts-sdk/allof/src/api/client/requests/RuleCreateRequest.ts b/seed/ts-sdk/allof/src/api/client/requests/RuleCreateRequest.ts index bb42c4d24ac9..2c25b033514f 100644 --- a/seed/ts-sdk/allof/src/api/client/requests/RuleCreateRequest.ts +++ b/seed/ts-sdk/allof/src/api/client/requests/RuleCreateRequest.ts @@ -1,7 +1,5 @@ // This file was auto-generated by Fern from our API Definition. -import type * as SeedApi from "../../index.js"; - /** * @example * { @@ -11,5 +9,16 @@ import type * as SeedApi from "../../index.js"; */ export interface RuleCreateRequest { name: string; - executionContext: SeedApi.RuleExecutionContext; + /** Execution context for the rule, excluding the prod environment. */ + executionContext: RuleCreateRequest.ExecutionContext; +} + +export namespace RuleCreateRequest { + /** Execution context for the rule, excluding the prod environment. */ + export const ExecutionContext = { + Prod: "prod", + Staging: "staging", + Dev: "dev", + } as const; + export type ExecutionContext = (typeof ExecutionContext)[keyof typeof ExecutionContext]; } diff --git a/seed/ts-sdk/allof/src/api/client/requests/index.ts b/seed/ts-sdk/allof/src/api/client/requests/index.ts index 07aecd81dd45..c8c22b703233 100644 --- a/seed/ts-sdk/allof/src/api/client/requests/index.ts +++ b/seed/ts-sdk/allof/src/api/client/requests/index.ts @@ -1,2 +1,2 @@ -export type { RuleCreateRequest } from "./RuleCreateRequest.js"; +export { RuleCreateRequest } from "./RuleCreateRequest.js"; export type { SearchRuleTypesRequest } from "./SearchRuleTypesRequest.js";