sql-love 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +52 -32
  2. package/dist/index.cjs +16 -0
  3. package/dist/index.d.ts +732 -9
  4. package/dist/index.mjs +16 -0
  5. package/package.json +27 -10
  6. package/.github/workflows/node.js.yml +0 -37
  7. package/.prettierrc.json +0 -13
  8. package/CHANGELOG.md +0 -39
  9. package/CONTRIBUTING.md +0 -85
  10. package/assets/sql-love-logo.png +0 -0
  11. package/codecov.yml +0 -7
  12. package/dist/index.js +0 -9
  13. package/dist/src/Parser/Parser.d.ts +0 -157
  14. package/dist/src/Parser/Parser.js +0 -304
  15. package/dist/src/SelectBuilder/SelectBuilder.d.ts +0 -379
  16. package/dist/src/SelectBuilder/SelectBuilder.js +0 -810
  17. package/dist/src/extractGrouped/extractGrouped.d.ts +0 -17
  18. package/dist/src/extractGrouped/extractGrouped.js +0 -31
  19. package/dist/src/extractIndexed/extractIndexed.d.ts +0 -12
  20. package/dist/src/extractIndexed/extractIndexed.js +0 -23
  21. package/dist/src/extractLookup/extractLookup.d.ts +0 -9
  22. package/dist/src/extractLookup/extractLookup.js +0 -21
  23. package/dist/src/getPagination/getPagination.d.ts +0 -16
  24. package/dist/src/getPagination/getPagination.js +0 -40
  25. package/dist/src/runMysql/runMysql.d.ts +0 -58
  26. package/dist/src/runMysql/runMysql.js +0 -61
  27. package/dist/src/runPrisma/runPrisma.d.ts +0 -41
  28. package/dist/src/runPrisma/runPrisma.js +0 -34
  29. package/dist/src/substrCount/substrCount.d.ts +0 -6
  30. package/dist/src/substrCount/substrCount.js +0 -14
  31. package/dist/src/toSafeJson/toSafeJson.d.ts +0 -25
  32. package/dist/src/toSafeJson/toSafeJson.js +0 -45
  33. package/index.ts +0 -19
  34. package/src/Parser/Parser.spec.ts +0 -226
  35. package/src/Parser/Parser.ts +0 -325
  36. package/src/SelectBuilder/SelectBuilder.spec.ts +0 -785
  37. package/src/SelectBuilder/SelectBuilder.ts +0 -914
  38. package/src/extractGrouped/extractGrouped.spec.ts +0 -43
  39. package/src/extractGrouped/extractGrouped.ts +0 -36
  40. package/src/extractIndexed/extractIndexed.spec.ts +0 -40
  41. package/src/extractIndexed/extractIndexed.ts +0 -28
  42. package/src/extractLookup/extractLookup.spec.ts +0 -38
  43. package/src/extractLookup/extractLookup.ts +0 -33
  44. package/src/getPagination/getPagination.spec.ts +0 -75
  45. package/src/getPagination/getPagination.ts +0 -42
  46. package/src/runMysql/runMysql.spec.ts +0 -286
  47. package/src/runMysql/runMysql.ts +0 -106
  48. package/src/runPrisma/runPrisma.spec.ts +0 -99
  49. package/src/runPrisma/runPrisma.ts +0 -75
  50. package/src/substrCount/substrCount.spec.ts +0 -29
  51. package/src/substrCount/substrCount.ts +0 -14
  52. package/src/toSafeJson/toSafeJson.spec.ts +0 -28
  53. package/src/toSafeJson/toSafeJson.ts +0 -56
  54. package/tsconfig.build.json +0 -10
  55. package/tsconfig.json +0 -22
  56. package/vitest.config.ts +0 -11
