@kubb/plugin-faker 5.4.0-canary.20261109T173716 → 5.4.0-canary.20261109T175348
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/dist/index.cjs +288 -238
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +288 -238
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -334,242 +334,6 @@ function toFilePath(name, caseLast = _kubb_kit.camelCase) {
|
|
|
334
334
|
const parts = name.split(/\.(?=[a-zA-Z])/);
|
|
335
335
|
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : (0, _kubb_kit.camelCase)(part)).filter(Boolean).join("/");
|
|
336
336
|
}
|
|
337
|
-
// src/utils.ts
|
|
338
|
-
/**
|
|
339
|
-
* Returns the `@faker-js/faker` named export for a locale code.
|
|
340
|
-
*
|
|
341
|
-
* Without a locale, returns `'faker'` for the default English instance.
|
|
342
|
-
* With a locale, the language code is converted to upper case and joined with any region suffix.
|
|
343
|
-
*
|
|
344
|
-
* @example Default
|
|
345
|
-
* `localeToFakerImport() // 'faker'`
|
|
346
|
-
*
|
|
347
|
-
* @example Simple locale
|
|
348
|
-
* `localeToFakerImport('de') // 'fakerDE'`
|
|
349
|
-
*
|
|
350
|
-
* @example Compound locale
|
|
351
|
-
* `localeToFakerImport('de_AT') // 'fakerDE_AT'`
|
|
352
|
-
*/
|
|
353
|
-
function localeToFakerImport(locale) {
|
|
354
|
-
if (!locale) return "faker";
|
|
355
|
-
const parts = locale.split("_");
|
|
356
|
-
parts[0] = parts[0].toUpperCase();
|
|
357
|
-
return `faker${parts.join("_")}`;
|
|
358
|
-
}
|
|
359
|
-
/**
|
|
360
|
-
* Schema types a factory cannot override with `data`: they print a constant or have no faker value.
|
|
361
|
-
*/
|
|
362
|
-
const NON_OVERRIDABLE_TYPES = /* @__PURE__ */ new Set([
|
|
363
|
-
"any",
|
|
364
|
-
"unknown",
|
|
365
|
-
"void",
|
|
366
|
-
"null",
|
|
367
|
-
"never",
|
|
368
|
-
"ipv4",
|
|
369
|
-
"ipv6"
|
|
370
|
-
]);
|
|
371
|
-
/**
|
|
372
|
-
* Schema types a single response cannot inline: they reference or compose other schemas.
|
|
373
|
-
*/
|
|
374
|
-
const NON_INLINABLE_RESPONSE_TYPES = /* @__PURE__ */ new Set([
|
|
375
|
-
"object",
|
|
376
|
-
"intersection",
|
|
377
|
-
"ref",
|
|
378
|
-
"never",
|
|
379
|
-
"ipv4",
|
|
380
|
-
"ipv6"
|
|
381
|
-
]);
|
|
382
|
-
/**
|
|
383
|
-
* Determines if a schema node can be overridden during faker generation.
|
|
384
|
-
*/
|
|
385
|
-
function canOverrideSchema(node) {
|
|
386
|
-
return !NON_OVERRIDABLE_TYPES.has(node.type);
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* Whether a schema can supply object properties when merging faker values.
|
|
390
|
-
*/
|
|
391
|
-
function isObjectSchema(node, seen = /* @__PURE__ */ new Set()) {
|
|
392
|
-
const resolved = _kubb_kit.ast.resolveRef(node);
|
|
393
|
-
if (seen.has(resolved)) return false;
|
|
394
|
-
seen.add(resolved);
|
|
395
|
-
if (_kubb_kit.ast.narrowSchema(resolved, _kubb_kit.ast.schemaTypes.object) || _kubb_kit.ast.narrowSchema(resolved, _kubb_kit.ast.schemaTypes.ref)) return true;
|
|
396
|
-
const composition = _kubb_kit.ast.narrowSchema(resolved, _kubb_kit.ast.schemaTypes.intersection) ?? _kubb_kit.ast.narrowSchema(resolved, _kubb_kit.ast.schemaTypes.union);
|
|
397
|
-
if (!composition) return false;
|
|
398
|
-
return composition.type === _kubb_kit.ast.schemaTypes.intersection && !composition.members?.length || (composition.members ?? []).some((member) => isObjectSchema(member, seen));
|
|
399
|
-
}
|
|
400
|
-
function shouldInlineSingleResponseSchema(schema) {
|
|
401
|
-
return !NON_INLINABLE_RESPONSE_TYPES.has(schema.type);
|
|
402
|
-
}
|
|
403
|
-
/**
|
|
404
|
-
* Builds a response schema as a union of all response statuses.
|
|
405
|
-
* Returns null if no responses are provided, or embeds single simple responses inline.
|
|
406
|
-
*/
|
|
407
|
-
function buildResponseUnionSchema(node, resolver) {
|
|
408
|
-
const responses = node.responses.filter((response) => response.content?.[0]?.schema);
|
|
409
|
-
if (!responses.length) return null;
|
|
410
|
-
if (responses.length === 1) {
|
|
411
|
-
const schemas = responses[0].content?.flatMap((content) => content.schema ? [content.schema] : []) ?? [];
|
|
412
|
-
const schema = schemas.length > 1 ? _kubb_kit.ast.factory.createSchema({
|
|
413
|
-
type: "union",
|
|
414
|
-
members: schemas
|
|
415
|
-
}) : schemas[0];
|
|
416
|
-
if (schema && shouldInlineSingleResponseSchema(schema)) return schema;
|
|
417
|
-
return _kubb_kit.ast.factory.createSchema({
|
|
418
|
-
type: "ref",
|
|
419
|
-
name: resolver.response.status(node, responses[0].statusCode),
|
|
420
|
-
schema: responses[0].content?.length === 1 ? schema : void 0
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
return _kubb_kit.ast.factory.createSchema({
|
|
424
|
-
type: "union",
|
|
425
|
-
members: responses.map((response) => {
|
|
426
|
-
const schema = (response.content?.length ?? 0) === 1 ? response.content?.[0]?.schema : void 0;
|
|
427
|
-
return _kubb_kit.ast.factory.createSchema({
|
|
428
|
-
type: "ref",
|
|
429
|
-
name: resolver.response.status(node, response.statusCode),
|
|
430
|
-
schema
|
|
431
|
-
});
|
|
432
|
-
})
|
|
433
|
-
});
|
|
434
|
-
}
|
|
435
|
-
const SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
436
|
-
"string",
|
|
437
|
-
"email",
|
|
438
|
-
"url",
|
|
439
|
-
"uuid",
|
|
440
|
-
"number",
|
|
441
|
-
"integer",
|
|
442
|
-
"bigint",
|
|
443
|
-
"boolean",
|
|
444
|
-
"date",
|
|
445
|
-
"time",
|
|
446
|
-
"datetime",
|
|
447
|
-
"blob",
|
|
448
|
-
"enum"
|
|
449
|
-
]);
|
|
450
|
-
/**
|
|
451
|
-
* Resolves a type reference, determining if it needs an import statement or inline type reference.
|
|
452
|
-
* Takes into account whether the type can be overridden and the file paths.
|
|
453
|
-
*/
|
|
454
|
-
function resolveTypeReference({ node, canOverride, name, typeName, filePath, typeFilePath }) {
|
|
455
|
-
const { usesTypeName } = resolveFakerTypeUsage(node, typeName, canOverride);
|
|
456
|
-
if (!usesTypeName) return { typeName };
|
|
457
|
-
if (name === typeName) return { typeName: `import('${getRelativePath(node_path.posix.dirname(filePath), typeFilePath)}').${typeName}` };
|
|
458
|
-
return {
|
|
459
|
-
importPath: typeFilePath,
|
|
460
|
-
typeName
|
|
461
|
-
};
|
|
462
|
-
}
|
|
463
|
-
/**
|
|
464
|
-
* Maps a schema node type to its corresponding scalar type representation.
|
|
465
|
-
* Returns the type name for enums or the base type (string, number, etc.) for primitives.
|
|
466
|
-
*/
|
|
467
|
-
function getScalarType(node, typeName) {
|
|
468
|
-
switch (node.type) {
|
|
469
|
-
case "string":
|
|
470
|
-
case "email":
|
|
471
|
-
case "url":
|
|
472
|
-
case "uuid": return "string";
|
|
473
|
-
case "number":
|
|
474
|
-
case "integer": return "number";
|
|
475
|
-
case "bigint": return "bigint";
|
|
476
|
-
case "boolean": return "boolean";
|
|
477
|
-
case "date":
|
|
478
|
-
case "time": return node.representation === "date" ? "Date" : "string";
|
|
479
|
-
case "datetime": return "string";
|
|
480
|
-
case "blob": return "Blob";
|
|
481
|
-
default: return typeName;
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
/**
|
|
485
|
-
* Resolves faker type usage information for a schema.
|
|
486
|
-
* Determines the data type, return type, and whether it uses the type name.
|
|
487
|
-
*/
|
|
488
|
-
function resolveFakerTypeUsage(node, typeName, canOverride) {
|
|
489
|
-
const resolvedNode = _kubb_kit.ast.resolveRef(node);
|
|
490
|
-
const scalarType = SCALAR_TYPES.has(resolvedNode.type) ? `${getScalarType(resolvedNode, typeName)}${node.nullable || resolvedNode.nullable ? " | null" : ""}` : void 0;
|
|
491
|
-
const dataType = scalarType ?? `Partial<${typeName}>`;
|
|
492
|
-
const returnType = scalarType ?? (canOverride ? typeName : null);
|
|
493
|
-
return {
|
|
494
|
-
dataType,
|
|
495
|
-
returnType,
|
|
496
|
-
usesTypeName: canOverride && dataType.includes(typeName) || Boolean(returnType?.includes(typeName))
|
|
497
|
-
};
|
|
498
|
-
}
|
|
499
|
-
// src/components/Faker.tsx
|
|
500
|
-
function Faker({ node, description, name, typeName, printer, canOverride, typeMode = "inferred", keysToOmit }) {
|
|
501
|
-
const fakerText = printer.print(node) ?? "undefined";
|
|
502
|
-
const imports = printer.drainImports().map((imp) => /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, { ...imp }, [
|
|
503
|
-
name,
|
|
504
|
-
imp.path,
|
|
505
|
-
imp.name
|
|
506
|
-
].join("-")));
|
|
507
|
-
const isArray = node.type === "array";
|
|
508
|
-
const isObject = !!_kubb_kit.ast.narrowSchema(node, _kubb_kit.ast.schemaTypes.object) || node.type === _kubb_kit.ast.schemaTypes.intersection && isObjectSchema(node);
|
|
509
|
-
const isValueIntersection = node.type === _kubb_kit.ast.schemaTypes.intersection && !isObject;
|
|
510
|
-
const isTuple = node.type === "tuple";
|
|
511
|
-
const isScalar = SCALAR_TYPES.has(node.type);
|
|
512
|
-
const isUnion = node.type === "union";
|
|
513
|
-
const useObjectOverride = canOverride && (isObject || !!keysToOmit?.length);
|
|
514
|
-
const fakerTextWithOverride = (() => {
|
|
515
|
-
if (canOverride && node.type === "tuple") return `data && data.length === ${node.items?.length ?? 0} && !data.includes(undefined) ? data : ${fakerText}`;
|
|
516
|
-
if (canOverride && isArray) return `[\n ...${fakerText},\n ...(data || []).filter((item) => item !== undefined),\n]`;
|
|
517
|
-
if (canOverride && (isScalar || isUnion || isValueIntersection)) return node.nullable ? `data !== undefined ? data : ${fakerText}` : `data ?? ${fakerText}`;
|
|
518
|
-
return fakerText;
|
|
519
|
-
})();
|
|
520
|
-
const { dataType, returnType: resolvedReturnType } = resolveFakerTypeUsage(node, typeName, canOverride);
|
|
521
|
-
if (!useObjectOverride) {
|
|
522
|
-
const paramsSignature = `${/\bdata\b/.test(fakerTextWithOverride) ? "data" : "_data"}?: ${dataType}`;
|
|
523
|
-
const returnType = resolvedReturnType;
|
|
524
|
-
const returnExpression = canOverride && !!returnType && (node.type === "ref" && !SCALAR_TYPES.has(_kubb_kit.ast.resolveRef(node).type) || isArray || isTuple || isUnion) ? `${isTuple || isUnion ? `(${fakerTextWithOverride})` : fakerTextWithOverride} as ${returnType}` : fakerTextWithOverride;
|
|
525
|
-
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [imports, /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
|
|
526
|
-
name,
|
|
527
|
-
isExportable: true,
|
|
528
|
-
isIndexable: true,
|
|
529
|
-
children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.Function, {
|
|
530
|
-
export: true,
|
|
531
|
-
name,
|
|
532
|
-
JSDoc: { comments: description ? [`@description ${jsDocEscape(description)}`] : [] },
|
|
533
|
-
params: canOverride ? paramsSignature : void 0,
|
|
534
|
-
returnType: returnType ?? void 0,
|
|
535
|
-
children: `return ${returnExpression}`
|
|
536
|
-
})
|
|
537
|
-
})] });
|
|
538
|
-
}
|
|
539
|
-
const { cyclicSchemas, schemaName } = printer.options;
|
|
540
|
-
const isCyclic = !!schemaName && !!cyclicSchemas?.has(schemaName);
|
|
541
|
-
const returnType = typeMode === "schema" ? typeName : `Omit<${isCyclic ? typeName : "typeof defaultFakeData"}, keyof NoInfer<TData>> & NoInfer<TData>`;
|
|
542
|
-
const hasGetters = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => (0, _kubb_kit.containsCircularRef)(p.schema, {
|
|
543
|
-
circularSchemas: cyclicSchemas,
|
|
544
|
-
excludeName: schemaName
|
|
545
|
-
}));
|
|
546
|
-
const declaration = `const ${keysToOmit?.length ? `{ ${keysToOmit.map((key, index) => `${objectKey(key)}: _omit${index}`).join(", ")}, ...defaultFakeData }` : "defaultFakeData"} = ${fakerText}`;
|
|
547
|
-
const functionBody = hasGetters ? `${declaration}
|
|
548
|
-
if (data) {
|
|
549
|
-
for (const [key, value] of Object.entries(data)) {
|
|
550
|
-
Object.defineProperty(defaultFakeData, key, { value, configurable: true, writable: true, enumerable: true })
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
return defaultFakeData as ${returnType}` : `${declaration}
|
|
554
|
-
return {
|
|
555
|
-
...defaultFakeData,
|
|
556
|
-
...(data || {}),
|
|
557
|
-
} as ${returnType}`;
|
|
558
|
-
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [imports, /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
|
|
559
|
-
name,
|
|
560
|
-
isExportable: true,
|
|
561
|
-
isIndexable: true,
|
|
562
|
-
children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.Function, {
|
|
563
|
-
export: true,
|
|
564
|
-
name,
|
|
565
|
-
JSDoc: { comments: description ? [`@description ${jsDocEscape(description)}`] : [] },
|
|
566
|
-
generics: typeMode === "schema" ? void 0 : `TData extends Partial<${typeName}> = object`,
|
|
567
|
-
params: typeMode === "schema" ? `data?: Partial<${typeName}>` : "data?: TData",
|
|
568
|
-
returnType: typeMode === "schema" || isCyclic ? returnType : void 0,
|
|
569
|
-
children: functionBody
|
|
570
|
-
})
|
|
571
|
-
})] });
|
|
572
|
-
}
|
|
573
337
|
// ../../internals/shared/src/operation.ts
|
|
574
338
|
/**
|
|
575
339
|
* Builds the `ResolverFileParams` every operation generator passes to
|
|
@@ -610,6 +374,37 @@ function resolveDependencyOperationFile(options) {
|
|
|
610
374
|
group: group ?? void 0
|
|
611
375
|
}));
|
|
612
376
|
}
|
|
377
|
+
function baseContentType(contentType) {
|
|
378
|
+
return contentType.split(";")[0].trim().toLowerCase();
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Whether a content entry is a sequence of JSON values the adapter marks as a stream, such as `application/jsonl`,
|
|
382
|
+
* `application/x-ndjson`, `application/json-seq`, or any media type with an OpenAPI 3.2 `itemSchema`.
|
|
383
|
+
*/
|
|
384
|
+
function isJsonLines(entry) {
|
|
385
|
+
const baseType = baseContentType(entry.contentType);
|
|
386
|
+
return Boolean(entry.stream) && baseType !== "text/event-stream" && !baseType.startsWith("multipart/");
|
|
387
|
+
}
|
|
388
|
+
function isJsonContentType(baseType) {
|
|
389
|
+
return baseType === "application/json" || baseType.endsWith("+json") || baseType === "text/json";
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Parser for one response content entry.
|
|
393
|
+
*
|
|
394
|
+
* JSON stays unset so the runtime detects it. `text/event-stream` and JSON Lines are streams. A binary schema
|
|
395
|
+
* (`format: binary` / `contentMediaType`) is a blob even when the media type is not a well-known
|
|
396
|
+
* binary type. Other `text/*` is text, and `application/octet-stream`, `application/pdf`,
|
|
397
|
+
* `image/*`, `audio/*`, and `video/*` are blobs.
|
|
398
|
+
*/
|
|
399
|
+
function responseTypeForContent(entry) {
|
|
400
|
+
const baseType = baseContentType(entry.contentType);
|
|
401
|
+
if (!baseType) return void 0;
|
|
402
|
+
if (baseType === "text/event-stream" || isJsonLines(entry)) return "stream";
|
|
403
|
+
if (isJsonContentType(baseType)) return void 0;
|
|
404
|
+
if (entry.schema?.type === "blob") return "blob";
|
|
405
|
+
if (baseType.startsWith("text/")) return "text";
|
|
406
|
+
if (baseType === "application/octet-stream" || baseType === "application/pdf" || /^(image|audio|video)\//.test(baseType)) return "blob";
|
|
407
|
+
}
|
|
613
408
|
/**
|
|
614
409
|
* Maps a content type to the PascalCase suffix used to name per-content-type variants
|
|
615
410
|
* (e.g. `application/json` → `Json`, `application/xml` → `Xml`, `multipart/form-data` → `FormData`).
|
|
@@ -632,6 +427,22 @@ function getPerContentTypeName(baseName, suffix) {
|
|
|
632
427
|
return baseName + suffix;
|
|
633
428
|
}
|
|
634
429
|
/**
|
|
430
|
+
* Returns the entry with a `string` schema when the client runtime reads its body as text, such as `Pet` on `application/xml`.
|
|
431
|
+
* JSON, binary, and stream entries keep their schema, and so do wildcards such as `application/*` and the any-type `*`, so the runtime can pick the
|
|
432
|
+
* parser from the server's `Content-Type`. `text/*` reads as text.
|
|
433
|
+
*/
|
|
434
|
+
function toResponseContent(entry) {
|
|
435
|
+
const { contentType, schema } = entry;
|
|
436
|
+
if (!schema || entry.stream || _kubb_kit.ast.resolveRef(schema).primitive === "string") return entry;
|
|
437
|
+
const baseType = baseContentType(contentType);
|
|
438
|
+
const responseType = responseTypeForContent(entry);
|
|
439
|
+
return responseType === "text" || !responseType && Boolean(baseType) && !isJsonContentType(baseType) && !baseType.includes("*") ? {
|
|
440
|
+
...entry,
|
|
441
|
+
schema: _kubb_kit.ast.factory.createSchema({ type: "string" }),
|
|
442
|
+
keysToOmit: null
|
|
443
|
+
} : entry;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
635
446
|
* Resolves per-content-type variant names for a set of content entries, deduplicating suffix
|
|
636
447
|
* collisions with a numeric counter. Entries without a schema are skipped. The returned `suffix` is
|
|
637
448
|
* the final (possibly counter-augmented) value, so callers can derive parallel names in another
|
|
@@ -882,6 +693,245 @@ function mapSchemaItems(node, transform) {
|
|
|
882
693
|
output: transform(schema)
|
|
883
694
|
}));
|
|
884
695
|
}
|
|
696
|
+
// src/utils.ts
|
|
697
|
+
/**
|
|
698
|
+
* Returns the `@faker-js/faker` named export for a locale code.
|
|
699
|
+
*
|
|
700
|
+
* Without a locale, returns `'faker'` for the default English instance.
|
|
701
|
+
* With a locale, the language code is converted to upper case and joined with any region suffix.
|
|
702
|
+
*
|
|
703
|
+
* @example Default
|
|
704
|
+
* `localeToFakerImport() // 'faker'`
|
|
705
|
+
*
|
|
706
|
+
* @example Simple locale
|
|
707
|
+
* `localeToFakerImport('de') // 'fakerDE'`
|
|
708
|
+
*
|
|
709
|
+
* @example Compound locale
|
|
710
|
+
* `localeToFakerImport('de_AT') // 'fakerDE_AT'`
|
|
711
|
+
*/
|
|
712
|
+
function localeToFakerImport(locale) {
|
|
713
|
+
if (!locale) return "faker";
|
|
714
|
+
const parts = locale.split("_");
|
|
715
|
+
parts[0] = parts[0].toUpperCase();
|
|
716
|
+
return `faker${parts.join("_")}`;
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Schema types a factory cannot override with `data`: they print a constant or have no faker value.
|
|
720
|
+
*/
|
|
721
|
+
const NON_OVERRIDABLE_TYPES = /* @__PURE__ */ new Set([
|
|
722
|
+
"any",
|
|
723
|
+
"unknown",
|
|
724
|
+
"void",
|
|
725
|
+
"null",
|
|
726
|
+
"never",
|
|
727
|
+
"ipv4",
|
|
728
|
+
"ipv6"
|
|
729
|
+
]);
|
|
730
|
+
/**
|
|
731
|
+
* Schema types a single response cannot inline: they reference or compose other schemas.
|
|
732
|
+
*/
|
|
733
|
+
const NON_INLINABLE_RESPONSE_TYPES = /* @__PURE__ */ new Set([
|
|
734
|
+
"object",
|
|
735
|
+
"intersection",
|
|
736
|
+
"ref",
|
|
737
|
+
"never",
|
|
738
|
+
"ipv4",
|
|
739
|
+
"ipv6"
|
|
740
|
+
]);
|
|
741
|
+
/**
|
|
742
|
+
* Determines if a schema node can be overridden during faker generation.
|
|
743
|
+
*/
|
|
744
|
+
function canOverrideSchema(node) {
|
|
745
|
+
return !NON_OVERRIDABLE_TYPES.has(node.type);
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* Whether a schema can supply object properties when merging faker values.
|
|
749
|
+
*/
|
|
750
|
+
function isObjectSchema(node, seen = /* @__PURE__ */ new Set()) {
|
|
751
|
+
const resolved = _kubb_kit.ast.resolveRef(node);
|
|
752
|
+
if (seen.has(resolved)) return false;
|
|
753
|
+
seen.add(resolved);
|
|
754
|
+
if (_kubb_kit.ast.narrowSchema(resolved, _kubb_kit.ast.schemaTypes.object) || _kubb_kit.ast.narrowSchema(resolved, _kubb_kit.ast.schemaTypes.ref)) return true;
|
|
755
|
+
const composition = _kubb_kit.ast.narrowSchema(resolved, _kubb_kit.ast.schemaTypes.intersection) ?? _kubb_kit.ast.narrowSchema(resolved, _kubb_kit.ast.schemaTypes.union);
|
|
756
|
+
if (!composition) return false;
|
|
757
|
+
return composition.type === _kubb_kit.ast.schemaTypes.intersection && !composition.members?.length || (composition.members ?? []).some((member) => isObjectSchema(member, seen));
|
|
758
|
+
}
|
|
759
|
+
function shouldInlineSingleResponseSchema(schema) {
|
|
760
|
+
return !NON_INLINABLE_RESPONSE_TYPES.has(schema.type);
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* Builds a response schema as a union of all response statuses.
|
|
764
|
+
* Returns null if no responses are provided, or embeds single simple responses inline.
|
|
765
|
+
*/
|
|
766
|
+
function buildResponseUnionSchema(node, resolver) {
|
|
767
|
+
const responses = node.responses.map((response) => ({
|
|
768
|
+
...response,
|
|
769
|
+
content: response.content?.map(toResponseContent)
|
|
770
|
+
})).filter((response) => response.content?.[0]?.schema);
|
|
771
|
+
if (!responses.length) return null;
|
|
772
|
+
if (responses.length === 1) {
|
|
773
|
+
const schemas = responses[0].content?.flatMap((content) => content.schema ? [content.schema] : []) ?? [];
|
|
774
|
+
const schema = schemas.length > 1 ? _kubb_kit.ast.factory.createSchema({
|
|
775
|
+
type: "union",
|
|
776
|
+
members: schemas
|
|
777
|
+
}) : schemas[0];
|
|
778
|
+
if (schema && shouldInlineSingleResponseSchema(schema)) return schema;
|
|
779
|
+
return _kubb_kit.ast.factory.createSchema({
|
|
780
|
+
type: "ref",
|
|
781
|
+
name: resolver.response.status(node, responses[0].statusCode),
|
|
782
|
+
schema: responses[0].content?.length === 1 ? schema : void 0
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
return _kubb_kit.ast.factory.createSchema({
|
|
786
|
+
type: "union",
|
|
787
|
+
members: responses.map((response) => {
|
|
788
|
+
const schema = (response.content?.length ?? 0) === 1 ? response.content?.[0]?.schema : void 0;
|
|
789
|
+
return _kubb_kit.ast.factory.createSchema({
|
|
790
|
+
type: "ref",
|
|
791
|
+
name: resolver.response.status(node, response.statusCode),
|
|
792
|
+
schema
|
|
793
|
+
});
|
|
794
|
+
})
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
const SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
798
|
+
"string",
|
|
799
|
+
"email",
|
|
800
|
+
"url",
|
|
801
|
+
"uuid",
|
|
802
|
+
"number",
|
|
803
|
+
"integer",
|
|
804
|
+
"bigint",
|
|
805
|
+
"boolean",
|
|
806
|
+
"date",
|
|
807
|
+
"time",
|
|
808
|
+
"datetime",
|
|
809
|
+
"blob",
|
|
810
|
+
"enum"
|
|
811
|
+
]);
|
|
812
|
+
/**
|
|
813
|
+
* Resolves a type reference, determining if it needs an import statement or inline type reference.
|
|
814
|
+
* Takes into account whether the type can be overridden and the file paths.
|
|
815
|
+
*/
|
|
816
|
+
function resolveTypeReference({ node, canOverride, name, typeName, filePath, typeFilePath }) {
|
|
817
|
+
const { usesTypeName } = resolveFakerTypeUsage(node, typeName, canOverride);
|
|
818
|
+
if (!usesTypeName) return { typeName };
|
|
819
|
+
if (name === typeName) return { typeName: `import('${getRelativePath(node_path.posix.dirname(filePath), typeFilePath)}').${typeName}` };
|
|
820
|
+
return {
|
|
821
|
+
importPath: typeFilePath,
|
|
822
|
+
typeName
|
|
823
|
+
};
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* Maps a schema node type to its corresponding scalar type representation.
|
|
827
|
+
* Returns the type name for enums or the base type (string, number, etc.) for primitives.
|
|
828
|
+
*/
|
|
829
|
+
function getScalarType(node, typeName) {
|
|
830
|
+
switch (node.type) {
|
|
831
|
+
case "string":
|
|
832
|
+
case "email":
|
|
833
|
+
case "url":
|
|
834
|
+
case "uuid": return "string";
|
|
835
|
+
case "number":
|
|
836
|
+
case "integer": return "number";
|
|
837
|
+
case "bigint": return "bigint";
|
|
838
|
+
case "boolean": return "boolean";
|
|
839
|
+
case "date":
|
|
840
|
+
case "time": return node.representation === "date" ? "Date" : "string";
|
|
841
|
+
case "datetime": return "string";
|
|
842
|
+
case "blob": return "Blob";
|
|
843
|
+
default: return typeName;
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Resolves faker type usage information for a schema.
|
|
848
|
+
* Determines the data type, return type, and whether it uses the type name.
|
|
849
|
+
*/
|
|
850
|
+
function resolveFakerTypeUsage(node, typeName, canOverride) {
|
|
851
|
+
const resolvedNode = _kubb_kit.ast.resolveRef(node);
|
|
852
|
+
const scalarType = SCALAR_TYPES.has(resolvedNode.type) ? `${getScalarType(resolvedNode, typeName)}${node.nullable || resolvedNode.nullable ? " | null" : ""}` : void 0;
|
|
853
|
+
const dataType = scalarType ?? `Partial<${typeName}>`;
|
|
854
|
+
const returnType = scalarType ?? (canOverride ? typeName : null);
|
|
855
|
+
return {
|
|
856
|
+
dataType,
|
|
857
|
+
returnType,
|
|
858
|
+
usesTypeName: canOverride && dataType.includes(typeName) || Boolean(returnType?.includes(typeName))
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
// src/components/Faker.tsx
|
|
862
|
+
function Faker({ node, description, name, typeName, printer, canOverride, typeMode = "inferred", keysToOmit }) {
|
|
863
|
+
const fakerText = printer.print(node) ?? "undefined";
|
|
864
|
+
const imports = printer.drainImports().map((imp) => /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, { ...imp }, [
|
|
865
|
+
name,
|
|
866
|
+
imp.path,
|
|
867
|
+
imp.name
|
|
868
|
+
].join("-")));
|
|
869
|
+
const isArray = node.type === "array";
|
|
870
|
+
const isObject = !!_kubb_kit.ast.narrowSchema(node, _kubb_kit.ast.schemaTypes.object) || node.type === _kubb_kit.ast.schemaTypes.intersection && isObjectSchema(node);
|
|
871
|
+
const isValueIntersection = node.type === _kubb_kit.ast.schemaTypes.intersection && !isObject;
|
|
872
|
+
const isTuple = node.type === "tuple";
|
|
873
|
+
const isScalar = SCALAR_TYPES.has(node.type);
|
|
874
|
+
const isUnion = node.type === "union";
|
|
875
|
+
const useObjectOverride = canOverride && (isObject || !!keysToOmit?.length);
|
|
876
|
+
const fakerTextWithOverride = (() => {
|
|
877
|
+
if (canOverride && node.type === "tuple") return `data && data.length === ${node.items?.length ?? 0} && !data.includes(undefined) ? data : ${fakerText}`;
|
|
878
|
+
if (canOverride && isArray) return `[\n ...${fakerText},\n ...(data || []).filter((item) => item !== undefined),\n]`;
|
|
879
|
+
if (canOverride && (isScalar || isUnion || isValueIntersection)) return node.nullable ? `data !== undefined ? data : ${fakerText}` : `data ?? ${fakerText}`;
|
|
880
|
+
return fakerText;
|
|
881
|
+
})();
|
|
882
|
+
const { dataType, returnType: resolvedReturnType } = resolveFakerTypeUsage(node, typeName, canOverride);
|
|
883
|
+
if (!useObjectOverride) {
|
|
884
|
+
const paramsSignature = `${/\bdata\b/.test(fakerTextWithOverride) ? "data" : "_data"}?: ${dataType}`;
|
|
885
|
+
const returnType = resolvedReturnType;
|
|
886
|
+
const returnExpression = canOverride && !!returnType && (node.type === "ref" && !SCALAR_TYPES.has(_kubb_kit.ast.resolveRef(node).type) || isArray || isTuple || isUnion) ? `${isTuple || isUnion ? `(${fakerTextWithOverride})` : fakerTextWithOverride} as ${returnType}` : fakerTextWithOverride;
|
|
887
|
+
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [imports, /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
|
|
888
|
+
name,
|
|
889
|
+
isExportable: true,
|
|
890
|
+
isIndexable: true,
|
|
891
|
+
children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.Function, {
|
|
892
|
+
export: true,
|
|
893
|
+
name,
|
|
894
|
+
JSDoc: { comments: description ? [`@description ${jsDocEscape(description)}`] : [] },
|
|
895
|
+
params: canOverride ? paramsSignature : void 0,
|
|
896
|
+
returnType: returnType ?? void 0,
|
|
897
|
+
children: `return ${returnExpression}`
|
|
898
|
+
})
|
|
899
|
+
})] });
|
|
900
|
+
}
|
|
901
|
+
const { cyclicSchemas, schemaName } = printer.options;
|
|
902
|
+
const isCyclic = !!schemaName && !!cyclicSchemas?.has(schemaName);
|
|
903
|
+
const returnType = typeMode === "schema" ? typeName : `Omit<${isCyclic ? typeName : "typeof defaultFakeData"}, keyof NoInfer<TData>> & NoInfer<TData>`;
|
|
904
|
+
const hasGetters = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => (0, _kubb_kit.containsCircularRef)(p.schema, {
|
|
905
|
+
circularSchemas: cyclicSchemas,
|
|
906
|
+
excludeName: schemaName
|
|
907
|
+
}));
|
|
908
|
+
const declaration = `const ${keysToOmit?.length ? `{ ${keysToOmit.map((key, index) => `${objectKey(key)}: _omit${index}`).join(", ")}, ...defaultFakeData }` : "defaultFakeData"} = ${fakerText}`;
|
|
909
|
+
const functionBody = hasGetters ? `${declaration}
|
|
910
|
+
if (data) {
|
|
911
|
+
for (const [key, value] of Object.entries(data)) {
|
|
912
|
+
Object.defineProperty(defaultFakeData, key, { value, configurable: true, writable: true, enumerable: true })
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
return defaultFakeData as ${returnType}` : `${declaration}
|
|
916
|
+
return {
|
|
917
|
+
...defaultFakeData,
|
|
918
|
+
...(data || {}),
|
|
919
|
+
} as ${returnType}`;
|
|
920
|
+
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [imports, /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
|
|
921
|
+
name,
|
|
922
|
+
isExportable: true,
|
|
923
|
+
isIndexable: true,
|
|
924
|
+
children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.Function, {
|
|
925
|
+
export: true,
|
|
926
|
+
name,
|
|
927
|
+
JSDoc: { comments: description ? [`@description ${jsDocEscape(description)}`] : [] },
|
|
928
|
+
generics: typeMode === "schema" ? void 0 : `TData extends Partial<${typeName}> = object`,
|
|
929
|
+
params: typeMode === "schema" ? `data?: Partial<${typeName}>` : "data?: TData",
|
|
930
|
+
returnType: typeMode === "schema" || isCyclic ? returnType : void 0,
|
|
931
|
+
children: functionBody
|
|
932
|
+
})
|
|
933
|
+
})] });
|
|
934
|
+
}
|
|
885
935
|
// src/utils/imports.ts
|
|
886
936
|
function escapeRegExp(value) {
|
|
887
937
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -1351,7 +1401,7 @@ const fakerGenerator = (0, _kubb_kit.defineGenerator)({
|
|
|
1351
1401
|
skipImportNames: variants.map((variant) => variant.name)
|
|
1352
1402
|
}];
|
|
1353
1403
|
}
|
|
1354
|
-
const responseUnits = node.responses.flatMap((response) => expandContentUnits(response.content ?? [], resolver.response.status(node, response.statusCode), tsResolver.response.status(node, response.statusCode), response.description));
|
|
1404
|
+
const responseUnits = node.responses.flatMap((response) => expandContentUnits((response.content ?? []).map(toResponseContent), resolver.response.status(node, response.statusCode), tsResolver.response.status(node, response.statusCode), response.description));
|
|
1355
1405
|
const dataUnits = expandContentUnits(node.requestBody?.content ?? [], resolver.response.body(node), tsResolver.response.body(node), node.requestBody?.description, (schema) => ({
|
|
1356
1406
|
...schema,
|
|
1357
1407
|
description: node.requestBody?.description ?? schema.description
|
|
@@ -1513,7 +1563,7 @@ var compatibility = {
|
|
|
1513
1563
|
"node": ">=22.22"
|
|
1514
1564
|
};
|
|
1515
1565
|
// package.json
|
|
1516
|
-
var version = "5.4.0-canary.
|
|
1566
|
+
var version = "5.4.0-canary.20261109T175348";
|
|
1517
1567
|
// src/resolvers/resolverFaker.ts
|
|
1518
1568
|
/**
|
|
1519
1569
|
* Default resolver used by `@kubb/plugin-faker`. Decides the names and file
|