@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
@@ -9,6 +9,10 @@ var semver__default = /*#__PURE__*/_interopDefault(semver);
9
9
 
10
10
  // src/sdk-config-domain/v1/api.ts
11
11
  var nonEmptyStringSchema = zod.z.string().min(1);
12
+ var relativePathSchema = nonEmptyStringSchema.refine(
13
+ (value) => !/^(?:[\\/]|[A-Za-z]:)/.test(value) && !value.split(/[\\/]/).some((segment) => segment === ".."),
14
+ { message: "must be a relative path without parent directory segments" }
15
+ );
12
16
  var exactSemverSchema = zod.z.string().refine(
13
17
  (value) => {
14
18
  if (value.trim() !== value || !/^\d/.test(value)) {
@@ -195,26 +199,42 @@ var apiConfigSchema = zod.z.strictObject({
195
199
  var sdkConfigV1AuthSchemeSchema = authSchemeSchema;
196
200
  var sdkConfigV1AuthConfigSchema = authConfigSchema;
197
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);
198
227
  var retryConfigSchema = zod.z.strictObject({
228
+ ...retryOverrideShape,
199
229
  enabled: zod.z.boolean().default(true),
200
230
  maxAttempts: zod.z.number().int().min(1).default(3),
201
231
  retryDelayMs: zod.z.number().nonnegative().default(150),
202
232
  maxDelayMs: zod.z.number().nonnegative().default(5e3),
203
233
  jitterMs: zod.z.number().nonnegative().default(50),
204
234
  backoffFactor: zod.z.number().positive().default(2),
205
- statusCodes: zod.z.array(zod.z.number().int().min(100).max(599)).optional(),
206
235
  methods: zod.z.array(nonEmptyStringSchema).default(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]),
207
- statusCodeProfile: zod.z.enum(["legacy", "recommended"]).optional(),
208
236
  maxRetryAfterDelayMs: zod.z.number().nonnegative().default(6e4)
209
- }).superRefine(({ maxDelayMs, retryDelayMs }, context) => {
210
- if (maxDelayMs < retryDelayMs) {
211
- context.addIssue({
212
- code: "custom",
213
- message: "maxDelayMs must be greater than or equal to retryDelayMs",
214
- path: ["maxDelayMs"]
215
- });
216
- }
217
- });
237
+ }).superRefine(validateRetryDelays);
218
238
  var constructorParameterSchema = zod.z.strictObject({
219
239
  name: nonEmptyStringSchema,
220
240
  example: zod.z.string().optional(),
@@ -236,12 +256,12 @@ var tokenRefreshConfigSchema = zod.z.strictObject({
236
256
  });
237
257
  }
238
258
  });