package/dist/index.mjs ADDED
@@ -0,0 +1,16 @@
1
+ var c=class{query;constructor(t){this.query=t}_stripComments(t){return t=t.replace(/\/\*[\s\S]*?\*\//g,""),t=t.replace(/--([\r\n]|\s+[^\r\n]+[\r\n])/g,""),t=t.replace(/#[^\r\n]+[\r\n]/g,""),t}_extractSubQueries(t){let e={},n=0,s=r=>{let o=`~~SUBQUERY_${n++}~~`;return e[o]=r,o};return t=t.replace(/\(\s*SELECT\s+.+\)\s+AS\s+[^\s,]+/,s),t=t.replace(/\bIF\s*\(.+\)\s+AS\s+[^\s,]+/,s),t=t.replace(/\bIN\s*\(\s*SELECT\s.+?\)/,s),{sql:t,subQueries:e}}_injectSubQueries(t){let e=s=>t[s]||s,n=s=>s.replace(/~~SUBQUERY_\d+~~/g,e);this.query._columns=this.query._columns.map(e),this.query._joins=this.query._joins.map(n),this.query._wheres=this.query._wheres.map(n),this.query._havings=this.query._havings.map(n)}_split(t){let e=/(?:^|\s)(SELECT|FROM|(?:INNER|LEFT\s+OUTER|RIGHT\s+OUTER|LEFT|RIGHT|CROSS|FULL|FULL\s+OUTER)\s+JOIN|WHERE|GROUP\s+BY|HAVING|ORDER\s+BY|LIMIT|OFFSET|FETCH\s+NEXT)\b/i;return t.split(e)}parse(t){let e=this._stripComments(t),{sql:n,subQueries:s}=this._extractSubQueries(e),r=this._split(n),o=1;for(;o<r.length;){let l=r[o++].trim().toUpperCase().replace(/\s+/g,"_"),h=r[o++].trim(),a=`_handle${l}`;this[a](h)}return this._injectSubQueries(s),!0}_handleSELECT(t){let e=t.split(/s*,s*/),n="";e.forEach((s,r)=>{if(r===0){let o=/^(SQL_CALC_FOUND_ROWS)\s+/i,u=s.match(o);u&&(this.query.option(u[1]),s=s.replace(o,""))}n.length?s.indexOf(")")>0?(n+=s,this.query.column(n.trim()),n=""):n+=s+",":s.match(/\([^)]+$/)?n=s+",":this.query.column(s.trim())})}_handleFROM(t){t.split(/\s*,\s*/).forEach(n=>this.query.table(n))}_handleINNER_JOIN(t){this.query.innerJoin(t)}_handleLEFT_JOIN(t){this.query.leftJoin(t)}_handleLEFT_OUTER_JOIN(t){this.query.leftOuterJoin(t)}_handleRIGHT_JOIN(t){this.query.rightJoin(t)}_handleRIGHT_OUTER_JOIN(t){this.query.rightOuterJoin(t)}_handleCROSS_JOIN(t){this.query.crossJoin(t)}_handleFULL_JOIN(t){this.query.fullJoin(t)}_handleFULL_OUTER_JOIN(t){this.query.fullOuterJoin(t)}_handleWHERE(t){/^(1|'1'|true)$/i.test(t)?this.query._wheres.push(t):this._handleConditions("where",t)}_handleHAVING(t){this._handleConditions("having",t)}_handleConditions(t,e){e.split(/\bAND\b/i).forEach(s=>{let r=s.split(/\bOR\b/i).map(o=>o.trim());if(r.length===1){let o=t;this.query[o](r[0])}else{let o=t==="where"?"orWhere":"orHaving";this.query[o](r.map(u=>[u]))}})}_handleGROUP_BY(t){t.split(/\s*,\s*/).forEach(n=>this.query.groupBy(n))}_handleORDER_BY(t){t.split(/\s*,\s*/).forEach(n=>this.query.orderBy(n))}_handleLIMIT(t){let e=t.match(/^(\d+|\?|:\w+)\s*,\s*(\d+|\?|:\w+)$/);e?(this.query.offset(e[1]),this.query.limit(e[2])):(t=t.replace(/ ROWS$/i,""),this.query.limit(t))}_handleOFFSET(t){t=t.replace(/^(\d+) ROWS$/i,"$1"),this.query.offset(t)}_handleFETCH_NEXT(t){t=t.replace(/^(\d+) ROWS ONLY$/i,"$1"),this.query.limit(t)}};function m(i,t){let e=0,n=i.indexOf(t);for(;n!==-1;)e+=1,n=i.indexOf(t,n+1);return e}var _=i=>i==null||i===!1||isNaN(i),f="mysql",y=class i{_bindings=[];_options=[];_tables=[];_columns=[];_joins=[];_wheres=[];_groupBys=[];_havings=[];_orderBys=[];_limit;_offset;_page;constructor(t=null,e=null){if(t){if(e){let n=Object.keys(e),s=new RegExp(`:(${n.join("|")})`,"g");t=t.replace(s,(r,o)=>(this._bindings.push(e[o]),`__BOUND_${this._bindings.length-1}__`))}new c(this).parse(t)}}static setDefaultEngine(t){return f=t,i}compile({engine:t=f,bindingIndex:e=1}={}){let n=["SELECT",this._options.length?` ${this._options.join(`
2
+ `)}`:null,this._columns.length?` ${this._columns.join(`,
3
+ `)}`:` *
4
+ `,`FROM ${this._tables.join(", ")}`,this._joins.length?this._joins.join(`
5
+ `):null,this._wheres.length?`WHERE ${this._wheres.join(`
6
+ AND `)}`:null,this._groupBys.length?`GROUP BY ${this._groupBys.join(`,
7
+ `)}`:null,this._havings.length?`HAVING ${this._havings.join(`
8
+ AND `)}`:null,this._orderBys.length?`ORDER BY ${this._orderBys.join(`,
9
+ `)}`:null];if(this._page>0){let l=(this._page-1)*this._limit;n.push(this._compileOFFSET(t,l)),n.push(this._compileLIMIT(t,this._limit))}else this._offset&&n.push(this._compileOFFSET(t,this._offset)),this._limit&&n.push(this._compileLIMIT(t,this._limit));let s=n.filter(Boolean).join(`
10
+ `).trim(),r,o=[];if(t==="pg"){let l=e;r=(h,a)=>(o.push(this._bindings[a]),"$"+l++)}else r=(l,h)=>(o.push(this._bindings[h]),"?");return{sql:s.replace(/__BOUND_(\d+)__/g,r),bindings:o}}_compileLIMIT(t,e){if(t==="pg"||t==="mysql")return`LIMIT ${e}`;if(t==="mssql")return`FETCH NEXT ${e} ROWS ONLY`}_compileOFFSET(t,e){if(t==="pg"||t==="mysql")return`OFFSET ${e}`;if(t==="mssql"||t==="oracle")return`OFFSET ${e} ROWS`}compileCount({countExpr:t="*",engine:e=f,bindingIndex:n=1}={}){let s=this.getFoundRowsQuery(t),{sql:r,bindings:o}=s.compile({engine:e,bindingIndex:n});return this._havings.length===0?{sql:r,bindings:o}:{sql:`SELECT COUNT(*) AS found_rows
11
+ FROM (
12
+ ${r.replace(/\n/g,`
13
+ `)}
14
+ ) AS subquery_results`,bindings:o}}compileUnion(t,{engine:e=f,bindingIndex:n=1}={}){let s=this.compile({engine:e,bindingIndex:n}),r=t.compile({engine:e,bindingIndex:s.bindings.length+n});return{sql:`(${s.sql})
15
+ UNION
16
+ (${r.sql})`,bindings:[...s.bindings,...r.bindings]}}reset(t=null){if(Array.isArray(t))return t.forEach(e=>this.reset(e)),this;if(t){let e=["option","column","table","where","having","groupBy","orderBy"],n="_"+t.replace(/s$/,"");e.indexOf(t)>-1&&(n+="s");let s=["limit","offset","page"].indexOf(t)>-1;this[n]=s?null:[]}else this._options=[],this._columns=[],this._tables=[],this._joins=[],this._wheres=[],this._groupBys=[],this._havings=[],this._orderBys=[],this._limit=null,this._offset=null,this._page=null,this._bindings=[];return this}getClone(){let t=new i;return t._options=[...this._options],t._columns=[...this._columns],t._tables=[...this._tables],t._joins=[...this._joins],t._wheres=[...this._wheres],t._havings=[...this._havings],t._groupBys=[...this._groupBys],t._orderBys=[...this._orderBys],t._limit=this._limit,t._offset=this._offset,t._page=this._page,t._bindings=[...this._bindings],t}getFoundRowsQuery(t="*"){if(this._havings.length===0){let e=this.getClone();return e._columns=[`COUNT(${t}) AS found_rows`],e._options=[],e._groupBys=[],e._orderBys=[],e._limit=null,e._offset=null,e._page=null,e}else{let e=this.getClone();return e._limit=null,e._offset=null,e._page=null,e}}select(t){return this._columns=this._columns.concat(t),this}columns(t){return this._columns=this._columns.concat(t),this}column(t){return this._columns.push(t),this}option(t){return this._options.push(t),this}table(t){return this._tables.push(t),this}tables(t){return this._tables.push(...t),this}from(t){return this._tables.push(t),this}_addJoin(t,e,n=[]){n.length>0&&(e=e.replace(/\?/g,()=>(this._bindings.push(n.shift()),`__BOUND_${this._bindings.length-1}__`))),this._joins.push(`${t} ${e}`)}join(t,e=[]){return this._addJoin("JOIN",t,e),this}leftJoin(t,e=[]){return this._addJoin("LEFT JOIN",t,e),this}fullJoin(t,e=[]){return this._addJoin("FULL JOIN",t,e),this}rightJoin(t,e=[]){return this._addJoin("RIGHT JOIN",t,e),this}crossJoin(t,e=[]){return this._addJoin("CROSS JOIN",t,e),this}innerJoin(t,e=[]){return this._addJoin("INNER JOIN",t,e),this}leftOuterJoin(t,e=[]){return this._addJoin("LEFT OUTER JOIN",t,e),this}fullOuterJoin(t,e=[]){return this._addJoin("FULL OUTER JOIN",t,e),this}rightOuterJoin(t,e=[]){return this._addJoin("RIGHT OUTER JOIN",t,e),this}unjoin(t){return Array.isArray(t)?(t.forEach(e=>this.unjoin(e)),this):(this._joins=this._joins.filter(e=>!new RegExp(`JOIN ${t}\\b`).test(e)),this)}_conditions(t,e){let n=e.length,[s,r,o]=e;if(typeof s=="object"){for(let l of Object.entries(s))this._conditions(t,l);return this}if(n===1)return t.push(s),this;if(n===2&&Array.isArray(r)&&r.length>0&&m(s,"?")===r.length){let l=r,h=s.replace(/\?/g,()=>(this._bindings.push(l.shift()),`__BOUND_${this._bindings.length-1}__`));return t.push(h),this}else if(n===2){o=r;let l=s.split(" ");s=l.shift(),r=l.join(" ")}(typeof r!="string"||r==="")&&(r="="),r=r.toLocaleUpperCase();let u=r.match(/^(LIKE|NOT LIKE|ILIKE|NOT ILIKE)(?: (\?|\?%|%\?|%\?%))?$/i);if(r==="NOT BETWEEN"||r==="BETWEEN"){let l=this._bindings.length,h=this._bindings.length+1;t.push(`${s} ${r} __BOUND_${l}__ AND __BOUND_${h}__`),this._bindings.push(o[0],o[1])}else if(u){let l=u[1].toUpperCase(),h=u[2]||"?";if(Array.isArray(o)){let a=[];for(let T of o)a.push(`${s} ${l} __BOUND_${this._bindings.length}__`),this._bindings.push(h.replace("?",T));let d=a.join(" OR ");t.push(`(${d})`)}else t.push(`${s} ${l} __BOUND_${this._bindings.length}__`),this._bindings.push(h.replace("?",o||""))}else if(o===null)t.push(r==="="?`${s} IS NULL`:`${s} IS NOT NULL`);else if(Array.isArray(o)){let l=[];for(let a=0;a<o.length;a++)l.push(`__BOUND_${this._bindings.length}__`),this._bindings.push(o[a]);let h=l.join(", ");t.push(r==="="||r==="IN"?`${s} IN(${h})`:`${s} NOT IN(${h})`)}else r==="IN"||r==="NOT IN"?(t.push(`${s} ${r}(__BOUND_${this._bindings.length}__)`),this._bindings.push(o)):(t.push(`${s} ${r} __BOUND_${this._bindings.length}__`),this._bindings.push(o));return this}groupBy(t){return this._groupBys.push(t),this}where(...t){return this._conditions(this._wheres,t),this}whereBetween(t,e){return!_(e[0])&&!_(e[1])?this.where(t,"BETWEEN",e):!_(e[0])&&_(e[1])?this.where(t,">=",e[0]):_(e[0])&&!_(e[1])&&this.where(t,"<=",e[1]),this}_orConditions(t){let e=[];if(Array.isArray(t))for(let s of t)Array.isArray(s)?this._conditions(e,s):this._conditions(e,[s]);else for(let[s,r]of Object.entries(t)){let o=[];this._conditions(o,[s,r]),e.push(o[0])}let n=e.join(" OR ");return n.startsWith("(")&&n.endsWith(")")?n.slice(1,-1):n}orWhere(t){let e=this._orConditions(t);return this.where(`(${e})`),this}orHaving(t){let e=this._orConditions(t);return this.having(`(${e})`),this}having(...t){return this._conditions(this._havings,t),this}orderBy(t,e=null){if(e)this._orderBys.push(`${t} ${e}`);else{let n=t.replace(/^-(.+)/,"$1 DESC");this._orderBys.push(n)}return this}sortField(t,e={}){let n="ASC";t.startsWith("-")&&(n="DESC",t=t.slice(1));let s=e[t]||t;return this.orderBy(s,n),this}_isEntirelyDigits(t){return/^(0|[1-9]\d*)$/.test(t)}_isEntirelyDigitsNoZeros(t){return/^[1-9]\d*$/.test(t)}limit(t){if(typeof t=="string")t=t.trim(),this._isEntirelyDigitsNoZeros(t)&&(this._limit=parseInt(t,10));else if(typeof t=="number"&&Number.isInteger(t)&&t>=1)this._limit=t;else throw new Error(`SelectBuilder: "limit(n)" must receive a positive integer (got "${t}")`);return this}offset(t){if(typeof t=="string"&&this._isEntirelyDigits(t.trim()))this._offset=parseInt(t,10);else if(typeof t=="number"&&Number.isInteger(t)&&t>=0)this._offset=t;else throw new Error(`SelectBuilder: "offset(n)" must receive a positive integer (got "${t}")`);return this}page(t){if(typeof t=="string"&&this._isEntirelyDigitsNoZeros(t.trim()))this._page=parseInt(t,10);else if(typeof t=="number"&&Number.isInteger(t)&&t>=1)this._page=t;else throw new Error('SelectBuilder: "page(n)" must receive a positive integer');return this}};function S(i,t){let e=0,n={};for(let s of t){if(!(i in s))throw new Error(`Column "${String(i)}" is not present in record ${e}`);n[s[i]]||(n[s[i]]=[]),n[s[i]].push(s),e++}return n}function E(i,t){let e=0,n={};for(let s of t){if(!(i in s))throw new Error(`Column "${String(i)}" is not present in record ${e}`);n[s[i]]=s,e++}return n}function R(i,t,e){let n={},s=0;for(let r of e){if(!(i in r))throw new Error(`Column "${String(i)}" is not present in record ${s}`);if(!(t in r))throw new Error(`Column "${String(t)}" is not present in record ${s}`);s++,n[String(r[i])]=r[t]}return n}function g(i,t){t=Number(t)||0;let e=Number(i._limit)||null,n=null;t===0?n=null:i._page?n=Number(i._page):i._limit&&i._offset?n=Math.floor(Number(i._offset)/Number(i._limit))+1:i._limit&&!i._offset?n=1:n=null;let s=t===0||e===null?0:Math.ceil(t/e)||0,r=n===1,o=s>0&&n===s,u=s===0?null:n-1||null,l=s>0&&n+1<=s?n+1:null;return{page:n,prevPage:u,nextPage:l,perPage:e,numPages:s,total:t,isFirst:r,isLast:o}}function b(i,t,e){return new Promise((n,s)=>{i.query(t,e,(r,o,u)=>{if(r){s(r);return}n([o,u])})})}async function N(i,t){let{sql:e,bindings:n}=t.compile({engine:"mysql"});return b(i,e,n)}async function B(i,t,{countExpr:e="*"}={}){let{sql:n,bindings:s}=t.compile({engine:"mysql"}),[r,o]=await b(i,n,s);if(r.length>0){let{sql:u,bindings:l}=t.compileCount({engine:"mysql",countExpr:e}),[h]=await b(i,u,l),a=h[0].found_rows;return{records:r,total:a,pagination:g(t,a),fields:o}}else return{records:r,total:0,pagination:g(t,0),fields:o}}async function $(i,t){let{sql:e,bindings:n}=t.compile({engine:"mysql"});return i.query(e,n)}async function I(i,t,{engine:e="mysql",countExpr:n="*"}={}){let{sql:s,bindings:r}=t.compile({engine:e}),[o,u]=await i.query(s,r);if(o.length>0){let{sql:l,bindings:h}=t.compileCount({engine:e,countExpr:n}),[a]=await i.query(l,h),d=a[0].found_rows;return{records:o,total:d,pagination:g(t,d),fields:u}}else return{records:o,total:0,pagination:g(t,0),fields:u}}function p(i){if(typeof i=="bigint"){let t=Number(i);return i==t?t:i.toString()}return i}function O(i){let t={};for(let e in i)Object.prototype.hasOwnProperty.call(i,e)&&(t[e]=p(i[e]));return t}function C(i){return i.map(O)}function w(i){return JSON.stringify(i,(t,e)=>p(e))}async function x(i,t,{engine:e=void 0}={}){let{sql:n,bindings:s}=t.compile({engine:e});return i.$queryRawUnsafe(n,...s)}async function q(i,t,{engine:e=void 0,countExpr:n="*"}={}){let{sql:s,bindings:r}=t.compile({engine:e}),o=await i.$queryRawUnsafe(s,...r);if(o.length>0){let{sql:u,bindings:l}=t.compileCount({engine:e,countExpr:n}),h=await i.$queryRawUnsafe(u,...l),a=p(h[0].found_rows);return{records:o,total:a,pagination:g(t,a)}}else return{records:o,total:0,pagination:g(t,0)}}export{c as Parser,y as SelectBuilder,S as extractGrouped,E as extractIndexed,R as extractLookup,g as getPagination,N as runMysql,$ as runMysqlAsync,I as runMysqlAsyncWithCount,B as runMysqlWithCount,x as runPrisma,q as runPrismaWithCount,O as toSafeJsonRecord,C as toSafeJsonRecords,w as toSafeJsonString,p as toSafeJsonValue};
package/package.json CHANGED
@@ -1,18 +1,34 @@
1
1
  {
2
2
  "name": "sql-love",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Build SQL queries with JavaScript",
5
- "main": "dist/index.js",
6
5
  "type": "module",
7
- "sideEffects": false,
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "require": "./dist/index.cjs",
12
+ "import": "./dist/index.mjs",
13
+ "types": "./dist/index.d.ts"
14
+ }
15
+ },
8
16
  "scripts": {
9
17
  "test": "vitest run",
10
18
  "test-watch": "vitest",
11
19
  "coverage": "vitest run --coverage",
12
- "clean": "rimraf dist/ && mkdir dist && touch dist/.gitkeep",
13
- "build": "npm run clean && npx -p typescript tsc --project tsconfig.build.json",
14
- "release": "npm i && npm run build && npm publish"
20
+ "view-coverage": "open ./coverage/lcov-report/index.html",
21
+ "build": "npm run build:clean && npm run build:dts && npm run build:esm && npm run build:cjs",
22
+ "build:clean": "rimraf dist/ && mkdir dist && touch dist/.gitkeep",
23
+ "build:dts": "yes | npx dts-bundle-generator -o dist/index.d.ts index.ts",
24
+ "build:esm": "yes | npx esbuild index.ts --minify --bundle --platform=node --format=esm --outfile=dist/index.mjs",
25
+ "build:cjs": "yes | npx esbuild index.ts --minify --bundle --platform=node --format=cjs --outfile=dist/index.cjs"
15
26
  },
