@postman/sdk-config 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +8 -4
  2. package/dist/index.cjs +199 -45
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +1 -1
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.js +199 -45
  7. package/dist/index.js.map +1 -1
  8. package/dist/sdk-config/index.cjs +167 -28
  9. package/dist/sdk-config/index.cjs.map +1 -1
  10. package/dist/sdk-config/index.d.cts +1 -1
  11. package/dist/sdk-config/index.d.ts +1 -1
  12. package/dist/sdk-config/index.js +167 -28
  13. package/dist/sdk-config/index.js.map +1 -1
  14. package/dist/sdk-config/v1/index.cjs +167 -28
  15. package/dist/sdk-config/v1/index.cjs.map +1 -1
  16. package/dist/sdk-config/v1/index.d.cts +4803 -1
  17. package/dist/sdk-config/v1/index.d.ts +4803 -1
  18. package/dist/sdk-config/v1/index.js +167 -28
  19. package/dist/sdk-config/v1/index.js.map +1 -1
  20. package/dist/sdk-config-ir/index.cjs +40 -19
  21. package/dist/sdk-config-ir/index.cjs.map +1 -1
  22. package/dist/sdk-config-ir/index.d.cts +1 -1
  23. package/dist/sdk-config-ir/index.d.ts +1 -1
  24. package/dist/sdk-config-ir/index.js +40 -19
  25. package/dist/sdk-config-ir/index.js.map +1 -1
  26. package/dist/sdk-config-ir/v1/index.cjs +40 -19
  27. package/dist/sdk-config-ir/v1/index.cjs.map +1 -1
  28. package/dist/sdk-config-ir/v1/index.d.cts +490 -162
  29. package/dist/sdk-config-ir/v1/index.d.ts +490 -162
  30. package/dist/sdk-config-ir/v1/index.js +40 -19
  31. package/dist/sdk-config-ir/v1/index.js.map +1 -1
  32. package/dist/{typescript-DNqK3T3v.d.cts → typescript-CKRe_6MB.d.cts} +5 -0
  33. package/dist/{typescript-DNqK3T3v.d.ts → typescript-CKRe_6MB.d.ts} +5 -0
  34. package/package.json +1 -1
  35. package/src/sdk-config/v1/README.md +33 -23
  36. package/src/sdk-config-ir/v1/README.md +102 -96
