fakelab 0.0.10 → 0.0.11
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/lib/cli.js +1 -1
- package/lib/main.d.ts +3 -1
- package/lib/main.js +2 -2
- package/package.json +1 -1
package/lib/cli.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import P from'path';import {fileURLToPath}from'url';import M from'fs-extra';import m from'zod';import {Command}from'commander';import k from'express';import J from'cors';import K from'express-ejs-layouts';import q from'http';import'ejs';import $ from'qs';import {Project}from'ts-morph';import {v4}from'uuid';import u from'picocolors';import Q from'figlet';import {bundleRequire}from'bundle-require';import ee from'joycon';var c=class o{static prefix(e){let r=new Date().toLocaleTimeString();return {info:u.blue,warn:u.yellow,error:u.red,success:u.green,debug:u.magenta}[e](`[${r}] FAKELAB_${e.toUpperCase()}`)}static log(e,r,...n){let t=u.white,s=o.prefix(e);(e==="error"?console.error:e==="warn"?console.warn:console.log)(s,t(r),...n);}static info(e,...r){this.log("info",e,...r);}static warn(e,...r){this.log("warn",e,...r);}static error(e,...r){this.log("error",e,...r);}static success(e,...r){this.log("success",e,...r);}};var y=class{constructor(e){this.faker=e;}JSDOC_FAKER_FIELD="faker";FAKER_TAG_REGEX=/^([a-zA-Z0-9._]+)(?:\((.*)\))?$/;boolMapping={true:true,false:false};string(e){return this.execute(e,this.faker.word.noun)}int(e){return this.execute(e,this.faker.number.int)}bool(e){return this.execute(e,this.faker.datatype.boolean)}bigInt(e){return this.execute(e,this.faker.number.bigInt)}litbool(e){return this.boolMapping[e]}async object(e,r){let n={};return await Promise.all(e.map(async t=>{let s=t.getTypeAtLocation(t.getValueDeclarationOrThrow());n[t.getName()]=await r(s,this,this.readJSDocTags(t));})),n}async union(e){let r=await Promise.all(e);return r[Math.floor(Math.random()*r.length)]}async intersection(e){let r=await Promise.all(e);return r[Math.floor(Math.random()*r.length)]}evalArgs(e){if(!(!e||!e.trim()))return Function(`"use strict"; return (${e});`)()}readJSDocTags(e){let r=e.getJsDocTags().filter(n=>n.getName()===this.JSDOC_FAKER_FIELD);return r.length===0?[]:r.map(n=>{let[t]=n.getText();if(!t)return;let s=t.text.trim().match(this.FAKER_TAG_REGEX);if(!s)return;let[,i,a]=s,p=this.evalArgs(a);return {path:i,args:p}})}execute(e,r){if(!e)return r();let n=e.path.split("."),t=this.faker;for(let s of n)t=t[s],t||(c.error("Invalid faker module path:",e.path),process.exit(1));typeof t!="function"&&(c.error("Unresolvable faker function.",e.path),process.exit(1));try{return e.args?t(e.args):t()}catch{return c.error("Passed invalid arguments to faker function."),t()}}};var d=class{constructor(e){this.files=e;let n=new Project({tsConfigFilePath:"tsconfig.json"}).addSourceFilesAtPaths(e);this.__targets=n.flatMap(t=>{let s=t.getInterfaces(),i=t.getTypeAliases(),a=t.getExportDeclarations().flatMap(p=>p.getNamedExports().flatMap(f=>f.getLocalTargetDeclarations()));return [...s,...i,...a]});}__targets;async run(e){return await e()}normalizePath(e){return e.split(P.sep).join(P.posix.sep)}entities(){let e=this.__targets.map(r=>{let n=r.getName().toLowerCase(),t=r.getType(),s=this.normalizePath(process.cwd()),a=this.normalizePath(r.getSourceFile().getDirectoryPath()).replace(s,""),p=r.getSourceFile().getBaseName(),f=`${a}/${p}`;return [n,{type:t,filepath:f}]});return new Map(e)}async loadFaker(e
|
|
1
|
+
import P from'path';import {fileURLToPath}from'url';import M from'fs-extra';import m from'zod';import {Command}from'commander';import k from'express';import J from'cors';import K from'express-ejs-layouts';import q from'http';import'ejs';import $ from'qs';import {Project}from'ts-morph';import {v4}from'uuid';import u from'picocolors';import Q from'figlet';import {bundleRequire}from'bundle-require';import ee from'joycon';var c=class o{static prefix(e){let r=new Date().toLocaleTimeString();return {info:u.blue,warn:u.yellow,error:u.red,success:u.green,debug:u.magenta}[e](`[${r}] FAKELAB_${e.toUpperCase()}`)}static log(e,r,...n){let t=u.white,s=o.prefix(e);(e==="error"?console.error:e==="warn"?console.warn:console.log)(s,t(r),...n);}static info(e,...r){this.log("info",e,...r);}static warn(e,...r){this.log("warn",e,...r);}static error(e,...r){this.log("error",e,...r);}static success(e,...r){this.log("success",e,...r);}};var y=class{constructor(e){this.faker=e;}JSDOC_FAKER_FIELD="faker";FAKER_TAG_REGEX=/^([a-zA-Z0-9._]+)(?:\((.*)\))?$/;boolMapping={true:true,false:false};string(e){return this.execute(e,this.faker.word.noun)}int(e){return this.execute(e,this.faker.number.int)}bool(e){return this.execute(e,this.faker.datatype.boolean)}bigInt(e){return this.execute(e,this.faker.number.bigInt)}litbool(e){return this.boolMapping[e]}async object(e,r){let n={};return await Promise.all(e.map(async t=>{let s=t.getTypeAtLocation(t.getValueDeclarationOrThrow());n[t.getName()]=await r(s,this,this.readJSDocTags(t));})),n}async union(e){let r=await Promise.all(e);return r[Math.floor(Math.random()*r.length)]}async intersection(e){let r=await Promise.all(e);return r[Math.floor(Math.random()*r.length)]}evalArgs(e){if(!(!e||!e.trim()))return Function(`"use strict"; return (${e});`)()}readJSDocTags(e){let r=e.getJsDocTags().filter(n=>n.getName()===this.JSDOC_FAKER_FIELD);return r.length===0?[]:r.map(n=>{let[t]=n.getText();if(!t)return;let s=t.text.trim().match(this.FAKER_TAG_REGEX);if(!s)return;let[,i,a]=s,p=this.evalArgs(a);return {path:i,args:p}})}execute(e,r){if(!e)return r();let n=e.path.split("."),t=this.faker;for(let s of n)t=t[s],t||(c.error("Invalid faker module path:",e.path),process.exit(1));typeof t!="function"&&(c.error("Unresolvable faker function.",e.path),process.exit(1));try{return e.args?t(e.args):t()}catch{return c.error("Passed invalid arguments to faker function."),t()}}};var d=class{constructor(e){this.files=e;let n=new Project({tsConfigFilePath:"tsconfig.json"}).addSourceFilesAtPaths(e);this.__targets=n.flatMap(t=>{let s=t.getInterfaces(),i=t.getTypeAliases(),a=t.getExportDeclarations().flatMap(p=>p.getNamedExports().flatMap(f=>f.getLocalTargetDeclarations()));return [...s,...i,...a]});}__targets;async run(e){return await e()}normalizePath(e){return e.split(P.sep).join(P.posix.sep)}entities(){let e=this.__targets.map(r=>{let n=r.getName().toLowerCase(),t=r.getType(),s=this.normalizePath(process.cwd()),a=this.normalizePath(r.getSourceFile().getDirectoryPath()).replace(s,""),p=r.getSourceFile().getBaseName(),f=`${a}/${p}`;return [n,{type:t,filepath:f}]});return new Map(e)}async loadFaker(e){let{faker:r}=await import(`@faker-js/faker/locale/${e.locale}`);return r}};async function l(o,e,r=[],n=0){if(o.isString())return e.string(r[n]);if(o.isNumber())return e.int(r[n]);if(o.isBoolean())return e.bool(r[n]);if(o.isBigInt())return e.bigInt(r[n]);if(o.isBooleanLiteral())return e.litbool(o.getText());if(o.isLiteral())return o.getLiteralValue();if(!o.isUndefined()){if(o.isUnion()){let t=o.getUnionTypes();return await e.union(t.map((s,i)=>l(s,e,r,i)))}if(o.isIntersection()){let t=o.getIntersectionTypes();return await e.intersection(t.map((s,i)=>l(s,e,r,i)))}if(o.isArray()){let t=o.getArrayElementTypeOrThrow();return [await l(t,e,r,n)]}if(o.isObject()){let t=o.getProperties();return await e.object(t,(s,i,a)=>l(s,i,a,n))}return null}}function D({each:o}){return {resolve:async r=>await Promise.all(Array.from({length:r},(n,t)=>o(t)))}}function R(o,e){return o==="uuid"?v4():e+1}function N(o,e,r){return async n=>{let t=await l(o,e);return r.uid&&typeof t=="object"?{[r.uid]:R(r.strategy,n),...t}:t}}async function L(o,e){let r=await o.files(e.source),n=new d(r),t=await n.loadFaker(o.fakerOpts(e.locale)),s=new y(t),i=n.entities();async function a(p,f){let g=D({each:N(p,s,f)}),h=await(f.count?g.resolve(parseInt(f.count)):l(p,s)),x=JSON.stringify(h,null,2);return {data:h,json:x}}return {entities:i,forge:a}}var U=fileURLToPath(import.meta.url),B=P.dirname(U),A=M.readJSONSync(P.join(B,"../package.json")),v=class{constructor(e,r,n){this.router=e;this.config=r;this.opts=n;let{pathPrefix:t}=this.config.serverOpts(this.opts.pathPrefix);this.prefix=t;}prefix;get querySchema(){return m.object({count:m.string().optional(),uid:m.string().optional(),strategy:m.string().optional()})}async handleQueries(e){let{success:r,data:n,error:t}=await this.querySchema.safeParseAsync(e.query);return r?n:(c.warn(t.message),{})}async register(){let{entities:e,forge:r}=await L(this.config,this.opts);this.router.get("/",(n,t)=>{let s=n.path;t.render("index",{currentPath:s,entities:e,version:A.version});}),this.router.get("/:name",async(n,t)=>{let s=`${n.protocol}://${n.host}/`,i=n.path,a=n.params.name,p=await this.handleQueries(n),f=$.stringify(p,{addQueryPrefix:true}),g=e.get(a.toLowerCase());if(g){let{json:h}=await r(g.type,p),x=g.filepath;t.render("preview",{name:a,filepath:x,currentPath:i,address:s,search:f,json:h,entities:e,version:A.version,prefix:this.prefix});}else t.redirect("/");}),this.router.get(`/${this.prefix}/:name`,async(n,t)=>{try{let s=n.params.name,i=await this.handleQueries(n),a=e.get(s.toLowerCase());if(a){let{data:p}=await r(a.type,i);t.status(200).json(p);}else t.status(400).json({message:"The requested interface is not found"});}catch(s){t.status(500).send(s);}});}};var V=fileURLToPath(import.meta.url),C=P.dirname(V);function X(o,e,r){let{port:n}=e.serverOpts(r.pathPrefix,r.port);o.listen(n,"localhost",async()=>{c.info(`Server: http://localhost:${n}`),console.log(await Q.text("FAKELAB"));});}function H(o,e,r){e.setHeader("x-powered-by","fakelab"),r();}function Z(o){o.disable("x-powered-by"),o.use(k.json()),o.use(J({methods:"GET"})),o.use(k.static(C+"/public")),o.use(H);}function W(o){o.set("views",P.join(C,"views")),o.set("view engine","ejs"),o.use(K),o.set("layout","layouts/main");}async function E(o,e){let r=k(),n=k.Router(),t=q.createServer(r);Z(r),W(r),await new v(n,o,e).register(),r.use(n),X(t,o,e);}async function _(){try{let e=await new ee().resolve({files:["fakelab.config.ts"]});return e||(c.error("No fakelab config file is detected."),process.exit(1)),(await bundleRequire({filepath:e})).mod.default}catch{c.error("Could not load the config file."),process.exit(1);}}var b=new Command,ne=fileURLToPath(import.meta.url),se=P.dirname(ne),T=M.readJSONSync(P.join(se,"../package.json"));b.name(T.name).description(T.description).version(T.version);var ie=m.object({source:m.string().optional(),pathPrefix:m.string().optional(),port:m.number().int().optional(),locale:m.string().optional()});b.command("serve").description("start server").option("-s, --source <char>","config source path").option("-x, --pathPrefix <char>","server url path prefix").option("-p, --port <number>","server port number",parseInt).option("-l, --locale <char>","faker custom locale").action(async o=>{let e=await ie.safeParseAsync(o);e.error&&(c.error(m.treeifyError(e.error).errors.join(`
|
|
2
2
|
`)),process.exit(1));let r=await _();E(r,e.data);});b.parse();
|
package/lib/main.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
declare const FAKER_LOCALES: readonly ["af", "ar", "az", "bn", "cs", "cy", "da", "de", "dv", "el", "en", "eo", "es", "fa", "fi", "fr", "he", "hr", "hu", "hy", "id", "it", "ja", "ka", "ko", "ku", "lv", "mk", "nb", "ne", "nl", "pl", "pt", "ro"];
|
|
2
|
+
type FakerLocale = (typeof FAKER_LOCALES)[number];
|
|
3
|
+
|
|
1
4
|
type ServerOptions = {
|
|
2
5
|
/**
|
|
3
6
|
* @default 5200
|
|
@@ -16,7 +19,6 @@ type ConfigOptions = {
|
|
|
16
19
|
server?: ServerOptions;
|
|
17
20
|
faker?: FakerEngineOptions;
|
|
18
21
|
};
|
|
19
|
-
type FakerLocale = "af" | "ar" | "az" | "bn" | "cs" | "cy" | "da" | "de" | "dv" | "el" | "en" | "eo" | "es" | "fa" | "fi" | "fr" | "he" | "hr" | "hu" | "hy" | "id" | "it" | "ja" | "ka" | "ko" | "ku" | "lv" | "mk" | "nb" | "ne" | "nl" | "pl" | "pt" | "ro";
|
|
20
22
|
|
|
21
23
|
declare class Config {
|
|
22
24
|
private readonly opts;
|
package/lib/main.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
1
|
+
import h from'fast-glob';import f from'path';import {stat,access,constants}from'fs/promises';import i from'picocolors';var s=class o{static prefix(t){let r=new Date().toLocaleTimeString();return {info:i.blue,warn:i.yellow,error:i.red,success:i.green,debug:i.magenta}[t](`[${r}] FAKELAB_${t.toUpperCase()}`)}static log(t,r,...e){let n=i.white,l=o.prefix(t);(t==="error"?console.error:t==="warn"?console.warn:console.log)(l,n(r),...e);}static info(t,...r){this.log("info",t,...r);}static warn(t,...r){this.log("warn",t,...r);}static error(t,...r){this.log("error",t,...r);}static success(t,...r){this.log("success",t,...r);}};var c=["af","ar","az","bn","cs","cy","da","de","dv","el","en","eo","es","fa","fi","fr","he","hr","hu","hy","id","it","ja","ka","ko","ku","lv","mk","nb","ne","nl","pl","pt","ro"];function p(){let o=Intl.DateTimeFormat().resolvedOptions().locale;if(!o)return "en";let[t]=o.split("-"),r=t.toLowerCase();return c.includes(r)?r:"en"}var a=class{constructor(t){this.opts=t;this.files=this.files.bind(this),this.serverOpts=this.serverOpts.bind(this),this.fakerOpts=this.fakerOpts.bind(this);}async files(t){let r=this.resolveSourcePath(t||this.opts.sourcePath),e=Array.from(new Set((await Promise.all(r.map(n=>this.resolveTSFiles(n)))).flat()));return e.length===0&&(s.error(`No Typescript files found in:
|
|
2
2
|
%s`,r.join(`
|
|
3
|
-
`)),process.exit(1)),e}serverOpts(t,r){return {pathPrefix:t||this.opts.server?.pathPrefix||"api",port:r||this.opts.server?.port||5200}}fakerOpts(t){
|
|
3
|
+
`)),process.exit(1)),e}serverOpts(t,r){return {pathPrefix:t||this.opts.server?.pathPrefix||"api",port:r||this.opts.server?.port||5200}}fakerOpts(t){let r=(t||this.opts.faker?.locale)?.toLowerCase();return r&&c.includes(r)?{locale:r}:{locale:p()}}async tryStat(t){try{return await stat(t)}catch{return null}}async isReadable(t){try{return await access(t,constants.R_OK),!0}catch{return false}}resolveSourcePath(t){return (Array.isArray(t)?t:[t]).map(e=>f.resolve(e))}async resolveTSFiles(t){let r=f.resolve(t),e=r.endsWith(".ts")?r:r+".ts";if((await this.tryStat(e))?.isFile()){if(!await this.isReadable(e))throw new Error(`Cannot read file: ${e}`);return s.info("Source:",e),[e]}if((await this.tryStat(r))?.isDirectory())return s.info("Source:",r),h("**/*.ts",{cwd:r,absolute:true,ignore:["**/*.d.ts"]});s.error(`Invalid source path: ${t}`),process.exit(1);}};function d(o){return new a(o)}export{d as defineConfig};
|