@schmock/faker 2.1.6 → 2.2.1
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.js +1 -1
- package/dist/jsf-config.d.ts.map +1 -1
- package/dist/jsf-config.js +5 -2
- package/dist/schema-enhancement.js +22 -7
- package/package.json +2 -2
- package/src/audit-faker-args.test.ts +97 -0
- package/src/jsf-config.ts +9 -3
- package/src/schema-enhancement.ts +22 -8
- package/src/constants.d.ts +0 -6
- package/src/index.d.ts +0 -19
- package/src/jsf-config.d.ts +0 -10
- package/src/overrides.d.ts +0 -21
- package/src/schema-enhancement.d.ts +0 -3
- package/src/validation.d.ts +0 -20
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ResourceLimitError as o,SchemaGenerationError as v1,SchemaValidationError as n}from"@schmock/core";var k="2.1.6";var Y=1e4,M=10,V=3,F=3,H=100,E=0.05;import{base as m,en as s,Faker as h}from"@faker-js/faker";import{generate as c}from"json-schema-faker";function g(Q){let $=new h({locale:[s,m]});if(Q!==void 0)$.seed(Q);return $}async function x(Q,$){let Z=$??Math.floor(Math.random()*2147483647);return c(Q,{seed:Z,optionalsProbability:1,alwaysFakeOptionals:!0,useDefaultValue:!0,ignoreMissingRefs:!0,failOnInvalidTypes:!1,failOnInvalidFormat:!1,extensions:{faker:g($)}})}var f=new Set(["__proto__","constructor","prototype"]);function S(Q,$,Z=Math.random){if($!==void 0){if($<0)return 0;return $}if(Q.minItems!==void 0&&Q.maxItems!==void 0){let B=Q.minItems,K=Math.max(B,Q.maxItems);return Math.floor(Z()*(K-B+1))+B}if(Q.minItems!==void 0)return Math.max(Q.minItems,V);if(Q.maxItems!==void 0)return Math.min(Q.maxItems,V);return V}function J(Q,$,Z,B,K){if(!$)return Q;if(typeof Q!=="object"||Q===null)return Q;let j=structuredClone(Q);for(let[z,X]of Object.entries($)){if(f.has(z))continue;if(z.includes("."))t(j,z,X,{params:Z,state:B,query:K});else if(typeof X==="object"&&X!==null&&!Array.isArray(X)){let q=X;if(j[z]&&typeof j[z]==="object")j[z]=J(j[z],q,Z,B,K);else j[z]=J({},q,Z,B,K)}else if(typeof X==="string"&&X.includes("{{"))j[z]=l(X,{params:Z,state:B,query:K});else j[z]=X}return j}function t(Q,$,Z,B){let K=$.split("."),j=Q;for(let X=0;X<K.length-1;X++){let q=K[X];if(f.has(q))return;if(!(q in j)||typeof j[q]!=="object"||j[q]===null)j[q]={};j=j[q]}let z=K[K.length-1];if(f.has(z))return;if(typeof Z==="string"&&Z.includes("{{"))j[z]=l(Z,B);else j[z]=Z}function u(Q,$){let Z=$.trim().split("."),B=Q;for(let K of Z)if(B&&typeof B==="object")B=B[K];else return;return B}function l(Q,$){let Z=Q.match(/^\{\{\s*([^}]+)\s*\}\}$/);if(Z){let B=u($,Z[1]);return B!==void 0?B:Q}return Q.replace(/\{\{\s*([^}]+)\s*\}\}/g,(B,K)=>{let j=u($,K);return j!==void 0?String(j):B})}var a=[{keywords:["email"],fakerMethod:"internet.email",schemaType:"string",minScore:0.6,format:"email"},{keywords:["username","user_name","login","handle"],fakerMethod:"internet.username",schemaType:"string",minScore:0.6},{keywords:["password","passwd","secret"],fakerMethod:"internet.password",schemaType:"string",minScore:0.6},{keywords:["token","api_key","apikey","access_token","refresh_token"],fakerMethod:"string.alphanumeric",schemaType:"string",minScore:0.8}],e=[{keywords:["first_name","firstname","given_name","forename"],fakerMethod:"person.firstName",schemaType:"string",minScore:0.6},{keywords:["last_name","lastname","surname","family_name"],fakerMethod:"person.lastName",schemaType:"string",minScore:0.6},{keywords:["full_name","fullname","display_name","displayname","full_name"],fakerMethod:"person.fullName",schemaType:"string",minScore:0.6},{keywords:["name"],fakerMethod:"person.fullName",schemaType:"string",minScore:0.6},{keywords:["middle_name","middlename"],fakerMethod:"person.middleName",schemaType:"string",minScore:0.8},{keywords:["prefix","honorific","salutation"],fakerMethod:"person.prefix",schemaType:"string",minScore:0.8},{keywords:["suffix"],fakerMethod:"person.suffix",schemaType:"string",minScore:0.9},{keywords:["gender","sex"],fakerMethod:"person.sex",schemaType:"string",minScore:0.8},{keywords:["bio","biography"],fakerMethod:"lorem.paragraph",schemaType:"string",minScore:0.8},{keywords:["job_title","jobtitle","position","occupation","job","role"],fakerMethod:"person.jobTitle",schemaType:"string",minScore:0.6},{keywords:["job_area","department","division","team"],fakerMethod:"person.jobArea",schemaType:"string",minScore:0.8},{keywords:["zodiac","zodiac_sign"],fakerMethod:"person.zodiacSign",schemaType:"string",minScore:0.9}],Q1=[{keywords:["phone","mobile","cell","tel","telephone","cellphone","fax"],fakerMethod:"phone.number",schemaType:"string",minScore:0.6},{keywords:["imei"],fakerMethod:"phone.imei",schemaType:"string",minScore:0.9}],$1=[{keywords:["street","street_address"],fakerMethod:"location.streetAddress",schemaType:"string",minScore:0.6},{keywords:["address","mailing_address","postal_address"],fakerMethod:"location.streetAddress",schemaType:"string",minScore:0.6},{keywords:["city","town"],fakerMethod:"location.city",schemaType:"string",minScore:0.6},{keywords:["state","province","region"],fakerMethod:"location.state",schemaType:"string",minScore:0.8},{keywords:["country"],fakerMethod:"location.country",schemaType:"string",minScore:0.8},{keywords:["country_code","countrycode"],fakerMethod:"location.countryCode",schemaType:"string",minScore:0.8},{keywords:["county"],fakerMethod:"location.county",schemaType:"string",minScore:0.9},{keywords:["continent"],fakerMethod:"location.continent",schemaType:"string",minScore:0.9},{keywords:["zip","zipcode","zip_code","postal","postal_code"],fakerMethod:"location.zipCode",schemaType:"string",minScore:0.6},{keywords:["latitude","lat"],fakerMethod:"location.latitude",schemaType:"number",minScore:0.6},{keywords:["longitude","lng","lon","long"],fakerMethod:"location.longitude",schemaType:"number",minScore:0.6},{keywords:["timezone","time_zone","tz"],fakerMethod:"location.timeZone",schemaType:"string",minScore:0.8},{keywords:["building_number"],fakerMethod:"location.buildingNumber",schemaType:"string",minScore:0.9}],B1=[{keywords:["url","website","link","href","homepage","webpage"],fakerMethod:"internet.url",schemaType:"string",minScore:0.6},{keywords:["avatar","photo_url","profile_image","image_url","picture","thumbnail","icon"],fakerMethod:"image.avatar",schemaType:"string",minScore:0.6},{keywords:["domain","hostname","domain_name"],fakerMethod:"internet.domainName",schemaType:"string",minScore:0.8},{keywords:["ip","ip_address","ipaddress","ipv4"],fakerMethod:"internet.ipv4",schemaType:"string",minScore:0.8},{keywords:["ipv6"],fakerMethod:"internet.ipv6",schemaType:"string",minScore:0.9},{keywords:["mac","mac_address"],fakerMethod:"internet.mac",schemaType:"string",minScore:0.9},{keywords:["user_agent","useragent"],fakerMethod:"internet.userAgent",schemaType:"string",minScore:0.9},{keywords:["port"],fakerMethod:"internet.port",schemaType:"number",minScore:0.9},{keywords:["protocol"],fakerMethod:"internet.protocol",schemaType:"string",minScore:0.9}],Z1=[{keywords:["uuid","guid"],fakerMethod:"string.uuid",schemaType:"string",minScore:0.6},{keywords:["sku"],fakerMethod:"string.alphanumeric",schemaType:"string",minScore:0.9},{keywords:["slug"],fakerMethod:"lorem.slug",schemaType:"string",minScore:0.8},{keywords:["isbn"],fakerMethod:"commerce.isbn",schemaType:"string",minScore:0.9},{keywords:["vin"],fakerMethod:"vehicle.vin",schemaType:"string",minScore:0.9},{keywords:["iban"],fakerMethod:"finance.iban",schemaType:"string",minScore:0.9},{keywords:["bic","swift"],fakerMethod:"finance.bic",schemaType:"string",minScore:0.9},{keywords:["ssn","social_security"],fakerMethod:"string.numeric",schemaType:"string",minScore:0.9}],K1=[{keywords:["description","desc","summary","overview","about","excerpt"],fakerMethod:"lorem.paragraph",schemaType:"string",minScore:0.6},{keywords:["content","body","text","message"],fakerMethod:"lorem.paragraphs",schemaType:"string",minScore:0.6},{keywords:["title","heading","subject","headline"],fakerMethod:"lorem.sentence",schemaType:"string",minScore:0.6},{keywords:["tag","label","category","keyword"],fakerMethod:"lorem.word",schemaType:"string",minScore:0.8},{keywords:["comment","note","remark","feedback","review"],fakerMethod:"lorem.sentence",schemaType:"string",minScore:0.8},{keywords:["sentence"],fakerMethod:"lorem.sentence",schemaType:"string",minScore:0.9},{keywords:["paragraph"],fakerMethod:"lorem.paragraph",schemaType:"string",minScore:0.9},{keywords:["word"],fakerMethod:"lorem.word",schemaType:"string",minScore:0.9}],j1=[{keywords:["company","organization","org","employer","brand"],fakerMethod:"company.name",schemaType:"string",minScore:0.6},{keywords:["product","product_name","item_name"],fakerMethod:"commerce.productName",schemaType:"string",minScore:0.8},{keywords:["price","amount","cost","fee","salary","wage","total","subtotal","balance","revenue","income"],fakerMethod:"commerce.price",minScore:0.6},{keywords:["currency","currency_code"],fakerMethod:"finance.currencyCode",schemaType:"string",minScore:0.8},{keywords:["currency_name"],fakerMethod:"finance.currencyName",schemaType:"string",minScore:0.8},{keywords:["currency_symbol"],fakerMethod:"finance.currencySymbol",schemaType:"string",minScore:0.8},{keywords:["account_number","account_no"],fakerMethod:"finance.accountNumber",schemaType:"string",minScore:0.8},{keywords:["credit_card","card_number"],fakerMethod:"finance.creditCardNumber",schemaType:"string",minScore:0.8},{keywords:["cvv"],fakerMethod:"finance.creditCardCVV",schemaType:"string",minScore:0.9},{keywords:["transaction_type"],fakerMethod:"finance.transactionType",schemaType:"string",minScore:0.9}],X1=[{keywords:["created_at","createdat","creation_date","date_created","createddate"],fakerMethod:"date.recent",schemaType:"string",minScore:0.6,format:"date-time"},{keywords:["updated_at","updatedat","modified_at","modifiedat","date_updated","last_modified","date_modified"],fakerMethod:"date.recent",schemaType:"string",minScore:0.6,format:"date-time"},{keywords:["deleted_at","deletedat"],fakerMethod:"date.recent",schemaType:"string",minScore:0.6,format:"date-time"},{keywords:["published_at","publishedat","publish_date"],fakerMethod:"date.recent",schemaType:"string",minScore:0.6,format:"date-time"},{keywords:["expires_at","expiresat","expiration","expiry"],fakerMethod:"date.future",schemaType:"string",minScore:0.6,format:"date-time"},{keywords:["birthday","date_of_birth","dob","birthdate","born"],fakerMethod:"date.birthdate",schemaType:"string",minScore:0.8},{keywords:["start_date","begin_date"],fakerMethod:"date.past",schemaType:"string",minScore:0.8},{keywords:["end_date","due_date","deadline"],fakerMethod:"date.future",schemaType:"string",minScore:0.8},{keywords:["timestamp","ts"],fakerMethod:"date.recent",schemaType:"string",minScore:0.8}],z1=[{keywords:["color","colour"],fakerMethod:"color.human",schemaType:"string",minScore:0.8},{keywords:["hex_color","hexcolor"],fakerMethod:"color.rgb",schemaType:"string",minScore:0.9}],q1=[{keywords:["age"],fakerMethod:"number.int",schemaType:"number",minScore:0.8,fakerArgs:{min:18,max:80}},{keywords:["rating","score","stars"],fakerMethod:"number.int",schemaType:"number",minScore:0.8,fakerArgs:{min:1,max:5}},{keywords:["count","quantity","qty"],fakerMethod:"number.int",schemaType:"number",minScore:0.8,fakerArgs:{min:1,max:100}},{keywords:["percentage","percent"],fakerMethod:"number.int",schemaType:"number",minScore:0.8,fakerArgs:{min:0,max:100}},{keywords:["weight"],fakerMethod:"number.float",schemaType:"number",minScore:0.8,fakerArgs:{min:0.1,max:200}},{keywords:["height"],fakerMethod:"number.int",schemaType:"number",minScore:0.8,fakerArgs:{min:100,max:220}},{keywords:["width","length","depth"],fakerMethod:"number.int",schemaType:"number",minScore:0.8,fakerArgs:{min:1,max:1000}},{keywords:["priority","order","rank","level"],fakerMethod:"number.int",schemaType:"number",minScore:0.8,fakerArgs:{min:1,max:10}},{keywords:["version"],fakerMethod:"system.semver",schemaType:"string",minScore:0.8}],W1=[{keywords:["is_active","isactive","active","enabled","is_enabled"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.9},{keywords:["is_deleted","isdeleted","deleted"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.05},{keywords:["is_archived","isarchived","archived"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.1},{keywords:["is_verified","isverified","verified","confirmed","is_confirmed"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.8},{keywords:["is_admin","isadmin","admin"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.1},{keywords:["is_public","ispublic","public","visible","is_visible"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.7},{keywords:["is_read","isread","read","seen","is_seen"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.6},{keywords:["is_default","isdefault"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.8,trueProbability:0.1},{keywords:["is_required","isrequired","required","mandatory"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.5},{keywords:["is_featured","isfeatured","featured","promoted"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.8,trueProbability:0.15},{keywords:["available","in_stock"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.8,trueProbability:0.85}],b1=[{keywords:["filename","file_name"],fakerMethod:"system.fileName",schemaType:"string",minScore:0.8},{keywords:["file_type","filetype","mime_type","mimetype","content_type"],fakerMethod:"system.mimeType",schemaType:"string",minScore:0.8},{keywords:["file_ext","extension"],fakerMethod:"system.fileExt",schemaType:"string",minScore:0.9},{keywords:["file_path","filepath","path"],fakerMethod:"system.filePath",schemaType:"string",minScore:0.9},{keywords:["cron","cron_expression"],fakerMethod:"system.cron",schemaType:"string",minScore:0.9},{keywords:["semver"],fakerMethod:"system.semver",schemaType:"string",minScore:0.9}],U1=[{keywords:["aircraft_type","airplane","aircraft"],fakerMethod:"airline.aircraftType",schemaType:"string",minScore:0.9},{keywords:["flight_number","flight"],fakerMethod:"airline.flightNumber",schemaType:"string",minScore:0.9},{keywords:["record_locator","booking_ref","pnr"],fakerMethod:"airline.recordLocator",schemaType:"string",minScore:0.9},{keywords:["seat","seat_number"],fakerMethod:"airline.seat",schemaType:"string",minScore:0.9}],w1=[{keywords:["animal","animal_type","species"],fakerMethod:"animal.type",schemaType:"string",minScore:0.9},{keywords:["pet_name"],fakerMethod:"animal.petName",schemaType:"string",minScore:0.9},{keywords:["breed"],fakerMethod:"animal.dog",schemaType:"string",minScore:0.9},{keywords:["bird"],fakerMethod:"animal.bird",schemaType:"string",minScore:0.9},{keywords:["fish"],fakerMethod:"animal.fish",schemaType:"string",minScore:0.9},{keywords:["horse"],fakerMethod:"animal.horse",schemaType:"string",minScore:0.9},{keywords:["insect"],fakerMethod:"animal.insect",schemaType:"string",minScore:0.9}],V1=[{keywords:["book_title"],fakerMethod:"book.title",schemaType:"string",minScore:0.9},{keywords:["author","book_author","writer"],fakerMethod:"book.author",schemaType:"string",minScore:0.9},{keywords:["genre","book_genre"],fakerMethod:"book.genre",schemaType:"string",minScore:0.9},{keywords:["publisher","publishing_house"],fakerMethod:"book.publisher",schemaType:"string",minScore:0.9},{keywords:["book_series","series_name"],fakerMethod:"book.series",schemaType:"string",minScore:0.9}],Y1=[{keywords:["dish","meal","recipe_name"],fakerMethod:"food.dish",schemaType:"string",minScore:0.9},{keywords:["ingredient"],fakerMethod:"food.ingredient",schemaType:"string",minScore:0.9},{keywords:["spice"],fakerMethod:"food.spice",schemaType:"string",minScore:0.9},{keywords:["fruit"],fakerMethod:"food.fruit",schemaType:"string",minScore:0.9},{keywords:["vegetable"],fakerMethod:"food.vegetable",schemaType:"string",minScore:0.9},{keywords:["meat"],fakerMethod:"food.meat",schemaType:"string",minScore:0.9},{keywords:["food_description"],fakerMethod:"food.description",schemaType:"string",minScore:0.9},{keywords:["ethnic_category","cuisine"],fakerMethod:"food.ethnicCategory",schemaType:"string",minScore:0.9}],F1=[{keywords:["song","song_name","track","track_name"],fakerMethod:"music.songName",schemaType:"string",minScore:0.9},{keywords:["album","album_name"],fakerMethod:"music.album",schemaType:"string",minScore:0.9},{keywords:["artist","musician","band"],fakerMethod:"music.artist",schemaType:"string",minScore:0.9},{keywords:["music_genre"],fakerMethod:"music.genre",schemaType:"string",minScore:0.9}],C1=[],G1=[{keywords:["vehicle","vehicle_name"],fakerMethod:"vehicle.vehicle",schemaType:"string",minScore:0.9},{keywords:["vehicle_type"],fakerMethod:"vehicle.type",schemaType:"string",minScore:0.9},{keywords:["vehicle_manufacturer","car_make"],fakerMethod:"vehicle.manufacturer",schemaType:"string",minScore:0.9},{keywords:["vehicle_model","car_model"],fakerMethod:"vehicle.model",schemaType:"string",minScore:0.9},{keywords:["fuel","fuel_type"],fakerMethod:"vehicle.fuel",schemaType:"string",minScore:0.9},{keywords:["bicycle"],fakerMethod:"vehicle.bicycle",schemaType:"string",minScore:0.9},{keywords:["vehicle_color","car_color"],fakerMethod:"vehicle.color",schemaType:"string",minScore:0.9}],H1=[{keywords:["branch","branch_name","git_branch"],fakerMethod:"git.branch",schemaType:"string",minScore:0.9},{keywords:["commit_sha","commit_hash","sha"],fakerMethod:"git.commitSha",schemaType:"string",minScore:0.9},{keywords:["commit_message"],fakerMethod:"git.commitMessage",schemaType:"string",minScore:0.9}],J1=[{keywords:["db_column","column_name"],fakerMethod:"database.column",schemaType:"string",minScore:0.9},{keywords:["db_type","column_type"],fakerMethod:"database.type",schemaType:"string",minScore:0.9},{keywords:["db_engine","database_engine"],fakerMethod:"database.engine",schemaType:"string",minScore:0.9},{keywords:["collation"],fakerMethod:"database.collation",schemaType:"string",minScore:0.9},{keywords:["mongodb_id","object_id"],fakerMethod:"database.mongodbObjectId",schemaType:"string",minScore:0.9}],I1=[{keywords:["abbreviation","tech_abbreviation"],fakerMethod:"hacker.abbreviation",schemaType:"string",minScore:0.9},{keywords:["hacker_phrase","tech_phrase"],fakerMethod:"hacker.phrase",schemaType:"string",minScore:0.9}],M1=[{keywords:["adjective"],fakerMethod:"word.adjective",schemaType:"string",minScore:0.8},{keywords:["adverb"],fakerMethod:"word.adverb",schemaType:"string",minScore:0.8},{keywords:["noun"],fakerMethod:"word.noun",schemaType:"string",minScore:0.8},{keywords:["verb"],fakerMethod:"word.verb",schemaType:"string",minScore:0.8}],d=[...a,...e,...Q1,...$1,...B1,...Z1,...K1,...j1,...X1,...z1,...q1,...W1,...b1,...U1,...w1,...V1,...Y1,...F1,...C1,...G1,...H1,...J1,...I1,...M1];function p(Q){let $=Q.split(/[_-]/),Z=[];for(let B of $){if(!B)continue;let K=B.replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z0-9])([A-Z])/g,"$1_$2").split("_");for(let j of K)if(j)Z.push(j.toLowerCase())}return Z}function P1(Q,$){let Z=Q.join(""),B=0;for(let K of $){let j=p(K),z=j.join("");if(Z===z)return 1;if(j.length>0&&j.every((X)=>Q.includes(X))){let q=j.length/Q.length>0.5?0.9:0.65;B=Math.max(B,q)}if(j.length>0&&j.length<=Q.length){if(Q.slice(-j.length).every((q,W)=>q===j[W]))B=Math.max(B,0.8)}if(z.length>=3&&Z.includes(z))B=Math.max(B,0.7)}return B}function i(Q,$,Z=d){let B=$,K=typeof $.type==="string"?$.type:void 0;if(K==="string"&&$.format==="uuid")return{mapping:{keywords:["uuid"],fakerMethod:"string.uuid",schemaType:"string",minScore:0.5},score:1};if(B.pattern||B.enum||B.faker||B.$ref||K==="string"&&($.minLength!==void 0||$.maxLength!==void 0))return;let j=$.minimum!==void 0||$.maximum!==void 0||$.exclusiveMinimum!==void 0||$.exclusiveMaximum!==void 0,z=p(Q),X;for(let q of Z){if(j&&(q.schemaType==="number"||q.schemaType==="integer"))continue;if(K==="object"||K==="array")continue;if(q.schemaType&&K&&q.schemaType!==K){if(!(q.schemaType==="number"&&K==="integer"||q.schemaType==="integer"&&K==="number"))continue}let W=P1(z,q.keywords);if(W>=q.minScore&&(!X||W>X.score))X={mapping:q,score:W}}if(K==="string"){if(z[z.length-1]==="id"&&z.length>1){if(!X||X.score<0.8)X={mapping:{keywords:["id"],fakerMethod:"string.uuid",schemaType:"string",minScore:0.5},score:0.8}}}return X}import{ResourceLimitError as L,SchemaValidationError as U}from"@schmock/core";var _;function b(Q){return typeof Q==="object"&&Q!==null&&!Array.isArray(Q)}function C(Q,$="$"){if(!Q||typeof Q!=="object")throw new U($,"Schema must be a valid JSON Schema object");if(Object.keys(Q).length===0)throw new U($,"Schema cannot be empty");let Z=["object","array","string","number","integer","boolean","null"];if(Q.type&&typeof Q.type==="string"&&!Z.includes(Q.type))throw new U($,`Invalid schema type: "${Q.type}"`,"Supported types are: object, array, string, number, integer, boolean, null");if(Q.type==="object"&&Q.properties){if(typeof Q.properties!=="object"||Array.isArray(Q.properties))throw new U(`${$}.properties`,"Properties must be an object mapping property names to schemas",'Use { "propertyName": { "type": "string" } } format');for(let[B,K]of Object.entries(Q.properties))if(typeof K==="object"&&K!==null){let j="faker"in K?String(K.faker):void 0;if(j)try{y(j)}catch(z){if(z instanceof U){let X=z.context,q="Invalid faker method",W;if(X&&typeof X==="object"){if("issue"in X&&typeof X.issue==="string")q=X.issue;if("suggestion"in X&&typeof X.suggestion==="string")W=X.suggestion}throw new U(`${$}.properties.${B}.faker`,q,W)}if(z instanceof Error)throw z;throw Error(String(z))}C(K,`${$}.properties.${B}`)}}if(Q.type==="array"){if(Q.items===null||Q.items===void 0)throw new U(`${$}.items`,"Array schema must have valid items definition","Define items as a schema object or array of schemas");if(Array.isArray(Q.items)){if(Q.items.length===0)throw new U(`${$}.items`,"Array items cannot be empty array","Provide at least one item schema");Q.items.forEach((B,K)=>{if(typeof B==="object"&&B!==null)C(B,`${$}.items[${K}]`)})}else if(typeof Q.items==="object"&&Q.items!==null)C(Q.items,`${$}.items`)}if($==="$"){if(R(Q))throw new U($,"Schema contains circular references which are not supported");if(Q.$ref==="#")throw new U($,"Self-referencing schemas are not supported");let B=O(Q);if(B>M)throw new L("schema_nesting_depth",M,B);if(B>=F)L1(Q,$);P(Q,$)}}function R(Q,$=new Set){if($.has(Q))return!0;if(Q.$ref==="#")return!0;if($.add(Q),Q.type==="object"&&Q.properties){for(let Z of Object.values(Q.properties))if(b(Z)){if(R(Z,$))return!0}}if(Q.type==="array"&&Q.items){let Z=Array.isArray(Q.items)?Q.items:[Q.items];for(let B of Z)if(b(B)){if(R(B,$))return!0}}return $.delete(Q),!1}function O(Q,$=0){if($>M)return $;let Z=$;if(Q.type==="object"&&Q.properties){for(let B of Object.values(Q.properties))if(b(B))Z=Math.max(Z,O(B,$+1))}if(Q.type==="array"&&Q.items){let B=Array.isArray(Q.items)?Q.items:[Q.items];for(let K of B)if(b(K))Z=Math.max(Z,O(K,$+1))}return Z}function L1(Q,$){function Z(B,K){let j=B.type;if(Array.isArray(j)?j.includes("array"):j==="array"){let X=B.maxItems||V;if(K>=F&&X>=H)throw new L("deep_nesting_memory_risk",F*H,K*X);if(B.items){let q=Array.isArray(B.items)?B.items:[B.items];for(let W of q)if(b(W))Z(W,K+1)}return}if(j==="object"&&B.properties){for(let X of Object.values(B.properties))if(b(X))Z(X,K+1)}}Z(Q,0)}function P(Q,$){if(Q.type==="array"){if(Q.maxItems&&Q.maxItems>Y)throw new L("array_max_items",Y,Q.maxItems);let Z=O(Q),B=Q.maxItems||Q.minItems||V;if(Z>F&&B>H)throw new L("memory_estimation",F*H,Z*B)}if(Q.type==="object"&&Q.properties){for(let[Z,B]of Object.entries(Q.properties))if(b(B))P(B,`${$}.properties.${Z}`)}if(Q.type==="array"&&Q.items){if(Array.isArray(Q.items))Q.items.forEach((Z,B)=>{if(b(Z))P(Z,`${$}.items[${B}]`)});else if(b(Q.items))P(Q.items,`${$}.items`)}}function y(Q){let $=Q.split(".");if($.length<2)throw new U("$.faker",`Invalid faker method format: "${Q}"`,"Use format like 'person.firstName' or 'internet.email'");if(!_)_=g();let B=_;for(let K of $)if(B&&typeof B==="object"&&K in B)B=B[K];else throw new U("$.faker",`Invalid faker method: "${Q}"`,"Check faker.js documentation for valid methods");if(typeof B!=="function")throw new U("$.faker",`Invalid faker method: "${Q}" is not a function`,"Check faker.js documentation for valid methods")}function w(Q){if(!Q||typeof Q!=="object")return Q;let $={...Q};if($.properties){$.properties={...$.properties};for(let[Z,B]of Object.entries($.properties))if(b(B))$.properties[Z]=O1(Z,B)}for(let Z of["allOf","anyOf","oneOf"]){let B=$[Z];if(Array.isArray(B))$[Z]=B.map((K)=>b(K)?w(K):K)}if($.items){if(Array.isArray($.items))$.items=$.items.map((Z)=>b(Z)?w(Z):Z);else if(b($.items))$.items=w($.items)}if($.additionalProperties&&typeof $.additionalProperties==="object"&&!Array.isArray($.additionalProperties))$.additionalProperties=w($.additionalProperties);return $}function O1(Q,$){let Z={...$};if(Z.faker)return y(Z.faker),Z;let B=Z.allOf||Z.anyOf||Z.oneOf;if(Z.properties||B||Z.items){let j=w(Z);Object.assign(Z,j)}if(B)return Z;if(Z.const!==void 0||Z.enum)return Z;let K=i(Q,Z);if(K){if(Z.faker=K.mapping.fakerMethod,K.mapping.format)Z.format=K.mapping.format;if(K.mapping.trueProbability!==void 0)Z.schmockTrueProbability=K.mapping.trueProbability}return Z}function a1(Q){return C(Q.schema),{name:"faker",version:k,async process($,Z){if(Z!==void 0&&Z!==null)return{context:$,response:Z};try{let B=await D1({schema:Q.schema,count:Q.count,overrides:Q.overrides,params:$.params,state:$.routeState,query:$.query,seed:Q.seed});return{context:$,response:B}}catch(B){if(B instanceof n||B instanceof o)throw B;throw new v1($.path,B instanceof Error?B:Error(String(B)),Q.schema)}}}}async function D1(Q){let{schema:$,count:Z,overrides:B,params:K,state:j,query:z,seed:X}=Q;if(C($),$.type==="array"&&$.items){let I=S($,Z);if(I>Y)throw new o("array_size",Y,I);let D=Array.isArray($.items)?$.items[0]:$.items;if(!D||typeof D==="boolean")throw new n("$.items","Array schema must have valid items definition");let A=w(D),N=[];for(let T=0;T<I;T++){let G=await x(A,X);G=v(G,A),G=J(G,B,K,j,z),N.push(G)}return N}let q=w($),W=await x(q,X);return W=v(W,q),W=J(W,B,K,j,z),W}function v(Q,$){if(Q===null||Q===void 0||!$||typeof $!=="object")return Q;let Z=$;if(Z.schmockNullable===!0){if(Math.random()<E)return null}if($.type==="boolean"&&typeof Z.schmockTrueProbability==="number")return Math.random()<Z.schmockTrueProbability;if(typeof Q==="object"&&!Array.isArray(Q)&&$.properties){let B=Q;for(let[K,j]of Object.entries($.properties))if(K in B&&b(j))B[K]=v(B[K],j)}if(Array.isArray(Q)&&$.items&&b($.items))for(let B=0;B<Q.length;B++)Q[B]=v(Q[B],$.items);return Q}export{D1 as generateFromSchema,a1 as fakerPlugin};
|
|
1
|
+
import{ResourceLimitError as o,SchemaGenerationError as v0,SchemaValidationError as n}from"@schmock/core";var E="2.2.1";var w=1e4,M=10,b=3,F=3,H=100,k=0.05;import{base as m,en as s,Faker as c}from"@faker-js/faker";import{generate as h}from"json-schema-faker";function x(Q){let $=new c({locale:[s,m]});if(Q!==void 0)$.seed(Q);return $}async function _(Q,$){let Z=$??Math.floor(Math.random()*2147483647);return h(Q,{seed:Z,optionalsProbability:1,alwaysFakeOptionals:!0,useDefaultValue:!0,ignoreMissingRefs:!0,failOnInvalidTypes:!1,failOnInvalidFormat:!1,extensions:{faker:x($)}})}var g=new Set(["__proto__","constructor","prototype"]);function S(Q,$,Z=Math.random){if($!==void 0){if($<0)return 0;return $}if(Q.minItems!==void 0&&Q.maxItems!==void 0){let B=Q.minItems,K=Math.max(B,Q.maxItems);return Math.floor(Z()*(K-B+1))+B}if(Q.minItems!==void 0)return Math.max(Q.minItems,b);if(Q.maxItems!==void 0)return Math.min(Q.maxItems,b);return b}function J(Q,$,Z,B,K){if(!$)return Q;if(typeof Q!=="object"||Q===null)return Q;let j=structuredClone(Q);for(let[z,X]of Object.entries($)){if(g.has(z))continue;if(z.includes("."))t(j,z,X,{params:Z,state:B,query:K});else if(typeof X==="object"&&X!==null&&!Array.isArray(X)){let q=X;if(j[z]&&typeof j[z]==="object")j[z]=J(j[z],q,Z,B,K);else j[z]=J({},q,Z,B,K)}else if(typeof X==="string"&&X.includes("{{"))j[z]=l(X,{params:Z,state:B,query:K});else j[z]=X}return j}function t(Q,$,Z,B){let K=$.split("."),j=Q;for(let X=0;X<K.length-1;X++){let q=K[X];if(g.has(q))return;if(!(q in j)||typeof j[q]!=="object"||j[q]===null)j[q]={};j=j[q]}let z=K[K.length-1];if(g.has(z))return;if(typeof Z==="string"&&Z.includes("{{"))j[z]=l(Z,B);else j[z]=Z}function u(Q,$){let Z=$.trim().split("."),B=Q;for(let K of Z)if(B&&typeof B==="object")B=B[K];else return;return B}function l(Q,$){let Z=Q.match(/^\{\{\s*([^}]+)\s*\}\}$/);if(Z){let B=u($,Z[1]);return B!==void 0?B:Q}return Q.replace(/\{\{\s*([^}]+)\s*\}\}/g,(B,K)=>{let j=u($,K);return j!==void 0?String(j):B})}var a=[{keywords:["email"],fakerMethod:"internet.email",schemaType:"string",minScore:0.6,format:"email"},{keywords:["username","user_name","login","handle"],fakerMethod:"internet.username",schemaType:"string",minScore:0.6},{keywords:["password","passwd","secret"],fakerMethod:"internet.password",schemaType:"string",minScore:0.6},{keywords:["token","api_key","apikey","access_token","refresh_token"],fakerMethod:"string.alphanumeric",schemaType:"string",minScore:0.8}],e=[{keywords:["first_name","firstname","given_name","forename"],fakerMethod:"person.firstName",schemaType:"string",minScore:0.6},{keywords:["last_name","lastname","surname","family_name"],fakerMethod:"person.lastName",schemaType:"string",minScore:0.6},{keywords:["full_name","fullname","display_name","displayname","full_name"],fakerMethod:"person.fullName",schemaType:"string",minScore:0.6},{keywords:["name"],fakerMethod:"person.fullName",schemaType:"string",minScore:0.6},{keywords:["middle_name","middlename"],fakerMethod:"person.middleName",schemaType:"string",minScore:0.8},{keywords:["prefix","honorific","salutation"],fakerMethod:"person.prefix",schemaType:"string",minScore:0.8},{keywords:["suffix"],fakerMethod:"person.suffix",schemaType:"string",minScore:0.9},{keywords:["gender","sex"],fakerMethod:"person.sex",schemaType:"string",minScore:0.8},{keywords:["bio","biography"],fakerMethod:"lorem.paragraph",schemaType:"string",minScore:0.8},{keywords:["job_title","jobtitle","position","occupation","job","role"],fakerMethod:"person.jobTitle",schemaType:"string",minScore:0.6},{keywords:["job_area","department","division","team"],fakerMethod:"person.jobArea",schemaType:"string",minScore:0.8},{keywords:["zodiac","zodiac_sign"],fakerMethod:"person.zodiacSign",schemaType:"string",minScore:0.9}],Q0=[{keywords:["phone","mobile","cell","tel","telephone","cellphone","fax"],fakerMethod:"phone.number",schemaType:"string",minScore:0.6},{keywords:["imei"],fakerMethod:"phone.imei",schemaType:"string",minScore:0.9}],$0=[{keywords:["street","street_address"],fakerMethod:"location.streetAddress",schemaType:"string",minScore:0.6},{keywords:["address","mailing_address","postal_address"],fakerMethod:"location.streetAddress",schemaType:"string",minScore:0.6},{keywords:["city","town"],fakerMethod:"location.city",schemaType:"string",minScore:0.6},{keywords:["state","province","region"],fakerMethod:"location.state",schemaType:"string",minScore:0.8},{keywords:["country"],fakerMethod:"location.country",schemaType:"string",minScore:0.8},{keywords:["country_code","countrycode"],fakerMethod:"location.countryCode",schemaType:"string",minScore:0.8},{keywords:["county"],fakerMethod:"location.county",schemaType:"string",minScore:0.9},{keywords:["continent"],fakerMethod:"location.continent",schemaType:"string",minScore:0.9},{keywords:["zip","zipcode","zip_code","postal","postal_code"],fakerMethod:"location.zipCode",schemaType:"string",minScore:0.6},{keywords:["latitude","lat"],fakerMethod:"location.latitude",schemaType:"number",minScore:0.6},{keywords:["longitude","lng","lon","long"],fakerMethod:"location.longitude",schemaType:"number",minScore:0.6},{keywords:["timezone","time_zone","tz"],fakerMethod:"location.timeZone",schemaType:"string",minScore:0.8},{keywords:["building_number"],fakerMethod:"location.buildingNumber",schemaType:"string",minScore:0.9}],B0=[{keywords:["url","website","link","href","homepage","webpage"],fakerMethod:"internet.url",schemaType:"string",minScore:0.6},{keywords:["avatar","photo_url","profile_image","image_url","picture","thumbnail","icon"],fakerMethod:"image.avatar",schemaType:"string",minScore:0.6},{keywords:["domain","hostname","domain_name"],fakerMethod:"internet.domainName",schemaType:"string",minScore:0.8},{keywords:["ip","ip_address","ipaddress","ipv4"],fakerMethod:"internet.ipv4",schemaType:"string",minScore:0.8},{keywords:["ipv6"],fakerMethod:"internet.ipv6",schemaType:"string",minScore:0.9},{keywords:["mac","mac_address"],fakerMethod:"internet.mac",schemaType:"string",minScore:0.9},{keywords:["user_agent","useragent"],fakerMethod:"internet.userAgent",schemaType:"string",minScore:0.9},{keywords:["port"],fakerMethod:"internet.port",schemaType:"number",minScore:0.9},{keywords:["protocol"],fakerMethod:"internet.protocol",schemaType:"string",minScore:0.9}],Z0=[{keywords:["uuid","guid"],fakerMethod:"string.uuid",schemaType:"string",minScore:0.6},{keywords:["sku"],fakerMethod:"string.alphanumeric",schemaType:"string",minScore:0.9},{keywords:["slug"],fakerMethod:"lorem.slug",schemaType:"string",minScore:0.8},{keywords:["isbn"],fakerMethod:"commerce.isbn",schemaType:"string",minScore:0.9},{keywords:["vin"],fakerMethod:"vehicle.vin",schemaType:"string",minScore:0.9},{keywords:["iban"],fakerMethod:"finance.iban",schemaType:"string",minScore:0.9},{keywords:["bic","swift"],fakerMethod:"finance.bic",schemaType:"string",minScore:0.9},{keywords:["ssn","social_security"],fakerMethod:"string.numeric",schemaType:"string",minScore:0.9}],K0=[{keywords:["description","desc","summary","overview","about","excerpt"],fakerMethod:"lorem.paragraph",schemaType:"string",minScore:0.6},{keywords:["content","body","text","message"],fakerMethod:"lorem.paragraphs",schemaType:"string",minScore:0.6},{keywords:["title","heading","subject","headline"],fakerMethod:"lorem.sentence",schemaType:"string",minScore:0.6},{keywords:["tag","label","category","keyword"],fakerMethod:"lorem.word",schemaType:"string",minScore:0.8},{keywords:["comment","note","remark","feedback","review"],fakerMethod:"lorem.sentence",schemaType:"string",minScore:0.8},{keywords:["sentence"],fakerMethod:"lorem.sentence",schemaType:"string",minScore:0.9},{keywords:["paragraph"],fakerMethod:"lorem.paragraph",schemaType:"string",minScore:0.9},{keywords:["word"],fakerMethod:"lorem.word",schemaType:"string",minScore:0.9}],j0=[{keywords:["company","organization","org","employer","brand"],fakerMethod:"company.name",schemaType:"string",minScore:0.6},{keywords:["product","product_name","item_name"],fakerMethod:"commerce.productName",schemaType:"string",minScore:0.8},{keywords:["price","amount","cost","fee","salary","wage","total","subtotal","balance","revenue","income"],fakerMethod:"commerce.price",minScore:0.6},{keywords:["currency","currency_code"],fakerMethod:"finance.currencyCode",schemaType:"string",minScore:0.8},{keywords:["currency_name"],fakerMethod:"finance.currencyName",schemaType:"string",minScore:0.8},{keywords:["currency_symbol"],fakerMethod:"finance.currencySymbol",schemaType:"string",minScore:0.8},{keywords:["account_number","account_no"],fakerMethod:"finance.accountNumber",schemaType:"string",minScore:0.8},{keywords:["credit_card","card_number"],fakerMethod:"finance.creditCardNumber",schemaType:"string",minScore:0.8},{keywords:["cvv"],fakerMethod:"finance.creditCardCVV",schemaType:"string",minScore:0.9},{keywords:["transaction_type"],fakerMethod:"finance.transactionType",schemaType:"string",minScore:0.9}],X0=[{keywords:["created_at","createdat","creation_date","date_created","createddate"],fakerMethod:"date.recent",schemaType:"string",minScore:0.6,format:"date-time"},{keywords:["updated_at","updatedat","modified_at","modifiedat","date_updated","last_modified","date_modified"],fakerMethod:"date.recent",schemaType:"string",minScore:0.6,format:"date-time"},{keywords:["deleted_at","deletedat"],fakerMethod:"date.recent",schemaType:"string",minScore:0.6,format:"date-time"},{keywords:["published_at","publishedat","publish_date"],fakerMethod:"date.recent",schemaType:"string",minScore:0.6,format:"date-time"},{keywords:["expires_at","expiresat","expiration","expiry"],fakerMethod:"date.future",schemaType:"string",minScore:0.6,format:"date-time"},{keywords:["birthday","date_of_birth","dob","birthdate","born"],fakerMethod:"date.birthdate",schemaType:"string",minScore:0.8},{keywords:["start_date","begin_date"],fakerMethod:"date.past",schemaType:"string",minScore:0.8},{keywords:["end_date","due_date","deadline"],fakerMethod:"date.future",schemaType:"string",minScore:0.8},{keywords:["timestamp","ts"],fakerMethod:"date.recent",schemaType:"string",minScore:0.8}],z0=[{keywords:["color","colour"],fakerMethod:"color.human",schemaType:"string",minScore:0.8},{keywords:["hex_color","hexcolor"],fakerMethod:"color.rgb",schemaType:"string",minScore:0.9}],q0=[{keywords:["age"],fakerMethod:"number.int",schemaType:"number",minScore:0.8,fakerArgs:{min:18,max:80}},{keywords:["rating","score","stars"],fakerMethod:"number.int",schemaType:"number",minScore:0.8,fakerArgs:{min:1,max:5}},{keywords:["count","quantity","qty"],fakerMethod:"number.int",schemaType:"number",minScore:0.8,fakerArgs:{min:1,max:100}},{keywords:["percentage","percent"],fakerMethod:"number.int",schemaType:"number",minScore:0.8,fakerArgs:{min:0,max:100}},{keywords:["weight"],fakerMethod:"number.float",schemaType:"number",minScore:0.8,fakerArgs:{min:0.1,max:200}},{keywords:["height"],fakerMethod:"number.int",schemaType:"number",minScore:0.8,fakerArgs:{min:100,max:220}},{keywords:["width","length","depth"],fakerMethod:"number.int",schemaType:"number",minScore:0.8,fakerArgs:{min:1,max:1000}},{keywords:["priority","order","rank","level"],fakerMethod:"number.int",schemaType:"number",minScore:0.8,fakerArgs:{min:1,max:10}},{keywords:["version"],fakerMethod:"system.semver",schemaType:"string",minScore:0.8}],W0=[{keywords:["is_active","isactive","active","enabled","is_enabled"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.9},{keywords:["is_deleted","isdeleted","deleted"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.05},{keywords:["is_archived","isarchived","archived"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.1},{keywords:["is_verified","isverified","verified","confirmed","is_confirmed"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.8},{keywords:["is_admin","isadmin","admin"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.1},{keywords:["is_public","ispublic","public","visible","is_visible"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.7},{keywords:["is_read","isread","read","seen","is_seen"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.6},{keywords:["is_default","isdefault"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.8,trueProbability:0.1},{keywords:["is_required","isrequired","required","mandatory"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.6,trueProbability:0.5},{keywords:["is_featured","isfeatured","featured","promoted"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.8,trueProbability:0.15},{keywords:["available","in_stock"],fakerMethod:"datatype.boolean",schemaType:"boolean",minScore:0.8,trueProbability:0.85}],U0=[{keywords:["filename","file_name"],fakerMethod:"system.fileName",schemaType:"string",minScore:0.8},{keywords:["file_type","filetype","mime_type","mimetype","content_type"],fakerMethod:"system.mimeType",schemaType:"string",minScore:0.8},{keywords:["file_ext","extension"],fakerMethod:"system.fileExt",schemaType:"string",minScore:0.9},{keywords:["file_path","filepath","path"],fakerMethod:"system.filePath",schemaType:"string",minScore:0.9},{keywords:["cron","cron_expression"],fakerMethod:"system.cron",schemaType:"string",minScore:0.9},{keywords:["semver"],fakerMethod:"system.semver",schemaType:"string",minScore:0.9}],V0=[{keywords:["aircraft_type","airplane","aircraft"],fakerMethod:"airline.aircraftType",schemaType:"string",minScore:0.9},{keywords:["flight_number","flight"],fakerMethod:"airline.flightNumber",schemaType:"string",minScore:0.9},{keywords:["record_locator","booking_ref","pnr"],fakerMethod:"airline.recordLocator",schemaType:"string",minScore:0.9},{keywords:["seat","seat_number"],fakerMethod:"airline.seat",schemaType:"string",minScore:0.9}],Y0=[{keywords:["animal","animal_type","species"],fakerMethod:"animal.type",schemaType:"string",minScore:0.9},{keywords:["pet_name"],fakerMethod:"animal.petName",schemaType:"string",minScore:0.9},{keywords:["breed"],fakerMethod:"animal.dog",schemaType:"string",minScore:0.9},{keywords:["bird"],fakerMethod:"animal.bird",schemaType:"string",minScore:0.9},{keywords:["fish"],fakerMethod:"animal.fish",schemaType:"string",minScore:0.9},{keywords:["horse"],fakerMethod:"animal.horse",schemaType:"string",minScore:0.9},{keywords:["insect"],fakerMethod:"animal.insect",schemaType:"string",minScore:0.9}],b0=[{keywords:["book_title"],fakerMethod:"book.title",schemaType:"string",minScore:0.9},{keywords:["author","book_author","writer"],fakerMethod:"book.author",schemaType:"string",minScore:0.9},{keywords:["genre","book_genre"],fakerMethod:"book.genre",schemaType:"string",minScore:0.9},{keywords:["publisher","publishing_house"],fakerMethod:"book.publisher",schemaType:"string",minScore:0.9},{keywords:["book_series","series_name"],fakerMethod:"book.series",schemaType:"string",minScore:0.9}],w0=[{keywords:["dish","meal","recipe_name"],fakerMethod:"food.dish",schemaType:"string",minScore:0.9},{keywords:["ingredient"],fakerMethod:"food.ingredient",schemaType:"string",minScore:0.9},{keywords:["spice"],fakerMethod:"food.spice",schemaType:"string",minScore:0.9},{keywords:["fruit"],fakerMethod:"food.fruit",schemaType:"string",minScore:0.9},{keywords:["vegetable"],fakerMethod:"food.vegetable",schemaType:"string",minScore:0.9},{keywords:["meat"],fakerMethod:"food.meat",schemaType:"string",minScore:0.9},{keywords:["food_description"],fakerMethod:"food.description",schemaType:"string",minScore:0.9},{keywords:["ethnic_category","cuisine"],fakerMethod:"food.ethnicCategory",schemaType:"string",minScore:0.9}],F0=[{keywords:["song","song_name","track","track_name"],fakerMethod:"music.songName",schemaType:"string",minScore:0.9},{keywords:["album","album_name"],fakerMethod:"music.album",schemaType:"string",minScore:0.9},{keywords:["artist","musician","band"],fakerMethod:"music.artist",schemaType:"string",minScore:0.9},{keywords:["music_genre"],fakerMethod:"music.genre",schemaType:"string",minScore:0.9}],C0=[],G0=[{keywords:["vehicle","vehicle_name"],fakerMethod:"vehicle.vehicle",schemaType:"string",minScore:0.9},{keywords:["vehicle_type"],fakerMethod:"vehicle.type",schemaType:"string",minScore:0.9},{keywords:["vehicle_manufacturer","car_make"],fakerMethod:"vehicle.manufacturer",schemaType:"string",minScore:0.9},{keywords:["vehicle_model","car_model"],fakerMethod:"vehicle.model",schemaType:"string",minScore:0.9},{keywords:["fuel","fuel_type"],fakerMethod:"vehicle.fuel",schemaType:"string",minScore:0.9},{keywords:["bicycle"],fakerMethod:"vehicle.bicycle",schemaType:"string",minScore:0.9},{keywords:["vehicle_color","car_color"],fakerMethod:"vehicle.color",schemaType:"string",minScore:0.9}],H0=[{keywords:["branch","branch_name","git_branch"],fakerMethod:"git.branch",schemaType:"string",minScore:0.9},{keywords:["commit_sha","commit_hash","sha"],fakerMethod:"git.commitSha",schemaType:"string",minScore:0.9},{keywords:["commit_message"],fakerMethod:"git.commitMessage",schemaType:"string",minScore:0.9}],J0=[{keywords:["db_column","column_name"],fakerMethod:"database.column",schemaType:"string",minScore:0.9},{keywords:["db_type","column_type"],fakerMethod:"database.type",schemaType:"string",minScore:0.9},{keywords:["db_engine","database_engine"],fakerMethod:"database.engine",schemaType:"string",minScore:0.9},{keywords:["collation"],fakerMethod:"database.collation",schemaType:"string",minScore:0.9},{keywords:["mongodb_id","object_id"],fakerMethod:"database.mongodbObjectId",schemaType:"string",minScore:0.9}],I0=[{keywords:["abbreviation","tech_abbreviation"],fakerMethod:"hacker.abbreviation",schemaType:"string",minScore:0.9},{keywords:["hacker_phrase","tech_phrase"],fakerMethod:"hacker.phrase",schemaType:"string",minScore:0.9}],M0=[{keywords:["adjective"],fakerMethod:"word.adjective",schemaType:"string",minScore:0.8},{keywords:["adverb"],fakerMethod:"word.adverb",schemaType:"string",minScore:0.8},{keywords:["noun"],fakerMethod:"word.noun",schemaType:"string",minScore:0.8},{keywords:["verb"],fakerMethod:"word.verb",schemaType:"string",minScore:0.8}],d=[...a,...e,...Q0,...$0,...B0,...Z0,...K0,...j0,...X0,...z0,...q0,...W0,...U0,...V0,...Y0,...b0,...w0,...F0,...C0,...G0,...H0,...J0,...I0,...M0];function p(Q){let $=Q.split(/[_-]/),Z=[];for(let B of $){if(!B)continue;let K=B.replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z0-9])([A-Z])/g,"$1_$2").split("_");for(let j of K)if(j)Z.push(j.toLowerCase())}return Z}function P0(Q,$){let Z=Q.join(""),B=0;for(let K of $){let j=p(K),z=j.join("");if(Z===z)return 1;if(j.length>0&&j.every((X)=>Q.includes(X))){let q=j.length/Q.length>0.5?0.9:0.65;B=Math.max(B,q)}if(j.length>0&&j.length<=Q.length){if(Q.slice(-j.length).every((q,W)=>q===j[W]))B=Math.max(B,0.8)}if(z.length>=3&&Z.includes(z))B=Math.max(B,0.7)}return B}function i(Q,$,Z=d){let B=$,K=typeof $.type==="string"?$.type:void 0;if(K==="string"&&$.format==="uuid")return{mapping:{keywords:["uuid"],fakerMethod:"string.uuid",schemaType:"string",minScore:0.5},score:1};if(B.pattern||B.enum||B.faker||B.$ref||K==="string"&&($.minLength!==void 0||$.maxLength!==void 0))return;let j=$.minimum!==void 0||$.maximum!==void 0||$.exclusiveMinimum!==void 0||$.exclusiveMaximum!==void 0,z=p(Q),X;for(let q of Z){if(j&&(q.schemaType==="number"||q.schemaType==="integer"))continue;if(K==="object"||K==="array")continue;if(q.schemaType&&K&&q.schemaType!==K){if(!(q.schemaType==="number"&&K==="integer"||q.schemaType==="integer"&&K==="number"))continue}let W=P0(z,q.keywords);if(W>=q.minScore&&(!X||W>X.score))X={mapping:q,score:W}}if(K==="string"){if(z[z.length-1]==="id"&&z.length>1){if(!X||X.score<0.8)X={mapping:{keywords:["id"],fakerMethod:"string.uuid",schemaType:"string",minScore:0.5},score:0.8}}}return X}import{ResourceLimitError as L,SchemaValidationError as V}from"@schmock/core";var f;function U(Q){return typeof Q==="object"&&Q!==null&&!Array.isArray(Q)}function C(Q,$="$"){if(!Q||typeof Q!=="object")throw new V($,"Schema must be a valid JSON Schema object");if(Object.keys(Q).length===0)throw new V($,"Schema cannot be empty");let Z=["object","array","string","number","integer","boolean","null"];if(Q.type&&typeof Q.type==="string"&&!Z.includes(Q.type))throw new V($,`Invalid schema type: "${Q.type}"`,"Supported types are: object, array, string, number, integer, boolean, null");if(Q.type==="object"&&Q.properties){if(typeof Q.properties!=="object"||Array.isArray(Q.properties))throw new V(`${$}.properties`,"Properties must be an object mapping property names to schemas",'Use { "propertyName": { "type": "string" } } format');for(let[B,K]of Object.entries(Q.properties))if(typeof K==="object"&&K!==null){let j="faker"in K?String(K.faker):void 0;if(j)try{y(j)}catch(z){if(z instanceof V){let X=z.context,q="Invalid faker method",W;if(X&&typeof X==="object"){if("issue"in X&&typeof X.issue==="string")q=X.issue;if("suggestion"in X&&typeof X.suggestion==="string")W=X.suggestion}throw new V(`${$}.properties.${B}.faker`,q,W)}if(z instanceof Error)throw z;throw Error(String(z))}C(K,`${$}.properties.${B}`)}}if(Q.type==="array"){if(Q.items===null||Q.items===void 0)throw new V(`${$}.items`,"Array schema must have valid items definition","Define items as a schema object or array of schemas");if(Array.isArray(Q.items)){if(Q.items.length===0)throw new V(`${$}.items`,"Array items cannot be empty array","Provide at least one item schema");Q.items.forEach((B,K)=>{if(typeof B==="object"&&B!==null)C(B,`${$}.items[${K}]`)})}else if(typeof Q.items==="object"&&Q.items!==null)C(Q.items,`${$}.items`)}if($==="$"){if(R(Q))throw new V($,"Schema contains circular references which are not supported");if(Q.$ref==="#")throw new V($,"Self-referencing schemas are not supported");let B=O(Q);if(B>M)throw new L("schema_nesting_depth",M,B);if(B>=F)L0(Q,$);P(Q,$)}}function R(Q,$=new Set){if($.has(Q))return!0;if(Q.$ref==="#")return!0;if($.add(Q),Q.type==="object"&&Q.properties){for(let Z of Object.values(Q.properties))if(U(Z)){if(R(Z,$))return!0}}if(Q.type==="array"&&Q.items){let Z=Array.isArray(Q.items)?Q.items:[Q.items];for(let B of Z)if(U(B)){if(R(B,$))return!0}}return $.delete(Q),!1}function O(Q,$=0){if($>M)return $;let Z=$;if(Q.type==="object"&&Q.properties){for(let B of Object.values(Q.properties))if(U(B))Z=Math.max(Z,O(B,$+1))}if(Q.type==="array"&&Q.items){let B=Array.isArray(Q.items)?Q.items:[Q.items];for(let K of B)if(U(K))Z=Math.max(Z,O(K,$+1))}return Z}function L0(Q,$){function Z(B,K){let j=B.type;if(Array.isArray(j)?j.includes("array"):j==="array"){let X=B.maxItems||b;if(K>=F&&X>=H)throw new L("deep_nesting_memory_risk",F*H,K*X);if(B.items){let q=Array.isArray(B.items)?B.items:[B.items];for(let W of q)if(U(W))Z(W,K+1)}return}if(j==="object"&&B.properties){for(let X of Object.values(B.properties))if(U(X))Z(X,K+1)}}Z(Q,0)}function P(Q,$){if(Q.type==="array"){if(Q.maxItems&&Q.maxItems>w)throw new L("array_max_items",w,Q.maxItems);let Z=O(Q),B=Q.maxItems||Q.minItems||b;if(Z>F&&B>H)throw new L("memory_estimation",F*H,Z*B)}if(Q.type==="object"&&Q.properties){for(let[Z,B]of Object.entries(Q.properties))if(U(B))P(B,`${$}.properties.${Z}`)}if(Q.type==="array"&&Q.items){if(Array.isArray(Q.items))Q.items.forEach((Z,B)=>{if(U(Z))P(Z,`${$}.items[${B}]`)});else if(U(Q.items))P(Q.items,`${$}.items`)}}function y(Q){let $=Q.split(".");if($.length<2)throw new V("$.faker",`Invalid faker method format: "${Q}"`,"Use format like 'person.firstName' or 'internet.email'");if(!f)f=x();let B=f;for(let K of $)if(B&&typeof B==="object"&&K in B)B=B[K];else throw new V("$.faker",`Invalid faker method: "${Q}"`,"Check faker.js documentation for valid methods");if(typeof B!=="function")throw new V("$.faker",`Invalid faker method: "${Q}" is not a function`,"Check faker.js documentation for valid methods")}function Y(Q){if(!Q||typeof Q!=="object")return Q;let $={...Q};if($.properties){$.properties={...$.properties};for(let[Z,B]of Object.entries($.properties))if(U(B))$.properties[Z]=O0(Z,B)}for(let Z of["allOf","anyOf","oneOf"]){let B=$[Z];if(Array.isArray(B))$[Z]=B.map((K)=>U(K)?Y(K):K)}if($.items){if(Array.isArray($.items))$.items=$.items.map((Z)=>U(Z)?Y(Z):Z);else if(U($.items))$.items=Y($.items)}if($.additionalProperties&&typeof $.additionalProperties==="object"&&!Array.isArray($.additionalProperties))$.additionalProperties=Y($.additionalProperties);return $}function O0(Q,$){let Z={...$};if(Z.faker){if(typeof Z.faker==="string")y(Z.faker);return Z}let B=Z.allOf||Z.anyOf||Z.oneOf;if(Z.properties||B||Z.items){let j=Y(Z);Object.assign(Z,j)}if(B)return Z;if(Z.const!==void 0||Z.enum)return Z;let K=i(Q,Z);if(K){let{fakerMethod:j,format:z,trueProbability:X,fakerArgs:q}=K.mapping;if(q)Z.faker={[j]:[q]};else Z.faker=j;if(z)Z.format=z;if(X!==void 0)Z.schmockTrueProbability=X}return Z}function a0(Q){return C(Q.schema),{name:"faker",version:E,async process($,Z){if(Z!==void 0&&Z!==null)return{context:$,response:Z};try{let B=await D0({schema:Q.schema,count:Q.count,overrides:Q.overrides,params:$.params,state:$.routeState,query:$.query,seed:Q.seed});return{context:$,response:B}}catch(B){if(B instanceof n||B instanceof o)throw B;throw new v0($.path,B instanceof Error?B:Error(String(B)),Q.schema)}}}}async function D0(Q){let{schema:$,count:Z,overrides:B,params:K,state:j,query:z,seed:X}=Q;if(C($),$.type==="array"&&$.items){let I=S($,Z);if(I>w)throw new o("array_size",w,I);let D=Array.isArray($.items)?$.items[0]:$.items;if(!D||typeof D==="boolean")throw new n("$.items","Array schema must have valid items definition");let N=Y(D),A=[];for(let T=0;T<I;T++){let G=await _(N,X);G=v(G,N),G=J(G,B,K,j,z),A.push(G)}return A}let q=Y($),W=await _(q,X);return W=v(W,q),W=J(W,B,K,j,z),W}function v(Q,$){if(Q===null||Q===void 0||!$||typeof $!=="object")return Q;let Z=$;if(Z.schmockNullable===!0){if(Math.random()<k)return null}if($.type==="boolean"&&typeof Z.schmockTrueProbability==="number")return Math.random()<Z.schmockTrueProbability;if(typeof Q==="object"&&!Array.isArray(Q)&&$.properties){let B=Q;for(let[K,j]of Object.entries($.properties))if(K in B&&U(j))B[K]=v(B[K],j)}if(Array.isArray(Q)&&$.items&&U($.items))for(let B=0;B<Q.length;B++)Q[B]=v(Q[B],$.items);return Q}export{D0 as generateFromSchema,a0 as fakerPlugin};
|
package/dist/jsf-config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsf-config.d.ts","sourceRoot":"","sources":["../src/jsf-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"jsf-config.d.ts","sourceRoot":"","sources":["../src/jsf-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO/C;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,CAAC,EAAE,MAAM,SAMhD;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,WAAW,EACnB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC,CAoBlB"}
|
package/dist/jsf-config.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { base, en, Faker } from "@faker-js/faker";
|
|
2
|
-
import { generate } from "json-schema-faker";
|
|
2
|
+
import { generate, } from "json-schema-faker";
|
|
3
3
|
/**
|
|
4
4
|
* Create isolated faker instance to avoid race conditions.
|
|
5
5
|
* Each generation gets its own faker instance to ensure thread-safety.
|
|
@@ -19,7 +19,10 @@ export async function generateWithJsf(schema, seed) {
|
|
|
19
19
|
// When no seed is specified, generate a random seed to ensure different
|
|
20
20
|
// results on each call. JSF 0.6.0 treats seed=undefined as deterministic.
|
|
21
21
|
const effectiveSeed = seed ?? Math.floor(Math.random() * 2147483647);
|
|
22
|
-
return generate(
|
|
22
|
+
return generate(
|
|
23
|
+
// JSONSchema7.items allows arrays but JsonSchema.items does not — structural
|
|
24
|
+
// mismatch requires routing through `unknown`.
|
|
25
|
+
schema, {
|
|
23
26
|
seed: effectiveSeed,
|
|
24
27
|
optionalsProbability: 1.0,
|
|
25
28
|
alwaysFakeOptionals: true,
|
|
@@ -40,9 +40,13 @@ export function enhanceSchemaWithSmartMapping(schema) {
|
|
|
40
40
|
}
|
|
41
41
|
function enhanceFieldSchema(fieldName, fieldSchema) {
|
|
42
42
|
const enhanced = { ...fieldSchema };
|
|
43
|
-
// If already has faker extension, validate it and don't override
|
|
43
|
+
// If already has faker extension, validate it and don't override.
|
|
44
|
+
// User-supplied faker values are always strings; the object form is only
|
|
45
|
+
// produced internally by this function when fakerArgs are present.
|
|
44
46
|
if (enhanced.faker) {
|
|
45
|
-
|
|
47
|
+
if (typeof enhanced.faker === "string") {
|
|
48
|
+
validateFakerMethod(enhanced.faker);
|
|
49
|
+
}
|
|
46
50
|
return enhanced;
|
|
47
51
|
}
|
|
48
52
|
// Recursively enhance nested schemas first
|
|
@@ -62,12 +66,23 @@ function enhanceFieldSchema(fieldName, fieldSchema) {
|
|
|
62
66
|
// Apply smart field name mapping via the scoring matcher
|
|
63
67
|
const match = findBestMapping(fieldName, enhanced);
|
|
64
68
|
if (match) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
const { fakerMethod, format, trueProbability, fakerArgs } = match.mapping;
|
|
70
|
+
// Use the JSF object form when fakerArgs are present so the options object
|
|
71
|
+
// is forwarded to the faker method (e.g. number.int({ min, max })).
|
|
72
|
+
// JSF calls Q(...J) where J is the value, so we must wrap fakerArgs in an
|
|
73
|
+
// array: { "number.int": [{ min, max }] } → faker.number.int({ min, max }).
|
|
74
|
+
// Fall back to the plain string form when there are no args.
|
|
75
|
+
if (fakerArgs) {
|
|
76
|
+
enhanced.faker = { [fakerMethod]: [fakerArgs] };
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
enhanced.faker = fakerMethod;
|
|
80
|
+
}
|
|
81
|
+
if (format) {
|
|
82
|
+
enhanced.format = format;
|
|
68
83
|
}
|
|
69
|
-
if (
|
|
70
|
-
enhanced.schmockTrueProbability =
|
|
84
|
+
if (trueProbability !== undefined) {
|
|
85
|
+
enhanced.schmockTrueProbability = trueProbability;
|
|
71
86
|
}
|
|
72
87
|
}
|
|
73
88
|
return enhanced;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schmock/faker",
|
|
3
3
|
"description": "Faker-powered automatic data generation for Schmock",
|
|
4
|
-
"version": "2.1
|
|
4
|
+
"version": "2.2.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"json-schema-faker": "^0.6.1"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@schmock/core": "^2.1
|
|
37
|
+
"@schmock/core": "^2.2.1"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@amiceli/vitest-cucumber": "^6.5.0",
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { JSONSchema7 } from "json-schema";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { generateFromSchema } from "./index";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Regression tests for fakerArgs threading in field-mappings.
|
|
7
|
+
*
|
|
8
|
+
* Bug (4.5): enhanceFieldSchema read only fakerMethod/format/trueProbability
|
|
9
|
+
* from a matched mapping — it never forwarded fakerArgs — so numeric bounds
|
|
10
|
+
* defined in field-mappings.ts (e.g. age → {min:18, max:80}) were silently
|
|
11
|
+
* ignored and faker fell back to its own defaults (potentially a very wide
|
|
12
|
+
* range).
|
|
13
|
+
*
|
|
14
|
+
* Fix: when a matched mapping has fakerArgs, set
|
|
15
|
+
* enhanced.faker = { [fakerMethod]: fakerArgs }
|
|
16
|
+
* (the json-schema-faker object-form extension), so JSF passes the options
|
|
17
|
+
* object to faker's method. If the object form does not honour the bounds
|
|
18
|
+
* in the current JSF/faker setup, fall back to also stamping minimum/maximum
|
|
19
|
+
* onto the schema so numeric constraints are applied at the schema level.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
describe("fakerArgs on field mappings are honoured (fix 4.5)", () => {
|
|
23
|
+
it("generates age values always within [18, 80] across 50 samples", async () => {
|
|
24
|
+
const schema: JSONSchema7 = {
|
|
25
|
+
type: "object",
|
|
26
|
+
properties: {
|
|
27
|
+
age: { type: "integer" },
|
|
28
|
+
},
|
|
29
|
+
required: ["age"],
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const outOfRange: number[] = [];
|
|
33
|
+
|
|
34
|
+
for (let i = 0; i < 50; i++) {
|
|
35
|
+
const result = (await generateFromSchema({ schema })) as Record<
|
|
36
|
+
string,
|
|
37
|
+
unknown
|
|
38
|
+
>;
|
|
39
|
+
const age = result.age as number;
|
|
40
|
+
if (age < 18 || age > 80) {
|
|
41
|
+
outOfRange.push(age);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
expect(outOfRange).toEqual([]);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("generates rating values always within [1, 5] across 50 samples", async () => {
|
|
49
|
+
const schema: JSONSchema7 = {
|
|
50
|
+
type: "object",
|
|
51
|
+
properties: {
|
|
52
|
+
rating: { type: "integer" },
|
|
53
|
+
},
|
|
54
|
+
required: ["rating"],
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const outOfRange: number[] = [];
|
|
58
|
+
|
|
59
|
+
for (let i = 0; i < 50; i++) {
|
|
60
|
+
const result = (await generateFromSchema({ schema })) as Record<
|
|
61
|
+
string,
|
|
62
|
+
unknown
|
|
63
|
+
>;
|
|
64
|
+
const rating = result.rating as number;
|
|
65
|
+
if (rating < 1 || rating > 5) {
|
|
66
|
+
outOfRange.push(rating);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
expect(outOfRange).toEqual([]);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("generates count values always within [1, 100] across 50 samples", async () => {
|
|
74
|
+
const schema: JSONSchema7 = {
|
|
75
|
+
type: "object",
|
|
76
|
+
properties: {
|
|
77
|
+
count: { type: "integer" },
|
|
78
|
+
},
|
|
79
|
+
required: ["count"],
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const outOfRange: number[] = [];
|
|
83
|
+
|
|
84
|
+
for (let i = 0; i < 50; i++) {
|
|
85
|
+
const result = (await generateFromSchema({ schema })) as Record<
|
|
86
|
+
string,
|
|
87
|
+
unknown
|
|
88
|
+
>;
|
|
89
|
+
const count = result.count as number;
|
|
90
|
+
if (count < 1 || count > 100) {
|
|
91
|
+
outOfRange.push(count);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
expect(outOfRange).toEqual([]);
|
|
96
|
+
});
|
|
97
|
+
});
|
package/src/jsf-config.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { base, en, Faker } from "@faker-js/faker";
|
|
2
2
|
import type { JSONSchema7 } from "json-schema";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
type GenerateOptions,
|
|
5
|
+
generate,
|
|
6
|
+
type JsonSchema,
|
|
7
|
+
} from "json-schema-faker";
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* Create isolated faker instance to avoid race conditions.
|
|
@@ -27,7 +31,9 @@ export async function generateWithJsf(
|
|
|
27
31
|
const effectiveSeed = seed ?? Math.floor(Math.random() * 2147483647);
|
|
28
32
|
|
|
29
33
|
return generate(
|
|
30
|
-
|
|
34
|
+
// JSONSchema7.items allows arrays but JsonSchema.items does not — structural
|
|
35
|
+
// mismatch requires routing through `unknown`.
|
|
36
|
+
schema as unknown as JsonSchema,
|
|
31
37
|
{
|
|
32
38
|
seed: effectiveSeed,
|
|
33
39
|
optionalsProbability: 1.0,
|
|
@@ -37,6 +43,6 @@ export async function generateWithJsf(
|
|
|
37
43
|
failOnInvalidTypes: false,
|
|
38
44
|
failOnInvalidFormat: false,
|
|
39
45
|
extensions: { faker: createFakerInstance(seed) },
|
|
40
|
-
} as
|
|
46
|
+
} as GenerateOptions & Record<string, unknown>,
|
|
41
47
|
);
|
|
42
48
|
}
|
|
@@ -4,7 +4,7 @@ import { isJSONSchema7, validateFakerMethod } from "./validation.js";
|
|
|
4
4
|
|
|
5
5
|
/** JSONSchema7 extended with json-schema-faker's `faker` property and schmock markers */
|
|
6
6
|
interface FakerSchema extends JSONSchema7 {
|
|
7
|
-
faker?: string
|
|
7
|
+
faker?: string | Record<string, unknown>;
|
|
8
8
|
schmockNullable?: boolean;
|
|
9
9
|
schmockTrueProbability?: number;
|
|
10
10
|
}
|
|
@@ -75,9 +75,13 @@ function enhanceFieldSchema(
|
|
|
75
75
|
): FakerSchema {
|
|
76
76
|
const enhanced: FakerSchema = { ...fieldSchema };
|
|
77
77
|
|
|
78
|
-
// If already has faker extension, validate it and don't override
|
|
78
|
+
// If already has faker extension, validate it and don't override.
|
|
79
|
+
// User-supplied faker values are always strings; the object form is only
|
|
80
|
+
// produced internally by this function when fakerArgs are present.
|
|
79
81
|
if (enhanced.faker) {
|
|
80
|
-
|
|
82
|
+
if (typeof enhanced.faker === "string") {
|
|
83
|
+
validateFakerMethod(enhanced.faker);
|
|
84
|
+
}
|
|
81
85
|
return enhanced;
|
|
82
86
|
}
|
|
83
87
|
|
|
@@ -101,12 +105,22 @@ function enhanceFieldSchema(
|
|
|
101
105
|
// Apply smart field name mapping via the scoring matcher
|
|
102
106
|
const match = findBestMapping(fieldName, enhanced);
|
|
103
107
|
if (match) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
const { fakerMethod, format, trueProbability, fakerArgs } = match.mapping;
|
|
109
|
+
// Use the JSF object form when fakerArgs are present so the options object
|
|
110
|
+
// is forwarded to the faker method (e.g. number.int({ min, max })).
|
|
111
|
+
// JSF calls Q(...J) where J is the value, so we must wrap fakerArgs in an
|
|
112
|
+
// array: { "number.int": [{ min, max }] } → faker.number.int({ min, max }).
|
|
113
|
+
// Fall back to the plain string form when there are no args.
|
|
114
|
+
if (fakerArgs) {
|
|
115
|
+
enhanced.faker = { [fakerMethod]: [fakerArgs] };
|
|
116
|
+
} else {
|
|
117
|
+
enhanced.faker = fakerMethod;
|
|
118
|
+
}
|
|
119
|
+
if (format) {
|
|
120
|
+
enhanced.format = format;
|
|
107
121
|
}
|
|
108
|
-
if (
|
|
109
|
-
enhanced.schmockTrueProbability =
|
|
122
|
+
if (trueProbability !== undefined) {
|
|
123
|
+
enhanced.schmockTrueProbability = trueProbability;
|
|
110
124
|
}
|
|
111
125
|
}
|
|
112
126
|
|
package/src/constants.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export declare const MAX_ARRAY_SIZE = 10000;
|
|
2
|
-
export declare const MAX_NESTING_DEPTH = 10;
|
|
3
|
-
export declare const DEFAULT_ARRAY_COUNT = 3;
|
|
4
|
-
export declare const DEEP_NESTING_THRESHOLD = 3;
|
|
5
|
-
export declare const LARGE_ARRAY_THRESHOLD = 100;
|
|
6
|
-
//# sourceMappingURL=constants.d.ts.map
|
package/src/index.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { JSONSchema7 } from "json-schema";
|
|
2
|
-
export interface SchemaGenerationContext {
|
|
3
|
-
schema: JSONSchema7;
|
|
4
|
-
count?: number;
|
|
5
|
-
overrides?: Record<string, any>;
|
|
6
|
-
params?: Record<string, string>;
|
|
7
|
-
state?: any;
|
|
8
|
-
query?: Record<string, string>;
|
|
9
|
-
seed?: number;
|
|
10
|
-
}
|
|
11
|
-
export interface FakerPluginOptions {
|
|
12
|
-
schema: JSONSchema7;
|
|
13
|
-
count?: number;
|
|
14
|
-
overrides?: Record<string, any>;
|
|
15
|
-
seed?: number;
|
|
16
|
-
}
|
|
17
|
-
export declare function fakerPlugin(options: FakerPluginOptions): Schmock.Plugin;
|
|
18
|
-
export declare function generateFromSchema(options: SchemaGenerationContext): any;
|
|
19
|
-
//# sourceMappingURL=index.d.ts.map
|
package/src/jsf-config.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Faker } from "@faker-js/faker";
|
|
2
|
-
import jsf from "json-schema-faker";
|
|
3
|
-
/**
|
|
4
|
-
* Create isolated faker instance to avoid race conditions
|
|
5
|
-
* Each generation gets its own faker instance to ensure thread-safety
|
|
6
|
-
* @returns Fresh Faker instance with English locale
|
|
7
|
-
*/
|
|
8
|
-
export declare function createFakerInstance(seed?: number): Faker;
|
|
9
|
-
export declare function getJsf(seed?: number): typeof jsf;
|
|
10
|
-
//# sourceMappingURL=jsf-config.d.ts.map
|
package/src/overrides.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { JSONSchema7 } from "json-schema";
|
|
2
|
-
/**
|
|
3
|
-
* Determine number of items to generate for array schema
|
|
4
|
-
* Prefers explicit count, then schema minItems/maxItems, with sane defaults
|
|
5
|
-
* @param schema - Array schema with optional minItems/maxItems
|
|
6
|
-
* @param explicitCount - Explicit count override from plugin options
|
|
7
|
-
* @returns Number of array items to generate
|
|
8
|
-
*/
|
|
9
|
-
export declare function determineArrayCount(schema: JSONSchema7, explicitCount?: number, random?: () => number): number;
|
|
10
|
-
/**
|
|
11
|
-
* Apply overrides to generated data with support for templates
|
|
12
|
-
* Supports nested paths (dot notation), templates with {{params.id}}, and state access
|
|
13
|
-
* @param data - Generated data to apply overrides to
|
|
14
|
-
* @param overrides - Override values (can use templates)
|
|
15
|
-
* @param params - Route parameters for template expansion
|
|
16
|
-
* @param state - Plugin state for template expansion
|
|
17
|
-
* @param query - Query parameters for template expansion
|
|
18
|
-
* @returns Data with overrides applied
|
|
19
|
-
*/
|
|
20
|
-
export declare function applyOverrides(data: any, overrides?: Record<string, any>, params?: Record<string, string>, state?: any, query?: Record<string, string>): any;
|
|
21
|
-
//# sourceMappingURL=overrides.d.ts.map
|
package/src/validation.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { JSONSchema7 } from "json-schema";
|
|
2
|
-
export declare function isJSONSchema7(value: unknown): value is JSONSchema7;
|
|
3
|
-
/**
|
|
4
|
-
* Validate JSON Schema structure and enforce resource limits
|
|
5
|
-
* Checks for malformed schemas, circular references, excessive nesting,
|
|
6
|
-
* and dangerous patterns that could cause memory issues
|
|
7
|
-
* @param schema - JSON Schema to validate
|
|
8
|
-
* @param path - Current path in schema tree (for error messages)
|
|
9
|
-
* @throws {SchemaValidationError} When schema structure is invalid
|
|
10
|
-
* @throws {ResourceLimitError} When schema exceeds safety limits
|
|
11
|
-
*/
|
|
12
|
-
export declare function validateSchema(schema: JSONSchema7, path?: string): void;
|
|
13
|
-
/**
|
|
14
|
-
* Validate that faker method string references a valid Faker.js API
|
|
15
|
-
* Checks format (namespace.method) and validates against known namespaces
|
|
16
|
-
* @param fakerMethod - Faker method string (e.g., "person.fullName")
|
|
17
|
-
* @throws {SchemaValidationError} When faker method format or namespace is invalid
|
|
18
|
-
*/
|
|
19
|
-
export declare function validateFakerMethod(fakerMethod: string): void;
|
|
20
|
-
//# sourceMappingURL=validation.d.ts.map
|