@@ -48,6 +48,7 @@ declare const packageConfigSchema: z.ZodObject<{
48
48
  authors: z.ZodOptional<z.ZodArray<z.ZodObject<{
49
49
  name: z.ZodString;
50
50
  email: z.ZodOptional<z.ZodEmail>;
51
+ url: z.ZodOptional<z.ZodString>;
51
52
  }, z.core.$strict>>>;
52
53
  developers: z.ZodOptional<z.ZodArray<z.ZodObject<{
53
54
  name: z.ZodString;
@@ -307,6 +308,10 @@ declare const pythonGenerationConfigSchema: z.ZodObject<{
307
308
  }, z.core.$strict>>;
308
309
  alwaysInitializeOptionals: z.ZodOptional<z.ZodBoolean>;
309
310
  useTypedDictRequests: z.ZodOptional<z.ZodBoolean>;
311
+ additionalInitExports: z.ZodOptional<z.ZodArray<z.ZodObject<{
312
+ from: z.ZodString;
313
+ imports: z.ZodArray<z.ZodString>;
314
+ }, z.core.$strict>>>;
310
315
  }, z.core.$strict>;
311
316
  type PythonGenerationConfig = z.infer<typeof pythonGenerationConfigSchema>;
312
317
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@postman/sdk-config",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "Shared SDK configuration contracts and transformations for Postman SDK generation",
5
5
  "license": "UNLICENSED",
6
6
  "sideEffects": false,
@@ -62,9 +62,8 @@ severity, reason, suggested manual action, and the SDK Config destination when o
62
62
  cases. Generation must not recover omitted values from legacy configuration. Differing
63
63
  target-specific values are retained as sparse target overrides when the public shape can represent
64
64
  them. Optional `api` enrichment may be supplied after Fern's definition or IR has already been
65
- lowered into the public API shape. Credentials and signing material remain outside SDK Config; the
66
- mapper reports one target-level diagnostic when a Fern output contains them without logging their
67
- values.
65
+ lowered into the public API shape. Credentials and signing material are preserved in SDK Config
66
+ output blocks when present; callers must treat these fields as sensitive secrets.
68
67
 
69
68
  ## Contract boundaries
70
69
 
@@ -86,10 +85,11 @@ bytes for the build; the server replaces the customer locator with an internal s
86
85
  SDK Config IR. Customer URLs never become generator fetch URLs. Signed URLs, S3 locations, and
87
86
  server-generated artifact metadata are not valid public locators. The public schema deliberately has
88
87
  no `compatibility`, source-origin, artifact ID, credential-resolution, or server-generated
89
- publishing control fields. Unknown fields are rejected at every object boundary. Portable API,
90
- client, documentation, package, source settings, and language field schemas come from a neutral
91
- shared domain layer to prevent drift; the public and internal envelopes and their operational
92
- extensions remain separate explicit allowlists.
88
+ publishing control fields. Publishing credentials and signing material may appear in output blocks
89
+ and must be stored, logged, and transported as secrets. Unknown fields are rejected at every object
90
+ boundary. Portable API, client, documentation, package, source settings, and language field schemas
91
+ come from a neutral shared domain layer to prevent drift; the public and internal envelopes and
92
+ their operational extensions remain separate explicit allowlists.
93
93
 
94
94
  Source `path`, `overlays`, and `overrides` values must be relative paths without parent-directory
95
95
  segments. Absolute paths and `..` traversal are rejected at validation time.
@@ -104,7 +104,10 @@ segments. Absolute paths and `..` traversal are rejected at validation time.
104
104
  "source": {
105
105
  "specs": [{ "id": "payments", "type": "openapi", "url": "https://example.com/openapi.yml" }]
106
106
  },
107
- "package": { "description": "Acme API SDK" },
107
+ "package": {
108
+ "description": "Acme API SDK",
109
+ "authors": [{ "name": "Acme SDKs", "url": "https://example.com/sdk-team" }]
110
+ },
108
111
  "output": { "delivery": "zip" },
109
112
  "generation": {
110
113
  "includeWatermark": true,
@@ -114,6 +117,13 @@ segments. Absolute paths and `..` traversal are rejected at validation time.
114
117
  {
115
118
  "language": "typescript",
116
119
  "package": { "packageName": "@acme/sdk" },
120
+ "output": {
121
+ "delivery": "zip",
122
+ "publish": {
123
+ "registry": "npm",
124
+ "credentials": { "token": "npm-token" }
125
+ }
126
+ },
117
127
  "generation": {
118
128
  "packageManager": "pnpm",
119
129
  "namespaceExportName": "AcmeSDK"
@@ -153,21 +163,21 @@ properties of the generated language artifact.
153
163
  SdkConfig v1 is language-agnostic across every sdk-gen-core target available when this contract was
154
164
  defined. Each language has an explicitly allowlisted `generation` shape:
155
165
 
156
- | Language | `language` value | Representative target setting |
157
- | ---------- | ---------------- | ----------------------------- |
158
- | TypeScript | `typescript` | `namespaceExportName` |
159
- | Python | `python` | `pythonVersion` |
160
- | Java | `java` | `includeKotlinSnippets` |
161
- | Kotlin | `kotlin` | `asyncStyle` |
162
- | Go | `go` | `clientConstructorName` |
163
- | C# | `csharp` | `useOptionalWrapper` |
164
- | PHP | `php` | `propertyAccess` |
165
- | Ruby | `ruby` | `requirePaths` |
166
- | Rust | `rust` | `dateTimeType` |
167
- | Swift | `swift` | `moduleName` |
168
- | CLI | `cli` | `skills` |
169
- | MCP | `mcp` | `serverName` |
170
- | Terraform | `terraform` | `providerName` |
166
+ | Language | `language` value | Representative target setting |
167
+ | ---------- | ---------------- | ---------------------------------------- |
168
+ | TypeScript | `typescript` | `namespaceExportName` |
169
+ | Python | `python` | `pythonVersion`, `additionalInitExports` |
170
+ | Java | `java` | `includeKotlinSnippets` |
171
+ | Kotlin | `kotlin` | `asyncStyle` |
172
+ | Go | `go` | `clientConstructorName` |
173
+ | C# | `csharp` | `useOptionalWrapper` |
174
+ | PHP | `php` | `propertyAccess` |
175
+ | Ruby | `ruby` | `requirePaths` |
176
+ | Rust | `rust` | `dateTimeType` |
177
+ | Swift | `swift` | `moduleName` |
178
+ | CLI | `cli` | `skills` |
179
+ | MCP | `mcp` | `serverName` |
180
+ | Terraform | `terraform` | `providerName` |
171
181
 
172
182
  Adding an internal language setting to `SdkConfigIrV1` does not add it here. Portable settings are
173
183
  added to the shared domain deliberately; IR-only settings remain explicit internal extensions.
@@ -44,8 +44,9 @@ messages. Valid IR requests route only to the IR bridge and never fall through t
44
44
  - `compatibility.outputProfile` preserves converged, Postman-legacy, or Fern-legacy output defaults
45
45
  without introducing a permanent target flavor.
46
46
  - `target.sourceOrigin` identifies where a request originated; it does not select output behavior.
47
- - Credentials are references to externally managed secrets. Tokens and passwords do not belong in
48
- normalized output or publication configuration.
47
+ - Credentials may be references to externally managed secrets or raw credential/signing values when
48
+ an integration must carry the material through the normalized config. Raw values are sensitive and
49
+ must be handled as secrets.
49
50
 
50
51
  ## Configuration design rules
51
52
 
@@ -90,6 +91,7 @@ Legacy aliases below intentionally converge on one normalized behavior.
90
91
 
91
92
  Fields are not duplicated under `generation.language` when a shared row above can represent them.
92
93
  Translators are responsible for alias resolution, unit conversion, and inverted legacy booleans.
94
+ For Python Fern configs, `skip_validation` is read from the nested `pydantic_config` object.
93
95
 
94
96
  ## Source and target boundaries
95
97
 
@@ -112,52 +114,52 @@ Translators are responsible for alias resolution, unit conversion, and inverted
112
114
 
113
115
  ## Postman `BuildParameters` migration map
114
116
 
115
- | Legacy field | SDK Config IR v1 | Notes |
116
- | ---------------------------------------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
117
- | `specUrl` | `source.specs[].specUrl` | A legacy request creates a one-element array. |
118
- | `languages[]` | `target.language` | Translators emit one IR request per target. |
119
- | `sdkName` | `target.sdkName` | Public SDK identity, not package registry identity. |
120
- | `sdkVersion` / language `sdkVersion` | `target.sdkVersion` | Language override is resolved before emitting IR. |
121
- | `apiVersion` | `target.apiVersion` | API version metadata. |
122
- | `org` | `target.organization` | Source organization metadata. |
123
- | `baseUrl` | `api.baseUrl` | Default API URL. |
124
- | `environments` | `api.environments` | Every environment has a non-empty `urls` array; a single URL becomes one entry. |
125
- | `environmentVariables` | `api.environmentVariables` | Declarations; auth/header fields reference them by name. |
126
- | `auth` + `authentication` | `api.auth` | Legacy flags and settings become typed schemes and requirements. |
127
- | `refreshToken` | `client.tokenRefresh` | Response keys map to `accessTokenField` and `refreshTokenField`. |
128
- | `retry` | `client.retry` | Millisecond units are explicit in normalized names. |
129
- | `responseHeaders` | `client.responseHeaders` | Shared across languages. |
130
- | `multiTenant` | `client.multiTenant` | Shared client behavior. |
131
- | TypeScript `httpClient` | `generation.language.typescript.httpClient` | Only `fetch` and `axios` are selectable; other languages use their generator transport. |
132
- | `additionalConstructorParameters` | `client.additionalConstructorParameters` | Merged from language options. |
133
- | `deliveryMethods` | `output.delivery` | Normalized to `files`, `zip`, or `github`; multiple deliveries produce separate IR requests. |
134
- | `fileOutput` | `output.path` or `output.fileName` | Depends on delivery type. |
135
- | `githubRef` | `output.github.branch` | Only meaningful for GitHub delivery. |
136
- | `privateRepo` | `output.github.privateRepository` | Only meaningful for GitHub delivery. |
137
- | `publishing.githubOrg` | `output.github.repository` | Translator combines the organization and repository name. |
138
- | package names and IDs | `package` | Includes npm/PyPI/NuGet/RubyGems/Crates/Composer names and Maven IDs. |
139
- | `goModuleName` | `package.modulePath` | Go publication and import identity. |
140
- | `license`, `authors`, `developers`, `homepage` | `package` | Manifest metadata. |
141
- | TypeScript package privacy / JSR publication | `output.publish.isPackagePrivate` / `output.publish.publishToJsr` | NPM-specific publication options. |
142
- | registry workflow and env-var settings | `output.publish` | Per-registry workflow toggles, credential env vars, and trusted publishing flags. |
143
- | `documentation.url` | `docs.referenceBaseUrl` | Base URL for generated reference-file links. |
144
- | `documentation.snippets` | `docs.snippets` | `enabled` is explicit when the object is present. |
145
- | `docs[]` | `docs` | Legacy API/snippet selections are lowered to typed documentation settings. |
146
- | `includeWatermark` | `generation.includeWatermark` | Simple on/off behavior. |
147
- | `includeOptionalSnippetParameters` | `generation.includeOptionalSnippetParameters` | Simple on/off behavior. |
148
- | `inferServiceNames` | `generation.inferServiceNames` | Simple on/off behavior. |
149
- | `buildAllModels` | `generation.buildAllModels` | Simple on/off behavior. |
150
- | `deprecatedOperations.include` | `generation.includeDeprecatedOperations` | Simplified to a boolean. |
151
- | `multipleResponses.enabled` | `generation.multipleResponses` | Simplified to a boolean. |
152
- | `devContainer` | `generation.devContainer` | Simple on/off behavior. |
153
- | `ignoreFiles` / language `ignore` | `generation.ignoreFiles` | Language aliases are resolved by the translator. |
154
- | `reservedKeywords` | `generation.reservedKeywords` | Shared generator input. |
155
- | `hooks`, `hookDependencies`, `hooksLocation` | `generation.hooks` | Location and dependencies are one configurable feature. |
156
- | `customCode*`, previous artifact location | `generation.customCode` | Locations become typed generation assets. |
157
- | `workflow` | `generation.workflows[]` | The normalized shape supports more than one workflow. |
158
- | `customQueries` | `generation.customQueryPaths` | Query definitions are represented as paths. |
159
- | `analytics` | `generation.analytics` | `enabled` is explicit; timing fields use milliseconds. |
160
- | language options | `generation.language.<target>` or shared fields | Package, naming, validation, and dependency aliases are lifted out first. |
117
+ | Legacy field | SDK Config IR v1 | Notes |
118
+ | --------------------------------------------------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
119
+ | `specUrl` | `source.specs[].specUrl` | A legacy request creates a one-element array. |
120
+ | `languages[]` | `target.language` | Translators emit one IR request per target. |
121
+ | `sdkName` | `target.sdkName` | Public SDK identity, not package registry identity. |
122
+ | `sdkVersion` / language `sdkVersion` | `target.sdkVersion` | Language override is resolved before emitting IR. |
123
+ | `apiVersion` | `target.apiVersion` | API version metadata. |
124
+ | `org` | `target.organization` | Source organization metadata. |
125
+ | `baseUrl` | `api.baseUrl` | Default API URL. |
126
+ | `environments` | `api.environments` | Every environment has a non-empty `urls` array; a single URL becomes one entry. |
127
+ | `environmentVariables` | `api.environmentVariables` | Declarations; auth/header fields reference them by name. |
128
+ | `auth` + `authentication` | `api.auth` | Legacy flags and settings become typed schemes and requirements. |
129
+ | `refreshToken` | `client.tokenRefresh` | Response keys map to `accessTokenField` and `refreshTokenField`. |
130
+ | `retry` | `client.retry` | Millisecond units are explicit in normalized names. |
131
+ | `responseHeaders` | `client.responseHeaders` | Shared across languages. |
132
+ | `multiTenant` | `client.multiTenant` | Shared client behavior. |
133
+ | TypeScript `httpClient` | `generation.language.typescript.httpClient` | Only `fetch` and `axios` are selectable; other languages use their generator transport. |
134
+ | `additionalConstructorParameters` | `client.additionalConstructorParameters` | Merged from language options. |
135
+ | `deliveryMethods` | `output.delivery` | Normalized to `files`, `zip`, or `github`; multiple deliveries produce separate IR requests. |
136
+ | `fileOutput` | `output.path` or `output.fileName` | Depends on delivery type. |
137
+ | `githubRef` | `output.github.branch` | Only meaningful for GitHub delivery. |
138
+ | `privateRepo` | `output.github.privateRepository` | Only meaningful for GitHub delivery. |
139
+ | `publishing.githubOrg` | `output.github.repository` | Translator combines the organization and repository name. |
140
+ | package names and IDs | `package` | Includes npm/PyPI/NuGet/RubyGems/Crates/Composer names and Maven IDs. |
141
+ | `goModuleName` | `package.modulePath` | Go publication and import identity. |
142
+ | `license`, `authors`, `developers`, `homepage` | `package` and `output.github.license` | Manifest metadata and GitHub-specific repository license settings. |
143
+ | TypeScript package privacy / JSR publication | `output.publish.isPackagePrivate` / `output.publish.publishToJsr` | NPM-specific publication options. |
144
+ | registry workflow, credential, and env-var settings | `output.publish` | Per-registry workflow toggles, credential values/refs/env vars, and trusted publishing flags. |
145
+ | `documentation.url` | `docs.referenceBaseUrl` | Base URL for generated reference-file links. |
146
+ | `documentation.snippets` | `docs.snippets` | `enabled` is explicit when the object is present. |
147
+ | `docs[]` | `docs` | Legacy API/snippet selections are lowered to typed documentation settings. |
148
+ | `includeWatermark` | `generation.includeWatermark` | Simple on/off behavior. |
149
+ | `includeOptionalSnippetParameters` | `generation.includeOptionalSnippetParameters` | Simple on/off behavior. |
150
+ | `inferServiceNames` | `generation.inferServiceNames` | Simple on/off behavior. |
151
+ | `buildAllModels` | `generation.buildAllModels` | Simple on/off behavior. |
152
+ | `deprecatedOperations.include` | `generation.includeDeprecatedOperations` | Simplified to a boolean. |
153
+ | `multipleResponses.enabled` | `generation.multipleResponses` | Simplified to a boolean. |
154
+ | `devContainer` | `generation.devContainer` | Simple on/off behavior. |
155
+ | `ignoreFiles` / language `ignore` | `generation.ignoreFiles` | Language aliases are resolved by the translator. |
156
+ | `reservedKeywords` | `generation.reservedKeywords` | Shared generator input. |
157
+ | `hooks`, `hookDependencies`, `hooksLocation` | `generation.hooks` | Location and dependencies are one configurable feature. |
158
+ | `customCode*`, previous artifact location | `generation.customCode` | Locations become typed generation assets. |
159
+ | `workflow` | `generation.workflows[]` | The normalized shape supports more than one workflow. |
160
+ | `customQueries` | `generation.customQueryPaths` | Query definitions are represented as paths. |
161
+ | `analytics` | `generation.analytics` | `enabled` is explicit; timing fields use milliseconds. |
162
+ | language options | `generation.language.<target>` or shared fields | Package, naming, validation, and dependency aliases are lifted out first. |
161
163
 
162
164
  ### Postman language-option migration map
163
165
 
@@ -173,7 +175,7 @@ Translators are responsible for alias resolution, unit conversion, and inverted
173
175
  | TypeScript `generateEnumAs` | `generation.serialization.enumRepresentation` |
174
176
  | TypeScript versions, compiler options, bundle, default export, naming strategy, scripts | `generation.language.typescript` |
175
177
  | Python `pypiPackageName`, classifiers, and project URLs | `package.packageName`, `classifiers`, and `projectUrls` |
176
- | Python Pydantic version and optional initialization | `generation.language.python` |
178
+ | Python Pydantic version, optional initialization, and additional `__init__` exports | `generation.language.python` |
177
179
  | Java/Kotlin `groupId` / `artifactId` | `package.groupId` / `package.artifactId` |
178
180
  | Java/Kotlin `includeKotlinSnippets` | `generation.language.java.includeKotlinSnippets` |
179
181
  | Java/Go/C#/Rust `validateResponses` | `client.responseValidation` |
@@ -195,49 +197,52 @@ inputs were not restored as part of the normalized contract.
195
197
  Customer-use counts below are distinct projects observed in the 61-project configuration snapshot
196
198
  audited on 2026-07-17. Counts guide the initial contract; they are not a permanent support policy.
197
199
 
198
- | Fern field or aliases | SDK Config IR v1 | Observed projects |
199
- | --------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | -----------------------------------------: |
200
- | `api.specs[]` | `source.specs[]` | 53 OpenAPI, 3 AsyncAPI |
201
- | `api.specs[].namespace` | `source.specs[].namespace` | 1 |
202
- | `api.specs[].overlays` | `source.specs[].overlays` | 2 |
203
- | `api.specs[].overrides` | `source.specs[].overrides` | 39 |
204
- | `api.default-url` | `api.baseUrl` | 21 |
205
- | `api.default-environment` | `api.defaultEnvironment` | 22 |
206
- | `api.environments` | `api.environments` | 20+ |
207
- | `api.auth`, `api.auth-schemes` | `api.auth` | 27 |
208
- | `api.headers` | `api.headers` | 11+ |
209
- | generator-group `audiences` | `api.audiences` | Absent selects all audiences. |
210
- | generator `inlinePathParameters`, `inline-path-parameters`, and API setting | `client.pathParameterStyle` | 12 API; 1-3 per language |
211
- | generator `inlineFileProperties`, `inline-file-properties` | `client.filePropertyStyle` | 1-3 per language |
212
- | `inline_request_params` | `client.requestParameterStyle` | 6 Python |
213
- | `customPagerName`, `custom-pager-name`, `custom_pager_name` | `generation.naming.pagerName` | 2-5 per language |
214
- | `smart-casing`, `smart-casing-digit-word-boundary` | `generation.naming` | Preserved only when explicitly set. |
215
- | timeout aliases in seconds or milliseconds | `client.timeoutMs` | Translator converts units. |
216
- | `skipResponseValidation`, Python `skip_validation` | `client.responseValidation` | Inverted; 12 TS, 8 Python |
217
- | `useDefaultRequestParameterValues` aliases | `client.useDefaultRequestParameterValues` | 1 |
218
- | `respectOptionalRequestBody`, `respect-optional-request-body` | `client.respectOptionalRequestBody` | Not in the project snapshot; see below |
219
- | `enable-wire-tests`, `enableWireTests`, `generateWireTests` | `generation.wireTests` | 1-15 per language |
220
- | WebSocket generation aliases | `generation.webSockets` | 3 TS, 3 Python |
221
- | `streamType`, `fileResponseType` | `generation.streams` | 1 TS |
222
- | client/exported/environment class aliases | `generation.naming` | 1-28 per language |
223
- | base API/general exception class aliases | `generation.naming.apiErrorName` / `generation.naming.baseErrorName` | 3-6 Java/C# |
224
- | namespace/package-prefix aliases | `package.namespace` | 1-30 per language |
225
- | output registry package names | `package.packageName` | 5-28 per registry language |
226
- | Python custom `package_name` | `package.moduleName` | 18 |
227
- | Go `module.path` | `package.modulePath` | 3 |
228
- | Maven `group` / `artifact` | `package.groupId` / `package.artifactId` | 7 |
229
- | custom/extra dependencies | `package.extraDependencies` and related lists | Multiple languages |
230
- | local output | `output.delivery: "files"` | 49+ |
231
- | registry output | `output.publish` plus `package` identity | 5-28 per registry language |
232
- | GitHub output | `output.delivery: "github"` and `output.github` | Translator resolves Fern owner/repo forms. |
233
- | npm package privacy and JSR publication | `output.publish.isPackagePrivate` / `output.publish.publishToJsr` | NPM-only booleans |
234
- | registry version and workflow gate | `output.publish.version` / `output.publish.shouldGeneratePublishWorkflow` | Per-registry controls |
235
- | registry credential environment variables | `output.publish.*EnvironmentVariable` | Registry-specific env-var names |
236
- | trusted publishing / OIDC markers | `output.publish.trustedPublishing` | npm, PyPI, and NuGet |
237
- | Maven coordinate and signing env vars | `output.publish.coordinate` / `output.publish.signatureEnvironmentVariables` | Maven-specific |
238
- | Fern README config | `docs.readme` | 12 API names; 11 disabled-section configs |
239
- | `customReadmeSections` | `docs.readme.customSections` | Not in the project snapshot; see below |
240
- | `includeApiReference` | `docs.includeApiReference` | 10 TS |
200
+ | Fern field or aliases | SDK Config IR v1 | Observed projects |
201
+ | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | -----------------------------------------: |
202
+ | `api.specs[]` | `source.specs[]` | 53 OpenAPI, 3 AsyncAPI |
203
+ | `api.specs[].namespace` | `source.specs[].namespace` | 1 |
204
+ | `api.specs[].overlays` | `source.specs[].overlays` | 2 |
205
+ | `api.specs[].overrides` | `source.specs[].overrides` | 39 |
206
+ | `api.default-url` | `api.baseUrl` | 21 |
207
+ | `api.default-environment` | `api.defaultEnvironment` | 22 |
208
+ | `api.environments` | `api.environments` | 20+ |
209
+ | `api.auth`, `api.auth-schemes` | `api.auth` | 27 |
210
+ | `api.headers` | `api.headers` | 11+ |
211
+ | generator-group `audiences` | `api.audiences` | Absent selects all audiences. |
212
+ | generator `inlinePathParameters`, `inline-path-parameters`, and API setting | `client.pathParameterStyle` | 12 API; 1-3 per language |
213
+ | generator `inlineFileProperties`, `inline-file-properties` | `client.filePropertyStyle` | 1-3 per language |
214
+ | `inline_request_params` | `client.requestParameterStyle` | 6 Python |
215
+ | `customPagerName`, `custom-pager-name`, `custom_pager_name` | `generation.naming.pagerName` | 2-5 per language |
216
+ | `smart-casing`, `smart-casing-digit-word-boundary` | `generation.naming` | Preserved only when explicitly set. |
217
+ | timeout aliases in seconds or milliseconds | `client.timeoutMs` | Translator converts units. |
218
+ | `skipResponseValidation`, Python `pydantic_config.skip_validation` | `client.responseValidation` | Inverted; 12 TS, 8 Python |
219
+ | `useDefaultRequestParameterValues` aliases | `client.useDefaultRequestParameterValues` | 1 |
220
+ | `respectOptionalRequestBody`, `respect-optional-request-body` | `client.respectOptionalRequestBody` | Not in the project snapshot; see below |
221
+ | `enable-wire-tests`, `enableWireTests`, `generateWireTests` | `generation.wireTests` | 1-15 per language |
222
+ | WebSocket generation aliases | `generation.webSockets` | 3 TS, 3 Python |
223
+ | `streamType`, `fileResponseType` | `generation.streams` | 1 TS |
224
+ | client/exported/environment class aliases | `generation.naming` | 1-28 per language |
225
+ | base API/general exception class aliases | `generation.naming.apiErrorName` / `generation.naming.baseErrorName` | 3-6 Java/C# |
226
+ | namespace/package-prefix aliases | `package.namespace` | 1-30 per language |
227
+ | output registry package names | `package.packageName` | 5-28 per registry language |
228
+ | TypeScript `packageJson` / PHP `composerJson` portable metadata | `package.packageName`, `description`, `authors`, and `license` | Portable subset only. |
229
+ | TypeScript `fetchSupport: native` | `generation.language.typescript.httpClient.name: "fetch"` | Native only. |
230
+ | Python custom `package_name` | `package.moduleName` | 18 |
231
+ | Python `additional_init_exports` | `generation.language.python.additionalInitExports` | 3 |
232
+ | Go `module.path` | `package.modulePath` | 3 |
233
+ | Maven `group` / `artifact` | `package.groupId` / `package.artifactId` | 7 |
234
+ | custom/extra dependencies | `package.extraDependencies` and related lists | Multiple languages |
235
+ | local output | `output.delivery: "files"` | 49+ |
236
+ | registry output | `output.publish` plus `package` identity | 5-28 per registry language |
237
+ | GitHub output | `output.delivery: "github"` and `output.github` | Translator resolves Fern owner/repo forms. |
238
+ | npm package privacy and JSR publication | `output.publish.isPackagePrivate` / `output.publish.publishToJsr` | NPM-only booleans |
239
+ | registry version and workflow gate | `output.publish.version` / `output.publish.shouldGeneratePublishWorkflow` | Per-registry controls |
240
+ | registry credentials and environment variables | `output.publish.credentials` / `output.publish.*EnvironmentVariable` | Registry-specific secret values/names |
241
+ | trusted publishing / OIDC markers | `output.publish.trustedPublishing` | npm, PyPI, and NuGet |
242
+ | Maven coordinate and signing material/env vars | `output.publish.coordinate` / `output.publish.signature` / `output.publish.signatureEnvironmentVariables` | Maven-specific |
243
+ | Fern README config | `docs.readme` | 12 API names; 11 disabled-section configs |
244
+ | `customReadmeSections` | `docs.readme.customSections` | Not in the project snapshot; see below |
245
+ | `includeApiReference` | `docs.includeApiReference` | 10 TS |
241
246
 
242
247
  The Rust language config was added after the initial audit. That audit compared existing Fern
243
248
  _customer projects_, which surfaced no Rust-specific options; comparing the Fern Rust generator's
@@ -249,8 +254,9 @@ shared fields.
249
254
  `docs.readme.customSections` came from that same generator-schema comparison. Nine Fern generators
250
255
  declare an identical `customReadmeSections` array of `{title, content}`, so it is a shared
251
256
  documentation concern rather than a language one. `title` is the section's identity: a derived
252
- section carrying the same title is replaced rather than duplicated. Fern's per-section `language`
253
- discriminator is dropped, because one IR document already describes one target.
257
+ section carrying the same title is replaced rather than duplicated. During Fern migration, an
258
+ untagged section applies to every target and a language-tagged section applies only to its matching
259
+ selected target. The discriminator is then dropped because one IR document describes one target.
254
260
 
255
261
  `client.respectOptionalRequestBody` came from the same comparison and postdates the project
256
262
  snapshot. Eight Fern generators honour it — Rust, Go, PHP, Ruby, both TypeScript generators, C# and
@@ -336,8 +342,8 @@ the migration.
336
342
  | Legacy configuration | Observed projects | Reason |
337
343
  | ----------------------------------------------------------- | ----------------: | ------------------------------------------------------------------------ |
338
344
  | TypeScript arbitrary `packageJson` exports/scripts | 2 | Open-ended manifest rewriting conflicts with the typed package contract. |
339
- | TypeScript `outputEsm`, fetch runtime, form-data runtime | 1-2 | Runtime-specific and not required by sdk-gen-core today. |
340
- | Python additional `__init__` exports / excluded exports | 3 / 6 | File-layout customization with significant generator coupling. |
345
+ | TypeScript `outputEsm` and form-data runtime | 1-2 | Runtime-specific and not required by sdk-gen-core today. |
346
+ | Python excluded `__init__` exports | 6 | File-layout customization with significant generator coupling. |
341
347
  | Python improved imports and file-upload-only TypedDict mode | 1-3 | Experimental or narrow compatibility behavior. |
342
348
  | Java custom Gradle plugins / include-wrapper | 1 | Arbitrary build-file injection or one-customer behavior. |
343
349
  | C# experimental fully qualified/version namespaces | 1 | Experimental one-customer behavior. |