239
- var clientConfigSchema = zod.z.strictObject({
240
- retry: retryConfigSchema.prefault({}),
241
- responseHeaders: zod.z.boolean().default(false),
259
+ var clientOverrideShape = {
260
+ retry: clientRetryOverrideSchema.optional(),
261
+ responseHeaders: zod.z.boolean().optional(),
242
262
  responseValidation: zod.z.boolean().optional(),
243
- multiTenant: zod.z.boolean().default(false),
244
- additionalConstructorParameters: zod.z.array(constructorParameterSchema).default([]),
263
+ multiTenant: zod.z.boolean().optional(),
264
+ additionalConstructorParameters: zod.z.array(constructorParameterSchema).optional(),
245
265
  timeoutMs: zod.z.union([zod.z.number().nonnegative(), zod.z.literal("infinity")]).optional(),
246
266
  requestParameterStyle: parameterStyleSchema.optional(),
247
267
  pathParameterStyle: parameterStyleSchema.optional(),
@@ -249,11 +269,20 @@ var clientConfigSchema = zod.z.strictObject({
249
269
  useDefaultRequestParameterValues: zod.z.boolean().optional(),
250
270
  respectOptionalRequestBody: zod.z.boolean().optional(),
251
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([])
252
280
  });
253
281
 
254
282
  // src/sdk-config/v1/client.ts
255
283
  var sdkConfigV1ClientConfigSchema = clientConfigSchema;
256
- var goModulePathSchema = nonEmptyStringSchema.regex(
284
+ var sdkConfigV1ClientConfigOverrideSchema = clientConfigOverrideSchema;
285
+ var goModulePathSchema = relativePathSchema.regex(
257
286
  /^(?!.*(?:^|\/)\.{1,2}(?:\/|$))[A-Za-z0-9._~-]+(?:\/[A-Za-z0-9._~-]+)+$/,
258
287
  "Go module path must be a slash-delimited path using letters, numbers, dots, dashes, underscores, or tildes"
259
288
  );
@@ -857,26 +886,32 @@ function finishOutputMapping(mapping, outputMode, sourcePath, state, index) {
857
886
  for (const path of collectLeafPaths(outputMode, sourcePath)) {
858
887
  if (path[path.length - 1] === "_visit") consume(state, path);
859
888
  }
889
+ const unsupported = collectUnsupported(outputMode, sourcePath, state);
890
+ const hasCredentials = unsupported.some((diagnostic) => isCredentialPath(diagnostic.path));
860
891
  return {
861
892
  ...mapping,
862
- unsupportedFields: collectUnsupported(outputMode, sourcePath, state).map(
863
- (diagnostic) => outputDiagnostic(diagnostic.path, index)
864
- )
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
+ ]
865
905
  };
866
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
+ }
867
912
  function outputDiagnostic(path, index) {
868
913
  const fields = path.filter((part) => typeof part === "string");
869
914
  const field = fields[fields.length - 1];
870
- const credential = fields.some((part) => part === "credentials" || part === "signature") || ["apiKey", "keyId", "password", "secretKey", "token", "username"].includes(field ?? "");
871
- if (credential) {
872
- return {
873
- code: "FERN_OUTPUT_CREDENTIAL_UNSUPPORTED",
874
- severity: "warning",
875
- path,
876
- reason: "Fern output credentials and signatures are not represented by SDK Config v1",
877
- suggestedAction: "Configure publication credentials and signing secrets outside SDK Config."
878
- };
879
- }
880
915
  const guidance = {
881
916
  directory: {
882
917
  suggestedAction: "Preserve the GitHub output subdirectory outside SDK Config; public v1 has no repository subdirectory field."
@@ -933,8 +968,22 @@ function outputDiagnostic(path, index) {
933
968
  suggestedAction: resolvedGuidance?.suggestedAction ?? "Review this output setting and preserve it outside SDK Config when no equivalent exists."
934
969
  };
935
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
936
985
  var customerGenerationAssetSchema = zod.z.discriminatedUnion("type", [
937
- zod.z.strictObject({ type: zod.z.literal("path"), location: nonEmptyStringSchema }),
986
+ zod.z.strictObject({ type: zod.z.literal("path"), location: relativePathSchema }),
938
987
  zod.z.strictObject({ type: zod.z.literal("url"), location: nonEmptyStringSchema })
939
988
  ]);
940
989
  var hookDependencySchema = zod.z.strictObject({
@@ -955,7 +1004,7 @@ var customCodeConfigSchema = zod.z.strictObject({
955
1004
  protectedFiles: zod.z.array(nonEmptyStringSchema).optional()
956
1005
  });
957
1006
  var workflowConfigSchema = zod.z.strictObject({
958
- path: nonEmptyStringSchema,
1007
+ path: relativePathSchema,
959
1008
  outputName: nonEmptyStringSchema.optional()
960
1009
  });
961
1010
  var analyticsHeaderSchema = zod.z.union([
@@ -999,14 +1048,6 @@ var streamsSchema = zod.z.strictObject({
999
1048
  fileResponseType: zod.z.enum(["stream", "binary-response"]).optional(),
1000
1049
  defaultChunkSizeBytes: zod.z.number().int().positive().optional()
1001
1050
  });
1002
- var namingConfigSchema = zod.z.strictObject({
1003
- clientName: nonEmptyStringSchema.optional(),
1004
- exportedClientName: nonEmptyStringSchema.optional(),
1005
- environmentTypeName: nonEmptyStringSchema.optional(),
1006
- apiErrorName: nonEmptyStringSchema.optional(),
1007
- baseErrorName: nonEmptyStringSchema.optional(),
1008
- pagerName: nonEmptyStringSchema.optional()
1009
- });
1010
1051
  var layoutConfigSchema = zod.z.strictObject({
1011
1052
  outputDirectory: zod.z.enum(["project-root", "source-root"]).optional(),
1012
1053
  packagePath: nonEmptyStringSchema.optional()
@@ -1017,22 +1058,22 @@ var serializationConfigSchema = zod.z.strictObject({
1017
1058
  inlineTypes: zod.z.boolean().optional(),
1018
1059
  omitUndefined: zod.z.boolean().optional()
1019
1060
  });
1020
- var sdkConfigV1GenerationConfigSchema = zod.z.strictObject({
1021
- includeWatermark: zod.z.boolean().default(false),
1022
- ai: zod.z.boolean().default(false),
1061
+ var generationConfigOverrideShape = {
1062
+ includeWatermark: zod.z.boolean().optional(),
1063
+ ai: zod.z.boolean().optional(),
1023
1064
  includeOptionalSnippetParameters: zod.z.boolean().optional(),
1024
- buildAllModels: zod.z.boolean().default(false),
1025
- inferServiceNames: zod.z.boolean().default(false),
1026
- includeDeprecatedOperations: zod.z.boolean().default(true),
1027
- multipleResponses: zod.z.boolean().default(false),
1028
- devContainer: zod.z.boolean().default(false),
1029
- 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(),
1030
1071
  ignoreFiles: zod.z.array(nonEmptyStringSchema).optional(),
1031
1072
  reservedKeywords: zod.z.array(nonEmptyStringSchema).optional(),
1032
1073
  hooks: hooksConfigSchema.optional(),
1033
1074
  customCode: customCodeConfigSchema.optional(),
1034
1075
  workflows: zod.z.array(workflowConfigSchema).optional(),
1035
- customQueryPaths: zod.z.array(nonEmptyStringSchema).optional(),
1076
+ customQueryPaths: zod.z.array(relativePathSchema).optional(),
1036
1077
  analytics: analyticsConfigSchema.optional(),
1037
1078
  wireTests: wireTestsSchema.optional(),
1038
1079
  unitTests: unitTestsSchema.optional(),
@@ -1041,7 +1082,30 @@ var sdkConfigV1GenerationConfigSchema = zod.z.strictObject({
1041
1082
  naming: namingConfigSchema.optional(),
1042
1083
  layout: layoutConfigSchema.optional(),
1043
1084
  serialization: serializationConfigSchema.optional()
1044
- });
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
+ }
1045
1109
  var sdkConfigV1PublishRegistrySchema = zod.z.enum([
1046
1110
  "npm",
1047
1111
  "pypi",
@@ -1103,6 +1167,64 @@ var sdkConfigV1OutputConfigSchema = zod.z.discriminatedUnion(
1103
1167
  // src/sdk-config/v1/package.ts
1104
1168
  var sdkConfigV1DependencySchema = dependencySchema;
1105
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
+ });
1106
1228
  var cliGenerationConfigSchema = zod.z.strictObject({
1107
1229
  paginationParameters: zod.z.array(nonEmptyStringSchema).optional(),
1108
1230
  skills: zod.z.boolean().optional()
@@ -1164,6 +1286,8 @@ var typescriptGenerationConfigSchema = zod.z.strictObject({
1164
1286
  namingStrategy: zod.z.enum(["base", "originalPropertyNames"]).optional(),
1165
1287
  bundle: zod.z.boolean().optional(),
1166
1288
  exportClassDefault: zod.z.boolean().optional(),
1289
+ /** Name of the top-level namespace export emitted by Fern-compatible TypeScript SDKs. */
1290
+ namespaceExportName: nonEmptyStringSchema.optional(),
1167
1291
  allowCustomFetcher: zod.z.boolean().optional(),
1168
1292
  useBrandedStringAliases: zod.z.boolean().optional(),
1169
1293
  useLegacyExports: zod.z.boolean().optional(),
@@ -1268,73 +1392,75 @@ var targetOverrideShape = {
1268
1392
  generatorVersion: exactSemverSchema.optional(),
1269
1393
  sdkName: nonEmptyStringSchema.optional(),
1270
1394
  sdkVersion: nonEmptyStringSchema.optional(),
1395
+ client: sdkConfigV1ClientConfigOverrideSchema.optional(),
1396
+ docs: sdkConfigV1DocsConfigSchema.optional(),
1271
1397
  package: sdkConfigV1PackageConfigSchema.optional(),
1272
1398
  output: sdkConfigV1OutputConfigSchema.optional()
1273
1399
  };
1274
1400
  var sdkConfigV1TargetSchema = zod.z.discriminatedUnion("language", [
1275
1401
  zod.z.strictObject({
1276
1402
  language: zod.z.literal("typescript"),
1277
- generation: typescriptGenerationConfigSchema.optional(),
1403
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(typescriptGenerationConfigSchema.shape).optional(),
1278
1404
  ...targetOverrideShape
1279
1405
  }),
1280
1406
  zod.z.strictObject({
1281
1407
  language: zod.z.literal("python"),
1282
- generation: pythonGenerationConfigSchema.optional(),
1408
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(pythonGenerationConfigSchema.shape).optional(),
1283
1409
  ...targetOverrideShape
1284
1410
  }),
1285
1411
  zod.z.strictObject({
1286
1412
  language: zod.z.literal("java"),
1287
- generation: javaGenerationConfigSchema.optional(),
1413
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(javaGenerationConfigSchema.shape).optional(),
1288
1414
  ...targetOverrideShape
1289
1415
  }),
1290
1416
  zod.z.strictObject({
1291
1417
  language: zod.z.literal("kotlin"),
1292
- generation: kotlinGenerationConfigSchema.optional(),
1418
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(kotlinGenerationConfigSchema.shape).optional(),
1293
1419
  ...targetOverrideShape
1294
1420
  }),
1295
1421
  zod.z.strictObject({
1296
1422
  language: zod.z.literal("go"),
1297
- generation: goGenerationConfigSchema.optional(),
1423
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(goGenerationConfigSchema.shape).optional(),
1298
1424
  ...targetOverrideShape
1299
1425
  }),
1300
1426
  zod.z.strictObject({
1301
1427
  language: zod.z.literal("csharp"),
1302
- generation: csharpGenerationConfigSchema.optional(),
1428
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(csharpGenerationConfigSchema.shape).optional(),
1303
1429
  ...targetOverrideShape
1304
1430
  }),
1305
1431
  zod.z.strictObject({
1306
1432
  language: zod.z.literal("php"),
1307
- generation: phpGenerationConfigSchema.optional(),
1433
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(phpGenerationConfigSchema.shape).optional(),
1308
1434
  ...targetOverrideShape
1309
1435
  }),
1310
1436
  zod.z.strictObject({
1311
1437
  language: zod.z.literal("ruby"),
1312
- generation: rubyGenerationConfigSchema.optional(),
1438
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(rubyGenerationConfigSchema.shape).optional(),
1313
1439
  ...targetOverrideShape
1314
1440
  }),
1315
1441
  zod.z.strictObject({
1316
1442
  language: zod.z.literal("rust"),
1317
- generation: rustGenerationConfigSchema.optional(),
1443
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(rustGenerationConfigSchema.shape).optional(),
1318
1444
  ...targetOverrideShape
1319
1445
  }),
1320
1446
  zod.z.strictObject({
1321
1447
  language: zod.z.literal("swift"),
1322
- generation: swiftGenerationConfigSchema.optional(),
1448
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(swiftGenerationConfigSchema.shape).optional(),
1323
1449
  ...targetOverrideShape
1324
1450
  }),
1325
1451
  zod.z.strictObject({
1326
1452
  language: zod.z.literal("cli"),
1327
- generation: cliGenerationConfigSchema.optional(),
1453
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(cliGenerationConfigSchema.shape).optional(),
1328
1454
  ...targetOverrideShape
1329
1455
  }),
1330
1456
  zod.z.strictObject({
1331
1457
  language: zod.z.literal("mcp"),
1332
- generation: mcpGenerationConfigSchema.optional(),
1458
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(mcpGenerationConfigSchema.shape).optional(),
1333
1459
  ...targetOverrideShape
1334
1460
  }),
1335
1461
  zod.z.strictObject({
1336
1462
  language: zod.z.literal("terraform"),
1337
- generation: terraformGenerationConfigSchema.optional(),
1463
+ generation: sdkConfigV1GenerationConfigOverrideSchema.extend(terraformGenerationConfigSchema.shape).optional(),
1338
1464
  ...targetOverrideShape
1339
1465
  })
1340
1466
  ]);
@@ -1399,6 +1525,14 @@ function validatePublishingIdentity(packageConfig, registry, targetIndex, contex
1399
1525
  }
1400
1526
  function validateTargetPublishing(target, targetIndex, globalPackage, globalOutput, context) {
1401
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
+ }
1402
1536
  if (!output.publish) {
1403
1537
  return;
1404
1538
  }
@@ -1423,10 +1557,11 @@ var sdkConfigV1Schema = zod.z.strictObject({
1423
1557
  sdkName: nonEmptyStringSchema,
1424
1558
  sdkVersion: nonEmptyStringSchema.default("1.0.0"),
1425
1559
  apiVersion: nonEmptyStringSchema.optional(),
1560
+ source: sdkConfigV1SourceConfigSchema,
1426
1561
  api: sdkConfigV1ApiConfigSchema,
1427
1562
  client: sdkConfigV1ClientConfigSchema,
1428
1563
  package: sdkConfigV1PackageConfigSchema,
1429
- output: sdkConfigV1OutputConfigSchema,
1564
+ output: sdkConfigV1OutputConfigSchema.optional(),
1430
1565
  docs: sdkConfigV1DocsConfigSchema,
1431
1566
  generation: sdkConfigV1GenerationConfigSchema,
1432
1567
  targets: zod.z.array(sdkConfigV1TargetSchema).min(1)
@@ -1444,6 +1579,10 @@ var sdkConfigV1Schema = zod.z.strictObject({
1444
1579
  validateTargetPublishing(target, targetIndex, globalPackage, output, context);
1445
1580
  });
1446
1581
  });
1582
+ function validateSdkConfigV1(value) {
1583
+ sdkConfigV1Schema.parse(value);
1584
+ return value;
1585
+ }
1447
1586
  function parseSdkConfigV1(value) {
1448
1587
  return sdkConfigV1Schema.parse(value);
1449
1588
  }
@@ -1489,21 +1628,9 @@ function mapFernConfigToSdkConfigV1(input) {
1489
1628
  };
1490
1629
  });
1491
1630
  requireUniqueLanguages(mapped.map(({ language }) => language));
1492
- const client = requireSharedBlock(
1493
- mapped.map(({ invocation }) => invocation.client),
1494
- "client",
1495
- (value) => sdkConfigV1ClientConfigSchema.parse(value)
1496
- );
1497
- const docs = requireSharedBlock(
1498
- mapped.map(({ invocation }) => invocation.docs),
1499
- "docs",
1500
- (value) => sdkConfigV1DocsConfigSchema.parse(value)
1501
- );
1502
- const generation = requireSharedBlock(
1503
- mapped.map(({ invocation }) => invocation.generation),
1504
- "generation",
1505
- (value) => sdkConfigV1GenerationConfigSchema.parse(value)
1506
- );
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));
1507
1634
  const api = { ...input.api ?? {} };
1508
1635
  delete api.audiences;
1509
1636
  if (input.group.audiences.type === "select") {
@@ -1515,13 +1642,19 @@ function mapFernConfigToSdkConfigV1(input) {
1515
1642
  language,
1516
1643
  output,
1517
1644
  ...optional("sdkName", generator.sdkName),
1518
- ...optional("sdkVersion", generator.sdkVersion)
1645
+ ...optional("sdkVersion", generator.sdkVersion),
1646
+ ...optional("client", clients.targetOverrides[index]),
1647
+ ...optional("docs", docs.targetOverrides[index])
1519
1648
  };
1520
1649
  if (Object.keys(invocation.package).length > 0 || outputPackage || generator.package) {
1521
1650
  target.package = { ...invocation.package, ...outputPackage, ...generator.package };
1522
1651
  }
1523
- if (Object.keys(invocation.targetGeneration).length > 0) {
1524
- 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;
1525
1658
  }
1526
1659
  if (generator.version) {
1527
1660
  if (exactSemverSchema.safeParse(generator.version).success) {
@@ -1540,19 +1673,20 @@ function mapFernConfigToSdkConfigV1(input) {
1540
1673
  return target;
1541
1674
  }
1542
1675
  );
1543
- const parsed = sdkConfigV1Schema.safeParse({
1676
+ const sdkConfig = {
1544
1677
  schemaVersion: "sdk-config/v1",
1545
1678
  sdkName: input.apiName,
1679
+ source: input.source,
1546
1680
  ...optional("sdkVersion", input.sdkVersion),
1547
1681
  ...optional("apiVersion", input.apiVersion),
1548
1682
  api,
1549
- client,
1683
+ client: clients.shared,
1550
1684
  package: {},
1551
- output: mapped[0].output,
1552
- docs,
1553
- generation,
1685
+ docs: docs.shared,
1686
+ generation: generations.shared,
1554
1687
  targets
1555
- });
1688
+ };
1689
+ const parsed = sdkConfigV1Schema.safeParse(sdkConfig);
1556
1690
  if (!parsed.success) {
1557
1691
  throw new FernConfigMappingError(
1558
1692
  parsed.error.issues.map((issue) => {
@@ -1570,8 +1704,9 @@ function mapFernConfigToSdkConfigV1(input) {
1570
1704
  })
1571
1705
  );
1572
1706
  }
1707
+ const validatedSdkConfig = sdkConfig;
1573
1708
  return {
1574
- sdkConfig: parsed.data,
1709
+ sdkConfig: validatedSdkConfig,
1575
1710
  unsupportedFields: mapped.flatMap(({ invocation, unsupportedFields }) => [
1576
1711
  ...invocation.unsupportedFields,
1577
1712
  ...unsupportedFields
@@ -1623,19 +1758,46 @@ function requireUniqueLanguages(languages) {
1623
1758
  seen.add(language);
1624
1759
  }
1625
1760
  }
1626
- function requireSharedBlock(values, name, normalize) {
1627
- const first = normalize(values[0]);
1628
- const serialized = stableJson(first);
1629
- if (values.some((value) => stableJson(normalize(value)) !== serialized)) {
1630
- fail(
1631
- "FERN_TARGET_SPECIFIC_SHARED_CONFIG",
1632
- ["group", "generators"],
1633
- `SDK Config v1 cannot represent target-specific Fern ${name} configuration`,
1634
- `Choose one shared ${name} configuration manually or create separate SDK Config documents for the differing targets.`,
1635
- [name]
1636
- );
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
+ }
1637
1799
  }
1638
- return first;
1800
+ return { shared, overrides };
1639
1801
  }
1640
1802
  function mapInvocation(generator, language, index) {
1641
1803
  const prefix = ["group", "generators", index];
@@ -1645,14 +1807,21 @@ function mapInvocation(generator, language, index) {
1645
1807
  const generation = {};
1646
1808
  const packageConfig = {};
1647
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
+ }
1648
1820
  const targetGeneration = mapLanguageConfig(language, config, state, packageConfig, [
1649
1821
  ...prefix,
1650
1822
  "config"
1651
1823
  ]);
1652
1824
  mapPublishMetadata(generator.publishMetadata, packageConfig);
1653
- if (language === "go" && generator.smartCasing !== void 0) {
1654
- targetGeneration.smartCasing = generator.smartCasing;
1655
- }
1656
1825
  if (generator.keywords?.length) {
1657
1826
  generation.reservedKeywords = [...generator.keywords];
1658
1827
  }
@@ -1671,27 +1840,22 @@ function mapInvocation(generator, language, index) {
1671
1840
  ...collectUnsupported(config, [...prefix, "config"], state),
1672
1841
  ...settings ? collectUnsupported(settings, [...prefix, "settings"], state) : [],
1673
1842
  ...isObject(generator.readme) ? collectUnsupported(generator.readme, [...prefix, "readme"], state) : [],
1674
- ...unsupportedResolvedFields(generator, index, language)
1843
+ ...unsupportedResolvedFields(generator, index)
1675
1844
  ];
1676
1845
  return { client, docs, generation, package: packageConfig, targetGeneration, unsupportedFields };
1677
1846
  }
1678
- function unsupportedResolvedFields(generator, index, language) {
1847
+ function unsupportedResolvedFields(generator, index) {
1679
1848
  const values = [
1680
1849
  ["automation", isDefaultAutomation(generator.automation) ? void 0 : generator.automation],
1681
1850
  ["containerImage", generator.containerImage],
1682
1851
  ["irVersionOverride", generator.irVersionOverride],
1683
1852
  ["idempotencyKeyGenerationConfig", generator.idempotencyKeyGenerationConfig],
1684
1853
  ["absolutePathToLocalSnippets", generator.absolutePathToLocalSnippets],
1685
- [
1686
- "smartCasingDigitWordBoundary",
1687
- generator.smartCasingDigitWordBoundary === false ? void 0 : generator.smartCasingDigitWordBoundary
1688
- ],
1689
1854
  [
1690
1855
  "disableExamples",
1691
1856
  generator.disableExamples === false ? void 0 : generator.disableExamples
1692
1857
  ],
1693
- ["apiOverride", generator.apiOverride],
1694
- ...language === "go" || generator.smartCasing === true ? [] : [["smartCasing", generator.smartCasing]]
1858
+ ["apiOverride", generator.apiOverride]
1695
1859
  ];
1696
1860
  return values.flatMap(([field, value]) => {
1697
1861
  if (value === void 0) return [];
@@ -1855,6 +2019,12 @@ function mapTypescript(config, state, packageConfig, basePath) {
1855
2019
  testFramework: takeEnum(config, ["testFramework"], ["jest", "vitest"], state, basePath),
1856
2020
  bundle: takeBoolean(config, ["bundle"], state, basePath),
1857
2021
  exportClassDefault: takeBoolean(config, ["exportClassDefault"], state, basePath),
2022
+ namespaceExportName: takeString(
2023
+ config,
2024
+ ["namespaceExportName", "namespaceExport"],
2025
+ state,
2026
+ basePath
2027
+ ),
1858
2028
  allowCustomFetcher: takeBoolean(config, ["allowCustomFetcher"], state, basePath),
1859
2029
  useBrandedStringAliases: takeBoolean(config, ["useBrandedStringAliases"], state, basePath),
1860
2030
  useLegacyExports: takeBoolean(config, ["useLegacyExports"], state, basePath),
@@ -2201,12 +2371,14 @@ exports.sdkConfigV1ApiConfigSchema = sdkConfigV1ApiConfigSchema;
2201
2371
  exports.sdkConfigV1AuthConfigSchema = sdkConfigV1AuthConfigSchema;
2202
2372
  exports.sdkConfigV1AuthSchemeSchema = sdkConfigV1AuthSchemeSchema;
2203
2373
  exports.sdkConfigV1CliGenerationConfigSchema = cliGenerationConfigSchema;
2374
+ exports.sdkConfigV1ClientConfigOverrideSchema = sdkConfigV1ClientConfigOverrideSchema;
2204
2375
  exports.sdkConfigV1ClientConfigSchema = sdkConfigV1ClientConfigSchema;
2205
2376
  exports.sdkConfigV1ComposerPackageNameSchema = composerPackageNameSchema;
2206
2377
  exports.sdkConfigV1CsharpGenerationConfigSchema = csharpGenerationConfigSchema;
2207
2378
  exports.sdkConfigV1DependencySchema = sdkConfigV1DependencySchema;
2208
2379
  exports.sdkConfigV1DocsConfigSchema = sdkConfigV1DocsConfigSchema;
2209
2380
  exports.sdkConfigV1ExactSemverSchema = exactSemverSchema;
2381
+ exports.sdkConfigV1GenerationConfigOverrideSchema = sdkConfigV1GenerationConfigOverrideSchema;
2210
2382
  exports.sdkConfigV1GenerationConfigSchema = sdkConfigV1GenerationConfigSchema;
2211
2383
  exports.sdkConfigV1GoGenerationConfigSchema = goGenerationConfigSchema;
2212
2384
  exports.sdkConfigV1GoModulePathSchema = goModulePathSchema;
@@ -2222,12 +2394,17 @@ exports.sdkConfigV1PublishRegistrySchema = sdkConfigV1PublishRegistrySchema;
2222
2394
  exports.sdkConfigV1PythonGenerationConfigSchema = pythonGenerationConfigSchema;
2223
2395
  exports.sdkConfigV1ReadmeCustomSectionSchema = sdkConfigV1ReadmeCustomSectionSchema;
2224
2396
  exports.sdkConfigV1ReadmeEndpointSchema = sdkConfigV1ReadmeEndpointSchema;
2397
+ exports.sdkConfigV1RelativePathSchema = relativePathSchema;
2225
2398
  exports.sdkConfigV1RubyGenerationConfigSchema = rubyGenerationConfigSchema;
2226
2399
  exports.sdkConfigV1RustGenerationConfigSchema = rustGenerationConfigSchema;
2227
2400
  exports.sdkConfigV1Schema = sdkConfigV1Schema;
2401
+ exports.sdkConfigV1SourceConfigSchema = sdkConfigV1SourceConfigSchema;
2402
+ exports.sdkConfigV1SourceSpecSchema = sdkConfigV1SourceSpecSchema;
2228
2403
  exports.sdkConfigV1SwiftGenerationConfigSchema = swiftGenerationConfigSchema;
2229
2404
  exports.sdkConfigV1TargetSchema = sdkConfigV1TargetSchema;
2230
2405
  exports.sdkConfigV1TerraformGenerationConfigSchema = terraformGenerationConfigSchema;
2231
2406
  exports.sdkConfigV1TypescriptGenerationConfigSchema = typescriptGenerationConfigSchema;
2407
+ exports.splitSdkConfigV1TargetGeneration = splitSdkConfigV1TargetGeneration;
2408
+ exports.validateSdkConfigV1 = validateSdkConfigV1;
2232
2409
  //# sourceMappingURL=index.cjs.map
2233
2410
  //# sourceMappingURL=index.cjs.map