@postman/sdk-config 0.5.1 → 0.6.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.
package/README.md CHANGED
@@ -81,11 +81,26 @@ a dedicated secret channel and remove them from generation payloads, logs, and s
81
81
  Fern migration preserves a credential only when the raw `generators.yml` value is exactly an
82
82
  environment expression; normalized, resolved, or literal values are omitted with a warning.
83
83
 
84
+ Service-to-service consumers that must remain compatible with additive V1 fields can use
85
+ `parseSdkConfigV1ForConsumption`. It ignores unknown object properties recursively while retaining
86
+ all validation for known fields. Customer-authored configuration should continue to use the strict
87
+ parser or validator so misspellings are reported.
88
+
84
89
  `SdkConfigV1` accepts customer-facing local source paths and HTTP(S) source URLs, but not
85
90
  server-owned signed URLs or artifact metadata. See the
86
91
  [SDK Config v1 reference](src/sdk-config/v1/README.md) for source materialization and target
87
92
  precedence rules.
88
93
 
94
+ ## Version 1 evolution policy
95
+
96
+ SDK Config V1 and SDK Config IR V1 evolve additively. New properties must be optional. Existing
97
+ properties cannot be removed, renamed, narrowed, or made required; those changes require a new
98
+ schema version. Adding an enum or union member is also not automatically forward-compatible because
99
+ an older consumer cannot ignore an unfamiliar value.
100
+
101
+ Schema contract fingerprints make every V1 shape change visible in review. Do not update those
102
+ fingerprints for a removal, rename, narrower type, or newly required property under V1.
103
+
89
104
  ## Use SDK Config in an SDK Generation API request
90
105
 
91
106
  An SDK Generation API request combines three kinds of data:
package/dist/index.cjs CHANGED
@@ -1339,6 +1339,125 @@ function outputDiagnostic(path, index) {
1339
1339
  suggestedAction: resolvedGuidance?.suggestedAction ?? "Review this output setting and preserve it outside SDK Config when no equivalent exists."
1340
1340
  };
1341
1341
  }