27
+ "files": [
28
+ "dist",
29
+ "README.md",
30
+ "LICENSE.md"
31
+ ],
16
32
  "repository": {
17
33
  "type": "git",
18
34
  "url": "git+https://github.com/kensnyder/sql-love.git"
@@ -32,11 +48,12 @@
32
48
  },
33
49
  "homepage": "https://github.com/kensnyder/sql-love#readme",
34
50
  "devDependencies": {
35
- "@vitest/coverage-v8": "2.0.2",
51
+ "@types/node": "22.6.1",
52
+ "@vitest/coverage-v8": "2.1.1",
36
53
  "prettier": "3.3.3",
37
- "prettier-plugin-organize-imports": "4.0.0",
54
+ "prettier-plugin-organize-imports": "4.1.0",
38
55
  "rimraf": "6.0.1",
39
- "typescript": "5.5.3",
40
- "vitest": "2.0.2"
56
+ "typescript": "5.6.2",
57
+ "vitest": "2.1.1"
41
58
  }
42
59
  }
@@ -1,37 +0,0 @@
1
- # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
2
- # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
3
-
4
- name: build
5
-
6
- on:
7
- push:
8
- branches: ['main']
9
- pull_request:
10
- branches: ['main']
11
-
12
- jobs:
13
- build:
14
- runs-on: ubuntu-latest
15
-
16
- strategy:
17
- matrix:
18
- node-version: [18.x, 20.x]
19
- # See supported Node.js release schedule at https://nodejs.org/en/about/previous-releases
20
-
21
- steps:
22
- - uses: actions/checkout@v3
23
- - name: Use Node.js ${{ matrix.node-version }}
24
- uses: actions/setup-node@v3
25
- with:
26
- node-version: ${{ matrix.node-version }}
27
- cache: 'npm'
28
- - run: |
29
- npm ci
30
- npm run build
31
- npm test
32
- npm run coverage
33
- - name: Upload coverage to Codecov
34
- uses: codecov/codecov-action@v3
35
- with:
36
- token: ${{ secrets.CODECOV_TOKEN }}
37
- directory: ./coverage/
package/.prettierrc.json DELETED
@@ -1,13 +0,0 @@
1
- {
2
- "plugins": ["prettier-plugin-organize-imports"],
3
- "trailingComma": "es5",
4
- "printWidth": 80,
5
- "tabWidth": 2,
6
- "useTabs": false,
7
- "semi": true,
8
- "singleQuote": true,
9
- "bracketSpacing": true,
10
- "jsxBracketSameLine": false,
11
- "arrowParens": "avoid",
12
- "endOfLine": "lf"
13
- }
package/CHANGELOG.md DELETED
@@ -1,39 +0,0 @@
1
- ## Change Log
2
-
3
- ### v1.0.0 - 12 Dec 2023
4
-
5
- - Upgrade to vitest v1
6
- - More documentation
7
- - 100% test coverage
8
- - First stable release
9
-
10
- ### v0.9.7 - 7 Dec 2023
11
-
12
- - Added extractLookup utility
13
- - Added toSafeJson utilities
14
-
15
- ### v0.9.6 - 5 Dec 2023
16
-
17
- - Utility functions (extractGrouped, extractIndexed, getPagination, runPrisma, runMysql)
18
- - Added `SelectBuilder.setDefaultEngine(engine)`
19
- - More documentation
20
- - Fix `.sortField()` logic
21
-
22
- ### v0.9.4 - 30 Nov 2023
23
-
24
- - Support parsing and building "ILIKE" and "NOT ILIKE"
25
-
26
- ### v0.9.2 - 30 Nov 2023
27
-
28
- - Fixes to readme
29
-
30
- ### v0.9.1 - 30 Nov 2023
31
-
32
- - More documentation
33
- - GitHub Actions CI
34
- - Support for parsing "OFFSET # ROWS"
35
- - Support for parsing "FETCH NEXT # ROWS ONLY"
36
-
37
- ### v0.9.0 - 29 Nov 2023
38
-
39
- - Initial release with `SelectBuilder`
package/CONTRIBUTING.md DELETED
@@ -1,85 +0,0 @@
1
- # Contributing
2
-
3
- When contributing to this repository, please note we have a code of conduct;
4
- please follow it in all your interactions with the project.
5
-
6
- ## Pull Request Process
7
-
8
- 1. Ensure all unit tests pass. Add more unit tests if applicable.
9
- 2. Update the README.md with details of change if applicable.
10
- 3. Give maintainers some time to review the changes.
11
-
12
- ## Code of Conduct
13
-
14
- ### Our Pledge
15
-
16
- In the interest of fostering an open and welcoming environment, we as
17
- contributors and maintainers pledge to making participation in our project and
18
- our community a harassment-free experience for everyone, regardless of age, body
19
- size, disability, ethnicity, gender identity and expression, level of experience,
20
- nationality, personal appearance, race, religion, or sexual identity and
21
- orientation.
22
-
23
- ### Our Standards
24
-
25
- Examples of behavior that contributes to creating a positive environment
26
- include:
27
-
28
- * Using welcoming and inclusive language
29
- * Being respectful of differing viewpoints and experiences
30
- * Gracefully accepting constructive criticism
31
- * Focusing on what is best for the community
32
- * Showing empathy towards other community members
33
-
34
- Examples of unacceptable behavior by participants include:
35
-
36
- * The use of sexualized language or imagery and unwelcome sexual attention or
37
- advances
38
- * Trolling, insulting/derogatory comments, and personal or political attacks
39
- * Public or private harassment
40
- * Publishing others' private information, such as a physical or electronic
41
- address, without explicit permission
42
- * Other conduct which could reasonably be considered inappropriate in a
43
- professional setting
44
-
45
- ### Our Responsibilities
46
-
47
- Project maintainers are responsible for clarifying the standards of acceptable
48
- behavior and are expected to take appropriate and fair corrective action in
49
- response to any instances of unacceptable behavior.
50
-
51
- Project maintainers have the right and responsibility to remove, edit, or
52
- reject comments, commits, code, wiki edits, issues, and other contributions
53
- that are not aligned to this Code of Conduct, or to ban temporarily or
54
- permanently any contributor for other behaviors that they deem inappropriate,
55
- threatening, offensive, or harmful.
56
-
57
- ### Scope
58
-
59
- This Code of Conduct applies both within project spaces and in public spaces
60
- when an individual is representing the project or its community. Examples of
61
- representing a project or community include using an official project e-mail
62
- address, posting via an official social media account, or acting as an appointed
63
- representative at an online or offline event. Representation of a project may be
64
- further defined and clarified by project maintainers.
65
-
66
- ### Enforcement
67
-
68
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
69
- reported by opening a GitHub ticket. All complaints will be reviewed and
70
- investigated and will result in a response that is deemed necessary and
71
- appropriate to the circumstances. The project team is obligated to maintain
72
- confidentiality with regard to the reporter of an incident. Further details of
73
- specific enforcement policies may be posted separately.
74
-
75
- Project maintainers who do not follow or enforce the Code of Conduct in good
76
- faith may face temporary or permanent repercussions as determined by other
77
- members of the project's leadership.
78
-
79
- ### Attribution
80
-
81
- This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
82
- available at [http://contributor-covenant.org/version/1/4][version]
83
-
84
- [homepage]: http://contributor-covenant.org
85
- [version]: http://contributor-covenant.org/version/1/4/
Binary file
package/codecov.yml DELETED
@@ -1,7 +0,0 @@
1
- codecov:
2
- branch: main
3
-
4
- coverage:
5
- precision: 1
6
- round: down
7
- range: '70...100'
package/dist/index.js DELETED
@@ -1,9 +0,0 @@
1
- export { default as Parser } from './src/Parser/Parser';
2
- export { default as SelectBuilder } from './src/SelectBuilder/SelectBuilder';
3
- export { default as extractGrouped } from './src/extractGrouped/extractGrouped';
4
- export { default as extractIndexed } from './src/extractIndexed/extractIndexed';
5
- export { default as extractLookup } from './src/extractLookup/extractLookup';
6
- export { default as getPagination } from './src/getPagination/getPagination';
7
- export { runMysql, runMysqlAsync, runMysqlAsyncWithCount, runMysqlWithCount, } from './src/runMysql/runMysql';
8
- export { runPrisma, runPrismaWithCount } from './src/runPrisma/runPrisma';
9
- export { toSafeJsonRecord, toSafeJsonRecords, toSafeJsonString, toSafeJsonValue, } from './src/toSafeJson/toSafeJson';
@@ -1,157 +0,0 @@
1
- import type Select from '../SelectBuilder/SelectBuilder';
2
- /**
3
- * Parse SQL and populate onto a Select query object
4
- */
5
- export default class Parser {
6
- query: Select;
7
- /**
8
- * Create a new instance
9
- * @param query A Select object on which to build parsed conditions
10
- */
11
- constructor(query: Select);
12
- /**
13
- * Strip single-line and multi-line comment blocks
14
- * @param sql The SQL string
15
- * @return The SQL string without comments
16
- * @private
17
- */
18
- _stripComments(sql: string): string;
19
- /**
20
- * Before splitting into SQL clauses, extract some regex-able subQueries
21
- * @param sql The unparsed sql string
22
- * @return An array with new sql and subQueries
23
- * @private
24
- */
25
- _extractSubQueries(sql: string): {
26
- sql: string;
27
- subQueries: {};
28
- };
29
- /**
30
- * Inject column subQueries back into this object
31
- * @param subQueries The lookup of extracted subQueries
32
- * @private
33
- */
34
- _injectSubQueries(subQueries: Record<string, string>): void;
35
- /**
36
- * Split SQL into clauses (used by parse())
37
- * @param sql The SQL to split
38
- * @return
39
- * @private
40
- */
41
- _split(sql: string): string[];
42
- /**
43
- * Get a QuickSelect object representing the given SQL SELECT statement
44
- * @param rawSql The raw SQL for the SELECT statement
45
- * @return True if the SQL was parsed successfully
46
- */
47
- parse(rawSql: string): boolean;
48
- /**
49
- * Handle SQL_CALC_FOUND_ROWS and column names
50
- * @param clause The clause after the SELECT
51
- * @private
52
- */
53
- _handleSELECT(clause: string): void;
54
- /**
55
- * Handle table names
56
- * @param clause The clause after the FROM
57
- * @private
58
- */
59
- _handleFROM(clause: string): void;
60
- /**
61
- * Handle INNER JOIN statements
62
- * @param clause The clause after the INNER JOIN
63
- * @private
64
- */
65
- _handleINNER_JOIN(clause: string): void;
66
- /**
67
- * Handle LEFT JOIN statements
68
- * @param clause The clause after the LEFT JOIN
69
- * @private
70
- */
71
- _handleLEFT_JOIN(clause: string): void;
72
- /**
73
- * Handle LEFT OUTER JOIN statements
74
- * @param clause The clause after the LEFT OUTER JOIN
75
- * @private
76
- */
77
- _handleLEFT_OUTER_JOIN(clause: string): void;
78
- /**
79
- * Handle RIGHT JOIN statements
80
- * @param clause The clause after the RIGHT JOIN
81
- * @private
82
- */
83
- _handleRIGHT_JOIN(clause: string): void;
84
- /**
85
- * Handle RIGHT OUTER JOIN statements
86
- * @param clause The clause after the RIGHT OUTER JOIN
87
- * @private
88
- */
89
- _handleRIGHT_OUTER_JOIN(clause: string): void;
90
- /**
91
- * Handle CROSS JOIN statements
92
- * @param clause The clause after the CROSS JOIN
93
- * @private
94
- */
95
- _handleCROSS_JOIN(clause: string): void;
96
- /**
97
- * Handle FULL JOIN statements
98
- * @param clause The clause after the FULL JOIN
99
- * @private
100
- */
101
- _handleFULL_JOIN(clause: string): void;
102
- /**
103
- * Handle FULL OUTER JOIN statements
104
- * @param clause The clause after the FULL OUTER JOIN
105
- * @private
106
- */
107
- _handleFULL_OUTER_JOIN(clause: string): void;
108
- /**
109
- * Handle WHERE conditions
110
- * @param clause All the conditions after WHERE
111
- * @private
112
- */
113
- _handleWHERE(clause: string): void;
114
- /**
115
- * Handle HAVING statements
116
- * @param clause All the conditions after HAVING
117
- * @private
118
- */
119
- _handleHAVING(clause: string): void;
120
- /**
121
- * Build a conditions list
122
- * @param type Either where or having
123
- * @param clause The expressions following the type keyword
124
- * @private
125
- */
126
- _handleConditions(type: 'where' | 'having', clause: string): void;
127
- /**
128
- * Handle GROUP BY statements
129
- * @param clause The clauses after the GROUP BY
130
- * @private
131
- */
132
- _handleGROUP_BY(clause: string): void;
133
- /**
134
- * Handle ORDER BY statements
135
- * @param clause The clause after the ORDER BY
136
- * @private
137
- */
138
- _handleORDER_BY(clause: string): void;
139
- /**
140
- * Handle LIMIT statements including "LIMIT #" and "LIMIT #, #"
141
- * @param clause The clause after the LIMIT
142
- * @private
143
- */
144
- _handleLIMIT(clause: string): void;
145
- /**
146
- * Handle OFFSET statements
147
- * @param clause The number after the OFFSET
148
- * @private
149
- */
150
- _handleOFFSET(clause: string): void;
151
- /**
152
- * Handle OFFSET statements
153
- * @param clause The number after the OFFSET
154
- * @private
155
- */
156
- _handleFETCH_NEXT(clause: string): void;
157
- }