@miso.ai/doggoganger 0.9.0 → 0.9.1-beta.10

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/cli/index.js CHANGED
@@ -4,7 +4,7 @@ import { dirname, resolve, join } from 'path';
4
4
  import nodemon from 'nodemon';
5
5
  import yargs from 'yargs/yargs';
6
6
  import { hideBin } from 'yargs/helpers';
7
- import doggoganger from '../src/index.js';
7
+ import { doggoganger } from '../src/index.js';
8
8
 
9
9
  const __dirname = dirname(fileURLToPath(import.meta.url));
10
10
  const SRC_DIR = join(__dirname, '../src');
package/cli/server.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import doggoganger from '../src/index.js';
2
+ import { doggoganger } from '../src/index.js';
3
3
 
4
4
  doggoganger(JSON.parse(process.argv[2]));
@@ -1 +1 @@
1
- !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t="undefined"!=typeof globalThis?globalThis:t||self).doggoganger=n()}(this,(function(){"use strict";function t(t,n){return null!=n&&n>t?t+Math.floor(Math.random()*(n-t)):t}function n(){return Math.random().toString(36).substring(2,10)}function e(t){return`https://picsum.photos/seed/${Math.floor(1e3*Math.random())}/${Array.isArray(t)?t.length>1?`${t[0]}/${t[1]}`:""+t[0]:""+t}`}function r(t,n){return void 0!==n?Math.ceil(t*n):t}function o(){return 2*Math.random()-1}var s=["lorem","ipsum","dolor","sit","amet","consectetur","adipiscing","elit","curabitur","vel","hendrerit","libero","eleifend","blandit","nunc","ornare","odio","ut","orci","gravida","imperdiet","nullam","purus","lacinia","a","pretium","quis","congue","praesent","sagittis","laoreet","auctor","mauris","non","velit","eros","dictum","proin","accumsan","sapien","nec","massa","volutpat","venenatis","sed","eu","molestie","lacus","quisque","porttitor","ligula","dui","mollis","tempus","at","magna","vestibulum","turpis","ac","diam","tincidunt","id","condimentum","enim","sodales","in","hac","habitasse","platea","dictumst","aenean","neque","fusce","augue","leo","eget","semper","mattis","tortor","scelerisque","nulla","interdum","tellus","malesuada","rhoncus","porta","sem","aliquet","et","nam","suspendisse","potenti","vivamus","luctus","fringilla","erat","donec","justo","vehicula","ultricies","varius","ante","primis","faucibus","ultrices","posuere","cubilia","curae","etiam","cursus","aliquam","quam","dapibus","nisl","feugiat","egestas","class","aptent","taciti","sociosqu","ad","litora","torquent","per","conubia","nostra","inceptos","himenaeos","phasellus","nibh","pulvinar","vitae","urna","iaculis","lobortis","nisi","viverra","arcu","morbi","pellentesque","metus","commodo","ut","facilisis","felis","tristique","ullamcorper","placerat","aenean","convallis","sollicitudin","integer","rutrum","duis","est","etiam","bibendum","donec","pharetra","vulputate","maecenas","mi","fermentum","consequat","suscipit","aliquam","habitant","senectus","netus","fames","quisque","euismod","curabitur","lectus","elementum","tempor","risus","cras"];function i({decorates:n=[],output:e="string",size:r,min:o,max:i,...a}={}){let c=function(n=[5,10]){const e="number"==typeof n?n:t(...n);return function*(t){let n=0;for(let r of t){if(n++>=e)break;yield r}}}(r||[o,i])(function*({words:t=s,fixedStarts:n=0}={}){const e=t.length;for(let r=0;;r++)yield t[n>r?r:Math.floor(Math.random()*e)]}(a));for(const t of n)c=u(t)(c);return u(e)(c)}const a={string:function({separator:t=" "}={}){return n=>[...n].join(t)},array:function(){return t=>[...t]},title:function({}={}){return function*(t){for(let n of t)yield c(n)}},description:function({wordsPerSentence:t={avg:24,std:5,min:1},punctuation:n="."}={}){return function*(e){let r,o=0;for(let s of e)r&&(yield r),r=s,0===o&&(r=c(r),o=l(t)),0==--o&&(r+=n);r&&(r.endsWith(n)||(r+=n),yield r)}},multiline:function({wordsPerLine:t={avg:10,std:3,min:1}}={}){return n=>{let e=l(t),r="";for(let o of n)r&&(0==e--?(r+="\n",e=l(t)):r+=" "),r+=o;return r}}};function u(t){switch(typeof t){case"string":return a[t]();case"function":return t;case"object":if(Array.isArray(t)){const[n,e={}]=t;return a[n](e)}}throw Error("Unrecognized decorator/output form: "+t)}function c(t){return t[0].toUpperCase()+t.substring(1)}function l(t){if("number"==typeof t)return Math.round(n);let{avg:n,std:e,min:r,max:s}=t;void 0===e&&(e=n/4);let i=(o()+o()+o())*e+n;return void 0!==r&&(i=Math.max(r,i)),void 0!==s&&(i=Math.min(s,i)),Math.round(i)}const f="// module\nimport { a, b } from './module';\nimport * as module from './module';\nimport module from './module';\nexport default module;\nexport const a = 0;\nexport * from './module';\nexport * as module from './module';\n\n// variables\nlet a = 10;\nconst b = 20;\n\n// function declaration\nfunction sum(x, y) {\n return x + y;\n}\n\n// generator function\nfunction* iterator() {\n yield 0;\n yield 1;\n}\n\n// arrow function\nconst multiply = (x, y) => x * y;\n\n// class\nclass Person {\n constructor(name, age) {\n this.name = name;\n this.age = age;\n }\n\n greet() {\n console.log('Hello, my name is Miso.');\n }\n}\n\n// primitive\nconst str = 'Hello, world!';\nconst num = 10.99;\n\n// object\nconst person = new Person('John', 30);\nperson.greet();\n\n// object literal\nconst object = {\n name: 'John',\n [x]: 10,\n ...props,\n};\n\n// array literal\nconst arr = [1, 2, 3, 4, 5, ...props];\n\n// regexp literal\nconst regexp = /\\w+/g;\n\n// operators\nconst sum = a + b;\nconst product = a * b;\nconst negation = -a;\nconst max = a > b ? a : b;\n\n// flow control\nlet i = 9;\nfor (const n of arr) {\n if (n > i) {\n console.log(n);\n }\n i++;\n}\n\n// async/await\n(async () => {\n const result = await asyncFunction();\n})();\n\n// try/catch\ntry {\n} catch (e) {\n}\n\n// destructuring\nconst { name, age, ...rest } = person;\nconst [ x, y, ...rest ] = arr;\n\n// template literals\nconsole.log(`The sum of ${a} and ${b} is ${sum(a, b)}.`);";var d=Object.freeze({__proto__:null,javascript:function(){return f},js:function(){return f}});function p({features:n,blocks:r=[8,12],sampling:o=1}={}){let s=[];return[s,n]=function(t=[]){const n=new Set,e=[];for(const r of t)if(r.startsWith("lang-")){let t=r.slice(5);"javascript"===t&&(t="js"),n.add(t)}else e.push(r);return[[...n],e]}(n),function(t,n){const e=[];for(const r of t)1>n&&Math.random()>=n||e.push(r());return e}([()=>m({features:n}),()=>g({features:n}),...s.map((t=>()=>h({lang:t,features:n}))),...s.length?[]:[()=>h({features:n})],()=>g({features:n}),()=>function({columns:n=[2,4],rows:e=[2,8]}){n=t(...n),e=t(...e);const r=[...$({size:1},n-1),{size:[3,8]}],o=i({size:n,output:"array"}),s=r.map((()=>"---")),a=[o,s];for(let t=0;e-1>t;t++)a.push(r.map((({size:t})=>i({size:t}))));return a.map(x).join("\n")}({features:n}),()=>function({url:t,imageSize:n=[400,250],...r}={}){return t=t||e(n),`![${function({size:t=[1,3],content:n}={}){return n||i({size:t})}(r)}](${t})`}(),()=>g({features:n}),()=>"*-_".charAt(t(0,2)).repeat(t(3,6)),()=>m({features:n}),()=>g({features:n}),()=>w({features:n}),()=>g({features:n})],o).join("\n\n")}function m({level:n=[1,6],size:e=[1,8],content:r}){const o=r||i({size:e});return`${"#".repeat(t(...n))} ${o}`}function h({lang:n,content:e,size:r,fenceChar:o="`"}){return"random"===o&&(o="`~".charAt(t(0,1))),e=e||function({lang:t,size:n=[10,30]}){return t&&d[t]?d[t]():i({output:"multiline",size:n})}({lang:n,size:r}),`${o.repeat(3)}${n||""}\n${e}\n${o.repeat(3)}`}function g({size:t=[20,50]}){return i({size:t,decorates:["description",z()]})}const _=["ordered","bullet","task"];function w({features:n,type:e="random",count:r=[1,8],size:o=[5,15]}){r="number"==typeof r?r:t(...r);const s="random"===e?_[Math.floor(3*Math.random())]:e,i=[];for(;r>0;){const a=t(1,r);let u=g({features:n,size:o});a>1&&(u+="\n"+w({features:n,type:e,count:a-1,size:o})),i.push(M(s,u)),r-=a}return i.join("\n")}const y={"code-span":()=>["`","`"],"emphasis-1":()=>$(b(1),2),"emphasis-2":()=>$(b(2),2),"emphasis-3":()=>$(b(3),2),strikethrough:()=>["~","~"],link:({url:t="https://miso.ai"}={})=>["[",`](${t})`]};function b(n=[1,3]){return n="number"==typeof n?n:t(...n),"_*".charAt(t(0,1)).repeat(n)}const q=Object.keys(y),v=new Set(q);function z({features:n=q,size:e=[1,3],rest:r=[0,8]}={}){n=n.filter((t=>v.has(t)));const o=function(t){for(let n=t.length-1;n>0;n--){const e=Math.floor(Math.random()*(n+1));[t[n],t[e]]=[t[e],t[n]]}return t}([...n]);let s=o.length-1;const i=()=>"number"==typeof r?r:t(...r);return function*(r){let a,u,c=i();for(const l of r)if(u&&(yield u),0===c)if(a)u=`${l}${a}`,a=void 0,c=i();else{const[r,i]=y[0>s?n[t(0,n.length-1)]:o[s--]]();u=`${r}${l}`,a=i,c="number"==typeof e?e:t(...e)}else u=l,c--;u&&(yield void 0!==a?`${u}${a}`:u)}}function M(t,n){const[e,r]=n.split("\n",2),o=`${function(t,n="random"){switch(t){case"ordered":return"1.";case"bullet":return"-";case"task":return`- [${("random"===n?.5>Math.random():n)?"x":" "}]`;default:throw Error("unknown list item type: "+t)}}(t)} ${e}`;return r?o+"\n"+function(t,n){return n.split("\n").map((n=>" ".repeat(t)+n)).join("\n")}("ordered"===t?3:2,r):o}function x(t){return`| ${t.join(" | ")} |`}function $(t,n){const e=[];for(let r=0;n>r;r++)e.push("function"==typeof t?t():t);return e}function j({size:t=300}={}){return e(t)}function S({size:t=[1,3]}={}){return i({size:t,decorates:["title"],output:"array"})}function k({size:t=[1,4]}={}){return i({size:t,output:"array"})}function O({size:t=[2,6]}={}){return i({size:t,decorates:["title"]})}function A({size:t=[10,20],...n}={}){return i({size:t,decorates:[Object.keys(n).length?["description",n]:"description"]})}function T(){return Math.floor(1e4*Math.random())/100}function*C({rows:t,...n}={}){for(let e=0;t>e;e++)yield F({...n,index:e})}function F({}={}){const e=n(),r=function(n,e){const r=t(...e),o=[];for(let t=0;r>t;t++)o.push(n());return o}(T,[1,2]);return r.sort(),{product_id:e,authors:S(),categories:[],tags:k(),title:O(),description:A(),cover_image:j(),url:"/products/"+e,sale_price:r[0],original_price:r[r.length-1],rating:Math.floor(500*Math.random())/100+1,availability:Math.random()>.3?"IN_STOCK":"OUT_OF_STOCK"}}function*D({rows:t,...n}={}){for(let e=0;t>e;e++)yield L({...n,index:e})}function L({}={}){const t=n();return{product_id:t,authors:S(),categories:[],tags:k(),title:O({size:[4,10]}),snippet:A({size:[20,40]}),cover_image:j(),url:"/products/"+t}}function*P({rows:t,...n}={}){for(let e=0;t>e;e++)yield U({...n,index:e})}function U({}={}){return A({size:[4,8],punctuation:"?"})}function W({question:t,parent_question_id:n,timestamp:e=Date.now()},{answerFormat:o="markdown",answerSampling:s,answerLanguages:a=[]}={}){const u="10000000-1000-4000-8000-100000000000".replace(/[018]/g,(t=>(t^16*Math.random()>>t/4).toString(16))),c=function(t){const n=new Date(t).toISOString();return n.endsWith("Z")?n.slice(0,-1):n}(e),l=void 0!==s?Math.max(0,Math.min(1,s)):void 0,f=function({format:t,sampling:n,features:e}){return"markdown"===t?p({sampling:n,features:e}):i({min:r(50,n),max:r(50,n),decorates:["description"]})}({format:o,sampling:l,features:a.length?a.map((t=>"lang-"+t)):void 0}),d=[...D({rows:E(6,8,l)})];return{question:t,question_id:u,...n&&{parent_question_id:n},datetime:c,answer:f,sources:[...D({rows:E(4,6,l)})],related_resources:d,followup_questions:[...P({rows:E(3,6)})]}}function E(n,e,o){return t(r(n,o),r(e,o))}const H=[{name:"fetch",duration:1.5,text:"Checking the question and fetching results... "},{name:"verify",duration:1.5,text:"Verifying results... "},{name:"generate",duration:1.5,text:"Generating answer... "}];class I{constructor(t={}){this._options=t,this._answers=new Map}questions(t,n={}){return new J(t,{...this._options,...n})}}class J{constructor({question:t,parent_question_id:n},{answerFormat:e,answerSampling:r,answerLanguages:o,...s}={}){this._options=Object.freeze(s);const i=this.timestamp=Date.now();this._data=W({question:t,parent_question_id:n,timestamp:i},{answerFormat:e,answerSampling:r,answerLanguages:o})}get question_id(){return this._data.question_id}get(){const t=(Date.now()-this.timestamp)*(this._options.speedRate||1)/1e3,[n,e,r]=this._answer(t),o=this._sources(t,r),s=this._related_resources(t,r),i=this._followup_questions(t,r),{question_id:a,question:u,datetime:c,parent_question_id:l}=this._data;return{answer:e,answer_stage:n,datetime:c,finished:r,parent_question_id:l,question:u,question_id:a,sources:o,related_resources:s,followup_questions:i}}_answer(t){for(const n of H)if(0>(t-=n.duration))return[n.name,n.text,!1];const{answer:n}=this._data,e=Math.floor(100*t),r=e>=n.length;return["result",r?n:n.slice(0,e),r]}_sources(t,n){const{sources:e}=this._data;if(n)return e;const{length:r}=e;return e.slice(0,Math.floor(r*t/3))}_related_resources(t,n){const{related_resources:e}=this._data;if(n)return e;const{length:r}=e;return e.slice(0,Math.floor(r*t/3))}_followup_questions(t,n){const{followup_questions:e}=this._data;if(n||!e)return e;const{length:r}=e;return e.slice(0,Math.floor(r*t/3))}}class K{constructor(t){this._options=t}search({rows:t=5}){return{products:[...C({rows:t})]}}}class G{constructor(t){this._options=t}user_to_products({rows:t=5}){return{products:[...C({rows:t})]}}product_to_products({rows:t=5}){return{products:[...C({rows:t})]}}}class N{constructor(t){this._options=t}upload(t){return[]}}class R{constructor(t){this._options=t}upload(t){return[]}ids(){const t=[];for(let n=0;5e3>n;n++)t.push(V(n));return{ids:t}}}function V(t){return`${10>t?"p_000":100>t?"p_00":1e3>t?"p_0":"p_"}${t}`}class Z{constructor(t){this.ask=new I(t),this.search=new K(t),this.recommendation=new G(t),this.interactions=new N(t),this.products=new R(t)}}return{buildApi:(...t)=>new Z(...t)}}));
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).doggoganger=e()}(this,(function(){"use strict";function t(){return"10000000-1000-4000-8000-100000000000".replace(/[018]/g,(t=>(t^16*Math.random()>>t/4).toString(16)))}function e(t,e){return null!=e&&e>t?t+Math.floor(Math.random()*(e-t)):t}function n(t,n){const r=e(...n),o=[];for(let e=0;r>e;e++)o.push(t());return o}function r(){return Math.random().toString(36).substring(2,10)}function o(t){for(let e=t.length-1;e>0;e--){const n=Math.floor(Math.random()*(e+1));[t[e],t[n]]=[t[n],t[e]]}return t}function s(t){return`https://picsum.photos/seed/${Math.floor(1e3*Math.random())}/${Array.isArray(t)?t.length>1?`${t[0]}/${t[1]}`:""+t[0]:""+t}`}function i(t){const e=new Date(t).toISOString();return e.endsWith("Z")?e.slice(0,-1):e}function a(t,e){return void 0!==e?Math.ceil(t*e):t}function u(){return c()+c()+c()}function c(){return 2*Math.random()-1}var l=Object.freeze({__proto__:null,formatDatetime:i,gaussRandom:u,id:r,imageUrl:s,randomInt:e,repeat:n,sample:a,shuffle:o,uuid:t}),f=["lorem","ipsum","dolor","sit","amet","consectetur","adipiscing","elit","curabitur","vel","hendrerit","libero","eleifend","blandit","nunc","ornare","odio","ut","orci","gravida","imperdiet","nullam","purus","lacinia","a","pretium","quis","congue","praesent","sagittis","laoreet","auctor","mauris","non","velit","eros","dictum","proin","accumsan","sapien","nec","massa","volutpat","venenatis","sed","eu","molestie","lacus","quisque","porttitor","ligula","dui","mollis","tempus","at","magna","vestibulum","turpis","ac","diam","tincidunt","id","condimentum","enim","sodales","in","hac","habitasse","platea","dictumst","aenean","neque","fusce","augue","leo","eget","semper","mattis","tortor","scelerisque","nulla","interdum","tellus","malesuada","rhoncus","porta","sem","aliquet","et","nam","suspendisse","potenti","vivamus","luctus","fringilla","erat","donec","justo","vehicula","ultricies","varius","ante","primis","faucibus","ultrices","posuere","cubilia","curae","etiam","cursus","aliquam","quam","dapibus","nisl","feugiat","egestas","class","aptent","taciti","sociosqu","ad","litora","torquent","per","conubia","nostra","inceptos","himenaeos","phasellus","nibh","pulvinar","vitae","urna","iaculis","lobortis","nisi","viverra","arcu","morbi","pellentesque","metus","commodo","ut","facilisis","felis","tristique","ullamcorper","placerat","aenean","convallis","sollicitudin","integer","rutrum","duis","est","etiam","bibendum","donec","pharetra","vulputate","maecenas","mi","fermentum","consequat","suscipit","aliquam","habitant","senectus","netus","fames","quisque","euismod","curabitur","lectus","elementum","tempor","risus","cras"];function d({decorates:t=[],output:e="string",size:n,min:r,max:o,...s}={}){let i=b(n||[r,o])(h(s));for(const e of t)i=p(e)(i);return p(e)(i)}const m={string:g,array:_,title:y,description:q,multiline:w};function p(t){switch(typeof t){case"string":return m[t]();case"function":return t;case"object":if(Array.isArray(t)){const[e,n={}]=t;return m[e](n)}}throw Error("Unrecognized decorator/output form: "+t)}function*h({words:t=f,fixedStarts:e=0}={}){const n=t.length;for(let r=0;;r++)yield t[e>r?r:Math.floor(Math.random()*n)]}function g({separator:t=" "}={}){return e=>[...e].join(t)}function _(){return t=>[...t]}function w({wordsPerLine:t={avg:10,std:3,min:1}}={}){return e=>{let n=v(t),r="";for(let o of e)r&&(0==n--?(r+="\n",n=v(t)):r+=" "),r+=o;return r}}function b(t=[5,10]){const n="number"==typeof t?t:e(...t);return function*(t){let e=0;for(let r of t){if(e++>=n)break;yield r}}}function y({}={}){return function*(t){for(let e of t)yield z(e)}}function q({wordsPerSentence:t={avg:24,std:5,min:1},punctuation:e="."}={}){return function*(n){let r,o=0;for(let s of n)r&&(yield r),r=s,0===o&&(r=z(r),o=v(t)),0==--o&&(r+=e);r&&(r.endsWith(e)||(r+=e),yield r)}}function z(t){return t[0].toUpperCase()+t.substring(1)}function v(t){if("number"==typeof t)return Math.round(e);let{avg:e,std:n,min:r,max:o}=t;void 0===n&&(n=e/4);let s=u()*n+e;return void 0!==r&&(s=Math.max(r,s)),void 0!==o&&(s=Math.min(o,s)),Math.round(s)}var $=Object.freeze({__proto__:null,array:_,base:h,description:q,limit:b,lorem:d,multiline:w,string:g,title:y});const M="// module\nimport { a, b } from './module';\nimport * as module from './module';\nimport module from './module';\nexport default module;\nexport const a = 0;\nexport * from './module';\nexport * as module from './module';\n\n// variables\nlet a = 10;\nconst b = 20;\n\n// function declaration\nfunction sum(x, y) {\n return x + y;\n}\n\n// generator function\nfunction* iterator() {\n yield 0;\n yield 1;\n}\n\n// arrow function\nconst multiply = (x, y) => x * y;\n\n// class\nclass Person {\n constructor(name, age) {\n this.name = name;\n this.age = age;\n }\n\n greet() {\n console.log('Hello, my name is Miso.');\n }\n}\n\n// primitive\nconst str = 'Hello, world!';\nconst num = 10.99;\n\n// object\nconst person = new Person('John', 30);\nperson.greet();\n\n// object literal\nconst object = {\n name: 'John',\n [x]: 10,\n ...props,\n};\n\n// array literal\nconst arr = [1, 2, 3, 4, 5, ...props];\n\n// regexp literal\nconst regexp = /\\w+/g;\n\n// operators\nconst sum = a + b;\nconst product = a * b;\nconst negation = -a;\nconst max = a > b ? a : b;\n\n// flow control\nlet i = 9;\nfor (const n of arr) {\n if (n > i) {\n console.log(n);\n }\n i++;\n}\n\n// async/await\n(async () => {\n const result = await asyncFunction();\n})();\n\n// try/catch\ntry {\n} catch (e) {\n}\n\n// destructuring\nconst { name, age, ...rest } = person;\nconst [ x, y, ...rest ] = arr;\n\n// template literals\nconsole.log(`The sum of ${a} and ${b} is ${sum(a, b)}.`);";var x=Object.freeze({__proto__:null,javascript:function(){return M},js:function(){return M}});function j({features:t,blocks:e=[8,12],sampling:n=1}={}){let r=[];return[r,t]=function(t=[]){const e=new Set,n=[];for(const r of t)if(r.startsWith("lang-")){let t=r.slice(5);"javascript"===t&&(t="js"),e.add(t)}else n.push(r);return[[...e],n]}(t),function(t,e){const n=[];for(const r of t)1>e&&Math.random()>=e||n.push(r());return n}([()=>S({features:t}),()=>A({features:t}),...r.map((e=>()=>O({lang:e,features:t}))),...r.length?[]:[()=>O({features:t})],()=>A({features:t}),()=>C({features:t}),()=>D(),()=>A({features:t}),()=>k(),()=>S({features:t}),()=>A({features:t}),()=>F({features:t}),()=>A({features:t})],n).join("\n\n")}function k(){return"*-_".charAt(e(0,2)).repeat(e(3,6))}function S({level:t=[1,6],size:n=[1,8],content:r}){const o=r||d({size:n});return`${"#".repeat(e(...t))} ${o}`}function O({lang:t,content:n,size:r,fenceChar:o="`"}){return"random"===o&&(o="`~".charAt(e(0,1))),n=n||B({lang:t,size:r}),`${o.repeat(3)}${t||""}\n${n}\n${o.repeat(3)}`}function A({size:t=[20,50]}){return d({size:t,decorates:["description",U()]})}function C({columns:t=[2,4],rows:n=[2,8]}){t=e(...t),n=e(...n);const r=[...K({size:1},t-1),{size:[3,8]}],o=[d({size:t,output:"array"}),r.map((()=>"---"))];for(let t=0;n-1>t;t++)o.push(r.map((({size:t})=>d({size:t}))));return o.map(J).join("\n")}function D({url:t,imageSize:e=[400,250],...n}={}){return t=t||s(e),`![${E(n)}](${t})`}const T=["ordered","bullet","task"];function F({features:t,type:n="random",count:r=[1,8],size:o=[5,15]}){r="number"==typeof r?r:e(...r);const s="random"===n?T[Math.floor(3*Math.random())]:n,i=[];for(;r>0;){const a=e(1,r);let u=A({features:t,size:o});a>1&&(u+="\n"+F({features:t,type:n,count:a-1,size:o})),i.push(W(s,u)),r-=a}return i.join("\n")}const H={"code-span":()=>["`","`"],"emphasis-1":()=>K(I(1),2),"emphasis-2":()=>K(I(2),2),"emphasis-3":()=>K(I(3),2),strikethrough:()=>["~","~"],link:({url:t="https://miso.ai"}={})=>["[",`](${t})`]};function I(t=[1,3]){return t="number"==typeof t?t:e(...t),"_*".charAt(e(0,1)).repeat(t)}const L=Object.keys(H),P=new Set(L);function U({features:t=L,size:n=[1,3],rest:r=[0,8]}={}){t=t.filter((t=>P.has(t)));const s=o([...t]);let i=s.length-1;const a=()=>"number"==typeof r?r:e(...r);return function*(r){let o,u,c=a();for(const l of r)if(u&&(yield u),0===c)if(o)u=`${l}${o}`,o=void 0,c=a();else{const[r,a]=H[0>i?t[e(0,t.length-1)]:s[i--]]();u=`${r}${l}`,o=a,c="number"==typeof n?n:e(...n)}else u=l,c--;u&&(yield void 0!==o?`${u}${o}`:u)}}function E({size:t=[1,3],content:e}={}){return e||d({size:t})}function R(t,e){return e.split("\n").map((e=>" ".repeat(t)+e)).join("\n")}function W(t,e){const[n,r]=e.split("\n",2),o=`${function(t,e="random"){switch(t){case"ordered":return"1.";case"bullet":return"-";case"task":return`- [${("random"===e?.5>Math.random():e)?"x":" "}]`;default:throw Error("unknown list item type: "+t)}}(t)} ${n}`;return r?o+"\n"+R("ordered"===t?3:2,r):o}function B({lang:t,size:e=[10,30]}){return t&&x[t]?x[t]():d({output:"multiline",size:e})}function J(t){return`| ${t.join(" | ")} |`}function K(t,e){const n=[];for(let r=0;e>r;r++)n.push("function"==typeof t?t():t);return n}var G=Object.freeze({__proto__:null,atxHeading:S,blockquote:function({size:t=[3,5]}){return d({size:t}).split("\n").map((t=>"> "+t)).join("\n")},codeSpan:function(t){return`\`${E(t)}\``},decorate:U,emphasis:function({level:t=[1,3],options:n}){t="number"==typeof t?t:e(...t);const r="_*".charAt(e(0,1)).repeat(t);return`${r}${E(n)}${r}`},fencedCodeBlock:O,hr:k,image:D,indent:R,indentedCodeBlock:function({lang:t,content:e,size:n}){return R(4,e=e||B({lang:t,size:n}))},link:function({url:t="https://miso.ai",...e}={}){return`[${E(e)}](${t})`},linkReferenceDefinition:function({label:t,destination:e,title:n}){return`[${t}]: ${e}${void 0!==n?" "+n:""}`},list:F,listItem:W,markdown:j,paragraph:A,setextHeading:function({level:t=[1,2],size:n=[1,8],content:r}){return`${r||d({size:n})}\n${"=-".charAt(e(...t)-1).repeat(3)}`},table:C});function N({size:t=300}={}){return s(t)}function Q({size:t=[1,3]}={}){return d({size:t,decorates:["title"],output:"array"})}function V({size:t=[1,4]}={}){return d({size:t,output:"array"})}function Z({size:t=[2,6]}={}){return d({size:t,decorates:["title"]})}function X({size:t=[10,20],...e}={}){return d({size:t,decorates:[Object.keys(e).length?["description",e]:"description"]})}function Y(){return Math.floor(1e4*Math.random())/100}function*tt({rows:t,...e}={}){for(let n=0;t>n;n++)yield et({...e,index:n})}function et({}={}){const t=r(),e=n(Y,[1,2]);return e.sort(),{product_id:t,authors:Q(),categories:[],tags:V(),title:Z(),description:X(),cover_image:N(),url:"https://dummy.miso.ai/products/"+t,sale_price:e[0],original_price:e[e.length-1],rating:Math.floor(500*Math.random())/100+1,availability:Math.random()>.3?"IN_STOCK":"OUT_OF_STOCK"}}function*nt({rows:t,...e}={}){for(let n=0;t>n;n++)yield rt({...e,index:n})}function rt({}={}){const t=r();return{product_id:t,authors:Q(),categories:[],tags:V(),title:Z({size:[4,10]}),snippet:X({size:[20,40]}),cover_image:N(),url:"/products/"+t}}function*ot({rows:t=5,...e}={}){for(let n=0;t>n;n++)yield st({...e,index:n})}function st({}={}){return X({size:[4,8],punctuation:"?"})}function it({question:e,parent_question_id:n,timestamp:r=Date.now()},{answerFormat:o="markdown",answerSampling:s,answerLanguages:u=[]}={}){const c=t(),l=i(r),f=void 0!==s?Math.max(0,Math.min(1,s)):void 0,m=function({format:t,sampling:e,features:n}){return"markdown"===t?j({sampling:e,features:n}):d({min:a(50,e),max:a(50,e),decorates:["description"]})}({format:o,sampling:f,features:u.length?u.map((t=>"lang-"+t)):void 0}),p=[...nt({rows:at(6,8,f)})];return{question:e,question_id:c,...n&&{parent_question_id:n},datetime:l,answer:m,sources:[...nt({rows:at(4,6,f)})],related_resources:p,followup_questions:[...ot({rows:at(3,6)})]}}function at(t,n,r){return e(a(t,r),a(n,r))}var ut=Object.freeze({__proto__:null,answer:it,articles:nt,lorem:$,md:G,products:tt,questions:ot,utils:l});const ct=[{name:"fetch",duration:1.5,text:"Checking the question and fetching results... "},{name:"verify",duration:1.5,text:"Verifying results... "},{name:"generate",duration:1.5,text:"Generating answer... "}];class lt{constructor(t={}){this._options=t,this._answers=new Map}questions(t,e={}){const n=new ft(t,{...this._options,...e}),{question_id:r}=n;return this._answers.set(r,n),{question_id:r}}answer(t){const e=this._answers.get(t);if(!e){const e=Error("Question not found: "+t);throw e.status=404,e}return e.get()}related_questions(t){return{related_questions:[...ot(t)]}}}class ft{constructor({question:t,parent_question_id:e},{answerFormat:n,answerSampling:r,answerLanguages:o,...s}={}){this._options=Object.freeze(s);const i=this.timestamp=Date.now();this._data=it({question:t,parent_question_id:e,timestamp:i},{answerFormat:n,answerSampling:r,answerLanguages:o})}get question_id(){return this._data.question_id}get(){const t=(Date.now()-this.timestamp)*(this._options.speedRate||1)/1e3,[e,n,r]=this._answer(t),o=this._sources(t,r),s=this._related_resources(t,r),i=this._followup_questions(t,r),{question_id:a,question:u,datetime:c,parent_question_id:l}=this._data;return{answer:n,answer_stage:e,datetime:c,finished:r,parent_question_id:l,question:u,question_id:a,sources:o,related_resources:s,followup_questions:i}}_answer(t){for(const e of ct)if(0>(t-=e.duration))return[e.name,e.text,!1];const{answer:e}=this._data,n=Math.floor(100*t),r=n>=e.length;return["result",r?e:e.slice(0,n),r]}_sources(t,e){const{sources:n}=this._data;if(e)return n;const{length:r}=n;return n.slice(0,Math.floor(r*t/3))}_related_resources(t,e){const{related_resources:n}=this._data;if(e)return n;const{length:r}=n;return n.slice(0,Math.floor(r*t/3))}_followup_questions(t,e){const{followup_questions:n}=this._data;if(e||!n)return n;const{length:r}=n;return n.slice(0,Math.floor(r*t/3))}}class dt{constructor(t){this._options=t}search({rows:t=5}){return{products:[...tt({rows:t})]}}}class mt{constructor(t){this._options=t}user_to_products({rows:t=5}){return{products:[...tt({rows:t})]}}product_to_products({rows:t=5}){return{products:[...tt({rows:t})]}}}class pt{constructor(t){this._options=t}upload(t){return[]}}class ht{constructor(t){this._options=t}upload(t){return[]}ids(){const t=[];for(let e=0;5e3>e;e++)t.push(gt(e));return{ids:t}}}function gt(t){return`${10>t?"p_000":100>t?"p_00":1e3>t?"p_0":"p_"}${t}`}class _t{constructor(t){this.ask=new lt(t),this.search=new dt(t),this.recommendation=new mt(t),this.interactions=new pt(t),this.products=new ht(t)}}return{buildApi:(...t)=>new _t(...t),data:ut}}));
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "@miso.ai/doggoganger",
3
- "version": "0.9.0",
3
+ "version": "0.9.1-beta.10",
4
4
  "description": "A dummy miso endpoint for demo and testing",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "doggoganger": "cli/index.js"
