Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@minatojs/sql-utils

Package Overview
Dependencies
Maintainers
2
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@minatojs/sql-utils - npm Package Compare versions

Comparing version 1.1.0 to 2.0.0

lib/utils.d.ts

39

lib/index.d.ts
import { Dict } from 'cosmokit';
import { Eval, Field, Model, Query } from '@minatojs/core';
import { Eval, Field, Model, Modifier, Query, Selection } from '@minatojs/core';
export * from './utils';
export declare type QueryOperators = {

@@ -12,10 +13,14 @@ [K in keyof Query.FieldExpr]?: (key: string, value: Query.FieldExpr[K]) => string;

};
export declare abstract class Builder {
export interface Transformer<S = any, T = any> {
types: Field.Type<S>[];
dump: (value: S) => T;
load: (value: T, initial?: S) => S;
}
export declare class Builder {
tables: Dict<Model>;
protected types: Dict<Transformer>;
protected createEqualQuery: (key: string, value: any) => string;
protected queryOperators: QueryOperators;
protected evalOperators: EvalOperators;
abstract escapeId(value: any): string;
abstract escape(value: any, table?: string, field?: string): string;
abstract format(sql: string, args?: object | any[]): string;
constructor();
constructor(tables: Dict<Model>);
protected createNullQuery(key: string, value: boolean): string;

@@ -35,16 +40,10 @@ protected createMemberQuery(key: string, value: any[], notStr?: string): string;

private getRecursive;
parseEval(expr: any, table?: string, field?: string): string;
parseEval(expr: any): string;
suffix(modifier: Modifier): string;
get(sel: Selection.Immutable): any;
define<S, T>(converter: Transformer<S, T>): void;
dump(model: Model, obj: any): any;
load(model: Model, obj: any): any;
escape(value: any, field?: Field): string;
stringify(value: any, field?: Field): any;
}
export interface TypeCaster<S = any, T = any> {
types: Field.Type<S>[];
dump: (value: S) => T;
load: (value: T, initial?: S) => S;
}
export declare class Caster {
private models;
protected types: Dict<TypeCaster>;
constructor(models: Dict<Model>);
register<S, T>(typeCaster: TypeCaster<S, T>): void;
dump(table: string, obj: any): any;
load(table: string, obj: any): any;
}

@@ -20,12 +20,67 @@ var __defProp = Object.defineProperty;

// packages/sql-utils/src/index.ts
// minato/packages/sql-utils/src/index.ts
var src_exports = {};
__export(src_exports, {
Builder: () => Builder,
Caster: () => Caster
escape: () => escape,
escapeId: () => escapeId,
quote: () => quote
});
module.exports = __toCommonJS(src_exports);
var import_cosmokit2 = require("cosmokit");
// minato/packages/sql-utils/src/utils.ts
var import_cosmokit = require("cosmokit");
var ESCAPE_CHARS_MAP = {
"\0": "\\0",
"\b": "\\b",
" ": "\\t",
"\n": "\\n",
"\r": "\\r",
"": "\\Z",
"'": "\\'",
"\\": "\\\\"
};
var ESCAPE_CHARS_REGEXP = new RegExp(`[${Object.values(ESCAPE_CHARS_MAP).join("")}]`, "g");
function escapeId(value) {
return "`" + value + "`";
}
__name(escapeId, "escapeId");
function escape(value) {
if ((0, import_cosmokit.isNullable)(value))
return "NULL";
switch (typeof value) {
case "boolean":
case "number":
return value + "";
case "object":
return quote(JSON.stringify(value));
default:
return quote(value);
}
}
__name(escape, "escape");
function quote(value) {
let chunkIndex = ESCAPE_CHARS_REGEXP.lastIndex = 0;
let escapedVal = "";
let match;
while (match = ESCAPE_CHARS_REGEXP.exec(value)) {
escapedVal += value.slice(chunkIndex, match.index) + ESCAPE_CHARS_MAP[match[0]];
chunkIndex = ESCAPE_CHARS_REGEXP.lastIndex;
}
if (chunkIndex === 0) {
return "'" + value + "'";
}
if (chunkIndex < value.length) {
return "'" + escapedVal + value.slice(chunkIndex) + "'";
}
return "'" + escapedVal + "'";
}
__name(quote, "quote");
// minato/packages/sql-utils/src/index.ts
var Builder = class {
constructor() {
constructor(tables) {
this.tables = tables;
this.types = {};
this.createEqualQuery = this.comparator("=");

@@ -68,4 +123,4 @@ this.queryOperators = {

$: (key) => this.getRecursive(key),
$if: (args) => `IF(${args.map((arg) => this.parseEval(arg)).join(", ")})`,
$ifNull: (args) => `IFNULL(${args.map((arg) => this.parseEval(arg)).join(", ")})`,
$if: (args) => `if(${args.map((arg) => this.parseEval(arg)).join(", ")})`,
$ifNull: (args) => `ifnull(${args.map((arg) => this.parseEval(arg)).join(", ")})`,
$add: (args) => `(${args.map((arg) => this.parseEval(arg)).join(" + ")})`,

@@ -107,10 +162,10 @@ $multiply: (args) => `(${args.map((arg) => this.parseEval(arg)).join(" * ")})`,

comparator(operator) {
return function(key, value) {
return (key, value) => {
return `${key} ${operator} ${this.escape(value)}`;
}.bind(this);
};
}
binary(operator) {
return function([left, right]) {
return ([left, right]) => {
return `(${this.parseEval(left)} ${operator} ${this.parseEval(right)})`;
}.bind(this);
};
}

@@ -142,3 +197,3 @@ logicalAnd(conditions) {

conditions.push(this.createEqualQuery(key, query));
} else if ((0, import_cosmokit.isNullable)(query)) {
} else if ((0, import_cosmokit2.isNullable)(query)) {
conditions.push(this.createNullQuery(key, false));

@@ -166,3 +221,3 @@ } else {

} else {
conditions.push(this.parseFieldQuery(this.escapeId(key), query[key]));
conditions.push(this.parseFieldQuery(escapeId(key), query[key]));
}

@@ -172,3 +227,3 @@ }

}
parseEvalExpr(expr, table, field) {
parseEvalExpr(expr) {
for (const key in expr) {

@@ -179,3 +234,3 @@ if (key in this.evalOperators) {

}
return this.escape(expr, table, field);
return this.escape(expr);
}

@@ -189,58 +244,107 @@ parseAggr(expr) {

getRecursive(args) {
var _a;
if (typeof args === "string") {
return this.getRecursive(["_", args]);
} else {
const [, key] = args;
if (!key.includes("."))
return this.escapeId(key);
const [field, ...rest] = key.split(".");
return `json_unquote(json_extract(${this.escapeId(field)}, '$${rest.map((key2) => `."${key2}"`).join("")}'))`;
const [table, key] = args;
const fields = ((_a = this.tables[table]) == null ? void 0 : _a.fields) || {};
if (key in fields || !key.includes("."))
return escapeId(key);
const field = Object.keys(fields).find((k) => key.startsWith(k + ".")) || key.split(".")[0];
const rest = key.slice(field.length + 1).split(".");
return `json_unquote(json_extract(${escapeId(field)}, '$${rest.map((key2) => `."${key2}"`).join("")}'))`;
}
}
parseEval(expr, table, field) {
parseEval(expr) {
if (typeof expr === "string" || typeof expr === "number" || typeof expr === "boolean" || expr instanceof Date) {
return this.escape(expr, table, field);
return this.escape(expr);
}
return this.parseEvalExpr(expr, table, field);
return this.parseEvalExpr(expr);
}
};
__name(Builder, "Builder");
var Caster = class {
constructor(models) {
this.models = models;
this.types = /* @__PURE__ */ Object.create(null);
suffix(modifier) {
const { limit, offset, sort, group, having } = modifier;
let sql = "";
if (group.length) {
sql += ` GROUP BY ${group.map(escapeId).join(", ")}`;
const filter = this.parseEval(having);
if (filter !== "1")
sql += ` HAVING ${filter}`;
}
if (sort.length) {
sql += " ORDER BY " + sort.map(([expr, dir]) => {
return `${this.parseEval(expr)} ${dir.toUpperCase()}`;
}).join(", ");
}
if (limit < Infinity)
sql += " LIMIT " + limit;
if (offset > 0)
sql += " OFFSET " + offset;
return sql;
}
register(typeCaster) {
typeCaster.types.forEach((type) => this.types[type] = typeCaster);
get(sel) {
const { args, table, query, ref } = sel;
const filter = this.parseQuery(query);
if (filter === "0")
return;
const { fields } = args[0];
const keys = !fields ? "*" : Object.entries(fields).map(([key, value]) => {
key = escapeId(key);
value = this.parseEval(value);
return key === value ? key : `${value} AS ${key}`;
}).join(", ");
let prefix = `SELECT ${keys} FROM `;
let suffix = this.suffix(args[0]);
if (filter !== "1") {
suffix = ` WHERE ${filter}` + suffix;
}
if (typeof table === "string") {
prefix += escapeId(table);
} else {
const inner = this.get(table);
if (!inner)
return;
if (!fields && !suffix)
return inner;
prefix += `(${inner})`;
}
return `${prefix} ${ref}${suffix}`;
}
dump(table, obj) {
var _a;
obj = this.models[table].format(obj);
const { fields } = this.models[table];
define(converter) {
converter.types.forEach((type) => this.types[type] = converter);
}
dump(model, obj) {
obj = model.format(obj);
const result = {};
for (const key in obj) {
const converter = this.types[(_a = fields[key]) == null ? void 0 : _a.type];
result[key] = converter ? converter.dump(obj[key]) : obj[key];
result[key] = this.stringify(obj[key], model.fields[key]);
}
return result;
}
load(table, obj) {
const { fields } = this.models[table];
load(model, obj) {
const result = {};
for (const key in obj) {
if (!(key in fields))
if (!(key in model.fields))
continue;
const { type, initial } = fields[key];
const { type, initial } = model.fields[key];
const converter = this.types[type];
result[key] = converter ? converter.load(obj[key], initial) : obj[key];
}
return this.models[table].parse(result);
return model.parse(result);
}
escape(value, field) {
return escape(this.stringify(value, field));
}
stringify(value, field) {
const converter = this.types[field == null ? void 0 : field.type];
return converter ? converter.dump(value) : value;
}
};
__name(Caster, "Caster");
__name(Builder, "Builder");
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Builder,
Caster
escape,
escapeId,
quote
});
//# sourceMappingURL=index.js.map
{
"name": "@minatojs/sql-utils",
"version": "1.1.0",
"version": "2.0.0",
"description": "SQL Utilities for Minato",

@@ -32,7 +32,7 @@ "main": "lib/index.js",

"peerDependencies": {
"@minatojs/core": "^1.3.0"
"@minatojs/core": "^2.0.0"
},
"dependencies": {
"cosmokit": "^1.2.1"
"cosmokit": "^1.3.3"
}
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc