@postman/sdk-config 0.1.0 → 0.2.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 +139 -124
  2. package/dist/index.cjs +301 -149
  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 +292 -150
  7. package/dist/index.js.map +1 -1
  8. package/dist/sdk-config/index.cjs +290 -113
  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 +284 -114
  13. package/dist/sdk-config/index.js.map +1 -1
  14. package/dist/sdk-config/v1/index.cjs +290 -113
  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 +284 -114
  19. package/dist/sdk-config/v1/index.js.map +1 -1
  20. package/dist/sdk-config-ir/index.cjs +71 -31
  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 +69 -32
  25. package/dist/sdk-config-ir/index.js.map +1 -1
  26. package/dist/sdk-config-ir/v1/index.cjs +71 -31
  27. package/dist/sdk-config-ir/v1/index.cjs.map +1 -1
  28. package/dist/sdk-config-ir/v1/index.d.cts +130 -43
  29. package/dist/sdk-config-ir/v1/index.d.ts +130 -43
  30. package/dist/sdk-config-ir/v1/index.js +69 -32
  31. package/dist/sdk-config-ir/v1/index.js.map +1 -1
  32. package/dist/{typescript-ByDbin_v.d.cts → typescript-DNqK3T3v.d.cts} +5 -1
  33. package/dist/{typescript-ByDbin_v.d.ts → typescript-DNqK3T3v.d.ts} +5 -1
  34. package/docs/releasing.md +114 -0
  35. package/package.json +2 -2
  36. package/src/sdk-config/v1/README.md +91 -23
  37. package/src/sdk-config-ir/v1/README.md +3 -2
@@ -3,6 +3,10 @@ import semver from 'semver';
3
3
 
4
4
  // src/sdk-config-domain/v1/api.ts
5
5
  var nonEmptyStringSchema = z.string().min(1);