8
8
  },
9
+ "main": "src/index.js",
10
+ "module": "src/index.js",
9
11
  "publishConfig": {
10
12
  "access": "public"
11
13
  },
package/src/api/ask.js CHANGED
@@ -1,4 +1,4 @@
1
- import { answer } from '../data/index.js';
1
+ import { answer, questions } from '../data/index.js';
2
2
 
3
3
  const CPS = 100;
4
4
  const ITEMS_LOADING_TIME = 3;
@@ -28,7 +28,26 @@ export default class Ask {
28
28
  }
29
29
 
30
30
  questions(payload, options = {}) {
31
- return new Answer(payload, { ...this._options, ...options });
31
+ const answer = new Answer(payload, { ...this._options, ...options });
32
+ const { question_id } = answer;
33
+ this._answers.set(question_id, answer);
34
+ return { question_id };
35
+ }
36
+
37
+ answer(questionId) {
38
+ const answer = this._answers.get(questionId);
39
+ if (!answer) {
40
+ const error = new Error(`Question not found: ${questionId}`);
41
+ error.status = 404;
42
+ throw error;
43
+ }
44
+ return answer.get();
45
+ }
46
+
47
+ related_questions(payload) {
48
+ return {
49
+ related_questions: [...questions(payload)],
50
+ };
32
51
  }
