@postman/sdk-config 0.5.1 → 0.7.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 (35) hide show
  1. package/README.md +15 -0
  2. package/dist/index.cjs +263 -27
  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 +260 -28
  7. package/dist/index.js.map +1 -1
  8. package/dist/sdk-config/index.cjs +224 -27
  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 +224 -28
  13. package/dist/sdk-config/index.js.map +1 -1
  14. package/dist/sdk-config/v1/index.cjs +224 -27
  15. package/dist/sdk-config/v1/index.cjs.map +1 -1
  16. package/dist/sdk-config/v1/index.d.cts +20 -2
  17. package/dist/sdk-config/v1/index.d.ts +20 -2
  18. package/dist/sdk-config/v1/index.js +224 -28
  19. package/dist/sdk-config/v1/index.js.map +1 -1
  20. package/dist/sdk-config-ir/index.cjs +153 -0
  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 +151 -1
  25. package/dist/sdk-config-ir/index.js.map +1 -1
  26. package/dist/sdk-config-ir/v1/index.cjs +153 -0
  27. package/dist/sdk-config-ir/v1/index.cjs.map +1 -1
  28. package/dist/sdk-config-ir/v1/index.d.cts +43 -3
  29. package/dist/sdk-config-ir/v1/index.d.ts +43 -3
  30. package/dist/sdk-config-ir/v1/index.js +151 -1
  31. package/dist/sdk-config-ir/v1/index.js.map +1 -1
  32. package/dist/{typescript-BruxA5zG.d.cts → typescript-BdDv_kwT.d.cts} +8 -0
  33. package/dist/{typescript-BruxA5zG.d.ts → typescript-BdDv_kwT.d.ts} +8 -0
  34. package/package.json +1 -1
  35. package/src/sdk-config-ir/v1/README.md +10 -2
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
@@ -790,6 +790,7 @@ function githubOutput(value, publishInfo, rawOutput, language, sourcePath, state
790
790
  consume(state, [...sourcePath, "repo"]);
791
791
  const publication = publishInfo ? mapPublication(publishInfo, rawOutput, language, [...sourcePath, "publishInfo"], state, index) : void 0;
792
792
  const type = stringValue(value.type);
793
+ const licensePackage = mapGithubLicense(value.license, [...sourcePath, "license"], state);
793
794
  const reviewers = mapReviewers(value.reviewers, [...sourcePath, "reviewers"], state);
794
795
  if (type) consume(state, [...sourcePath, "type"]);
795
796
  if (typeof value.makePr === "boolean") consume(state, [...sourcePath, "makePr"]);
@@ -816,9 +817,20 @@ function githubOutput(value, publishInfo, rawOutput, language, sourcePath, state
816
817
  },
817
818
  ...publication ? { publish: publication.publish } : {}
818
819
  },
819
- ...optional("package", publication?.package)
820
+ // The GitHub license wins over a publication-supplied one; `licensePackage` is `{}` or `{ license }`.
821
+ ...optionalObject("package", { ...publication?.package, ...licensePackage })
820
822
  };
821
823
  }
