@postman/sdk-config 0.1.1 → 0.3.0

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 (37) hide show
  1. package/README.md +29 -12
  2. package/dist/index.cjs +352 -145
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +3 -3
  5. package/dist/index.d.ts +3 -3
  6. package/dist/index.js +345 -146
  7. package/dist/index.js.map +1 -1
  8. package/dist/sdk-config/index.cjs +281 -109
  9. package/dist/sdk-config/index.cjs.map +1 -1
  10. package/dist/sdk-config/index.d.cts +2 -2
  11. package/dist/sdk-config/index.d.ts +2 -2
  12. package/dist/sdk-config/index.js +276 -110
  13. package/dist/sdk-config/index.js.map +1 -1
  14. package/dist/sdk-config/v1/index.cjs +281 -109
  15. package/dist/sdk-config/v1/index.cjs.map +1 -1
  16. package/dist/sdk-config/v1/index.d.cts +6903 -289
  17. package/dist/sdk-config/v1/index.d.ts +6903 -289
  18. package/dist/sdk-config/v1/index.js +276 -110
  19. package/dist/sdk-config/v1/index.js.map +1 -1
  20. package/dist/sdk-config-ir/index.cjs +126 -30
  21. package/dist/sdk-config-ir/index.cjs.map +1 -1
  22. package/dist/sdk-config-ir/index.d.cts +2 -2
  23. package/dist/sdk-config-ir/index.d.ts +2 -2
  24. package/dist/sdk-config-ir/index.js +125 -31
  25. package/dist/sdk-config-ir/index.js.map +1 -1
  26. package/dist/sdk-config-ir/v1/index.cjs +126 -30
  27. package/dist/sdk-config-ir/v1/index.cjs.map +1 -1
  28. package/dist/sdk-config-ir/v1/index.d.cts +534 -15
  29. package/dist/sdk-config-ir/v1/index.d.ts +534 -15
  30. package/dist/sdk-config-ir/v1/index.js +125 -31
  31. package/dist/sdk-config-ir/v1/index.js.map +1 -1
  32. package/dist/{typescript-DK97815_.d.cts → typescript-DNqK3T3v.d.cts} +3 -0
  33. package/dist/{typescript-DK97815_.d.ts → typescript-DNqK3T3v.d.ts} +3 -0
  34. package/docs/releasing.md +114 -0
  35. package/package.json +1 -1
  36. package/src/sdk-config/v1/README.md +91 -23
  37. package/src/sdk-config-ir/v1/README.md +91 -83
@@ -199,26 +199,42 @@ var apiConfigSchema = zod.z.strictObject({
199
199
  var sdkConfigV1AuthSchemeSchema = authSchemeSchema;
200
200
  var sdkConfigV1AuthConfigSchema = authConfigSchema;
201
201
  var sdkConfigV1ApiConfigSchema = apiConfigSchema;
202
+ var retryOverrideShape = {
203
+ enabled: zod.z.boolean().optional(),
204
+ maxAttempts: zod.z.number().int().min(1).optional(),
205
+ retryDelayMs: zod.z.number().nonnegative().optional(),
206
+ maxDelayMs: zod.z.number().nonnegative().optional(),
207
+ jitterMs: zod.z.number().nonnegative().optional(),
208
+ backoffFactor: zod.z.number().positive().optional(),
209
+ statusCodes: zod.z.array(zod.z.number().int().min(100).max(599)).optional(),
210
+ methods: zod.z.array(nonEmptyStringSchema).optional(),
211
+ statusCodeProfile: zod.z.enum(["legacy", "recommended"]).optional(),
212
+ maxRetryAfterDelayMs: zod.z.number().nonnegative().optional()
213
+ };
214
+ function validateRetryDelays({
215
+ maxDelayMs,
216
+ retryDelayMs
217
+ }, context) {
218
+ if (maxDelayMs !== void 0 && retryDelayMs !== void 0 && maxDelayMs < retryDelayMs) {
219
+ context.addIssue({
220
+ code: "custom",
221
+ message: "maxDelayMs must be greater than or equal to retryDelayMs",
222
+ path: ["maxDelayMs"]
223
+ });
224
+ }
225
+ }
226
+ var clientRetryOverrideSchema = zod.z.strictObject(retryOverrideShape).superRefine(validateRetryDelays);
202
227
  var retryConfigSchema = zod.z.strictObject({
228
+ ...retryOverrideShape,
203
229
  enabled: zod.z.boolean().default(true),
204
230
  maxAttempts: zod.z.number().int().min(1).default(3),
205
231
  retryDelayMs: zod.z.number().nonnegative().default(150),
206
232
  maxDelayMs: zod.z.number().nonnegative().default(5e3),
207
233
  jitterMs: zod.z.number().nonnegative().default(50),
208
234
  backoffFactor: zod.z.number().positive().default(2),
209
- statusCodes: zod.z.array(zod.z.number().int().min(100).max(599)).optional(),
210
235
  methods: zod.z.array(nonEmptyStringSchema).default(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]),
211
- statusCodeProfile: zod.z.enum(["legacy", "recommended"]).optional(),
212
236
  maxRetryAfterDelayMs: zod.z.number().nonnegative().default(6e4)
213
- }).superRefine(({ maxDelayMs, retryDelayMs }, context) => {
214
- if (maxDelayMs < retryDelayMs) {
215
- context.addIssue({
216
- code: "custom",
217
- message: "maxDelayMs must be greater than or equal to retryDelayMs",
218
- path: ["maxDelayMs"]
219
- });
220
- }
221
- });
237
+ }).superRefine(validateRetryDelays);
222
238
  var constructorParameterSchema = zod.z.strictObject({
223
239
  name: nonEmptyStringSchema,
224
240
  example: zod.z.string().optional(),
@@ -240,12 +256,12 @@ var tokenRefreshConfigSchema = zod.z.strictObject({
240
256
  });
241
257
  }
242
258
  });
243
- var clientConfigSchema = zod.z.strictObject({
244
- retry: retryConfigSchema.prefault({}),
245
- responseHeaders: zod.z.boolean().default(false),
259
+ var clientOverrideShape = {
260
+ retry: clientRetryOverrideSchema.optional(),
261
+ responseHeaders: zod.z.boolean().optional(),
246
262
  responseValidation: zod.z.boolean().optional(),
247
- multiTenant: zod.z.boolean().default(false),
248
- additionalConstructorParameters: zod.z.array(constructorParameterSchema).default([]),
263
+ multiTenant: zod.z.boolean().optional(),
264
+ additionalConstructorParameters: zod.z.array(constructorParameterSchema).optional(),
249
265
  timeoutMs: zod.z.union([zod.z.number().nonnegative(), zod.z.literal("infinity")]).optional(),
250
266
  requestParameterStyle: parameterStyleSchema.optional(),
251
267
  pathParameterStyle: parameterStyleSchema.optional(),
@@ -253,10 +269,19 @@ var clientConfigSchema = zod.z.strictObject({
253
269
  useDefaultRequestParameterValues: zod.z.boolean().optional(),
254
270
  respectOptionalRequestBody: zod.z.boolean().optional(),
255
271
  tokenRefresh: tokenRefreshConfigSchema.optional()
272
+ };
273
+ var clientConfigOverrideSchema = zod.z.strictObject(clientOverrideShape);
274
+ var clientConfigSchema = zod.z.strictObject({
275
+ ...clientOverrideShape,
276
+ retry: retryConfigSchema.prefault({}),
277
+ responseHeaders: zod.z.boolean().default(false),
278
+ multiTenant: zod.z.boolean().default(false),
279
+ additionalConstructorParameters: zod.z.array(constructorParameterSchema).default([])
256
280
  });
257
281
 
258
282
  // src/sdk-config/v1/client.ts
259
283
  var sdkConfigV1ClientConfigSchema = clientConfigSchema;
284
+ var sdkConfigV1ClientConfigOverrideSchema = clientConfigOverrideSchema;
260
285
  var goModulePathSchema = relativePathSchema.regex(
261
286
  /^(?!.*(?:^|\/)\.{1,2}(?:\/|$))[A-Za-z0-9._~-]+(?:\/[A-Za-z0-9._~-]+)+$/,
262
287
  "Go module path must be a slash-delimited path using letters, numbers, dots, dashes, underscores, or tildes"
@@ -861,26 +886,32 @@ function finishOutputMapping(mapping, outputMode, sourcePath, state, index) {
861
886
  for (const path of collectLeafPaths(outputMode, sourcePath)) {
862
887
  if (path[path.length - 1] === "_visit") consume(state, path);
863
888
  }
889
+ const unsupported = collectUnsupported(outputMode, sourcePath, state);
890
+ const hasCredentials = unsupported.some((diagnostic) => isCredentialPath(diagnostic.path));
864
891
  return {
865
892
  ...mapping,
866
- unsupportedFields: collectUnsupported(outputMode, sourcePath, state).map(
867
- (diagnostic) => outputDiagnostic(diagnostic.path, index)
868
- )
893
+ unsupportedFields: [
894
+ ...hasCredentials ? [
895
+ {
896
+ code: "FERN_OUTPUT_CREDENTIAL_UNSUPPORTED",
897
+ severity: "warning",
898
+ path: sourcePath,
899
+ reason: "Fern output credentials and signatures are intentionally excluded from SDK Config v1",
900
+ suggestedAction: "Provide publishing credentials through the build request or external secret resolution."
901
+ }
902
+ ] : [],
903
+ ...unsupported.filter((diagnostic) => !isCredentialPath(diagnostic.path)).map((diagnostic) => outputDiagnostic(diagnostic.path, index))
904
+ ]
869
905
  };
870
906
  }
907
+ function isCredentialPath(path) {
908
+ const fields = path.filter((part) => typeof part === "string");
909
+ const field = fields[fields.length - 1];
910
+ return fields.some((part) => part === "credentials" || part === "signature") || ["apiKey", "keyId", "password", "secretKey", "token", "username"].includes(field ?? "");
911
+ }
871
912
  function outputDiagnostic(path, index) {
872
913
  const fields = path.filter((part) => typeof part === "string");
873
914
  const field = fields[fields.length - 1];
874
- const credential = fields.some((part) => part === "credentials" || part === "signature") || ["apiKey", "keyId", "password", "secretKey", "token", "username"].includes(field ?? "");
875
- if (credential) {
876
- return {
877
- code: "FERN_OUTPUT_CREDENTIAL_UNSUPPORTED",
878
- severity: "warning",
879
- path,
880
- reason: "Fern output credentials and signatures are not represented by SDK Config v1",
881
- suggestedAction: "Configure publication credentials and signing secrets outside SDK Config."
882
- };
883
- }
884
915
  const guidance = {
885
916
  directory: {
886
917
  suggestedAction: "Preserve the GitHub output subdirectory outside SDK Config; public v1 has no repository subdirectory field."
@@ -937,6 +968,20 @@ function outputDiagnostic(path, index) {
937
968
  suggestedAction: resolvedGuidance?.suggestedAction ?? "Review this output setting and preserve it outside SDK Config when no equivalent exists."
938
969
  };
939
970
  }
971
+ var namingConfigSchema = zod.z.strictObject({
972
+ clientName: nonEmptyStringSchema.optional(),
973
+ exportedClientName: nonEmptyStringSchema.optional(),
974
+ environmentTypeName: nonEmptyStringSchema.optional(),
975
+ apiErrorName: nonEmptyStringSchema.optional(),
976
+ baseErrorName: nonEmptyStringSchema.optional(),
977
+ pagerName: nonEmptyStringSchema.optional(),
978
+ /** Apply Fern's initialism-aware casing rules when deriving generated identifiers. */
979
+ smartCasing: zod.z.boolean().optional(),
980
+ /** Preserve a word boundary after digits when Fern smart casing is enabled. */
981
+ smartCasingDigitWordBoundary: zod.z.boolean().optional()
982
+ });
983
+
984
+ // src/sdk-config/v1/generation.ts
940
985
  var customerGenerationAssetSchema = zod.z.discriminatedUnion("type", [
941
986
  zod.z.strictObject({ type: zod.z.literal("path"), location: relativePathSchema }),
942
987
  zod.z.strictObject({ type: zod.z.literal("url"), location: nonEmptyStringSchema })
@@ -1003,14 +1048,6 @@ var streamsSchema = zod.z.strictObject({
1003
1048
  fileResponseType: zod.z.enum(["stream", "binary-response"]).optional(),
1004
1049
  defaultChunkSizeBytes: zod.z.number().int().positive().optional()
1005
1050
  });
1006
- var namingConfigSchema = zod.z.strictObject({
1007
- clientName: nonEmptyStringSchema.optional(),
1008
- exportedClientName: nonEmptyStringSchema.optional(),
1009
- environmentTypeName: nonEmptyStringSchema.optional(),
1010
- apiErrorName: nonEmptyStringSchema.optional(),
1011
- baseErrorName: nonEmptyStringSchema.optional(),
1012
- pagerName: nonEmptyStringSchema.optional()
1013
- });
1014
1051
  var layoutConfigSchema = zod.z.strictObject({
1015
1052
  outputDirectory: zod.z.enum(["project-root", "source-root"]).optional(),
1016
1053
  packagePath: nonEmptyStringSchema.optional()
@@ -1021,16 +1058,16 @@ var serializationConfigSchema = zod.z.strictObject({
1021
1058
  inlineTypes: zod.z.boolean().optional(),
1022
1059
  omitUndefined: zod.z.boolean().optional()
1023
1060
  });
1024
- var sdkConfigV1GenerationConfigSchema = zod.z.strictObject({
1025
- includeWatermark: zod.z.boolean().default(false),
1026
- ai: zod.z.boolean().default(false),
1061
+ var generationConfigOverrideShape = {
1062
+ includeWatermark: zod.z.boolean().optional(),
1063
+ ai: zod.z.boolean().optional(),
1027
1064
  includeOptionalSnippetParameters: zod.z.boolean().optional(),
1028
- buildAllModels: zod.z.boolean().default(false),
1029
- inferServiceNames: zod.z.boolean().default(false),
1030
- includeDeprecatedOperations: zod.z.boolean().default(true),
1031
- multipleResponses: zod.z.boolean().default(false),
1032
- devContainer: zod.z.boolean().default(false),
1033
- allowMockClient: zod.z.boolean().default(false),
1065
+ buildAllModels: zod.z.boolean().optional(),
1066
+ inferServiceNames: zod.z.boolean().optional(),
1067
+ includeDeprecatedOperations: zod.z.boolean().optional(),
1068
+ multipleResponses: zod.z.boolean().optional(),
1069
+ devContainer: zod.z.boolean().optional(),
1070
+ allowMockClient: zod.z.boolean().optional(),
1034
1071
  ignoreFiles: zod.z.array(nonEmptyStringSchema).optional(),
1035
1072
  reservedKeywords: zod.z.array(nonEmptyStringSchema).optional(),
1036
1073
  hooks: hooksConfigSchema.optional(),
@@ -1045,7 +1082,30 @@ var sdkConfigV1GenerationConfigSchema = zod.z.strictObject({
1045
1082
  naming: namingConfigSchema.optional(),
1046
1083
  layout: layoutConfigSchema.optional(),
1047
1084
  serialization: serializationConfigSchema.optional()
1048
- });
1085
+ };
1086
+ var sdkConfigV1GenerationConfigOverrideSchema = zod.z.strictObject(
1087
+ generationConfigOverrideShape
1088
+ );
1089
+ var sdkConfigV1GenerationConfigSchema = zod.z.strictObject({
1090
+ ...generationConfigOverrideShape,
1091
+ includeWatermark: zod.z.boolean().default(false),
1092
+ ai: zod.z.boolean().default(false),
1093
+ buildAllModels: zod.z.boolean().default(false),
1094
+ inferServiceNames: zod.z.boolean().default(false),
1095
+ includeDeprecatedOperations: zod.z.boolean().default(true),
1096
+ multipleResponses: zod.z.boolean().default(false),
1097
+ devContainer: zod.z.boolean().default(false),
1098
+ allowMockClient: zod.z.boolean().default(false)
1099
+ });
1100
+ var commonGenerationKeys = new Set(Object.keys(generationConfigOverrideShape));
1101
+ function splitSdkConfigV1TargetGeneration(generation) {
1102
+ const common = {};
1103
+ const language = {};
1104
+ for (const [key, value] of Object.entries(generation ?? {})) {
1105
+ (commonGenerationKeys.has(key) ? common : language)[key] = value;
1106
+ }
1107
+ return { common, language };
1108
+ }
1049
1109
  var sdkConfigV1PublishRegistrySchema = zod.z.enum([
1050
1110
  "npm",
1051
1111
  "pypi",
@@ -1107,6 +1167,64 @@ var sdkConfigV1OutputConfigSchema = zod.z.discriminatedUnion(
1107
1167
  // src/sdk-config/v1/package.ts
1108
1168
  var sdkConfigV1DependencySchema = dependencySchema;
1109
1169
  var sdkConfigV1PackageConfigSchema = packageConfigSchema;
1170
+ var apiImportSettingsSchema = zod.z.strictObject({
1171
+ respectNullableSchemas: zod.z.boolean().optional(),
1172
+ titleAsSchemaName: zod.z.boolean().optional(),
1173
+ coerceEnumsToLiterals: zod.z.boolean().optional(),
1174
+ idiomaticRequestNames: zod.z.boolean().optional(),
1175
+ wrapReferencesToNullableInOptional: zod.z.boolean().optional(),
1176
+ coerceOptionalSchemasToNullable: zod.z.boolean().optional(),
1177
+ pathParameterOrder: zod.z.enum(["url-order", "spec-order"]).optional(),
1178
+ onlyIncludeReferencedSchemas: zod.z.boolean().optional(),
1179
+ objectQueryParameters: zod.z.boolean().optional(),
1180
+ typeDatesAsStrings: zod.z.boolean().optional(),
1181
+ groupMultiApiEnvironments: zod.z.boolean().optional(),
1182
+ defaultIntegerFormat: zod.z.enum(["int32", "int64", "uint32", "uint64"]).optional()
1183
+ });
1184
+ var sourceSpecTypeSchema = zod.z.enum([
1185
+ "openapi",
1186
+ "swagger",
1187
+ "postman",
1188
+ "asyncapi",
1189
+ "graphql"
1190
+ ]);
1191
+
1192
+ // src/sdk-config/v1/source.ts
1193
+ var sourceSpecShape = {
1194
+ id: nonEmptyStringSchema,
1195
+ type: sourceSpecTypeSchema,
1196
+ name: nonEmptyStringSchema.optional(),
1197
+ namespace: nonEmptyStringSchema.optional(),
1198
+ apiImportSettings: apiImportSettingsSchema.optional(),
1199
+ overlays: zod.z.array(relativePathSchema).optional(),
1200
+ overrides: zod.z.array(relativePathSchema).optional()
1201
+ };
1202
+ var sdkConfigV1SourceSpecSchema = zod.z.union(
1203
+ [
1204
+ zod.z.strictObject({ ...sourceSpecShape, path: relativePathSchema }),
1205
+ zod.z.strictObject({
1206
+ ...sourceSpecShape,
1207
+ url: zod.z.url({ protocol: /^https?$/ })
1208
+ })
1209
+ ],
1210
+ { error: "source spec must contain exactly one locator: path or HTTP(S) url" }
1211
+ );
1212
+ var sdkConfigV1SourceConfigSchema = zod.z.strictObject({
1213
+ specs: zod.z.array(sdkConfigV1SourceSpecSchema).min(1, "source.specs must contain at least one source spec"),
1214
+ apiImportSettings: apiImportSettingsSchema.optional()
1215
+ }).superRefine(({ specs }, context) => {
1216
+ const seenIds = /* @__PURE__ */ new Set();
1217
+ specs.forEach(({ id }, index) => {
1218
+ if (seenIds.has(id)) {
1219
+ context.addIssue({
1220
+ code: "custom",
1221
+ message: `source spec id "${id}" must be unique`,
1222
+ path: ["specs", index, "id"]
1223
+ });
1224
+ }
1225
+ seenIds.add(id);
1226
+ });
1227
+ });
1110
1228
  var cliGenerationConfigSchema = zod.z.strictObject({
1111
1229
  paginationParameters: zod.z.array(nonEmptyStringSchema).optional(),
1112
1230
  skills: zod.z.boolean().optional()
@@ -1168,6 +1286,8 @@ var typescriptGenerationConfigSchema = zod.z.strictObject({
1168
1286
  namingStrategy: zod.z.enum(["base", "originalPropertyNames"]).optional(),
1169
1287
  bundle: zod.z.boolean().optional(),
1170
1288
  exportClassDefault: zod.z.boolean().optional(),
1289
+ /** Name of the top-level namespace export emitted by Fern-compatible TypeScript SDKs. */
1290
+ namespaceExportName: nonEmptyStringSchema.optional(),
1171
1291
  allowCustomFetcher: zod.z.boolean().optional(),
1172
1292
  useBrandedStringAliases: zod.z.boolean().optional(),
1173
1293
  useLegacyExports: zod.z.boolean().optional(),
@@ -1272,73 +1392,75 @@ var targetOverrideShape = {
1272
1392
  generatorVersion: exactSemverSchema.optional(),
1273
1393
  sdkName: nonEmptyStringSchema.optional(),
1274
1394
  sdkVersion: nonEmptyStringSchema.optional(),
1395
+ client: sdkConfigV1ClientConfigOverrideSchema.optional(),
1396
+ docs: sdkConfigV1DocsConfigSchema.optional(),
1275
1397
  package: sdkConfigV1PackageConfigSchema.optional(),
1276
1398
  output: sdkConfigV1OutputConfigSchema.optional()
1277
1399
  };
1278
1400
  var sdkConfigV1TargetSchema = zod.z.discriminatedUnion("language", [
1279
1401
  zod.z.strictObject({
1280
1402
  language: zod.z.literal("typescript"),
1281
- generation: typescriptGenerationConfigSchema.optional(),
1403
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(typescriptGenerationConfigSchema.shape).optional(),
1282
1404
  ...targetOverrideShape
1283
1405
  }),
1284
1406
  zod.z.strictObject({
1285
1407
  language: zod.z.literal("python"),
1286
- generation: pythonGenerationConfigSchema.optional(),
1408
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(pythonGenerationConfigSchema.shape).optional(),
1287
1409
  ...targetOverrideShape
1288
1410
  }),
1289
1411
  zod.z.strictObject({
1290
1412
  language: zod.z.literal("java"),
1291
- generation: javaGenerationConfigSchema.optional(),
1413
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(javaGenerationConfigSchema.shape).optional(),
1292
1414
  ...targetOverrideShape
1293
1415
  }),
1294
1416
  zod.z.strictObject({
1295
1417
  language: zod.z.literal("kotlin"),
1296
- generation: kotlinGenerationConfigSchema.optional(),
1418
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(kotlinGenerationConfigSchema.shape).optional(),
1297
1419
  ...targetOverrideShape
1298
1420
  }),
1299
1421
  zod.z.strictObject({
1300
1422
  language: zod.z.literal("go"),
1301
- generation: goGenerationConfigSchema.optional(),
1423
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(goGenerationConfigSchema.shape).optional(),
1302
1424
  ...targetOverrideShape
1303
1425
  }),
1304
1426
  zod.z.strictObject({
1305
1427
  language: zod.z.literal("csharp"),
1306
- generation: csharpGenerationConfigSchema.optional(),
1428
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(csharpGenerationConfigSchema.shape).optional(),
1307
1429
  ...targetOverrideShape
1308
1430
  }),
1309
1431
  zod.z.strictObject({
1310
1432
  language: zod.z.literal("php"),
1311
- generation: phpGenerationConfigSchema.optional(),
1433
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(phpGenerationConfigSchema.shape).optional(),
1312
1434
  ...targetOverrideShape
1313
1435
  }),
1314
1436
  zod.z.strictObject({
1315
1437
  language: zod.z.literal("ruby"),
1316
- generation: rubyGenerationConfigSchema.optional(),
1438
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(rubyGenerationConfigSchema.shape).optional(),
1317
1439
  ...targetOverrideShape
1318
1440
  }),
1319
1441
  zod.z.strictObject({
1320
1442
  language: zod.z.literal("rust"),
1321
- generation: rustGenerationConfigSchema.optional(),
1443
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(rustGenerationConfigSchema.shape).optional(),
1322
1444
  ...targetOverrideShape
1323
1445
  }),
1324
1446
  zod.z.strictObject({
1325
1447
  language: zod.z.literal("swift"),
1326
- generation: swiftGenerationConfigSchema.optional(),
1448
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(swiftGenerationConfigSchema.shape).optional(),
1327
1449
  ...targetOverrideShape
1328
1450
  }),
1329
1451
  zod.z.strictObject({
1330
1452
  language: zod.z.literal("cli"),
1331
- generation: cliGenerationConfigSchema.optional(),
1453
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(cliGenerationConfigSchema.shape).optional(),
1332
1454
  ...targetOverrideShape
1333
1455
  }),
1334
1456
  zod.z.strictObject({
1335
1457
  language: zod.z.literal("mcp"),
1336
- generation: mcpGenerationConfigSchema.optional(),
1458
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(mcpGenerationConfigSchema.shape).optional(),
1337
1459
  ...targetOverrideShape
1338
1460
  }),
1339
1461
  zod.z.strictObject({
1340
1462
  language: zod.z.literal("terraform"),
1341
- generation: terraformGenerationConfigSchema.optional(),
1463
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(terraformGenerationConfigSchema.shape).optional(),
1342
1464
  ...targetOverrideShape
1343
1465
  })
1344
1466
  ]);
@@ -1403,6 +1525,14 @@ function validatePublishingIdentity(packageConfig, registry, targetIndex, contex
1403
1525
  }
1404
1526
  function validateTargetPublishing(target, targetIndex, globalPackage, globalOutput, context) {
1405
1527
  const output = target.output ?? globalOutput;
1528
+ if (!output) {
1529
+ context.addIssue({
1530
+ code: "custom",
1531
+ message: "output is required on the target when no global output is configured",
1532
+ path: ["targets", targetIndex, "output"]
1533
+ });
1534
+ return;
1535
+ }
1406
1536
  if (!output.publish) {
1407
1537
  return;
1408
1538
  }
@@ -1427,10 +1557,11 @@ var sdkConfigV1Schema = zod.z.strictObject({
1427
1557
  sdkName: nonEmptyStringSchema,
1428
1558
  sdkVersion: nonEmptyStringSchema.default("1.0.0"),
1429
1559
  apiVersion: nonEmptyStringSchema.optional(),
1560
+ source: sdkConfigV1SourceConfigSchema,
1430
1561
  api: sdkConfigV1ApiConfigSchema,
1431
1562
  client: sdkConfigV1ClientConfigSchema,
1432
1563
  package: sdkConfigV1PackageConfigSchema,
1433
- output: sdkConfigV1OutputConfigSchema,
1564
+ output: sdkConfigV1OutputConfigSchema.optional(),
1434
1565
  docs: sdkConfigV1DocsConfigSchema,
1435
1566
  generation: sdkConfigV1GenerationConfigSchema,
1436
1567
  targets: zod.z.array(sdkConfigV1TargetSchema).min(1)
@@ -1448,6 +1579,10 @@ var sdkConfigV1Schema = zod.z.strictObject({
1448
1579
  validateTargetPublishing(target, targetIndex, globalPackage, output, context);
1449
1580
  });
1450
1581
  });
1582
+ function validateSdkConfigV1(value) {
1583
+ sdkConfigV1Schema.parse(value);
1584
+ return value;
1585
+ }
1451
1586
  function parseSdkConfigV1(value) {
1452
1587
  return sdkConfigV1Schema.parse(value);
1453
1588
  }
@@ -1493,21 +1628,9 @@ function mapFernConfigToSdkConfigV1(input) {
1493
1628
  };
1494
1629
  });
1495
1630
  requireUniqueLanguages(mapped.map(({ language }) => language));
1496
- const client = requireSharedBlock(
1497
- mapped.map(({ invocation }) => invocation.client),
1498
- "client",
1499
- (value) => sdkConfigV1ClientConfigSchema.parse(value)
1500
- );
1501
- const docs = requireSharedBlock(
1502
- mapped.map(({ invocation }) => invocation.docs),
1503
- "docs",
1504
- (value) => sdkConfigV1DocsConfigSchema.parse(value)
1505
- );
1506
- const generation = requireSharedBlock(
1507
- mapped.map(({ invocation }) => invocation.generation),
1508
- "generation",
1509
- (value) => sdkConfigV1GenerationConfigSchema.parse(value)
1510
- );
1631
+ const clients = partitionSharedBlock(mapped.map(({ invocation }) => invocation.client));
1632
+ const docs = partitionSharedBlock(mapped.map(({ invocation }) => invocation.docs));
1633
+ const generations = partitionSharedBlock(mapped.map(({ invocation }) => invocation.generation));
1511
1634
  const api = { ...input.api ?? {} };
1512
1635
  delete api.audiences;
1513
1636
  if (input.group.audiences.type === "select") {
@@ -1519,13 +1642,19 @@ function mapFernConfigToSdkConfigV1(input) {
1519
1642
  language,
1520
1643
  output,
1521
1644
  ...optional("sdkName", generator.sdkName),
1522
- ...optional("sdkVersion", generator.sdkVersion)
1645
+ ...optional("sdkVersion", generator.sdkVersion),
1646
+ ...optional("client", clients.targetOverrides[index]),
1647
+ ...optional("docs", docs.targetOverrides[index])
1523
1648
  };
1524
1649
  if (Object.keys(invocation.package).length > 0 || outputPackage || generator.package) {
1525
1650
  target.package = { ...invocation.package, ...outputPackage, ...generator.package };
1526
1651
  }
1527
- if (Object.keys(invocation.targetGeneration).length > 0) {
1528
- target.generation = invocation.targetGeneration;
1652
+ const targetGeneration = {
1653
+ ...generations.targetOverrides[index],
1654
+ ...invocation.targetGeneration
1655
+ };
1656
+ if (Object.keys(targetGeneration).length > 0) {
1657
+ target.generation = targetGeneration;
1529
1658
  }
1530
1659
  if (generator.version) {
1531
1660
  if (exactSemverSchema.safeParse(generator.version).success) {
@@ -1544,19 +1673,20 @@ function mapFernConfigToSdkConfigV1(input) {
1544
1673
  return target;
1545
1674
  }
1546
1675
  );
1547
- const parsed = sdkConfigV1Schema.safeParse({
1676
+ const sdkConfig = {
1548
1677
  schemaVersion: "sdk-config/v1",
1549
1678
  sdkName: input.apiName,
1679
+ source: input.source,
1550
1680
  ...optional("sdkVersion", input.sdkVersion),
1551
1681
  ...optional("apiVersion", input.apiVersion),
1552
1682
  api,
1553
- client,
1683
+ client: clients.shared,
1554
1684
  package: {},
1555
- output: mapped[0].output,
1556
- docs,
1557
- generation,
1685
+ docs: docs.shared,
1686
+ generation: generations.shared,
1558
1687
  targets
1559
- });
1688
+ };
1689
+ const parsed = sdkConfigV1Schema.safeParse(sdkConfig);
1560
1690
  if (!parsed.success) {
1561
1691
  throw new FernConfigMappingError(
1562
1692
  parsed.error.issues.map((issue) => {
@@ -1574,8 +1704,9 @@ function mapFernConfigToSdkConfigV1(input) {
1574
1704
  })
1575
1705
  );
1576
1706
  }
1707
+ const validatedSdkConfig = sdkConfig;
1577
1708
  return {
1578
- sdkConfig: parsed.data,
1709
+ sdkConfig: validatedSdkConfig,
1579
1710
  unsupportedFields: mapped.flatMap(({ invocation, unsupportedFields }) => [
1580
1711
  ...invocation.unsupportedFields,
1581
1712
  ...unsupportedFields
@@ -1627,19 +1758,46 @@ function requireUniqueLanguages(languages) {
1627
1758
  seen.add(language);
1628
1759
  }
1629
1760
  }
1630
- function requireSharedBlock(values, name, normalize) {
1631
- const first = normalize(values[0]);
1632
- const serialized = stableJson(first);
1633
- if (values.some((value) => stableJson(normalize(value)) !== serialized)) {
1634
- fail(
1635
- "FERN_TARGET_SPECIFIC_SHARED_CONFIG",
1636
- ["group", "generators"],
1637
- `SDK Config v1 cannot represent target-specific Fern ${name} configuration`,
1638
- `Choose one shared ${name} configuration manually or create separate SDK Config documents for the differing targets.`,
1639
- [name]
1640
- );
1761
+ function partitionSharedBlock(values) {
1762
+ const partition = partitionObjectValues(values);
1763
+ return {
1764
+ shared: partition.shared,
1765
+ targetOverrides: partition.overrides.map(
1766
+ (override) => Object.keys(override).length > 0 ? override : void 0
1767
+ )
1768
+ };
1769
+ }
1770
+ function partitionObjectValues(values) {
1771
+ const shared = {};
1772
+ const overrides = values.map(() => ({}));
1773
+ const keys = new Set(values.flatMap((value) => Object.keys(value)));
1774
+ for (const key of keys) {
1775
+ const fieldValues = values.map((value) => value[key]);
1776
+ const presentOnEveryTarget = fieldValues.every((value) => value !== void 0);
1777
+ if (!presentOnEveryTarget) {
1778
+ fieldValues.forEach((value, index) => {
1779
+ if (value !== void 0) overrides[index][key] = value;
1780
+ });
1781
+ continue;
1782
+ }
1783
+ if (fieldValues.every(isObject)) {
1784
+ const nested = partitionObjectValues(fieldValues);
1785
+ if (Object.keys(nested.shared).length > 0) shared[key] = nested.shared;
1786
+ nested.overrides.forEach((override, index) => {
1787
+ if (Object.keys(override).length > 0) overrides[index][key] = override;
1788
+ });
1789
+ continue;
1790
+ }
1791
+ const first = fieldValues[0];
1792
+ if (fieldValues.every((value) => stableJson(value) === stableJson(first))) {
1793
+ shared[key] = first;
1794
+ } else {
1795
+ fieldValues.forEach((value, index) => {
1796
+ overrides[index][key] = value;
1797
+ });
1798
+ }
1641
1799
  }
1642
- return first;
1800
+ return { shared, overrides };
1643
1801
  }
1644
1802
  function mapInvocation(generator, language, index) {
1645
1803
  const prefix = ["group", "generators", index];
@@ -1649,14 +1807,21 @@ function mapInvocation(generator, language, index) {
1649
1807
  const generation = {};
1650
1808
  const packageConfig = {};
1651
1809
  mapCommonConfig(config, state, client, generation, packageConfig, [...prefix, "config"]);
1810
+ const rawGenerator = isObject(generator.raw) ? generator.raw : void 0;
1811
+ const smartCasing = typeof rawGenerator?.["smart-casing"] === "boolean" ? rawGenerator["smart-casing"] : generator.smartCasing === false ? false : void 0;
1812
+ const smartCasingDigitWordBoundary = typeof rawGenerator?.["smart-casing-digit-word-boundary"] === "boolean" ? rawGenerator["smart-casing-digit-word-boundary"] : generator.smartCasingDigitWordBoundary === true ? true : void 0;
1813
+ if (smartCasing !== void 0 || smartCasingDigitWordBoundary !== void 0) {
1814
+ generation.naming = {
1815
+ ...generation.naming,
1816
+ ...optional("smartCasing", smartCasing),
1817
+ ...optional("smartCasingDigitWordBoundary", smartCasingDigitWordBoundary)
1818
+ };
1819
+ }
1652
1820
  const targetGeneration = mapLanguageConfig(language, config, state, packageConfig, [
1653
1821
  ...prefix,
1654
1822
  "config"
1655
1823
  ]);
1656
1824
  mapPublishMetadata(generator.publishMetadata, packageConfig);
1657
- if (language === "go" && generator.smartCasing !== void 0) {
1658
- targetGeneration.smartCasing = generator.smartCasing;
1659
- }
1660
1825
  if (generator.keywords?.length) {
1661
1826
  generation.reservedKeywords = [...generator.keywords];
1662
1827
  }
@@ -1675,27 +1840,22 @@ function mapInvocation(generator, language, index) {
1675
1840
  ...collectUnsupported(config, [...prefix, "config"], state),
1676
1841
  ...settings ? collectUnsupported(settings, [...prefix, "settings"], state) : [],
1677
1842
  ...isObject(generator.readme) ? collectUnsupported(generator.readme, [...prefix, "readme"], state) : [],
1678
- ...unsupportedResolvedFields(generator, index, language)
1843
+ ...unsupportedResolvedFields(generator, index)
1679
1844
  ];
1680
1845
  return { client, docs, generation, package: packageConfig, targetGeneration, unsupportedFields };
1681
1846
  }
1682
- function unsupportedResolvedFields(generator, index, language) {
1847
+ function unsupportedResolvedFields(generator, index) {
1683
1848
  const values = [
1684
1849
  ["automation", isDefaultAutomation(generator.automation) ? void 0 : generator.automation],
1685
1850
  ["containerImage", generator.containerImage],
1686
1851
  ["irVersionOverride", generator.irVersionOverride],
1687
1852
  ["idempotencyKeyGenerationConfig", generator.idempotencyKeyGenerationConfig],
1688
1853
  ["absolutePathToLocalSnippets", generator.absolutePathToLocalSnippets],
1689
- [
1690
- "smartCasingDigitWordBoundary",
1691
- generator.smartCasingDigitWordBoundary === false ? void 0 : generator.smartCasingDigitWordBoundary
1692
- ],
1693
1854
  [
1694
1855
  "disableExamples",
1695
1856
  generator.disableExamples === false ? void 0 : generator.disableExamples
1696
1857
  ],
1697
- ["apiOverride", generator.apiOverride],
1698
- ...language === "go" || generator.smartCasing === true ? [] : [["smartCasing", generator.smartCasing]]
1858
+ ["apiOverride", generator.apiOverride]
1699
1859
  ];
1700
1860
  return values.flatMap(([field, value]) => {
1701
1861
  if (value === void 0) return [];
@@ -1859,6 +2019,12 @@ function mapTypescript(config, state, packageConfig, basePath) {
1859
2019
  testFramework: takeEnum(config, ["testFramework"], ["jest", "vitest"], state, basePath),
1860
2020
  bundle: takeBoolean(config, ["bundle"], state, basePath),
1861
2021
  exportClassDefault: takeBoolean(config, ["exportClassDefault"], state, basePath),
2022
+ namespaceExportName: takeString(
2023
+ config,
2024
+ ["namespaceExportName", "namespaceExport"],
2025
+ state,
2026
+ basePath
2027
+ ),
1862
2028
  allowCustomFetcher: takeBoolean(config, ["allowCustomFetcher"], state, basePath),
1863
2029
  useBrandedStringAliases: takeBoolean(config, ["useBrandedStringAliases"], state, basePath),
1864
2030
  useLegacyExports: takeBoolean(config, ["useLegacyExports"], state, basePath),
@@ -2205,12 +2371,14 @@ exports.sdkConfigV1ApiConfigSchema = sdkConfigV1ApiConfigSchema;
2205
2371
  exports.sdkConfigV1AuthConfigSchema = sdkConfigV1AuthConfigSchema;
2206
2372
  exports.sdkConfigV1AuthSchemeSchema = sdkConfigV1AuthSchemeSchema;
2207
2373
  exports.sdkConfigV1CliGenerationConfigSchema = cliGenerationConfigSchema;
2374
+ exports.sdkConfigV1ClientConfigOverrideSchema = sdkConfigV1ClientConfigOverrideSchema;
2208
2375
  exports.sdkConfigV1ClientConfigSchema = sdkConfigV1ClientConfigSchema;
2209
2376
  exports.sdkConfigV1ComposerPackageNameSchema = composerPackageNameSchema;
2210
2377
  exports.sdkConfigV1CsharpGenerationConfigSchema = csharpGenerationConfigSchema;
2211
2378
  exports.sdkConfigV1DependencySchema = sdkConfigV1DependencySchema;
2212
2379
  exports.sdkConfigV1DocsConfigSchema = sdkConfigV1DocsConfigSchema;
2213
2380
  exports.sdkConfigV1ExactSemverSchema = exactSemverSchema;
2381
+ exports.sdkConfigV1GenerationConfigOverrideSchema = sdkConfigV1GenerationConfigOverrideSchema;
2214
2382
  exports.sdkConfigV1GenerationConfigSchema = sdkConfigV1GenerationConfigSchema;
2215
2383
  exports.sdkConfigV1GoGenerationConfigSchema = goGenerationConfigSchema;
2216
2384
  exports.sdkConfigV1GoModulePathSchema = goModulePathSchema;
@@ -2230,9 +2398,13 @@ exports.sdkConfigV1RelativePathSchema = relativePathSchema;
2230
2398
  exports.sdkConfigV1RubyGenerationConfigSchema = rubyGenerationConfigSchema;
2231
2399
  exports.sdkConfigV1RustGenerationConfigSchema = rustGenerationConfigSchema;
2232
2400
  exports.sdkConfigV1Schema = sdkConfigV1Schema;
2401
+ exports.sdkConfigV1SourceConfigSchema = sdkConfigV1SourceConfigSchema;
2402
+ exports.sdkConfigV1SourceSpecSchema = sdkConfigV1SourceSpecSchema;
2233
2403
  exports.sdkConfigV1SwiftGenerationConfigSchema = swiftGenerationConfigSchema;
2234
2404
  exports.sdkConfigV1TargetSchema = sdkConfigV1TargetSchema;
2235
2405
  exports.sdkConfigV1TerraformGenerationConfigSchema = terraformGenerationConfigSchema;
2236
2406
  exports.sdkConfigV1TypescriptGenerationConfigSchema = typescriptGenerationConfigSchema;
2407
+ exports.splitSdkConfigV1TargetGeneration = splitSdkConfigV1TargetGeneration;
2408
+ exports.validateSdkConfigV1 = validateSdkConfigV1;
2237
2409
  //# sourceMappingURL=index.cjs.map
2238
2410
  //# sourceMappingURL=index.cjs.map