33
52
 
34
53
  }
package/src/api.js ADDED
@@ -0,0 +1,5 @@
1
+ import Api from './api/index.js';
2
+
3
+ export default function buildApi(...args) {
4
+ return new Api(...args);
5
+ };
package/src/browser.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import Api from './api/index.js';
2
+ import * as data from './data/index.js';
2
3
 
3
4
  export default {
4
5
  buildApi: (...args) => new Api(...args),
6
+ data,
5
7
  };
@@ -21,7 +21,7 @@ function product({} = {}) {
21
21
  description: fields.description(),
22
22
  //html,
23
23
  cover_image: fields.image(),
24
- url: `/products/${id}`,
24
+ url: `https://dummy.miso.ai/products/${id}`,
25
25
  sale_price: prices[0],
26
26
  original_price: prices[prices.length - 1],
27
27
  rating: fields.rating(),
@@ -1,6 +1,6 @@
1
1
  import * as fields from './fields.js';
2
2
 
3
- export function *questions({ rows, ...options } = {}) {
3
+ export function *questions({ rows = 5, ...options } = {}) {
4
4
  for (let i = 0; i < rows; i++) {
5
5
  yield question({ ...options, index: i });
6
6
  }
@@ -0,0 +1,54 @@
1
+ import Koa from 'koa';
2
+ import Router from '@koa/router';
3
+ import cors from '@koa/cors';
4
+ import serveStatic from 'koa-static';
5
+ import { koaBody } from 'koa-body';
6
+ import _route from './route/index.js';
7
+ import Api from './api/index.js';
8
+ import { exclusion } from './utils.js';
9
+
10
+ export default function doggoganger({ port = 9901, serve = false, ...options } = {}) {
11
+ const app = new Koa();
12
+ const router = new Router();
13
+ const api = _route(new Api(options), options);
14
+
15
+ router.use('/api', api.routes(), api.allowedMethods());
16
+ router.use('/v1', api.routes(), api.allowedMethods());
17
+
18
+ if (serve) {
19
+ app
20
+ .use(exclusion)
21
+ .use(serveStatic('.'));
22
+ }
23
+
24
+ app
25
+ .use(cors())
26
+ .use(koaBody({
27
+ formLimit: '100mb',
28
+ textLimit: '100mb',
29
+ jsonLimit: '100mb',
30
+ onerror: function (err, ctx) {
31
+ console.error(err);
32
+ ctx.throw('body parse error', 422);
33
+ },
34
+ }))
35
+ .use(handleAllPath(options))
36
+ .use(router.routes())
37
+ .use(router.allowedMethods())
38
+ .use(handleUnrecognizedPath(options))
39
+ .listen(port);
40
+ }
41
+
42
+ function handleAllPath({ verbose } = {}) {
43
+ return async (ctx, next) => {
44
+ verbose && console.log(`${ctx.method} ${ctx.url}`);
45
+ await next();
46
+ };
47
+ }
48
+
49
+ function handleUnrecognizedPath({ verbose } = {}) {
50
+ return async (ctx, next) => {
51
+ verbose && console.log(`Unrecognized path: ${ctx.method} ${ctx.url}`);
52
+ await next();
53
+ };
54
+ }
package/src/fetch.js ADDED
@@ -0,0 +1,35 @@
1
+ import { wrapResponse } from './route/utils.js';
2
+
3
+ export default async function fetch(api, url, { method = 'GET', body } = {}) {
4
+ method = method.toUpperCase();
5
+ if (typeof body === 'string') {
6
+ body = JSON.parse(body);
7
+ }
8
+ url = new URL(url);
9
+ const segments = url.pathname.substring(1).split('/');
10
+ if (segments[0] === 'v1') {
11
+ segments.splice(0, 1);
12
+ }
13
+ const group = segments[0];
14
+ let name = segments[1];
15
+ let type = 'query';
16
+
17
+ if (group === 'interactions' && segments.length === 1) {
18
+ name = 'upload';
19
+ type = 'data';
20
+ } else if (group === 'ask' && segments.length === 4 && segments[1] === 'questions' && segments[3] === 'answer') {
21
+ name = 'answer';
22
+ body = segments[2];
23
+ }
24
+
25
+ if (!api[group][name]) {
26
+ throw new Error(`Unknown path: ${url.pathname}`);
27
+ }
28
+
29
+ const fn = api[group][name].bind(api[group]);
30
+ const resBody = await wrapResponse(fn, type)(body);
31
+
32
+ return new Response(JSON.stringify(resBody), {
33
+ status: 200,
34
+ });
35
+ }
package/src/index.js CHANGED
@@ -1,54 +1,2 @@
1
- import Koa from 'koa';
2
- import Router from '@koa/router';
3
- import cors from '@koa/cors';
4
- import serveStatic from 'koa-static';
5
- import { koaBody } from 'koa-body';
6
- import _route from './route/index.js';
7
- import Api from './api/index.js';
8
- import { exclusion } from './utils.js';
9
-
10
- export default function doggoganger({ port = 9901, serve = false, ...options } = {}) {
11
- const app = new Koa();
12
- const router = new Router();
13
- const api = _route(new Api(options), options);
14
-
15
- router.use('/api', api.routes(), api.allowedMethods());
16
- router.use('/v1', api.routes(), api.allowedMethods());
17
-
18
- if (serve) {
19
- app
20
- .use(exclusion)
21
- .use(serveStatic('.'));
22
- }
23
-
24
- app
25
- .use(cors())
26
- .use(koaBody({
27
- formLimit: '100mb',
28
- textLimit: '100mb',
29
- jsonLimit: '100mb',
30
- onerror: function (err, ctx) {
31
- console.error(err);
32
- ctx.throw('body parse error', 422);
33
- },
34
- }))
35
- .use(handleAllPath(options))
36
- .use(router.routes())
37
- .use(router.allowedMethods())
38
- .use(handleUnrecognizedPath(options))
39
- .listen(port);
40
- }
41
-
42
- function handleAllPath({ verbose } = {}) {
43
- return async (ctx, next) => {
44
- verbose && console.log(`${ctx.method} ${ctx.url}`);
45
- await next();
46
- };
47
- }
48
-
49
- function handleUnrecognizedPath({ verbose } = {}) {
50
- return async (ctx, next) => {
51
- verbose && console.log(`Unrecognized path: ${ctx.method} ${ctx.url}`);
52
- await next();
53
- };
54
- }
1
+ export { default as doggoganger } from './doggoganger.js';
2
+ export { default as buildApi } from './api.js';
package/src/route/ask.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import Router from '@koa/router';
2
- import { parseBodyIfNecessary } from './utils.js';
2
+ import { handler, parseBodyIfNecessary } from './utils.js';
3
3
 
4
4
  function getOptionsFromCtx(ctx) {
5
5
  const speedRate = Number(ctx.get('x-speed-rate')) || undefined;
@@ -11,27 +11,21 @@ function getOptionsFromCtx(ctx) {
11
11
  }
12
12
 
13
13
  export default function(api) {
14
- const answers = new Map();
15
14
  const router = new Router();
16
15
 
17
16
  router.post('/questions', (ctx) => {
18
- const { question, parent_question_id } = parseBodyIfNecessary(ctx.request.body);
19
- const answer = api.ask.questions({ question, parent_question_id }, getOptionsFromCtx(ctx));
20
- const { question_id } = answer;
21
- answers.set(question_id, answer);
22
- ctx.body = JSON.stringify({ data: { question_id } });
17
+ const payload = parseBodyIfNecessary(ctx.request.body);
18
+ const data = api.ask.questions(payload, getOptionsFromCtx(ctx));
19
+ ctx.body = JSON.stringify({ data });
23
20
  });
24
21
 
25
22
  router.get('/questions/:id/answer', (ctx) => {
26
23
  const { id } = ctx.params;
27
- const answer = answers.get(id);
28
- if (!answer) {
29
- ctx.status = 404;
30
- } else {
31
- const data = answer.get();
32
- ctx.body = JSON.stringify({ data });
33
- }
24
+ const data = api.ask.answer(id);
25
+ ctx.body = JSON.stringify({ data });
34
26
  });
35
27
 
28
+ router.post('/related_questions', handler(api.ask.related_questions, 'query'));
29
+
36
30
  return router;
37
31
  }
@@ -1,17 +1,10 @@
1
1
  import Router from '@koa/router';
2
- import { parseBodyIfNecessary } from './utils.js';
2
+ import { handler } from './utils.js';
3
3
 
4
4
  export default function(api) {
5
5
  const router = new Router();
6
6
 
7
- router.post('/', (ctx) => {
8
- const { data } = parseBodyIfNecessary(ctx.request.body);
9
- ctx.body = {
10
- took: 5,
11
- errors: false,
12
- data: api.interactions.upload(data),
13
- };
14
- });
7
+ router.post('/', handler(api.interactions.upload, 'data'));
15
8
 
16
9
  return router;
17
10
  }
@@ -1,17 +1,10 @@
1
1
  import Router from '@koa/router';
2
- import { parseBodyIfNecessary } from './utils.js';
2
+ import { handler } from './utils.js';
3
3
 
4
4
  export default function(api) {
5
5
  const router = new Router();
6
6
 
7
- router.post('/', (ctx) => {
8
- const { data } = parseBodyIfNecessary(ctx.request.body);
9
- ctx.body = {
10
- took: 5,
11
- errors: false,
12
- data: api.products.upload(data),
13
- };
14
- });
7
+ router.post('/', handler(api.products.upload, 'data'));
15
8
 
16
9
  router.get('/_ids', (ctx) => {
17
10
  ctx.body = {
@@ -1,22 +1,11 @@
1
1
  import Router from '@koa/router';
2
- import { parseBodyIfNecessary } from './utils.js';
2
+ import { handler } from './utils.js';
3
3
 
4
4
  export default function(api) {
5
5
  const router = new Router();
6
6
 
7
- router.post('/user_to_products', (ctx) => {
8
- const { rows = 5 } = parseBodyIfNecessary(ctx.request.body);
9
- ctx.body = {
10
- data: api.recommendation.user_to_products({ rows }),
11
- };
12
- });
13
-
14
- router.post('/product_to_products', (ctx) => {
15
- const { rows = 5 } = parseBodyIfNecessary(ctx.request.body);
16
- ctx.body = {
17
- data: api.recommendation.product_to_products({ rows }),
18
- };
19
- });
7
+ router.post('/user_to_products', handler(api.recommendation.user_to_products, 'query'));
8
+ router.post('/product_to_products', handler(api.recommendation.product_to_products, 'query'));
20
9
 
21
10
  return router;
22
11
  }
@@ -1,15 +1,10 @@
1
1
  import Router from '@koa/router';
2
- import { parseBodyIfNecessary } from './utils.js';
2
+ import { handler } from './utils.js';
3
3
 
4
4
  export default function(api) {
5
5
  const router = new Router();
6
6
 
7
- router.post('/search', (ctx) => {
8
- const { rows = 5 } = parseBodyIfNecessary(ctx.request.body);
9
- ctx.body = {
10
- data: api.search.search({ rows }),
11
- };
12
- });
7
+ router.post('/search', handler(api.search.search, 'query'));
13
8
 
14
9
  return router;
15
10
  }
@@ -4,3 +4,49 @@ export function parseBodyIfNecessary(body) {
4
4
  }
5
5
  return body;
6
6
  }
7
+
8
+ export function handler(fn, response) {
9
+ fn = wrapResponse(fn, response);
10
+ return async (ctx) => {
11
+ try {
12
+ ctx.body = await fn(parseBodyIfNecessary(ctx.request.body));
13
+ } catch (error) {
14
+ ctx.status = error.status || 500;
15
+ ctx.body = {
16
+ errors: true,
17
+ message: error.message || '',
18
+ };
19
+ }
20
+ };
21
+ }
22
+
23
+ export function wrapResponse(fn, response) {
24
+ response = responseFunction(response);
25
+ return async (payload) => {
26
+ try {
27
+ return response(await fn(payload));
28
+ } catch (error) {
29
+ error.status = error.status || 500;
30
+ error.data = {
31
+ errors: true,
32
+ message: error.message,
33
+ };
34
+ throw error;
35
+ }
36
+ };
37
+ }
38
+
39
+ export function responseFunction(response) {
40
+ if (typeof response === 'function') {
41
+ return response;
42
+ }
43
+ switch (response) {
44
+ case 'query':
45
+ // TODO: miso_id
46
+ return data => ({ data });
47
+ case 'data':
48
+ return data => ({ took: 5, errors: false, data });
49
+ default:
50
+ throw new Error(`Unknown response type: ${response}`);
51
+ }
52
+ }