New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

leoric

Package Overview
Dependencies
Maintainers
1
Versions
144
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

leoric - npm Package Compare versions

Comparing version 0.5.0-alpha.2 to 0.5.0-alpha.3

124

lib/adapters/sequelize.js

@@ -24,2 +24,3 @@ 'use strict';

// https://sequelize.org/master/class/lib/model.js~Model.html
// https://sequelize.org/master/manual/model-querying-finders.html
module.exports = Bone => {

@@ -77,9 +78,7 @@ return class Spine extends Bone {

// static async count() {
// return await super.count();
// }
// EXISTS
// static async count() {}
// static async create(props) {
// return await super.create(props);
// }
// EXISTS
// static async create(props) {}

@@ -99,5 +98,4 @@ static decrement() {

// static drop() {
// throw new Error('unimplemented');
// }
// EXISTS
// static drop() {}

@@ -121,4 +119,15 @@ static async findAll(options = {}) {

static findCreateFind() {
throw new Error('unimplemented');
static async findCreateFind(options = {}) {
const { where, defaults } = options;
let instance = await this.findOne({ where });
if (!instance) {
try {
instance = await this.create({ ...defaults, ...where });
} catch (err) {
instance = await this.findOne({ where });
}
}
return instance;
}

@@ -148,9 +157,7 @@

// static hasMany() {
// throw new Error('unimplemented');
// }
// BREAKING
// static hasMany() {}
// static hasOne() {
// throw new Error('unimplemented');
// }
// BREAKING
// static hasOne() {}

@@ -161,9 +168,7 @@ static increment() {

// static async max() {
// return await super.max();
// }
// EXISTS
// static async max() {}
// static async min() {
// return await super.min();
// }
// EXISTS
// static async min() {}

@@ -178,10 +183,10 @@ static removeAttribute(name) {

static restore() {
static async restore(options = {}) {
await super.update(options.where || {}, { deltedAt: null });
}
static schema() {
throw new Error('unimplemented');
}
// static schema() {
// throw new Error('unimplemented');
// }
static scope() {

@@ -191,9 +196,7 @@ throw new Error('unimplemented');

// static async sum() {
// return await super.sum();
// }
// EXISTS
// static async sum() {}
// static async sync() {
// return await super.sync();
// }
// EXISTS
// static async sync() {}

@@ -225,4 +228,10 @@ static truncate() {

changed() {
throw new Error('unimplemented');
changed(key) {
if (key != null) return this.attributeChanged(key);
const result = [];
for (const key of Object.keys(this.constructor.attributes)) {
if (this.attributeChanged(key)) result.push(key);
}
return result.length > 0 ? result : false;
}

@@ -247,7 +256,7 @@

get(key) {
return this.attribute(key);
return this[key];
}
getDataValue(key) {
return this.raw[key];
return this.attribute(key);
}

@@ -264,29 +273,33 @@

previous() {
throw new Error('unimplemented');
}
previous(key) {
if (key != null) return this.attributeWas(key);
reload() {
throw new Error('unimplemented');
const result = {};
for (const key of Object.keys(this.attributes)) {
result[key] = this.attributeWas(key);
}
return result;
}
save() {
throw new Error('unimplemented');
}
// EXISTS
// async reload() {}
restore() {}
// EXISTS
// async save() {}
set(key, value) {
this.attribute(key, value);
this[key] = value;
}
setDataValue(key, value) {
this.raw[key] = value;
this.attribute(key, value);
}
toJSON() {
return super.toJSON();
}
// EXISTS
// toJSON() {}
async update() {
return await super.update();
}
// EXISTS
// async update() {}

@@ -298,5 +311,6 @@ validate() {

where() {
throw new Error('unimplemented');
const { primaryKey } = this.constructor;
return { [primaryKey]: this[primaryKey] };
}
};
};

@@ -93,2 +93,26 @@ 'use strict';

/**
* Find the corresponding JavaScript type of the type in database.
* @param {string} dataType
*/
function findJsType(dataType) {
switch (dataType.toLowerCase().split('(')[0]) {
case 'bigint':
case 'smallint':
case 'tinyint':
case 'int':
case 'integer':
case 'decimal':
return Number;
case 'datetime':
return Date;
case 'longtext':
case 'mediumtext':
case 'text':
case 'varchar':
default:
return String;
}
}
/**
* The base class that provides Object-relational mapping. This class is never intended to be used directly. We need to create models that extends from Bone. Most of the query features of Bone is implemented by {@link Spell} such as {@link Spell#$group} and {@link Spell#$join}. With Bone, you can create models like this:

@@ -112,3 +136,3 @@ *

* @property {Object} raw
* @property {Object} rawOriginal
* @property {Object} rawInitial
* @property {Set} rawUnset

@@ -128,3 +152,3 @@ * @example

raw: {},
rawOriginal: {},
rawInitial: {},
rawUnset: new Set(),

@@ -161,8 +185,11 @@ }));

*/
attribute(name, value) {
attribute(...args) {
const [ name, value ] = args;
const { attributes } = this.constructor;
if (!(name in attributes)) {
if (!attributes.hasOwnProperty(name)) {
throw new Error(`${this.constructor.name} has no attribute "${name}"`);
}
if (arguments.length > 1) {
if (args.length > 1) {
this.raw[name] = value;

@@ -189,3 +216,3 @@ this.rawUnset.delete(name);

if (this.rawUnset.has(name)) throw new Error(`Unset attribute "${name}"`);
const value = this.rawOriginal[name];
const value = this.rawInitial[name];
return value == null ? null : value;

@@ -297,3 +324,3 @@ }

/**
* Sync changes made in {@link Bone.raw} back to {@link Bone.rawOriginal}. Mostly used after the changes are persisted to database, to make {@link Bone.attributeChanged} function properly.
* Sync changes made in {@link Bone.raw} back to {@link Bone.rawInitial}. Mostly used after the changes are persisted to database, to make {@link Bone.attributeChanged} function properly.
* @private

@@ -305,6 +332,6 @@ */

for (const name in attributes) {
const { type } = attributes[name];
const { jsType } = attributes[name];
// Take advantage of uncast/cast to create new copy of value
const value = this.constructor.uncast(this.raw[name], type);
this.rawOriginal[name] = this.constructor.cast(value, type);
const value = this.constructor.uncast(this.raw[name], jsType);
this.rawInitial[name] = this.constructor.cast(value, jsType);
}

@@ -423,2 +450,11 @@ }

async reload() {
const { primaryKey } = this.constructor;
const instance = await this.constructor.findOne(this[primaryKey]);
if (instance) {
Object.assign(this.raw, instance.raw);
Object.assign(this.rawInitial, instance.rawInitial);
}
}
/**

@@ -446,2 +482,16 @@ * Delete current instance. If `deletedAt` attribute exists, calling {@link Bone#remove} does not actually delete the record from the database. Instead, it updates the value of `deletedAt` attribute to current date. This is called [soft delete](../querying#scopes). To force a regular `DELETE`, use `.remove(true)`.

async restore() {
const Model = this.constructor;
const { primaryKey, shardingKey } = Model;
if (this[primaryKey] == null) {
throw new Error('The instance is not persisted yet.');
}
const conditions = { [primaryKey]: this[primaryKey] };
if (shardingKey) conditions[shardingKey] = this[shardingKey];
return await this.constructor.update(conditions, { deltedAt: null });
}
/**

@@ -458,7 +508,8 @@ * Override attribute metadata. Currently only `type` is needed to be overriden with this method.

*/
static attribute(name, meta) {
static attribute(name, meta = {}) {
if (!this.attributes[name]) {
throw new Error(`${this.name} has no attribute called ${name}`);
}
Object.assign(this.attributes[name], meta);
const { type: jsType } = meta;
Object.assign(this.attributes[name], { jsType });
}

@@ -589,39 +640,2 @@

/**
* Find model by class name. Models are stored at {@link Bone.model}.
* @param {string} className
* @returns {Bone}
*/
static reflectClass(className) {
const model = this.models[className];
if (!(model && model.prototype instanceof Bone)) {
throw new Error(`Unable to find model "${className}"`);
}
return model;
}
/**
* Find the corresponding JavaScript type of the type in database.
* @param {string} dataType
*/
static reflectType(dataType) {
switch (dataType.toLowerCase().split('(')[0]) {
case 'bigint':
case 'smallint':
case 'tinyint':
case 'int':
case 'integer':
case 'decimal':
return Number;
case 'datetime':
return Date;
case 'longtext':
case 'mediumtext':
case 'text':
case 'varchar':
default:
return String;
}
}
/**
* Cast raw values from database to JavaScript types. When the raw packet is fetched from database, `Date`s and special numbers are transformed by drivers already. This method is used to cast said values to custom types set by {@link Bone.attribute}, such as `JSON`.

@@ -663,3 +677,3 @@ * @private

/**
* Set a `hasOne` association to another model. The model is inferred by {@link Bone.reflectClass} from `opts.className` or the association `name` by default.
* Set a `hasOne` association to another model. The model is inferred by `opts.className` or the association `name` by default.
* @param {string} name

@@ -682,3 +696,3 @@ * @param {Object} [opts]

/**
* Set a `hasMany` association to another model. The model is inferred by {@link Bone.reflectClass} from `opts.className` or the association `name` by default.
* Set a `hasMany` association to another model. The model is inferred by `opts.className` or the association `name` by default.
* @param {string} name

@@ -702,3 +716,3 @@ * @param {Object} [opts]

/**
* Set a `belongsTo` association to another model. The model is inferred by {@link Bone.reflectClass} from `opts.className` or the association `name` by default.
* Set a `belongsTo` association to another model. The model is inferred by `opts.className` or the association `name` by default.
* @param {string} name

@@ -730,7 +744,10 @@ * @param {Object} [opts]

*/
static associate(name, opts) {
static associate(name, opts = {}) {
if (name in this.associations) {
throw new Error(this.name + ' has duplicated association at: ' + name);
}
const Model = this.reflectClass(opts.className);
const { className } = opts;
const Model = this.models[className];
if (!Model) throw new Error(`Unable to find model "${className}"`);
const { deletedAt } = this.timestamps;

@@ -857,10 +874,10 @@ if (Model.attributes[deletedAt] && !opts.where) {

const instance = new this();
const { raw, rawOriginal, rawUnset } = instance;
const { raw, rawInitial, rawUnset } = instance;
for (const name in this.attributes) {
const { columnName, type } = this.attributes[name];
const { columnName, jsType } = this.attributes[name];
if (columnName in row) {
// to make sure raw and rawOriginal hold two different objects
raw[name] = this.cast(row[columnName], type);
rawOriginal[name] = this.cast(row[columnName], type);
// to make sure raw and rawInitial hold two different objects
raw[name] = this.cast(row[columnName], jsType);
rawInitial[name] = this.cast(row[columnName], jsType);
} else {

@@ -1062,7 +1079,12 @@ rawUnset.add(name);

static init(attributes, opts = {}) {
opts = {
underscored: true,
table: this.table || opts.tableName,
...(this.options && this.options.define),
...opts,
};
const result = {};
const table = this.table || opts.table || opts.tableName ||
snakeCase(pluralize(this.name));
const table = opts.table || snakeCase(pluralize(this.name));
const aliasName = camelCase(pluralize(this.name || table));
const { underscored } = this.options && this.options.define || {};
const { underscored } = opts;

@@ -1072,16 +1094,12 @@ for (const name in attributes) {

const definition = typeof opts === 'function' ? { type: opts } : opts;
const {
type: dataType,
allowNull,
defaultValue,
...others
} = {
const { allowNull, defaultValue, ...others } = {
columnName: underscored === false ? name : snakeCase(name),
...definition,
};
const dataType = definition.dataType || definition.type.type;
result[name] = {
dataType,
...others,
type: this.reflectType(dataType.type || dataType),
dataType,
jsType: findJsType(dataType),
allowNull: allowNull == null ? true : allowNull,

@@ -1113,2 +1131,3 @@ defaultValue: defaultValue == null ? null : defaultValue,

// a model that is not connected before
if (this.synchronized == null) {

@@ -1122,3 +1141,3 @@ const schemaInfo = await driver.querySchemaInfo(database, [ table ]);

if (this.physicTables) {
throw new Error('Unable to migrate multiple tables simutaneously');
throw new Error('Unable to sync model with custom physic tables');
}

@@ -1125,0 +1144,0 @@

@@ -6,2 +6,3 @@ 'use strict';

const { findDriver } = require('./drivers');
const { STRING, INTEGER, BIGINT, DATE, TEXT, BOOLEAN } = require('./data_types');

@@ -35,2 +36,27 @@ const fs = require('fs').promises;

function findType(dataType) {
switch (dataType) {
case 'varchar':
return STRING;
case 'text':
return TEXT;
case 'datetime':
case 'timestamp':
return DATE;
case 'decimal':
case 'int':
case 'integer':
case 'numeric':
case 'smallint':
case 'tinyint':
return INTEGER;
case 'bigint':
return BIGINT;
case 'boolean':
return BOOLEAN;
default:
throw new Error(`Unexpected data type ${dataType}`);
}
}
function initAttributes(model, columns) {

@@ -43,4 +69,4 @@ const attributes = {};

attributes[ LEGACY_TIMESTAMP_MAP[name] || name ] = {
type: dataType,
...columnInfo,
type: findType(dataType),
};

@@ -47,0 +73,0 @@ }

@@ -8,4 +8,4 @@ 'use strict';

function formatColumnDefinition(definition) {
const { dataType, allowNull, defaultValue, primaryKey } = definition;
const chunks = [ dataType.toSqlString() ];
const { type, allowNull, defaultValue, primaryKey } = definition;
const chunks = [ type.toSqlString() ];

@@ -36,3 +36,9 @@ if (primaryKey) chunks.push('PRIMARY KEY');

const { logger } = opts;
this.logger = logger && logger.info ? logger : { info: debug };
if (logger != null && typeof logger === 'object') {
this.logger = logger;
} else if (typeof logger === 'function') {
this.logger = { info: logger, debug };
} else {
this.logger = { info: debug, debug };
}
}

@@ -39,0 +45,0 @@

@@ -90,2 +90,3 @@ 'use strict';

WHERE table_schema = ? AND table_name in (?)
ORDER BY table_name, column_name
`);

@@ -92,0 +93,0 @@

@@ -5,3 +5,2 @@ 'use strict';

const SqlString = require('sqlstring');
const debug = require('debug')('leoric');
const spellbook = require('../abstract/spellbook');

@@ -11,4 +10,4 @@ const AbstractDriver = require('../abstract');

function formatColumnDefinition({ dataType, allowNull, defaultValue }) {
const chunks = [ dataType.toSqlString() ];
function formatColumnDefinition({ type, allowNull, defaultValue }) {
const chunks = [ type.toSqlString() ];

@@ -131,5 +130,5 @@ if (allowNull != null) {

function formatAlterColumns(columnName, definition) {
const { allowNull, dataType, defaultValue } = definition;
const { allowNull, type, defaultValue } = definition;
const sets = [
`TYPE ${dataType.toSqlString()}`,
`TYPE ${type.toSqlString()}`,
allowNull ? 'DROP NOT NULL' : 'SET NOT NULL',

@@ -221,3 +220,6 @@ defaultValue == null ? 'DROP DEFAULT' : `SET DEFAULT ${SqlString.format(defaultValue)}`,

let { data_type: dataType, character_octet_length: maxLength } = row;
if (dataType === 'character varying') dataType = 'varchar';
if (dataType === 'timestamp without time zone') dataType = 'timestamp';
const columnType = maxLength > 0 ? `${dataType}(${maxLength})` : dataType;

@@ -224,0 +226,0 @@

'use strict';
const path = require('path');
const SqlString = require('sqlstring');

@@ -10,10 +9,4 @@ const debug = require('debug')('leoric');

const { heresql, camelCase, snakeCase } = require('../../utils/string');
const sqlite = require('sqlite3');
let sqlite;
try {
sqlite = require(path.join(process.cwd(), 'node_modules/sqlite3'));
} catch (e) {
sqlite = require('sqlite3');
}
// SELECT users.id AS "users:id", ...

@@ -44,9 +37,6 @@ // => [ { users: { id, ... } } ]

function formatColumnDefinition(definition) {
const { allowNull, defaultValue, primaryKey } = definition;
const { type, allowNull, defaultValue, primaryKey } = definition;
// int => integer
// - https://www.sqlite.org/datatype3.html
const dataType = typeof definition.dataType === 'string'
? definition.dataType
: definition.dataType.toSqlString().replace(/^INT\b/, 'INTEGER');
const chunks = [ dataType ];
const chunks = [ type.toSqlString().replace(/^INT\b/, 'INTEGER') ];

@@ -53,0 +43,0 @@ if (primaryKey) chunks.push('PRIMARY KEY');

@@ -239,3 +239,3 @@ 'use strict';

if (name in Model.attributes) {
sets[name] = Model.uncast(obj[name], Model.attributes[name].type);
sets[name] = Model.uncast(obj[name], Model.attributes[name].jsType);
} else {

@@ -242,0 +242,0 @@ throw new Error(`Undefined attribute "${name}"`);

@@ -8,4 +8,2 @@ 'use strict';

function invokable(DataType) {
let dataType;
return new Proxy(DataType, {

@@ -24,4 +22,3 @@ // STRING(255)

get(target, p) {
if (!dataType) dataType = new target();
return dataType[p];
return new target()[p];
}

@@ -28,0 +25,0 @@ });

{
"name": "leoric",
"version": "0.5.0-alpha.2",
"version": "0.5.0-alpha.3",
"description": "JavaScript Object-relational mapping alchemy",

@@ -5,0 +5,0 @@ "main": "index.js",

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