824
+ var basicLicenseTypes = { mit: "MIT", apache: "APACHE" };
825
+ function mapGithubLicense(value, sourcePath, state) {
826
+ if (!isObject(value) || stringValue(value.type) !== "basic") return {};
827
+ const id = stringValue(value.id);
828
+ const type = id ? basicLicenseTypes[id.toLowerCase()] : void 0;
829
+ if (!type) return {};
830
+ consume(state, [...sourcePath, "type"]);
831
+ consume(state, [...sourcePath, "id"]);
832
+ return { license: { type } };
833
+ }
822
834
  function consumeCredentialObject(value, sourcePath, state) {
823
835
  if (!isObject(value)) return;
824
836
  for (const field of ["username", "password", "token", "apiKey"]) {
@@ -1339,6 +1351,125 @@ function outputDiagnostic(path, index) {
1339
1351
  suggestedAction: resolvedGuidance?.suggestedAction ?? "Review this output setting and preserve it outside SDK Config when no equivalent exists."
1340
1352
  };
1341
1353
  }
1354
+ var OMIT = /* @__PURE__ */ Symbol("omit");
1355
+ function inputJsonSchema(schema) {
1356
+ return zod.z.toJSONSchema(schema, {
1357
+ io: "input",
1358
+ unrepresentable: "any"
1359
+ });
1360
+ }
1361
+ function stripUnknownProperties(value, schema) {
1362
+ return project(value, schema, schema, false);
1363
+ }
1364
+ function omitSchemaDefaults(value, schema) {
1365
+ const projected = project(value, schema, schema, true);
1366
+ return projected === OMIT ? void 0 : projected;
1367
+ }
1368
+ function project(value, candidateSchema, rootSchema, omitDefaults) {
1369
+ const resolvedCandidate = resolveSchema(candidateSchema, rootSchema);
1370
+ if (omitDefaults && Object.hasOwn(resolvedCandidate, "default") && deepEqual(value, resolvedCandidate.default)) {
1371
+ return OMIT;
1372
+ }
1373
+ const schema = selectSchema(value, resolvedCandidate, rootSchema);
1374
+ if (omitDefaults && schema !== resolvedCandidate && Object.hasOwn(schema, "default") && deepEqual(value, schema.default)) {
1375
+ return OMIT;
1376
+ }
1377
+ if (Array.isArray(value)) {
1378
+ if (!schema.items) return value;
1379
+ return value.map((item) => {
1380
+ const projected = project(item, schema.items, rootSchema, omitDefaults);
1381
+ return projected === OMIT ? item : projected;
1382
+ });
1383
+ }
1384
+ if (!isRecord(value) || schema.type !== "object") return value;
1385
+ const entries = [];
1386
+ const properties = schema.properties ?? {};
1387
+ const unionProperties = omitDefaults ? properties : collectAlternativeProperties(resolvedCandidate, rootSchema);
1388
+ for (const [key, propertySchema] of Object.entries(properties)) {
1389
+ if (!Object.hasOwn(value, key)) continue;
1390
+ const projected = project(value[key], propertySchema, rootSchema, omitDefaults);
1391
+ if (projected !== OMIT) entries.push([key, projected]);
1392
+ }
1393
+ for (const [key, fieldValue] of Object.entries(value)) {
1394
+ if (Object.hasOwn(properties, key)) continue;
1395
+ if (Object.hasOwn(unionProperties, key)) {
1396
+ entries.push([key, fieldValue]);
1397
+ continue;
1398
+ }
1399
+ if (schema.additionalProperties !== false) {
1400
+ const projected = typeof schema.additionalProperties === "object" ? project(fieldValue, schema.additionalProperties, rootSchema, omitDefaults) : fieldValue;
1401
+ if (projected !== OMIT) entries.push([key, projected]);
1402
+ } else if (omitDefaults) {
1403
+ throw new Error(`Cannot serialize property unknown to the wire schema: ${key}`);
1404
+ }
1405
+ }
1406
+ return Object.fromEntries(entries);
1407
+ }
1408
+ function collectAlternativeProperties(schema, rootSchema) {
1409
+ const alternatives = schema.oneOf ?? schema.anyOf;
1410
+ if (!alternatives) return schema.properties ?? {};
1411
+ return Object.assign(
1412
+ {},
1413
+ ...alternatives.map((alternative) => resolveSchema(alternative, rootSchema).properties ?? {})
1414
+ );
1415
+ }
1416
+ function selectSchema(value, schema, rootSchema) {
1417
+ const alternatives = schema.oneOf ?? schema.anyOf;
1418
+ if (!alternatives || alternatives.length === 0) return schema;
1419
+ const best = alternatives.map((alternative, index) => {
1420
+ const resolved = resolveSchema(alternative, rootSchema);
1421
+ return { index, schema: resolved, score: schemaMatchScore(value, resolved) };
1422
+ }).sort((left, right) => right.score - left.score || left.index - right.index)[0];
1423
+ return best.score === Number.NEGATIVE_INFINITY ? schema : best.schema;
1424
+ }
1425
+ function schemaMatchScore(value, schema) {
1426
+ if (Object.hasOwn(schema, "const") && !deepEqual(value, schema.const)) {
1427
+ return Number.NEGATIVE_INFINITY;
1428
+ }
1429
+ if (schema.enum && !schema.enum.some((candidate) => deepEqual(value, candidate))) {
1430
+ return Number.NEGATIVE_INFINITY;
1431
+ }
1432
+ if (schema.type === "object") {
1433
+ if (!isRecord(value)) return Number.NEGATIVE_INFINITY;
1434
+ const properties = schema.properties ?? {};
1435
+ for (const [key, propertySchema] of Object.entries(properties)) {
1436
+ if (!Object.hasOwn(value, key)) continue;
1437
+ if (Object.hasOwn(propertySchema, "const") && !deepEqual(value[key], propertySchema.const)) {
1438
+ return Number.NEGATIVE_INFINITY;
1439
+ }
1440
+ }
1441
+ return Object.keys(value).filter((key) => Object.hasOwn(properties, key)).length;
1442
+ }
1443
+ if (schema.type === "array") return Array.isArray(value) ? 1 : Number.NEGATIVE_INFINITY;
1444
+ if (schema.type === "string") return typeof value === "string" ? 1 : Number.NEGATIVE_INFINITY;
1445
+ if (schema.type === "number" || schema.type === "integer") {
1446
+ return typeof value === "number" ? 1 : Number.NEGATIVE_INFINITY;
1447
+ }
1448
+ if (schema.type === "boolean") return typeof value === "boolean" ? 1 : Number.NEGATIVE_INFINITY;
1449
+ if (schema.type === "null") return value === null ? 1 : Number.NEGATIVE_INFINITY;
1450
+ return 0;
1451
+ }
1452
+ function resolveSchema(schema, rootSchema) {
1453
+ if (!schema.$ref) return schema;
1454
+ if (!schema.$ref.startsWith("#/$defs/")) return schema;
1455
+ const name = schema.$ref.slice("#/$defs/".length).replaceAll("~1", "/").replaceAll("~0", "~");
1456
+ return rootSchema.$defs?.[name] ?? schema;
1457
+ }
1458
+ function isRecord(value) {
1459
+ return value !== null && typeof value === "object" && !Array.isArray(value);
1460
+ }
1461
+ function deepEqual(left, right) {
1462
+ if (Object.is(left, right)) return true;
1463
+ if (Array.isArray(left) && Array.isArray(right)) {
1464
+ return left.length === right.length && left.every((value, index) => deepEqual(value, right[index]));
1465
+ }
1466
+ if (isRecord(left) && isRecord(right)) {
1467
+ const leftKeys = Object.keys(left);
1468
+ const rightKeys = Object.keys(right);
1469
+ return leftKeys.length === rightKeys.length && leftKeys.every((key) => Object.hasOwn(right, key) && deepEqual(left[key], right[key]));
1470
+ }
1471
+ return false;
1472
+ }
1342
1473
  var namingConfigSchema = zod.z.strictObject({
1343
1474
  clientName: nonEmptyStringSchema.optional(),
1344
1475
  exportedClientName: nonEmptyStringSchema.optional(),
@@ -1699,17 +1830,22 @@ var typescriptGenerationConfigSchema = zod.z.strictObject({
1699
1830
  compilerOptions: compilerOptionsSchema.optional(),
1700
1831
  httpClient: httpClientSchema.optional(),
1701
1832
  packageManager: zod.z.enum(["pnpm", "yarn"]).optional(),
1833
+ /** e.g. `1.22.22` — from the customer's own `config.packageJson.packageManager` (`yarn@1.22.22`). */
1834
+ packageManagerVersion: nonEmptyStringSchema.optional(),
1702
1835
  testFramework: zod.z.enum(["jest", "vitest"]).optional(),
1703
1836
  namingStrategy: zod.z.enum(["base", "originalPropertyNames"]).optional(),
1704
1837
  bundle: zod.z.boolean().optional(),
1705
1838
  exportClassDefault: zod.z.boolean().optional(),
1706
1839
  /** Name of the top-level namespace export emitted by Fern-compatible TypeScript SDKs. */
1707
1840
  namespaceExportName: nonEmptyStringSchema.optional(),
1841
+ consolidateTypeFiles: zod.z.boolean().optional(),
1708
1842
  allowCustomFetcher: zod.z.boolean().optional(),
1709
1843
  useBrandedStringAliases: zod.z.boolean().optional(),
1710
1844
  useLegacyExports: zod.z.boolean().optional(),
1711
1845
  useBigInt: zod.z.boolean().optional(),
1712
1846
  serdeLayer: zod.z.boolean().optional(),
1847
+ /** Ship only the ESM build (drops CJS) to avoid the Node dual-package hazard. */
1848
+ esmOnly: zod.z.boolean().optional(),
1713
1849
  scripts: zod.z.array(packageScriptSchema).optional()
1714
1850
  });
1715
1851
 
@@ -2017,6 +2153,10 @@ function validateSdkConfigV1(value) {
2017
2153
  function parseSdkConfigV1(value) {
2018
2154
  return sdkConfigV1Schema.parse(value);
2019
2155
  }
2156
+ var sdkConfigV1InputJsonSchema = inputJsonSchema(sdkConfigV1Schema);
2157
+ function parseSdkConfigV1ForConsumption(value) {
2158
+ return parseSdkConfigV1(stripUnknownProperties(value, sdkConfigV1InputJsonSchema));
2159
+ }
2020
2160
 
2021
2161
  // src/sdk-config/v1/fern-config-mapper.ts
2022
2162
  var generatorLanguages = {
@@ -2379,15 +2519,23 @@ function mapCommonConfig(language, config, state, client, generation, packageCon
2379
2519
  };
2380
2520
  }
2381
2521
  const pythonClient = language === "python" ? takeObject(config, ["client"], state, basePath) : void 0;
2522
+ const typescriptNaming = language === "typescript" || language === "mcp" ? takeObject(config, ["naming"], state, basePath) : void 0;
2382
2523
  const directClientName = takeString(config, ["clientName", "clientClassName"], state, basePath);
2383
- const nestedClientName = pythonClient ? takeString(pythonClient.value, ["className"], state, pythonClient.path) : void 0;
2524
+ const nestedClientName = pythonClient ? takeString(pythonClient.value, ["className"], state, pythonClient.path) : typescriptNaming ? takeString(typescriptNaming.value, ["client"], state, typescriptNaming.path) : void 0;
2384
2525
  const directExportedClientName = takeString(
2385
2526
  config,
2386
2527
  ["exportedClientName", "exportedClientClassName"],
2387
2528
  state,
2388
2529
  basePath
2389
2530
  );
2390
- const nestedExportedClientName = pythonClient ? takeString(pythonClient.value, ["exportedClassName"], state, pythonClient.path) : void 0;
2531
+ const nestedExportedClientName = pythonClient ? takeString(pythonClient.value, ["exportedClassName"], state, pythonClient.path) : typescriptNaming ? (
2532
+ // TypeScript's `naming.namespace` is the base every other naming.* field defaults from
2533
+ // (Fern's docs: `client` defaults to `${PascalCase(namespace)}Client`, same for
2534
+ // `environment`/`error`/etc.) — the same role `exportedClientName` already plays for every
2535
+ // other language's `clientPrefix` derivation.
2536
+ takeString(typescriptNaming.value, ["namespace"], state, typescriptNaming.path)
2537
+ ) : void 0;
2538
+ const nestedEnvironmentTypeName = typescriptNaming ? takeString(typescriptNaming.value, ["environment"], state, typescriptNaming.path) : void 0;
2391
2539
  const naming = compact({
2392
2540
  pagerName: takeString(
2393
2541
  config,
@@ -2397,12 +2545,7 @@ function mapCommonConfig(language, config, state, client, generation, packageCon
2397
2545
  ),
2398
2546
  clientName: directClientName ?? nestedClientName,
2399
2547
  exportedClientName: directExportedClientName ?? nestedExportedClientName,
2400
- environmentTypeName: takeString(
2401
- config,
2402
- ["environmentClassName", "environmentEnumName"],
2403
- state,
2404
- basePath
2405
- ),
2548
+ environmentTypeName: takeString(config, ["environmentClassName", "environmentEnumName"], state, basePath) ?? nestedEnvironmentTypeName,
2406
2549
  apiErrorName: takeString(config, ["baseApiExceptionClassName"], state, basePath),
2407
2550
  baseErrorName: takeString(config, ["baseExceptionClassName"], state, basePath)
2408
2551
  });
@@ -2416,6 +2559,10 @@ function mapCommonConfig(language, config, state, client, generation, packageCon
2416
2559
  basePath
2417
2560
  );
2418
2561
  if (webSockets !== void 0) generation.webSockets = webSockets;
2562
+ if (language === "typescript") {
2563
+ const streams = mapTypescriptStreams(config, state, basePath);
2564
+ if (streams) generation.streams = streams;
2565
+ }
2419
2566
  const generateFullProject = takeBoolean(config, ["generateFullProject"], state, basePath);
2420
2567
  if (generateFullProject !== void 0) generation.generateFullProject = generateFullProject;
2421
2568
  const inlineTypes = takeBoolean(config, ["enableInlineTypes"], state, basePath);
@@ -2433,6 +2580,18 @@ function mapCommonConfig(language, config, state, client, generation, packageCon
2433
2580
  if (packagePath !== void 0) generation.layout = { packagePath };
2434
2581
  mapDependencies(config, state, packageConfig, basePath);
2435
2582
  }
2583
+ function mapTypescriptStreams(config, state, basePath) {
2584
+ const responseType = takeEnum(config, ["streamType"], ["wrapper", "web"], state, basePath);
2585
+ const fileResponseType = takeEnum(
2586
+ config,
2587
+ ["fileResponseType"],
2588
+ ["stream", "binary-response"],
2589
+ state,
2590
+ basePath
2591
+ );
2592
+ if (responseType === void 0 && fileResponseType === void 0) return void 0;
2593
+ return { enabled: true, ...compact({ responseType, fileResponseType }) };
2594
+ }
2436
2595
  function mapLanguageConfig(language, config, state, packageConfig, basePath) {
2437
2596
  switch (language) {
2438
2597
  case "typescript":
@@ -2466,29 +2625,39 @@ function mapLanguageConfig(language, config, state, packageConfig, basePath) {
2466
2625
  }
2467
2626
  }
2468
2627
  function mapTypescript(config, state, packageConfig, basePath) {
2469
- mapPackageManifest(config, ["packageJson"], state, packageConfig, basePath);
2628
+ const packageJsonManifest = mapPackageManifest(
2629
+ config,
2630
+ ["packageJson"],
2631
+ state,
2632
+ packageConfig,
2633
+ basePath
2634
+ );
2635
+ const packageJsonPackageManager = packageJsonManifest ? takeString(packageJsonManifest.value, ["packageManager"], state, packageJsonManifest.path) : void 0;
2636
+ const packageManagerAtIndex = packageJsonPackageManager ? packageJsonPackageManager.indexOf("@", packageJsonPackageManager.startsWith("@") ? 1 : 0) : -1;
2637
+ const packageManagerVersionPart = packageManagerAtIndex >= 0 ? packageJsonPackageManager?.slice(packageManagerAtIndex + 1).split("+")[0] : void 0;
2638
+ const packageManagerVersion = packageManagerVersionPart || void 0;
2470
2639
  const serdeLayer = takeBoolean(config, ["serdeLayer"], state, basePath);
2471
2640
  const noSerdeLayer = takeBoolean(config, ["noSerdeLayer"], state, basePath);
2472
2641
  const fetchSupport = takeEnum(config, ["fetchSupport"], ["native"], state, basePath);
2642
+ const namingObject = takeObject(config, ["naming"], state, basePath);
2643
+ const nestedNamespace = namingObject ? takeString(namingObject.value, ["namespace"], state, namingObject.path) : void 0;
2473
2644
  return compact({
2474
2645
  typescriptVersion: takeString(config, ["typescriptVersion"], state, basePath),
2475
2646
  zodVersion: takeString(config, ["zodVersion"], state, basePath),
2476
2647
  packageManager: takeEnum(config, ["packageManager"], ["pnpm", "yarn"], state, basePath),
2648
+ packageManagerVersion,
2477
2649
  testFramework: takeEnum(config, ["testFramework"], ["jest", "vitest"], state, basePath),
2478
2650
  httpClient: fetchSupport === "native" ? { name: "fetch" } : void 0,
2479
2651
  bundle: takeBoolean(config, ["bundle"], state, basePath),
2480
2652
  exportClassDefault: takeBoolean(config, ["exportClassDefault"], state, basePath),
2481
- namespaceExportName: takeString(
2482
- config,
2483
- ["namespaceExportName", "namespaceExport"],
2484
- state,
2485
- basePath
2486
- ),
2653
+ namespaceExportName: takeString(config, ["namespaceExportName", "namespaceExport"], state, basePath) ?? nestedNamespace,
2654
+ consolidateTypeFiles: takeBoolean(config, ["consolidateTypeFiles"], state, basePath),
2487
2655
  allowCustomFetcher: takeBoolean(config, ["allowCustomFetcher"], state, basePath),
2488
2656
  useBrandedStringAliases: takeBoolean(config, ["useBrandedStringAliases"], state, basePath),
2489
2657
  useLegacyExports: takeBoolean(config, ["useLegacyExports"], state, basePath),
2490
2658
  useBigInt: takeBoolean(config, ["useBigInt"], state, basePath),
2491
- serdeLayer: serdeLayer ?? (noSerdeLayer === void 0 ? void 0 : !noSerdeLayer)
2659
+ serdeLayer: serdeLayer ?? (noSerdeLayer === void 0 ? void 0 : !noSerdeLayer),
2660
+ esmOnly: takeBoolean(config, ["esmOnly"], state, basePath)
2492
2661
  });
2493
2662
  }
2494
2663
  function mapPython(config, state, packageConfig, basePath) {
@@ -2599,7 +2768,8 @@ function mapCsharp(config, state, packageConfig, basePath) {
2599
2768
  });
2600
2769
  }
2601
2770
  function mapPhp(config, state, packageConfig, basePath) {
2602
- mapPackageManifest(config, ["composerJson"], state, packageConfig, basePath);
2771
+ const manifest = mapPackageManifest(config, ["composerJson"], state, packageConfig, basePath);
2772
+ if (manifest) mapComposerRequirements(manifest, state, packageConfig);
2603
2773
  const packageName = takeString(config, ["packageName"], state, basePath);
2604
2774
  if (packageName !== void 0) packageConfig.packageName = packageName;
2605
2775
  return compact({
@@ -2607,6 +2777,20 @@ function mapPhp(config, state, packageConfig, basePath) {
2607
2777
  generateClientInterfaces: takeBoolean(config, ["generateClientInterfaces"], state, basePath)
2608
2778
  });
2609
2779
  }
2780
+ function mapComposerRequirements(manifest, state, packageConfig) {
2781
+ const fields = [
2782
+ ["require", "extraDependencies"],
2783
+ ["require-dev", "extraDevDependencies"]
2784
+ ];
2785
+ for (const [composerField, packageField] of fields) {
2786
+ const located = takeObject(manifest.value, [composerField], state, manifest.path);
2787
+ if (!located) continue;
2788
+ const dependencies = Object.entries(located.value).flatMap(
2789
+ ([name, dependency]) => mapDependency(name, dependency, state, [...located.path, name])
2790
+ );
2791
+ if (dependencies.length) packageConfig[packageField] = dependencies;
2792
+ }
2793
+ }
2610
2794
  function mapRuby(config, state, packageConfig, basePath) {
2611
2795
  const moduleName = takeString(config, ["moduleName"], state, basePath);
2612
2796
  if (moduleName !== void 0) packageConfig.moduleName = moduleName;
@@ -2776,28 +2960,52 @@ function takeCustomSections(value, language, activeLanguages, state, basePath) {
2776
2960
  }
2777
2961
  function mapPackageManifest(config, aliases, state, packageConfig, basePath) {
2778
2962
  const manifest = takeObject(config, aliases, state, basePath);
2779
- if (!manifest) return;
2963
+ if (!manifest) return void 0;
2780
2964
  const packageName = takeString(manifest.value, ["name"], state, manifest.path);
2781
2965
  const description = takeString(manifest.value, ["description"], state, manifest.path);
2966
+ const keywords = takeStringArray(manifest.value, ["keywords"], state, manifest.path);
2782
2967
  const license = takeString(manifest.value, ["license"], state, manifest.path);
2783
2968
  const author = takeObject(manifest.value, ["author"], state, manifest.path);
2784
2969
  const authorName = author ? takeString(author.value, ["name"], state, author.path) : void 0;
2785
- const authors = authorName && author ? [
2786
- compact({
2787
- name: authorName,
2788
- email: takeString(author.value, ["email"], state, author.path),
2789
- url: takeString(author.value, ["url"], state, author.path)
2790
- })
2791
- ] : void 0;
2970
+ const authors = [
2971
+ ...authorName && author ? [
2972
+ compact({
2973
+ name: authorName,
2974
+ email: takeString(author.value, ["email"], state, author.path),
2975
+ url: takeString(author.value, ["url"], state, author.path)
2976
+ })
2977
+ ] : [],
2978
+ ...takeManifestAuthors(manifest, state)
2979
+ ];
2792
2980
  Object.assign(
2793
2981
  packageConfig,
2794
2982
  compact({
2795
2983
  packageName,
2796
2984
  description,
2797
- authors,
2985
+ homepage: takeString(manifest.value, ["homepage"], state, manifest.path),
2986
+ keywords,
2987
+ authors: authors.length ? authors : void 0,
2798
2988
  license: license ? { type: license } : void 0
2799
2989
  })
2800
2990
  );
2991
+ return manifest;
2992
+ }
2993
+ function takeManifestAuthors(manifest, state) {
2994
+ const located = locate(manifest.value, ["authors"], manifest.path);
2995
+ if (!located || !Array.isArray(located.value)) return [];
2996
+ return located.value.flatMap((entry, index) => {
2997
+ if (!isObject(entry)) return [];
2998
+ const path = [...located.path, index];
2999
+ const name = takeString(entry, ["name"], state, path);
3000
+ if (!name) return [];
3001
+ return [
3002
+ compact({
3003
+ name,
3004
+ email: takeString(entry, ["email"], state, path),
3005
+ url: takeString(entry, ["url"], state, path)
3006
+ })
3007
+ ];
3008
+ });
2801
3009
  }
2802
3010
  function takePythonAdditionalInitExports(config, state, basePath) {
2803
3011
  const located = locate(config, ["additionalInitExports"], basePath);
@@ -3423,6 +3631,30 @@ var sdkConfigIrV1Schema = zod.z.strictObject({
3423
3631
  function parseSdkConfigIrV1(value) {
3424
3632
  return sdkConfigIrV1Schema.parse(value);
3425
3633
  }
3634
+ var sdkConfigIrCapabilitySchema = zod.z.enum(["generation.generateFullProject"]);
3635
+ var sdkConfigIrV1InputJsonSchema = inputJsonSchema(sdkConfigIrV1Schema);
3636
+ function serializeSdkConfigIrV1(value) {
3637
+ const parsed = parseSdkConfigIrV1(value);
3638
+ const wireValue = omitSchemaDefaults(parsed, sdkConfigIrV1InputJsonSchema);
3639
+ const requiredCapabilities = [];
3640
+ if (wireValue === void 0) {
3641
+ throw new Error("SDK Config IR v1 root cannot be omitted from its wire payload");
3642
+ }
3643
+ if (parsed.generation.generateFullProject) {
3644
+ requiredCapabilities.push("generation.generateFullProject");
3645
+ }
3646
+ const json = JSON.stringify(wireValue);
3647
+ if (json === void 0) {
3648
+ throw new Error("SDK Config IR v1 could not be serialized as JSON");
3649
+ }
3650
+ return {
3651
+ body: new TextEncoder().encode(json),
3652
+ requiredCapabilities
3653
+ };
3654
+ }
3655
+ function parseSdkConfigIrV1ForConsumption(value) {
3656
+ return parseSdkConfigIrV1(stripUnknownProperties(value, sdkConfigIrV1InputJsonSchema));
3657
+ }
3426
3658
 
3427
3659
  exports.FernConfigMappingError = FernConfigMappingError;
3428
3660
  exports.SDK_CONFIG_IR_V1_SCHEMA_VERSION = SDK_CONFIG_IR_V1_SCHEMA_VERSION;
@@ -3457,7 +3689,9 @@ exports.nonEmptyStringSchema = nonEmptyStringSchema;
3457
3689
  exports.outputConfigSchema = outputConfigSchema;
3458
3690
  exports.packageConfigSchema = packageConfigSchema;
3459
3691
  exports.parseSdkConfigIrV1 = parseSdkConfigIrV1;
3692
+ exports.parseSdkConfigIrV1ForConsumption = parseSdkConfigIrV1ForConsumption;
3460
3693
  exports.parseSdkConfigV1 = parseSdkConfigV1;
3694
+ exports.parseSdkConfigV1ForConsumption = parseSdkConfigV1ForConsumption;
3461
3695
  exports.phpGenerationConfigSchema = phpGenerationConfigSchema;
3462
3696
  exports.publishConfigSchema = publishConfigSchema;
3463
3697
  exports.publishRegistrySchema = publishRegistrySchema;
@@ -3468,6 +3702,7 @@ exports.relativePathSchema = relativePathSchema;
3468
3702
  exports.replayConfigSchema = replayConfigSchema;
3469
3703
  exports.rubyGenerationConfigSchema = rubyGenerationConfigSchema;
3470
3704
  exports.rustGenerationConfigSchema = rustGenerationConfigSchema;
3705
+ exports.sdkConfigIrCapabilitySchema = sdkConfigIrCapabilitySchema;
3471
3706
  exports.sdkConfigIrV1Schema = sdkConfigIrV1Schema;
3472
3707
  exports.sdkConfigV1ApiConfigSchema = sdkConfigV1ApiConfigSchema;
3473
3708
  exports.sdkConfigV1AuthConfigSchema = sdkConfigV1AuthConfigSchema;
@@ -3508,6 +3743,7 @@ exports.sdkConfigV1TargetSchema = sdkConfigV1TargetSchema;
3508
3743
  exports.sdkConfigV1TerraformGenerationConfigSchema = terraformGenerationConfigSchema;
3509
3744
  exports.sdkConfigV1TypescriptGenerationConfigSchema = typescriptGenerationConfigSchema;
3510
3745
  exports.sdkConfigV1WebhookSignatureSchema = sdkConfigV1WebhookSignatureSchema;
3746
+ exports.serializeSdkConfigIrV1 = serializeSdkConfigIrV1;
3511
3747
  exports.sourceConfigSchema = sourceConfigSchema;
3512
3748
  exports.sourceSpecConfigSchema = sourceSpecConfigSchema;
3513
3749
  exports.sourceSpecTypeSchema = sourceSpecTypeSchema;