1342
+ var OMIT = /* @__PURE__ */ Symbol("omit");
1343
+ function inputJsonSchema(schema) {
1344
+ return zod.z.toJSONSchema(schema, {
1345
+ io: "input",
1346
+ unrepresentable: "any"
1347
+ });
1348
+ }
1349
+ function stripUnknownProperties(value, schema) {
1350
+ return project(value, schema, schema, false);
1351
+ }
1352
+ function omitSchemaDefaults(value, schema) {
1353
+ const projected = project(value, schema, schema, true);
1354
+ return projected === OMIT ? void 0 : projected;
1355
+ }
1356
+ function project(value, candidateSchema, rootSchema, omitDefaults) {
1357
+ const resolvedCandidate = resolveSchema(candidateSchema, rootSchema);
1358
+ if (omitDefaults && Object.hasOwn(resolvedCandidate, "default") && deepEqual(value, resolvedCandidate.default)) {
1359
+ return OMIT;
1360
+ }
1361
+ const schema = selectSchema(value, resolvedCandidate, rootSchema);
1362
+ if (omitDefaults && schema !== resolvedCandidate && Object.hasOwn(schema, "default") && deepEqual(value, schema.default)) {
1363
+ return OMIT;
1364
+ }
1365
+ if (Array.isArray(value)) {
1366
+ if (!schema.items) return value;
1367
+ return value.map((item) => {
1368
+ const projected = project(item, schema.items, rootSchema, omitDefaults);
1369
+ return projected === OMIT ? item : projected;
1370
+ });
1371
+ }
1372
+ if (!isRecord(value) || schema.type !== "object") return value;
1373
+ const entries = [];
1374
+ const properties = schema.properties ?? {};
1375
+ const unionProperties = omitDefaults ? properties : collectAlternativeProperties(resolvedCandidate, rootSchema);
1376
+ for (const [key, propertySchema] of Object.entries(properties)) {
1377
+ if (!Object.hasOwn(value, key)) continue;
1378
+ const projected = project(value[key], propertySchema, rootSchema, omitDefaults);
1379
+ if (projected !== OMIT) entries.push([key, projected]);
1380
+ }
1381
+ for (const [key, fieldValue] of Object.entries(value)) {
1382
+ if (Object.hasOwn(properties, key)) continue;
1383
+ if (Object.hasOwn(unionProperties, key)) {
1384
+ entries.push([key, fieldValue]);
1385
+ continue;
1386
+ }
1387
+ if (schema.additionalProperties !== false) {
1388
+ const projected = typeof schema.additionalProperties === "object" ? project(fieldValue, schema.additionalProperties, rootSchema, omitDefaults) : fieldValue;
1389
+ if (projected !== OMIT) entries.push([key, projected]);
1390
+ } else if (omitDefaults) {
1391
+ throw new Error(`Cannot serialize property unknown to the wire schema: ${key}`);
1392
+ }
1393
+ }
1394
+ return Object.fromEntries(entries);
1395
+ }
1396
+ function collectAlternativeProperties(schema, rootSchema) {
1397
+ const alternatives = schema.oneOf ?? schema.anyOf;
1398
+ if (!alternatives) return schema.properties ?? {};
1399
+ return Object.assign(
1400
+ {},
1401
+ ...alternatives.map((alternative) => resolveSchema(alternative, rootSchema).properties ?? {})
1402
+ );
1403
+ }
1404
+ function selectSchema(value, schema, rootSchema) {
1405
+ const alternatives = schema.oneOf ?? schema.anyOf;
1406
+ if (!alternatives || alternatives.length === 0) return schema;
1407
+ const best = alternatives.map((alternative, index) => {
1408
+ const resolved = resolveSchema(alternative, rootSchema);
1409
+ return { index, schema: resolved, score: schemaMatchScore(value, resolved) };
1410
+ }).sort((left, right) => right.score - left.score || left.index - right.index)[0];
1411
+ return best.score === Number.NEGATIVE_INFINITY ? schema : best.schema;
1412
+ }
1413
+ function schemaMatchScore(value, schema) {
1414
+ if (Object.hasOwn(schema, "const") && !deepEqual(value, schema.const)) {
1415
+ return Number.NEGATIVE_INFINITY;
1416
+ }
1417
+ if (schema.enum && !schema.enum.some((candidate) => deepEqual(value, candidate))) {
1418
+ return Number.NEGATIVE_INFINITY;
1419
+ }
1420
+ if (schema.type === "object") {
1421
+ if (!isRecord(value)) return Number.NEGATIVE_INFINITY;
1422
+ const properties = schema.properties ?? {};
1423
+ for (const [key, propertySchema] of Object.entries(properties)) {
1424
+ if (!Object.hasOwn(value, key)) continue;
1425
+ if (Object.hasOwn(propertySchema, "const") && !deepEqual(value[key], propertySchema.const)) {
1426
+ return Number.NEGATIVE_INFINITY;
1427
+ }
1428
+ }
1429
+ return Object.keys(value).filter((key) => Object.hasOwn(properties, key)).length;
1430
+ }
1431
+ if (schema.type === "array") return Array.isArray(value) ? 1 : Number.NEGATIVE_INFINITY;
1432
+ if (schema.type === "string") return typeof value === "string" ? 1 : Number.NEGATIVE_INFINITY;
1433
+ if (schema.type === "number" || schema.type === "integer") {
1434
+ return typeof value === "number" ? 1 : Number.NEGATIVE_INFINITY;
1435
+ }
1436
+ if (schema.type === "boolean") return typeof value === "boolean" ? 1 : Number.NEGATIVE_INFINITY;
1437
+ if (schema.type === "null") return value === null ? 1 : Number.NEGATIVE_INFINITY;
1438
+ return 0;
1439
+ }
1440
+ function resolveSchema(schema, rootSchema) {
1441
+ if (!schema.$ref) return schema;
1442
+ if (!schema.$ref.startsWith("#/$defs/")) return schema;
1443
+ const name = schema.$ref.slice("#/$defs/".length).replaceAll("~1", "/").replaceAll("~0", "~");
1444
+ return rootSchema.$defs?.[name] ?? schema;
1445
+ }
1446
+ function isRecord(value) {
1447
+ return value !== null && typeof value === "object" && !Array.isArray(value);
1448
+ }
1449
+ function deepEqual(left, right) {
1450
+ if (Object.is(left, right)) return true;
1451
+ if (Array.isArray(left) && Array.isArray(right)) {
1452
+ return left.length === right.length && left.every((value, index) => deepEqual(value, right[index]));
1453
+ }
1454
+ if (isRecord(left) && isRecord(right)) {
1455
+ const leftKeys = Object.keys(left);
1456
+ const rightKeys = Object.keys(right);
1457
+ return leftKeys.length === rightKeys.length && leftKeys.every((key) => Object.hasOwn(right, key) && deepEqual(left[key], right[key]));
1458
+ }
1459
+ return false;
1460
+ }
1342
1461
  var namingConfigSchema = zod.z.strictObject({
1343
1462
  clientName: nonEmptyStringSchema.optional(),
1344
1463
  exportedClientName: nonEmptyStringSchema.optional(),
@@ -2017,6 +2136,10 @@ function validateSdkConfigV1(value) {
2017
2136
  function parseSdkConfigV1(value) {
2018
2137
  return sdkConfigV1Schema.parse(value);
2019
2138
  }
2139
+ var sdkConfigV1InputJsonSchema = inputJsonSchema(sdkConfigV1Schema);
2140
+ function parseSdkConfigV1ForConsumption(value) {
2141
+ return parseSdkConfigV1(stripUnknownProperties(value, sdkConfigV1InputJsonSchema));
2142
+ }
2020
2143
 
2021
2144
  // src/sdk-config/v1/fern-config-mapper.ts
2022
2145
  var generatorLanguages = {
@@ -3423,6 +3546,30 @@ var sdkConfigIrV1Schema = zod.z.strictObject({
3423
3546
  function parseSdkConfigIrV1(value) {
3424
3547
  return sdkConfigIrV1Schema.parse(value);
3425
3548
  }
3549
+ var sdkConfigIrCapabilitySchema = zod.z.enum(["generation.generateFullProject"]);
3550
+ var sdkConfigIrV1InputJsonSchema = inputJsonSchema(sdkConfigIrV1Schema);
3551
+ function serializeSdkConfigIrV1(value) {
3552
+ const parsed = parseSdkConfigIrV1(value);
3553
+ const wireValue = omitSchemaDefaults(parsed, sdkConfigIrV1InputJsonSchema);
3554
+ const requiredCapabilities = [];
3555
+ if (wireValue === void 0) {
3556
+ throw new Error("SDK Config IR v1 root cannot be omitted from its wire payload");
3557
+ }
3558
+ if (parsed.generation.generateFullProject) {
3559
+ requiredCapabilities.push("generation.generateFullProject");
3560
+ }
3561
+ const json = JSON.stringify(wireValue);
3562
+ if (json === void 0) {
3563
+ throw new Error("SDK Config IR v1 could not be serialized as JSON");
3564
+ }
3565
+ return {
3566
+ body: new TextEncoder().encode(json),
3567
+ requiredCapabilities
3568
+ };
3569
+ }
3570
+ function parseSdkConfigIrV1ForConsumption(value) {
3571
+ return parseSdkConfigIrV1(stripUnknownProperties(value, sdkConfigIrV1InputJsonSchema));
3572
+ }
3426
3573
 
3427
3574
  exports.FernConfigMappingError = FernConfigMappingError;
3428
3575
  exports.SDK_CONFIG_IR_V1_SCHEMA_VERSION = SDK_CONFIG_IR_V1_SCHEMA_VERSION;
@@ -3457,7 +3604,9 @@ exports.nonEmptyStringSchema = nonEmptyStringSchema;
3457
3604
  exports.outputConfigSchema = outputConfigSchema;
3458
3605
  exports.packageConfigSchema = packageConfigSchema;
3459
3606
  exports.parseSdkConfigIrV1 = parseSdkConfigIrV1;
3607
+ exports.parseSdkConfigIrV1ForConsumption = parseSdkConfigIrV1ForConsumption;
3460
3608
  exports.parseSdkConfigV1 = parseSdkConfigV1;
3609
+ exports.parseSdkConfigV1ForConsumption = parseSdkConfigV1ForConsumption;
3461
3610
  exports.phpGenerationConfigSchema = phpGenerationConfigSchema;
3462
3611
  exports.publishConfigSchema = publishConfigSchema;
3463
3612
  exports.publishRegistrySchema = publishRegistrySchema;
@@ -3468,6 +3617,7 @@ exports.relativePathSchema = relativePathSchema;
3468
3617
  exports.replayConfigSchema = replayConfigSchema;
3469
3618
  exports.rubyGenerationConfigSchema = rubyGenerationConfigSchema;
3470
3619
  exports.rustGenerationConfigSchema = rustGenerationConfigSchema;
3620
+ exports.sdkConfigIrCapabilitySchema = sdkConfigIrCapabilitySchema;
3471
3621
  exports.sdkConfigIrV1Schema = sdkConfigIrV1Schema;
3472
3622
  exports.sdkConfigV1ApiConfigSchema = sdkConfigV1ApiConfigSchema;
3473
3623
  exports.sdkConfigV1AuthConfigSchema = sdkConfigV1AuthConfigSchema;
@@ -3508,6 +3658,7 @@ exports.sdkConfigV1TargetSchema = sdkConfigV1TargetSchema;
3508
3658
  exports.sdkConfigV1TerraformGenerationConfigSchema = terraformGenerationConfigSchema;
3509
3659
  exports.sdkConfigV1TypescriptGenerationConfigSchema = typescriptGenerationConfigSchema;
3510
3660
  exports.sdkConfigV1WebhookSignatureSchema = sdkConfigV1WebhookSignatureSchema;
3661
+ exports.serializeSdkConfigIrV1 = serializeSdkConfigIrV1;
3511
3662
  exports.sourceConfigSchema = sourceConfigSchema;
3512
3663
  exports.sourceSpecConfigSchema = sourceSpecConfigSchema;
3513
3664
  exports.sourceSpecTypeSchema = sourceSpecTypeSchema;