6
+ var relativePathSchema = nonEmptyStringSchema.refine(
7
+ (value) => !/^(?:[\\/]|[A-Za-z]:)/.test(value) && !value.split(/[\\/]/).some((segment) => segment === ".."),
8
+ { message: "must be a relative path without parent directory segments" }
9
+ );
6
10
  var exactSemverSchema = z.string().refine(
7
11
  (value) => {
8
12
  if (value.trim() !== value || !/^\d/.test(value)) {
@@ -189,26 +193,42 @@ var apiConfigSchema = z.strictObject({
189
193
  var sdkConfigV1AuthSchemeSchema = authSchemeSchema;
190
194
  var sdkConfigV1AuthConfigSchema = authConfigSchema;
191
195
  var sdkConfigV1ApiConfigSchema = apiConfigSchema;
196
+ var retryOverrideShape = {
197
+ enabled: z.boolean().optional(),
198
+ maxAttempts: z.number().int().min(1).optional(),
199
+ retryDelayMs: z.number().nonnegative().optional(),
200
+ maxDelayMs: z.number().nonnegative().optional(),
201
+ jitterMs: z.number().nonnegative().optional(),
202
+ backoffFactor: z.number().positive().optional(),
203
+ statusCodes: z.array(z.number().int().min(100).max(599)).optional(),
204
+ methods: z.array(nonEmptyStringSchema).optional(),
205
+ statusCodeProfile: z.enum(["legacy", "recommended"]).optional(),
206
+ maxRetryAfterDelayMs: z.number().nonnegative().optional()
207
+ };
208
+ function validateRetryDelays({
209
+ maxDelayMs,
210
+ retryDelayMs
211
+ }, context) {
212
+ if (maxDelayMs !== void 0 && retryDelayMs !== void 0 && maxDelayMs < retryDelayMs) {
213
+ context.addIssue({
214
+ code: "custom",
215
+ message: "maxDelayMs must be greater than or equal to retryDelayMs",
216
+ path: ["maxDelayMs"]
217
+ });
218
+ }
219
+ }
220
+ var clientRetryOverrideSchema = z.strictObject(retryOverrideShape).superRefine(validateRetryDelays);
192
221
  var retryConfigSchema = z.strictObject({
222
+ ...retryOverrideShape,
193
223
  enabled: z.boolean().default(true),
194
224
  maxAttempts: z.number().int().min(1).default(3),
195
225
  retryDelayMs: z.number().nonnegative().default(150),
196
226
  maxDelayMs: z.number().nonnegative().default(5e3),
197
227
  jitterMs: z.number().nonnegative().default(50),
198
228
  backoffFactor: z.number().positive().default(2),
199
- statusCodes: z.array(z.number().int().min(100).max(599)).optional(),
200
229
  methods: z.array(nonEmptyStringSchema).default(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]),
201
- statusCodeProfile: z.enum(["legacy", "recommended"]).optional(),
202
230
  maxRetryAfterDelayMs: z.number().nonnegative().default(6e4)
203
- }).superRefine(({ maxDelayMs, retryDelayMs }, context) => {
204
- if (maxDelayMs < retryDelayMs) {
205
- context.addIssue({
206
- code: "custom",
207
- message: "maxDelayMs must be greater than or equal to retryDelayMs",
208
- path: ["maxDelayMs"]
209
- });
210
- }
211
- });
231
+ }).superRefine(validateRetryDelays);
212
232
  var constructorParameterSchema = z.strictObject({
213
233
  name: nonEmptyStringSchema,
214
234
  example: z.string().optional(),
@@ -230,12 +250,12 @@ var tokenRefreshConfigSchema = z.strictObject({
230
250
  });
231
251
  }
232
252
  });
233
- var clientConfigSchema = z.strictObject({
234
- retry: retryConfigSchema.prefault({}),
235
- responseHeaders: z.boolean().default(false),
253
+ var clientOverrideShape = {
254
+ retry: clientRetryOverrideSchema.optional(),
255
+ responseHeaders: z.boolean().optional(),
236
256
  responseValidation: z.boolean().optional(),
237
- multiTenant: z.boolean().default(false),
238
- additionalConstructorParameters: z.array(constructorParameterSchema).default([]),
257
+ multiTenant: z.boolean().optional(),
258
+ additionalConstructorParameters: z.array(constructorParameterSchema).optional(),
239
259
  timeoutMs: z.union([z.number().nonnegative(), z.literal("infinity")]).optional(),
240
260
  requestParameterStyle: parameterStyleSchema.optional(),
241
261
  pathParameterStyle: parameterStyleSchema.optional(),
@@ -243,11 +263,20 @@ var clientConfigSchema = z.strictObject({
243
263
  useDefaultRequestParameterValues: z.boolean().optional(),
244
264
  respectOptionalRequestBody: z.boolean().optional(),
245
265
  tokenRefresh: tokenRefreshConfigSchema.optional()
266
+ };
267
+ var clientConfigOverrideSchema = z.strictObject(clientOverrideShape);
268
+ var clientConfigSchema = z.strictObject({
269
+ ...clientOverrideShape,
270
+ retry: retryConfigSchema.prefault({}),
271
+ responseHeaders: z.boolean().default(false),
272
+ multiTenant: z.boolean().default(false),
273
+ additionalConstructorParameters: z.array(constructorParameterSchema).default([])
246
274
  });
247
275
 
248
276
  // src/sdk-config/v1/client.ts
249
277
  var sdkConfigV1ClientConfigSchema = clientConfigSchema;
250
- var goModulePathSchema = nonEmptyStringSchema.regex(
278
+ var sdkConfigV1ClientConfigOverrideSchema = clientConfigOverrideSchema;
279
+ var goModulePathSchema = relativePathSchema.regex(
251
280
  /^(?!.*(?:^|\/)\.{1,2}(?:\/|$))[A-Za-z0-9._~-]+(?:\/[A-Za-z0-9._~-]+)+$/,
252
281
  "Go module path must be a slash-delimited path using letters, numbers, dots, dashes, underscores, or tildes"
253
282
  );
@@ -851,26 +880,32 @@ function finishOutputMapping(mapping, outputMode, sourcePath, state, index) {
851
880
  for (const path of collectLeafPaths(outputMode, sourcePath)) {
852
881
  if (path[path.length - 1] === "_visit") consume(state, path);
853
882
  }
883
+ const unsupported = collectUnsupported(outputMode, sourcePath, state);
884
+ const hasCredentials = unsupported.some((diagnostic) => isCredentialPath(diagnostic.path));
854
885
  return {
855
886
  ...mapping,
856
- unsupportedFields: collectUnsupported(outputMode, sourcePath, state).map(
857
- (diagnostic) => outputDiagnostic(diagnostic.path, index)
858
- )
887
+ unsupportedFields: [
888
+ ...hasCredentials ? [
889
+ {
890
+ code: "FERN_OUTPUT_CREDENTIAL_UNSUPPORTED",
891
+ severity: "warning",
892
+ path: sourcePath,
893
+ reason: "Fern output credentials and signatures are intentionally excluded from SDK Config v1",
894
+ suggestedAction: "Provide publishing credentials through the build request or external secret resolution."
895
+ }
896
+ ] : [],
897
+ ...unsupported.filter((diagnostic) => !isCredentialPath(diagnostic.path)).map((diagnostic) => outputDiagnostic(diagnostic.path, index))
898
+ ]
859
899
  };
860
900
  }
901
+ function isCredentialPath(path) {
902
+ const fields = path.filter((part) => typeof part === "string");
903
+ const field = fields[fields.length - 1];
904
+ return fields.some((part) => part === "credentials" || part === "signature") || ["apiKey", "keyId", "password", "secretKey", "token", "username"].includes(field ?? "");
905
+ }
861
906
  function outputDiagnostic(path, index) {
862
907
  const fields = path.filter((part) => typeof part === "string");
863
908
  const field = fields[fields.length - 1];
864
- const credential = fields.some((part) => part === "credentials" || part === "signature") || ["apiKey", "keyId", "password", "secretKey", "token", "username"].includes(field ?? "");
865
- if (credential) {
866
- return {
867
- code: "FERN_OUTPUT_CREDENTIAL_UNSUPPORTED",
868
- severity: "warning",
869
- path,
870
- reason: "Fern output credentials and signatures are not represented by SDK Config v1",
871
- suggestedAction: "Configure publication credentials and signing secrets outside SDK Config."
872
- };
873
- }
874
909
  const guidance = {
875
910
  directory: {
876
911
  suggestedAction: "Preserve the GitHub output subdirectory outside SDK Config; public v1 has no repository subdirectory field."
@@ -927,8 +962,22 @@ function outputDiagnostic(path, index) {
927
962
  suggestedAction: resolvedGuidance?.suggestedAction ?? "Review this output setting and preserve it outside SDK Config when no equivalent exists."
928
963
  };
929
964
  }
965
+ var namingConfigSchema = z.strictObject({
966
+ clientName: nonEmptyStringSchema.optional(),
967
+ exportedClientName: nonEmptyStringSchema.optional(),
968
+ environmentTypeName: nonEmptyStringSchema.optional(),
969
+ apiErrorName: nonEmptyStringSchema.optional(),
970
+ baseErrorName: nonEmptyStringSchema.optional(),
971
+ pagerName: nonEmptyStringSchema.optional(),
972
+ /** Apply Fern's initialism-aware casing rules when deriving generated identifiers. */
973
+ smartCasing: z.boolean().optional(),
974
+ /** Preserve a word boundary after digits when Fern smart casing is enabled. */
975
+ smartCasingDigitWordBoundary: z.boolean().optional()
976
+ });
977
+
978
+ // src/sdk-config/v1/generation.ts
930
979
  var customerGenerationAssetSchema = z.discriminatedUnion("type", [
931
- z.strictObject({ type: z.literal("path"), location: nonEmptyStringSchema }),
980
+ z.strictObject({ type: z.literal("path"), location: relativePathSchema }),
932
981
  z.strictObject({ type: z.literal("url"), location: nonEmptyStringSchema })
933
982
  ]);
934
983
  var hookDependencySchema = z.strictObject({
@@ -949,7 +998,7 @@ var customCodeConfigSchema = z.strictObject({
949
998
  protectedFiles: z.array(nonEmptyStringSchema).optional()
950
999
  });
951
1000
  var workflowConfigSchema = z.strictObject({
952
- path: nonEmptyStringSchema,
1001
+ path: relativePathSchema,
953
1002
  outputName: nonEmptyStringSchema.optional()
954
1003
  });
955
1004
  var analyticsHeaderSchema = z.union([
@@ -993,14 +1042,6 @@ var streamsSchema = z.strictObject({
993
1042
  fileResponseType: z.enum(["stream", "binary-response"]).optional(),
994
1043
  defaultChunkSizeBytes: z.number().int().positive().optional()
995
1044
  });
996
- var namingConfigSchema = z.strictObject({
997
- clientName: nonEmptyStringSchema.optional(),
998
- exportedClientName: nonEmptyStringSchema.optional(),
999
- environmentTypeName: nonEmptyStringSchema.optional(),
1000
- apiErrorName: nonEmptyStringSchema.optional(),
1001
- baseErrorName: nonEmptyStringSchema.optional(),
1002
- pagerName: nonEmptyStringSchema.optional()
1003
- });
1004
1045
  var layoutConfigSchema = z.strictObject({
1005
1046
  outputDirectory: z.enum(["project-root", "source-root"]).optional(),
1006
1047
  packagePath: nonEmptyStringSchema.optional()
@@ -1011,22 +1052,22 @@ var serializationConfigSchema = z.strictObject({
1011
1052
  inlineTypes: z.boolean().optional(),
1012
1053
  omitUndefined: z.boolean().optional()
1013
1054
  });
1014
- var sdkConfigV1GenerationConfigSchema = z.strictObject({
1015
- includeWatermark: z.boolean().default(false),
1016
- ai: z.boolean().default(false),
1055
+ var generationConfigOverrideShape = {
1056
+ includeWatermark: z.boolean().optional(),
1057
+ ai: z.boolean().optional(),
1017
1058
  includeOptionalSnippetParameters: z.boolean().optional(),
1018
- buildAllModels: z.boolean().default(false),
1019
- inferServiceNames: z.boolean().default(false),
1020
- includeDeprecatedOperations: z.boolean().default(true),
1021
- multipleResponses: z.boolean().default(false),
1022
- devContainer: z.boolean().default(false),
1023
- allowMockClient: z.boolean().default(false),
1059
+ buildAllModels: z.boolean().optional(),
1060
+ inferServiceNames: z.boolean().optional(),
1061
+ includeDeprecatedOperations: z.boolean().optional(),
1062
+ multipleResponses: z.boolean().optional(),
1063
+ devContainer: z.boolean().optional(),
1064
+ allowMockClient: z.boolean().optional(),
1024
1065
  ignoreFiles: z.array(nonEmptyStringSchema).optional(),
1025
1066
  reservedKeywords: z.array(nonEmptyStringSchema).optional(),
1026
1067
  hooks: hooksConfigSchema.optional(),
1027
1068
  customCode: customCodeConfigSchema.optional(),
1028
1069
  workflows: z.array(workflowConfigSchema).optional(),
1029
- customQueryPaths: z.array(nonEmptyStringSchema).optional(),
1070
+ customQueryPaths: z.array(relativePathSchema).optional(),
1030
1071
  analytics: analyticsConfigSchema.optional(),
1031
1072
  wireTests: wireTestsSchema.optional(),
1032
1073
  unitTests: unitTestsSchema.optional(),
@@ -1035,7 +1076,30 @@ var sdkConfigV1GenerationConfigSchema = z.strictObject({
1035
1076
  naming: namingConfigSchema.optional(),
1036
1077
  layout: layoutConfigSchema.optional(),
1037
1078
  serialization: serializationConfigSchema.optional()
1038
- });
1079
+ };
1080
+ var sdkConfigV1GenerationConfigOverrideSchema = z.strictObject(
1081
+ generationConfigOverrideShape
1082
+ );
1083
+ var sdkConfigV1GenerationConfigSchema = z.strictObject({
1084
+ ...generationConfigOverrideShape,
1085
+ includeWatermark: z.boolean().default(false),
1086
+ ai: z.boolean().default(false),
1087
+ buildAllModels: z.boolean().default(false),
1088
+ inferServiceNames: z.boolean().default(false),
1089
+ includeDeprecatedOperations: z.boolean().default(true),
1090
+ multipleResponses: z.boolean().default(false),
1091
+ devContainer: z.boolean().default(false),
1092
+ allowMockClient: z.boolean().default(false)
1093
+ });
1094
+ var commonGenerationKeys = new Set(Object.keys(generationConfigOverrideShape));
1095
+ function splitSdkConfigV1TargetGeneration(generation) {
1096
+ const common = {};
1097
+ const language = {};
1098
+ for (const [key, value] of Object.entries(generation ?? {})) {
1099
+ (commonGenerationKeys.has(key) ? common : language)[key] = value;
1100
+ }
1101
+ return { common, language };
1102
+ }
1039
1103
  var sdkConfigV1PublishRegistrySchema = z.enum([
1040
1104
  "npm",
1041
1105
  "pypi",
@@ -1097,6 +1161,64 @@ var sdkConfigV1OutputConfigSchema = z.discriminatedUnion(
1097
1161
  // src/sdk-config/v1/package.ts
1098
1162
  var sdkConfigV1DependencySchema = dependencySchema;
1099
1163
  var sdkConfigV1PackageConfigSchema = packageConfigSchema;
1164
+ var apiImportSettingsSchema = z.strictObject({
1165
+ respectNullableSchemas: z.boolean().optional(),
1166
+ titleAsSchemaName: z.boolean().optional(),
1167
+ coerceEnumsToLiterals: z.boolean().optional(),
1168
+ idiomaticRequestNames: z.boolean().optional(),
1169
+ wrapReferencesToNullableInOptional: z.boolean().optional(),
1170
+ coerceOptionalSchemasToNullable: z.boolean().optional(),
1171
+ pathParameterOrder: z.enum(["url-order", "spec-order"]).optional(),
1172
+ onlyIncludeReferencedSchemas: z.boolean().optional(),
1173
+ objectQueryParameters: z.boolean().optional(),
1174
+ typeDatesAsStrings: z.boolean().optional(),
1175
+ groupMultiApiEnvironments: z.boolean().optional(),
1176
+ defaultIntegerFormat: z.enum(["int32", "int64", "uint32", "uint64"]).optional()
1177
+ });
1178
+ var sourceSpecTypeSchema = z.enum([
1179
+ "openapi",
1180
+ "swagger",
1181
+ "postman",
1182
+ "asyncapi",
1183
+ "graphql"
1184
+ ]);
1185
+
1186
+ // src/sdk-config/v1/source.ts
1187
+ var sourceSpecShape = {
1188
+ id: nonEmptyStringSchema,
1189
+ type: sourceSpecTypeSchema,
1190
+ name: nonEmptyStringSchema.optional(),
1191
+ namespace: nonEmptyStringSchema.optional(),
1192
+ apiImportSettings: apiImportSettingsSchema.optional(),
1193
+ overlays: z.array(relativePathSchema).optional(),
1194
+ overrides: z.array(relativePathSchema).optional()
1195
+ };
1196
+ var sdkConfigV1SourceSpecSchema = z.union(
1197
+ [
1198
+ z.strictObject({ ...sourceSpecShape, path: relativePathSchema }),
1199
+ z.strictObject({
1200
+ ...sourceSpecShape,
1201
+ url: z.url({ protocol: /^https?$/ })
1202
+ })
1203
+ ],
1204
+ { error: "source spec must contain exactly one locator: path or HTTP(S) url" }
1205
+ );
1206
+ var sdkConfigV1SourceConfigSchema = z.strictObject({
1207
+ specs: z.array(sdkConfigV1SourceSpecSchema).min(1, "source.specs must contain at least one source spec"),
1208
+ apiImportSettings: apiImportSettingsSchema.optional()
1209
+ }).superRefine(({ specs }, context) => {
1210
+ const seenIds = /* @__PURE__ */ new Set();
1211
+ specs.forEach(({ id }, index) => {
1212
+ if (seenIds.has(id)) {
1213
+ context.addIssue({
1214
+ code: "custom",
1215
+ message: `source spec id "${id}" must be unique`,
1216
+ path: ["specs", index, "id"]
1217
+ });
1218
+ }
1219
+ seenIds.add(id);
1220
+ });
1221
+ });
1100
1222
  var cliGenerationConfigSchema = z.strictObject({
1101
1223
  paginationParameters: z.array(nonEmptyStringSchema).optional(),
1102
1224
  skills: z.boolean().optional()
@@ -1158,6 +1280,8 @@ var typescriptGenerationConfigSchema = z.strictObject({
1158
1280
  namingStrategy: z.enum(["base", "originalPropertyNames"]).optional(),
1159
1281
  bundle: z.boolean().optional(),
1160
1282
  exportClassDefault: z.boolean().optional(),
1283
+ /** Name of the top-level namespace export emitted by Fern-compatible TypeScript SDKs. */
1284
+ namespaceExportName: nonEmptyStringSchema.optional(),
1161
1285
  allowCustomFetcher: z.boolean().optional(),
1162
1286
  useBrandedStringAliases: z.boolean().optional(),
1163
1287
  useLegacyExports: z.boolean().optional(),
@@ -1262,73 +1386,75 @@ var targetOverrideShape = {
1262
1386
  generatorVersion: exactSemverSchema.optional(),
1263
1387
  sdkName: nonEmptyStringSchema.optional(),
1264
1388
  sdkVersion: nonEmptyStringSchema.optional(),
1389
+ client: sdkConfigV1ClientConfigOverrideSchema.optional(),
1390
+ docs: sdkConfigV1DocsConfigSchema.optional(),
1265
1391
  package: sdkConfigV1PackageConfigSchema.optional(),
1266
1392
  output: sdkConfigV1OutputConfigSchema.optional()
1267
1393
  };
1268
1394
  var sdkConfigV1TargetSchema = z.discriminatedUnion("language", [
1269
1395
  z.strictObject({
1270
1396
  language: z.literal("typescript"),
1271
- generation: typescriptGenerationConfigSchema.optional(),
1397
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(typescriptGenerationConfigSchema.shape).optional(),
1272
1398
  ...targetOverrideShape
1273
1399
  }),
1274
1400
  z.strictObject({
1275
1401
  language: z.literal("python"),
1276
- generation: pythonGenerationConfigSchema.optional(),
1402
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(pythonGenerationConfigSchema.shape).optional(),
1277
1403
  ...targetOverrideShape
1278
1404
  }),
1279
1405
  z.strictObject({
1280
1406
  language: z.literal("java"),
1281
- generation: javaGenerationConfigSchema.optional(),
1407
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(javaGenerationConfigSchema.shape).optional(),
1282
1408
  ...targetOverrideShape
1283
1409
  }),
1284
1410
  z.strictObject({
1285
1411
  language: z.literal("kotlin"),
1286
- generation: kotlinGenerationConfigSchema.optional(),
1412
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(kotlinGenerationConfigSchema.shape).optional(),
1287
1413
  ...targetOverrideShape
1288
1414
  }),
1289
1415
  z.strictObject({
1290
1416
  language: z.literal("go"),
1291
- generation: goGenerationConfigSchema.optional(),
1417
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(goGenerationConfigSchema.shape).optional(),
1292
1418
  ...targetOverrideShape
1293
1419
  }),
1294
1420
  z.strictObject({
1295
1421
  language: z.literal("csharp"),
1296
- generation: csharpGenerationConfigSchema.optional(),
1422
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(csharpGenerationConfigSchema.shape).optional(),
1297
1423
  ...targetOverrideShape
1298
1424
  }),
1299
1425
  z.strictObject({
1300
1426
  language: z.literal("php"),
1301
- generation: phpGenerationConfigSchema.optional(),
1427
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(phpGenerationConfigSchema.shape).optional(),
1302
1428
  ...targetOverrideShape
1303
1429
  }),
1304
1430
  z.strictObject({
1305
1431
  language: z.literal("ruby"),
1306
- generation: rubyGenerationConfigSchema.optional(),
1432
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(rubyGenerationConfigSchema.shape).optional(),
1307
1433
  ...targetOverrideShape
1308
1434
  }),
1309
1435
  z.strictObject({
1310
1436
  language: z.literal("rust"),
1311
- generation: rustGenerationConfigSchema.optional(),
1437
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(rustGenerationConfigSchema.shape).optional(),
1312
1438
  ...targetOverrideShape
1313
1439
  }),
1314
1440
  z.strictObject({
1315
1441
  language: z.literal("swift"),
1316
- generation: swiftGenerationConfigSchema.optional(),
1442
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(swiftGenerationConfigSchema.shape).optional(),
1317
1443
  ...targetOverrideShape
1318
1444
  }),
1319
1445
  z.strictObject({
1320
1446
  language: z.literal("cli"),
1321
- generation: cliGenerationConfigSchema.optional(),
1447
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(cliGenerationConfigSchema.shape).optional(),
1322
1448
  ...targetOverrideShape
1323
1449
  }),
1324
1450
  z.strictObject({
1325
1451
  language: z.literal("mcp"),
1326
- generation: mcpGenerationConfigSchema.optional(),
1452
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(mcpGenerationConfigSchema.shape).optional(),
1327
1453
  ...targetOverrideShape
1328
1454
  }),
1329
1455
  z.strictObject({
1330
1456
  language: z.literal("terraform"),
1331
- generation: terraformGenerationConfigSchema.optional(),
1457
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(terraformGenerationConfigSchema.shape).optional(),
1332
1458
  ...targetOverrideShape
1333
1459
  })
1334
1460
  ]);
@@ -1393,6 +1519,14 @@ function validatePublishingIdentity(packageConfig, registry, targetIndex, contex
1393
1519
  }
1394
1520
  function validateTargetPublishing(target, targetIndex, globalPackage, globalOutput, context) {
1395
1521
  const output = target.output ?? globalOutput;
1522
+ if (!output) {
1523
+ context.addIssue({
1524
+ code: "custom",
1525
+ message: "output is required on the target when no global output is configured",
1526
+ path: ["targets", targetIndex, "output"]
1527
+ });
1528
+ return;
1529
+ }
1396
1530
  if (!output.publish) {
1397
1531
  return;
1398
1532
  }
@@ -1417,10 +1551,11 @@ var sdkConfigV1Schema = z.strictObject({
1417
1551
  sdkName: nonEmptyStringSchema,
1418
1552
  sdkVersion: nonEmptyStringSchema.default("1.0.0"),
1419
1553
  apiVersion: nonEmptyStringSchema.optional(),
1554
+ source: sdkConfigV1SourceConfigSchema,
1420
1555
  api: sdkConfigV1ApiConfigSchema,
1421
1556
  client: sdkConfigV1ClientConfigSchema,
1422
1557
  package: sdkConfigV1PackageConfigSchema,
1423
- output: sdkConfigV1OutputConfigSchema,
1558
+ output: sdkConfigV1OutputConfigSchema.optional(),
1424
1559
  docs: sdkConfigV1DocsConfigSchema,
1425
1560
  generation: sdkConfigV1GenerationConfigSchema,
1426
1561
  targets: z.array(sdkConfigV1TargetSchema).min(1)
@@ -1438,6 +1573,10 @@ var sdkConfigV1Schema = z.strictObject({
1438
1573
  validateTargetPublishing(target, targetIndex, globalPackage, output, context);
1439
1574
  });
1440
1575
  });
1576
+ function validateSdkConfigV1(value) {
1577
+ sdkConfigV1Schema.parse(value);
1578
+ return value;
1579
+ }
1441
1580
  function parseSdkConfigV1(value) {
1442
1581
  return sdkConfigV1Schema.parse(value);
1443
1582
  }
@@ -1483,21 +1622,9 @@ function mapFernConfigToSdkConfigV1(input) {
1483
1622
  };
1484
1623
  });
1485
1624
  requireUniqueLanguages(mapped.map(({ language }) => language));
1486
- const client = requireSharedBlock(
1487
- mapped.map(({ invocation }) => invocation.client),
1488
- "client",
1489
- (value) => sdkConfigV1ClientConfigSchema.parse(value)
1490
- );
1491
- const docs = requireSharedBlock(
1492
- mapped.map(({ invocation }) => invocation.docs),
1493
- "docs",
1494
- (value) => sdkConfigV1DocsConfigSchema.parse(value)
1495
- );
1496
- const generation = requireSharedBlock(
1497
- mapped.map(({ invocation }) => invocation.generation),
1498
- "generation",
1499
- (value) => sdkConfigV1GenerationConfigSchema.parse(value)
1500
- );
1625
+ const clients = partitionSharedBlock(mapped.map(({ invocation }) => invocation.client));
1626
+ const docs = partitionSharedBlock(mapped.map(({ invocation }) => invocation.docs));
1627
+ const generations = partitionSharedBlock(mapped.map(({ invocation }) => invocation.generation));
1501
1628
  const api = { ...input.api ?? {} };
1502
1629
  delete api.audiences;
1503
1630
  if (input.group.audiences.type === "select") {
@@ -1509,13 +1636,19 @@ function mapFernConfigToSdkConfigV1(input) {
1509
1636
  language,
1510
1637
  output,
1511
1638
  ...optional("sdkName", generator.sdkName),
1512
- ...optional("sdkVersion", generator.sdkVersion)
1639
+ ...optional("sdkVersion", generator.sdkVersion),
1640
+ ...optional("client", clients.targetOverrides[index]),
1641
+ ...optional("docs", docs.targetOverrides[index])
1513
1642
  };
1514
1643
  if (Object.keys(invocation.package).length > 0 || outputPackage || generator.package) {
1515
1644
  target.package = { ...invocation.package, ...outputPackage, ...generator.package };
1516
1645
  }
1517
- if (Object.keys(invocation.targetGeneration).length > 0) {
1518
- target.generation = invocation.targetGeneration;
1646
+ const targetGeneration = {
1647
+ ...generations.targetOverrides[index],
1648
+ ...invocation.targetGeneration
1649
+ };
1650
+ if (Object.keys(targetGeneration).length > 0) {
1651
+ target.generation = targetGeneration;
1519
1652
  }
1520
1653
  if (generator.version) {
1521
1654
  if (exactSemverSchema.safeParse(generator.version).success) {
@@ -1534,19 +1667,20 @@ function mapFernConfigToSdkConfigV1(input) {
1534
1667
  return target;
1535
1668
  }
1536
1669
  );
1537
- const parsed = sdkConfigV1Schema.safeParse({
1670
+ const sdkConfig = {
1538
1671
  schemaVersion: "sdk-config/v1",
1539
1672
  sdkName: input.apiName,
1673
+ source: input.source,
1540
1674
  ...optional("sdkVersion", input.sdkVersion),
1541
1675
  ...optional("apiVersion", input.apiVersion),
1542
1676
  api,
1543
- client,
1677
+ client: clients.shared,
1544
1678
  package: {},
1545
- output: mapped[0].output,
1546
- docs,
1547
- generation,
1679
+ docs: docs.shared,
1680
+ generation: generations.shared,
1548
1681
  targets
1549
- });
1682
+ };
1683
+ const parsed = sdkConfigV1Schema.safeParse(sdkConfig);
1550
1684
  if (!parsed.success) {
1551
1685
  throw new FernConfigMappingError(
1552
1686
  parsed.error.issues.map((issue) => {
@@ -1564,8 +1698,9 @@ function mapFernConfigToSdkConfigV1(input) {
1564
1698
  })
1565
1699
  );
1566
1700
  }
1701
+ const validatedSdkConfig = sdkConfig;
1567
1702
  return {
1568
- sdkConfig: parsed.data,
1703
+ sdkConfig: validatedSdkConfig,
1569
1704
  unsupportedFields: mapped.flatMap(({ invocation, unsupportedFields }) => [
1570
1705
  ...invocation.unsupportedFields,
1571
1706
  ...unsupportedFields
@@ -1617,19 +1752,46 @@ function requireUniqueLanguages(languages) {
1617
1752
  seen.add(language);
1618
1753
  }
1619
1754
  }
1620
- function requireSharedBlock(values, name, normalize) {
1621
- const first = normalize(values[0]);
1622
- const serialized = stableJson(first);
1623
- if (values.some((value) => stableJson(normalize(value)) !== serialized)) {
1624
- fail(
1625
- "FERN_TARGET_SPECIFIC_SHARED_CONFIG",
1626
- ["group", "generators"],
1627
- `SDK Config v1 cannot represent target-specific Fern ${name} configuration`,
1628
- `Choose one shared ${name} configuration manually or create separate SDK Config documents for the differing targets.`,
1629
- [name]
1630
- );
1755
+ function partitionSharedBlock(values) {
1756
+ const partition = partitionObjectValues(values);
1757
+ return {
1758
+ shared: partition.shared,
1759
+ targetOverrides: partition.overrides.map(
1760
+ (override) => Object.keys(override).length > 0 ? override : void 0
1761
+ )
1762
+ };
1763
+ }
1764
+ function partitionObjectValues(values) {
1765
+ const shared = {};
1766
+ const overrides = values.map(() => ({}));
1767
+ const keys = new Set(values.flatMap((value) => Object.keys(value)));
1768
+ for (const key of keys) {
1769
+ const fieldValues = values.map((value) => value[key]);
1770
+ const presentOnEveryTarget = fieldValues.every((value) => value !== void 0);
1771
+ if (!presentOnEveryTarget) {
1772
+ fieldValues.forEach((value, index) => {
1773
+ if (value !== void 0) overrides[index][key] = value;
1774
+ });
1775
+ continue;
1776
+ }
1777
+ if (fieldValues.every(isObject)) {
1778
+ const nested = partitionObjectValues(fieldValues);
1779
+ if (Object.keys(nested.shared).length > 0) shared[key] = nested.shared;
1780
+ nested.overrides.forEach((override, index) => {
1781
+ if (Object.keys(override).length > 0) overrides[index][key] = override;
1782
+ });
1783
+ continue;
1784
+ }
1785
+ const first = fieldValues[0];
1786
+ if (fieldValues.every((value) => stableJson(value) === stableJson(first))) {
1787
+ shared[key] = first;
1788
+ } else {
1789
+ fieldValues.forEach((value, index) => {
1790
+ overrides[index][key] = value;
1791
+ });
1792
+ }
1631
1793
  }
1632
- return first;
1794
+ return { shared, overrides };
1633
1795
  }
1634
1796
  function mapInvocation(generator, language, index) {
1635
1797
  const prefix = ["group", "generators", index];
@@ -1639,14 +1801,21 @@ function mapInvocation(generator, language, index) {
1639
1801
  const generation = {};
1640
1802
  const packageConfig = {};
1641
1803
  mapCommonConfig(config, state, client, generation, packageConfig, [...prefix, "config"]);
1804
+ const rawGenerator = isObject(generator.raw) ? generator.raw : void 0;
1805
+ const smartCasing = typeof rawGenerator?.["smart-casing"] === "boolean" ? rawGenerator["smart-casing"] : generator.smartCasing === false ? false : void 0;
1806
+ const smartCasingDigitWordBoundary = typeof rawGenerator?.["smart-casing-digit-word-boundary"] === "boolean" ? rawGenerator["smart-casing-digit-word-boundary"] : generator.smartCasingDigitWordBoundary === true ? true : void 0;
1807
+ if (smartCasing !== void 0 || smartCasingDigitWordBoundary !== void 0) {
1808
+ generation.naming = {
1809
+ ...generation.naming,
1810
+ ...optional("smartCasing", smartCasing),
1811
+ ...optional("smartCasingDigitWordBoundary", smartCasingDigitWordBoundary)
1812
+ };
1813
+ }
1642
1814
  const targetGeneration = mapLanguageConfig(language, config, state, packageConfig, [
1643
1815
  ...prefix,
1644
1816
  "config"
1645
1817
  ]);
1646
1818
  mapPublishMetadata(generator.publishMetadata, packageConfig);
1647
- if (language === "go" && generator.smartCasing !== void 0) {
1648
- targetGeneration.smartCasing = generator.smartCasing;
1649
- }
1650
1819
  if (generator.keywords?.length) {
1651
1820
  generation.reservedKeywords = [...generator.keywords];
1652
1821
  }
@@ -1665,27 +1834,22 @@ function mapInvocation(generator, language, index) {
1665
1834
  ...collectUnsupported(config, [...prefix, "config"], state),
1666
1835
  ...settings ? collectUnsupported(settings, [...prefix, "settings"], state) : [],
1667
1836
  ...isObject(generator.readme) ? collectUnsupported(generator.readme, [...prefix, "readme"], state) : [],
1668
- ...unsupportedResolvedFields(generator, index, language)
1837
+ ...unsupportedResolvedFields(generator, index)
1669
1838
  ];
1670
1839
  return { client, docs, generation, package: packageConfig, targetGeneration, unsupportedFields };
1671
1840
  }
1672
- function unsupportedResolvedFields(generator, index, language) {
1841
+ function unsupportedResolvedFields(generator, index) {
1673
1842
  const values = [
1674
1843
  ["automation", isDefaultAutomation(generator.automation) ? void 0 : generator.automation],
1675
1844
  ["containerImage", generator.containerImage],
1676
1845
  ["irVersionOverride", generator.irVersionOverride],
1677
1846
  ["idempotencyKeyGenerationConfig", generator.idempotencyKeyGenerationConfig],
1678
1847
  ["absolutePathToLocalSnippets", generator.absolutePathToLocalSnippets],
1679
- [
1680
- "smartCasingDigitWordBoundary",
1681
- generator.smartCasingDigitWordBoundary === false ? void 0 : generator.smartCasingDigitWordBoundary
1682
- ],
1683
1848
  [
1684
1849
  "disableExamples",
1685
1850
  generator.disableExamples === false ? void 0 : generator.disableExamples
1686
1851
  ],
1687
- ["apiOverride", generator.apiOverride],
1688
- ...language === "go" || generator.smartCasing === true ? [] : [["smartCasing", generator.smartCasing]]
1852
+ ["apiOverride", generator.apiOverride]
1689
1853
  ];
1690
1854
  return values.flatMap(([field, value]) => {
1691
1855
  if (value === void 0) return [];
@@ -1849,6 +2013,12 @@ function mapTypescript(config, state, packageConfig, basePath) {
1849
2013
  testFramework: takeEnum(config, ["testFramework"], ["jest", "vitest"], state, basePath),
1850
2014
  bundle: takeBoolean(config, ["bundle"], state, basePath),
1851
2015
  exportClassDefault: takeBoolean(config, ["exportClassDefault"], state, basePath),
2016
+ namespaceExportName: takeString(
2017
+ config,
2018
+ ["namespaceExportName", "namespaceExport"],
2019
+ state,
2020
+ basePath
2021
+ ),
1852
2022
  allowCustomFetcher: takeBoolean(config, ["allowCustomFetcher"], state, basePath),
1853
2023
  useBrandedStringAliases: takeBoolean(config, ["useBrandedStringAliases"], state, basePath),
1854
2024
  useLegacyExports: takeBoolean(config, ["useLegacyExports"], state, basePath),
@@ -2187,6 +2357,6 @@ function takeToolsets(value, aliases, state, basePath) {
2187
2357
  return Object.fromEntries(entries.filter((entry) => entry !== void 0));
2188
2358
  }
2189
2359
 
2190
- export { FernConfigMappingError, SDK_CONFIG_V1_SCHEMA_VERSION, mapFernConfigToSdkConfigV1, parseSdkConfigV1, sdkConfigV1ApiConfigSchema, sdkConfigV1AuthConfigSchema, sdkConfigV1AuthSchemeSchema, cliGenerationConfigSchema as sdkConfigV1CliGenerationConfigSchema, sdkConfigV1ClientConfigSchema, composerPackageNameSchema as sdkConfigV1ComposerPackageNameSchema, csharpGenerationConfigSchema as sdkConfigV1CsharpGenerationConfigSchema, sdkConfigV1DependencySchema, sdkConfigV1DocsConfigSchema, exactSemverSchema as sdkConfigV1ExactSemverSchema, sdkConfigV1GenerationConfigSchema, goGenerationConfigSchema as sdkConfigV1GoGenerationConfigSchema, goModulePathSchema as sdkConfigV1GoModulePathSchema, javaGenerationConfigSchema as sdkConfigV1JavaGenerationConfigSchema, kotlinGenerationConfigSchema as sdkConfigV1KotlinGenerationConfigSchema, mcpGenerationConfigSchema as sdkConfigV1McpGenerationConfigSchema, nonEmptyStringSchema as sdkConfigV1NonEmptyStringSchema, sdkConfigV1OutputConfigSchema, sdkConfigV1PackageConfigSchema, phpGenerationConfigSchema as sdkConfigV1PhpGenerationConfigSchema, sdkConfigV1PublishConfigSchema, sdkConfigV1PublishRegistrySchema, pythonGenerationConfigSchema as sdkConfigV1PythonGenerationConfigSchema, sdkConfigV1ReadmeCustomSectionSchema, sdkConfigV1ReadmeEndpointSchema, rubyGenerationConfigSchema as sdkConfigV1RubyGenerationConfigSchema, rustGenerationConfigSchema as sdkConfigV1RustGenerationConfigSchema, sdkConfigV1Schema, swiftGenerationConfigSchema as sdkConfigV1SwiftGenerationConfigSchema, sdkConfigV1TargetSchema, terraformGenerationConfigSchema as sdkConfigV1TerraformGenerationConfigSchema, typescriptGenerationConfigSchema as sdkConfigV1TypescriptGenerationConfigSchema };
2360
+ export { FernConfigMappingError, SDK_CONFIG_V1_SCHEMA_VERSION, mapFernConfigToSdkConfigV1, parseSdkConfigV1, sdkConfigV1ApiConfigSchema, sdkConfigV1AuthConfigSchema, sdkConfigV1AuthSchemeSchema, cliGenerationConfigSchema as sdkConfigV1CliGenerationConfigSchema, sdkConfigV1ClientConfigOverrideSchema, sdkConfigV1ClientConfigSchema, composerPackageNameSchema as sdkConfigV1ComposerPackageNameSchema, csharpGenerationConfigSchema as sdkConfigV1CsharpGenerationConfigSchema, sdkConfigV1DependencySchema, sdkConfigV1DocsConfigSchema, exactSemverSchema as sdkConfigV1ExactSemverSchema, sdkConfigV1GenerationConfigOverrideSchema, sdkConfigV1GenerationConfigSchema, goGenerationConfigSchema as sdkConfigV1GoGenerationConfigSchema, goModulePathSchema as sdkConfigV1GoModulePathSchema, javaGenerationConfigSchema as sdkConfigV1JavaGenerationConfigSchema, kotlinGenerationConfigSchema as sdkConfigV1KotlinGenerationConfigSchema, mcpGenerationConfigSchema as sdkConfigV1McpGenerationConfigSchema, nonEmptyStringSchema as sdkConfigV1NonEmptyStringSchema, sdkConfigV1OutputConfigSchema, sdkConfigV1PackageConfigSchema, phpGenerationConfigSchema as sdkConfigV1PhpGenerationConfigSchema, sdkConfigV1PublishConfigSchema, sdkConfigV1PublishRegistrySchema, pythonGenerationConfigSchema as sdkConfigV1PythonGenerationConfigSchema, sdkConfigV1ReadmeCustomSectionSchema, sdkConfigV1ReadmeEndpointSchema, relativePathSchema as sdkConfigV1RelativePathSchema, rubyGenerationConfigSchema as sdkConfigV1RubyGenerationConfigSchema, rustGenerationConfigSchema as sdkConfigV1RustGenerationConfigSchema, sdkConfigV1Schema, sdkConfigV1SourceConfigSchema, sdkConfigV1SourceSpecSchema, swiftGenerationConfigSchema as sdkConfigV1SwiftGenerationConfigSchema, sdkConfigV1TargetSchema, terraformGenerationConfigSchema as sdkConfigV1TerraformGenerationConfigSchema, typescriptGenerationConfigSchema as sdkConfigV1TypescriptGenerationConfigSchema, splitSdkConfigV1TargetGeneration, validateSdkConfigV1 };
2191
2361
  //# sourceMappingURL=index.js.map
2192
2362
  //# sourceMappingURL=index.js.map