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

orma

Package Overview
Dependencies
Maintainers
2
Versions
236
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

orma - npm Package Compare versions

Comparing version 1.0.225 to 1.0.226

4

build/mutate/statement_generation/tests/mutation_statements.test.js

@@ -125,3 +125,3 @@ "use strict";

paths: [mutation_pieces[1].path],
sql_string: "UPDATE users SET first_name = 'john' WHERE (id) = (1)",
sql_string: "UPDATE users SET first_name = 'john' WHERE id = 1",
},

@@ -139,3 +139,3 @@ {

paths: [mutation_pieces[2].path],
sql_string: 'DELETE FROM products WHERE (id) = (1)',
sql_string: 'DELETE FROM products WHERE id = 1',
},

@@ -142,0 +142,0 @@ ],

@@ -110,3 +110,3 @@ "use strict";

path: [key],
original_data: mutation,
// original_data: mutation,
},

@@ -152,3 +152,3 @@ ];

message: `Records must have an operation or an inherited operation.`,
original_data: mutation,
// original_data: mutation,
path: [...record_path, '$operation'],

@@ -194,3 +194,3 @@ },

path: [...record_path, key],
original_data: mutation,
// original_data: mutation,
},

@@ -208,3 +208,3 @@ ];

path: [...record_path, key],
original_data: mutation,
// original_data: mutation,
},

@@ -221,3 +221,3 @@ ];

path: [...record_path, key],
original_data: mutation,
// original_data: mutation,
},

@@ -258,3 +258,3 @@ ];

path: field_path,
original_data: mutation,
// original_data: mutation,
},

@@ -270,3 +270,3 @@ ];

path: field_path,
original_data: mutation,
// original_data: mutation,
},

@@ -290,3 +290,3 @@ ];

path: field_path,
original_data: mutation,
// original_data: mutation,
additional_info: {

@@ -315,3 +315,3 @@ enum_values,

path: field_path,
original_data: mutation,
// original_data: mutation,
additional_info: {

@@ -338,3 +338,3 @@ given_character_count,

path: field_path,
original_data: mutation,
// original_data: mutation,
},

@@ -348,3 +348,3 @@ ];

path: field_path,
original_data: mutation,
// original_data: mutation,
},

@@ -362,3 +362,3 @@ ];

path: field_path,
original_data: mutation,
// original_data: mutation,
additional_info: {

@@ -379,3 +379,3 @@ given_character_count,

path: field_path,
original_data: mutation,
// original_data: mutation,
additional_info: {

@@ -393,3 +393,3 @@ given_decimals,

path: field_path,
original_data: mutation,
// original_data: mutation,
additional_info: {

@@ -411,3 +411,3 @@ given_decimals,

path: field_path,
original_data: mutation,
// original_data: mutation,
},

@@ -428,3 +428,3 @@ ];

path: field_path,
original_data: mutation,
// original_data: mutation,
additional_info: {

@@ -457,3 +457,3 @@ required_data_type,

path: [...record_path, required_field],
original_data: mutation,
// original_data: mutation,
},

@@ -510,3 +510,3 @@ ];

// // path: [...record_path, '$operation'],
// // original_data: mutation,
// // // original_data: mutation,
// // additional_info: {

@@ -546,3 +546,3 @@ // // parent_entity,

// path: record_path,
// original_data: mutation,
// // original_data: mutation,
// // stack_trace: new Error().stack,

@@ -549,0 +549,0 @@ // additional_info: {

@@ -221,6 +221,6 @@ "use strict";

// DML commands
$select: args => `SELECT ${args.join(', ')}`, $as: args => `(${args[0]}) AS ${args[1]}`, $entity: args => `${args}`, $field: args => `.${args}`, $from: args => `FROM ${args}`, $where: args => `WHERE ${args}`, $group_by: args => `GROUP BY ${args.join(', ')}`, $having: args => `HAVING ${args}`, $order_by: args => `ORDER BY ${args.join(', ')}`, $asc: args => `${args} ASC`, $desc: args => `${args} DESC`, $limit: args => `LIMIT ${args}`, $offset: args => `OFFSET ${args}`, $in: (args, path) => {
$select: args => `SELECT ${args.join(', ')}`, $as: args => `${wrap_if_subquery(args[0])} AS ${args[1]}`, $entity: args => `${escape_field(args)}`, $field: args => `.${escape_field(args)}`, $from: args => `FROM ${escape_field(args)}`, $where: args => `WHERE ${args}`, $group_by: args => `GROUP BY ${args.join(', ')}`, $having: args => `HAVING ${args}`, $order_by: args => `ORDER BY ${args.join(', ')}`, $asc: args => `${args} ASC`, $desc: args => `${args} DESC`, $limit: args => `LIMIT ${args}`, $offset: args => `OFFSET ${args}`, $in: (args, path) => {
const [left_arg, right_arg] = args;
const left_arg_string = Array.isArray(left_arg)
? left_arg.map(val => `(${val})`).join(', ')
? `(${left_arg.map(val => `${wrap_if_subquery(val)}`).join(', ')})`
: left_arg;

@@ -231,7 +231,9 @@ const not_string = nested_under_odd_nots(path) ? ' NOT' : '';

.map(val => Array.isArray(val)
? `(${val.map(el => `(${el})`).join(', ')})`
: `(${val})`)
? `(${val
.map(el => wrap_if_subquery(el))
.join(', ')})`
: wrap_if_subquery(val))
.join(', ')
: right_arg;
return `(${left_arg_string})${not_string} IN (${right_arg_string})`;
return `${wrap_if_subquery(left_arg_string)}${not_string} IN (${right_arg_string})`;
}, $and: (args, path) => {

@@ -245,4 +247,4 @@ const res = `(${args.join(') AND (')})`;

const simple_eq = (left_val, right_val) => is_sql_null(right_val)
? `(${left_val}) IS${nested_under_odd_nots(path) ? ' NOT' : ''} NULL`
: `(${left_val}) ${nested_under_odd_nots(path) ? '!' : ''}= (${right_val})`;
? `${wrap_if_subquery(left_val)} IS${nested_under_odd_nots(path) ? ' NOT' : ''} NULL`
: `${wrap_if_subquery(left_val)} ${nested_under_odd_nots(path) ? '!' : ''}= ${wrap_if_subquery(right_val)}`;
const [left_arg, right_arg] = args;

@@ -259,3 +261,5 @@ // tuple equality, e.g. (id, parent_id) = (1, 2)

else {
return `(${left_arg.map(val => `(${val})`).join(', ')}) ${nested_under_odd_nots(path) ? '!' : ''}= (${right_arg.map(val => `(${val})`).join(', ')})`;
return `(${left_arg
.map(val => wrap_if_subquery(val))
.join(', ')}) ${nested_under_odd_nots(path) ? '!' : ''}= (${right_arg.map(val => wrap_if_subquery(val)).join(', ')})`;
}

@@ -265,3 +269,3 @@ }

return simple_eq(left_arg, right_arg);
}, $gt: (args, path) => `(${args[0]}) ${nested_under_odd_nots(path) ? '<=' : '>'} (${args[1]})`, $lt: (args, path) => `(${args[0]}) ${nested_under_odd_nots(path) ? '>=' : '<'} (${args[1]})`, $gte: (args, path) => `(${args[0]}) ${nested_under_odd_nots(path) ? '<' : '>='} (${args[1]})`, $lte: (args, path) => `(${args[0]}) ${nested_under_odd_nots(path) ? '>' : '<='} (${args[1]})`, $exists: (args, path) => `${nested_under_odd_nots(path) ? 'NOT ' : ''}EXISTS (${args})`, $like: (args, path) => {
}, $gt: (args, path) => `${wrap_if_subquery(args[0])} ${nested_under_odd_nots(path) ? '<=' : '>'} ${wrap_if_subquery(args[1])}`, $lt: (args, path) => `${wrap_if_subquery(args[0])} ${nested_under_odd_nots(path) ? '>=' : '<'} ${wrap_if_subquery(args[1])}`, $gte: (args, path) => `${wrap_if_subquery(args[0])} ${nested_under_odd_nots(path) ? '<' : '>='} ${wrap_if_subquery(args[1])}`, $lte: (args, path) => `${wrap_if_subquery(args[0])} ${nested_under_odd_nots(path) ? '>' : '<='} ${wrap_if_subquery(args[1])}`, $exists: (args, path) => `${nested_under_odd_nots(path) ? 'NOT ' : ''}EXISTS (${args})`, $like: (args, path) => {
// const string_arg = args[1].toString()

@@ -272,3 +276,3 @@ // const search_value = string_arg.replace(/^\'/, '').replace(/\'$/, '') // get rid of quotes if they were put there by escape()

// } LIKE '%${search_value}%'`
return `(${args[0]})${nested_under_odd_nots(path) ? ' NOT' : ''} LIKE (${args[1]})`;
return `${wrap_if_subquery(args[0])}${nested_under_odd_nots(path) ? ' NOT' : ''} LIKE ${wrap_if_subquery(args[1])}`;
}, $not: args => args }, Object.keys(exports.sql_function_definitions).reduce((acc, key) => {

@@ -283,3 +287,3 @@ acc[key] = exports.sql_function_definitions[key].ast_to_sql;

// alter
$alter_table: table_name => `ALTER TABLE ${table_name}`,
$alter_table: table_name => `ALTER TABLE \`${table_name}\``,
// definitions

@@ -344,2 +348,8 @@ $definitions: args => ((args === null || args === void 0 ? void 0 : args.length) ? `(${args.join(', ')})` : ''), $alter_operation: arg => arg === null || arg === void 0 ? void 0 : arg.toUpperCase(), $old_name: (arg, path, obj) => get_neighbour_field(obj, path, '$alter_operation') === 'rename'

$create_index: arg => `CREATE INDEX \`${arg}\``, $on: arg => `ON ${arg}` });
/**
* Only wrap SELECT ... statments with (), since sqlite doesnt support wrapping primitive values like
* numbers in (), I think its interpreting them as tuples when you do that
*/
const wrap_if_subquery = (val) => { var _a; return ((_a = val === null || val === void 0 ? void 0 : val.startsWith) === null || _a === void 0 ? void 0 : _a.call(val, 'SELECT')) ? `(${val})` : val; };
const escape_field = val => typeof val === 'string' && !['*'].includes(val) ? `\`${val}\`` : val;
const is_sql_null = val => {

@@ -346,0 +356,0 @@ var _a;

@@ -15,3 +15,3 @@ "use strict";

const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json));
const goal = (0, sql_formatter_1.format)(`SELECT a FROM b`);
const goal = (0, sql_formatter_1.format)(`SELECT a FROM \`b\``);
(0, chai_1.expect)(sql).to.equal(goal);

@@ -26,5 +26,14 @@ });

const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json));
const goal = (0, sql_formatter_1.format)('WHERE (a) = (b)');
const goal = (0, sql_formatter_1.format)('WHERE a = b');
(0, chai_1.expect)(sql).to.equal(goal);
});
(0, mocha_1.test)('handles selecting functions', () => {
const json = {
$select: [{ $as: ['SUM(views)', 'total_views'] }],
$from: 'posts',
};
const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json));
const goal = (0, sql_formatter_1.format)('SELECT SUM(views) AS total_views FROM \`posts\`');
(0, chai_1.expect)(sql).to.equal(goal);
});
(0, mocha_1.test)("'$not' command works", () => {

@@ -37,3 +46,3 @@ const json = {

const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json));
const goal = (0, sql_formatter_1.format)('(a) NOT IN ((1), (2))');
const goal = (0, sql_formatter_1.format)('a NOT IN (1, 2)');
(0, chai_1.expect)(sql).to.equal(goal);

@@ -59,3 +68,3 @@ });

const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json));
const goal = (0, sql_formatter_1.format)('((a) IS NOT NULL) AND ((a) IS NOT NULL)');
const goal = (0, sql_formatter_1.format)('(a IS NOT NULL) AND (a IS NOT NULL)');
(0, chai_1.expect)(sql).to.equal(goal);

@@ -71,3 +80,3 @@ });

const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json));
const goal = (0, sql_formatter_1.format)('((id), (parent_id)) = ((1), (2))');
const goal = (0, sql_formatter_1.format)('(id, parent_id) = (1, 2)');
(0, chai_1.expect)(sql).to.equal(goal);

@@ -85,3 +94,3 @@ });

const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json));
const goal = (0, sql_formatter_1.format)('((id) != (1)) AND ((parent_id) IS NOT NULL)');
const goal = (0, sql_formatter_1.format)('(id != 1) AND (parent_id IS NOT NULL)');
(0, chai_1.expect)(sql).to.equal(goal);

@@ -131,3 +140,3 @@ });

const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json));
const goal = (0, sql_formatter_1.format)(`IF ((1) = (1), "yes", "no")`);
const goal = (0, sql_formatter_1.format)(`IF (1 = 1, "yes", "no")`);
(0, chai_1.expect)(sql).to.equal(goal);

@@ -154,3 +163,3 @@ });

const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json));
const goal = (0, sql_formatter_1.format)('(a) IN ((1), (2))');
const goal = (0, sql_formatter_1.format)('a IN (1, 2)');
(0, chai_1.expect)(sql).to.equal(goal);

@@ -170,3 +179,3 @@ });

const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json));
const goal = (0, sql_formatter_1.format)("((a), (b)) IN (((1), ('c')), ((COALESCE(null, 2)), (3)))");
const goal = (0, sql_formatter_1.format)("(a, b) IN ((1, 'c'), (COALESCE(null, 2), 3))");
(0, chai_1.expect)(sql).to.equal(goal);

@@ -190,3 +199,3 @@ });

const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json));
const goal = (0, sql_formatter_1.format)('items.sku');
const goal = (0, sql_formatter_1.format)('`items`.`sku`');
(0, chai_1.expect)(sql).to.equal(goal);

@@ -210,8 +219,8 @@ });

HAVING
(SELECT
*
FROM
reviews
WHERE
(listing_id) = (0)) >= (4)`);
(SELECT
*
FROM
\`reviews\`
WHERE
listing_id = 0) >= 4`);
(0, chai_1.expect)(sql).to.equal(goal);

@@ -269,3 +278,3 @@ });

const goal = (0, sql_formatter_1.format)(`
ALTER TABLE my_table (
ALTER TABLE \`my_table\` (
ADD id INT,

@@ -414,3 +423,3 @@ DROP id,

const goal = (0, sql_formatter_1.format)(`
ALTER TABLE my_table (
ALTER TABLE \`my_table\` (
ADD INDEX invisible (label) INVISIBLE COMMENT "invis"

@@ -433,3 +442,3 @@ )`);

const goal = (0, sql_formatter_1.format)(`
ALTER TABLE my_table (
ALTER TABLE \`my_table\` (
ADD CONSTRAINT \`uq_ind\` UNIQUE (label)

@@ -452,3 +461,3 @@ )`);

const goal = (0, sql_formatter_1.format)(`
ALTER TABLE my_table (
ALTER TABLE \`my_table\` (
ADD FULLTEXT INDEX ft (size, label)

@@ -467,3 +476,3 @@ )`);

const goal = (0, sql_formatter_1.format)(`
CREATE INDEX \`my_index\` ON my_table (field1, field2)
CREATE INDEX \`my_index\` ON \`my_table\` (field1, field2)
`);

@@ -485,3 +494,3 @@ (0, chai_1.expect)((0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json))).to.equal(goal);

const goal = (0, sql_formatter_1.format)(`
ALTER TABLE my_table (
ALTER TABLE \`my_table\` (
ADD CONSTRAINT \`primary\` PRIMARY KEY (id)

@@ -518,7 +527,7 @@ )`);

const goal = (0, sql_formatter_1.format)(`
ALTER TABLE my_table (
ADD FOREIGN KEY (parent_id) REFERENCES parents (id),
ADD CONSTRAINT \`my_foreign_key\` FOREIGN KEY (parent_id) REFERENCES parents (id)
ALTER TABLE \`my_table\` (
ADD FOREIGN KEY (parent_id) REFERENCES \`parents\` (id),
ADD CONSTRAINT \`my_foreign_key\` FOREIGN KEY (parent_id) REFERENCES \`parents\` (id)
ON DELETE CASCADE ON UPDATE RESTRICT,
ADD FOREIGN KEY (parent_id) REFERENCES parents (id)
ADD FOREIGN KEY (parent_id) REFERENCES \`parents\` (id)
ON DELETE NO ACTION ON UPDATE SET NULL

@@ -525,0 +534,0 @@ )`);

import { GetAllEdges, GetAllEntities, GetFieldNotNull, GetFields, GetFieldType } from '../schema/schema_helper_types';
import { OrmaSchema } from '../schema/schema_types';
export type OrmaMutation<Schema extends OrmaSchema> = {
readonly [Entity in GetAllEntities<Schema>]?: readonly MutationRecord<Schema, Entity, true>[];
} | ({
readonly [Entity in GetAllEntities<Schema>]?: readonly MutationRecord<Schema, Entity, false>[];
} & {
readonly [Entity in GetAllEntities<Schema>]?: readonly MutationRecord<Schema, Entity>[];
} & OperationObj;
type MutationRecord<Schema extends OrmaSchema, Entity extends GetAllEntities<Schema>> = FieldsObj<Schema, Entity> & OperationObj & ForeignKeyFieldsObj<Schema, Entity, GetAllEdges<Schema, Entity>>;
type OperationObj = {
readonly $operation?: Operation;
});
type MutationRecord<Schema extends OrmaSchema, Entity extends GetAllEntities<Schema>, RequireOperation extends boolean> = FieldsObj<Schema, Entity> & OperationObj<RequireOperation> & ForeignKeyFieldsObj<Schema, Entity, GetAllEdges<Schema, Entity>>;
type OperationObj<RequireOperation extends boolean> = RequireOperation extends true ? {
readonly $operation: Operation;
} : {
readonly $operation?: Operation;
};

@@ -23,3 +17,3 @@ type Operation = 'create' | 'update' | 'delete' | 'upsert';

export type ForeignKeyFieldsObj<Schema extends OrmaSchema, Entity extends GetAllEntities<Schema>, AllEdges extends GetAllEdges<Schema, Entity>> = AllEdges extends never ? {} : AllEdges extends GetAllEdges<Schema, Entity> ? {
readonly [Field in AllEdges['to_entity']]?: readonly MutationRecord<Schema, Field, false>[];
readonly [Field in AllEdges['to_entity']]?: readonly MutationRecord<Schema, Field>[];
} : never;

@@ -26,0 +20,0 @@ export type FieldType<Schema extends OrmaSchema, Entity extends GetAllEntities<Schema>, Field extends GetFields<Schema, Entity>> = GetFieldType<Schema, Entity, Field> | NullableField<Schema, Entity, Field>;

@@ -49,2 +49,15 @@ "use strict";

}
{
// supports nesting with double map (not sure why, but double nested map can cause intellisense to fail)
const t = {
posts: [
{
title: 'test',
likes: [].map(el => ({
posts: [].map(el => ({})),
})),
},
],
};
}
};
{
"name": "orma",
"version": "1.0.225",
"version": "1.0.226",
"description": "A declarative relational syncronous orm",

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

@@ -140,3 +140,3 @@ import { expect } from 'chai'

sql_string:
"UPDATE users SET first_name = 'john' WHERE (id) = (1)",
"UPDATE users SET first_name = 'john' WHERE id = 1",
},

@@ -154,3 +154,3 @@ {

paths: [mutation_pieces[2].path],
sql_string: 'DELETE FROM products WHERE (id) = (1)',
sql_string: 'DELETE FROM products WHERE id = 1',
},

@@ -157,0 +157,0 @@ ],

@@ -130,3 +130,3 @@ import { validate } from 'jsonschema'

path: [key],
original_data: mutation,
// original_data: mutation,
},

@@ -201,3 +201,3 @@ ] as OrmaError[]

message: `Records must have an operation or an inherited operation.`,
original_data: mutation,
// original_data: mutation,
path: [...record_path, '$operation'],

@@ -264,3 +264,3 @@ },

path: [...record_path, key],
original_data: mutation,
// original_data: mutation,
},

@@ -286,3 +286,3 @@ ] as OrmaError[]

path: [...record_path, key],
original_data: mutation,
// original_data: mutation,
},

@@ -305,3 +305,3 @@ ] as OrmaError[]

path: [...record_path, key],
original_data: mutation,
// original_data: mutation,
},

@@ -353,3 +353,3 @@ ] as OrmaError[]

path: field_path,
original_data: mutation,
// original_data: mutation,
},

@@ -366,3 +366,3 @@ ]

path: field_path,
original_data: mutation,
// original_data: mutation,
},

@@ -388,3 +388,3 @@ ]

path: field_path,
original_data: mutation,
// original_data: mutation,
additional_info: {

@@ -425,3 +425,3 @@ enum_values,

path: field_path,
original_data: mutation,
// original_data: mutation,
additional_info: {

@@ -460,3 +460,3 @@ given_character_count,

path: field_path,
original_data: mutation,
// original_data: mutation,
},

@@ -471,3 +471,3 @@ ]

path: field_path,
original_data: mutation,
// original_data: mutation,
},

@@ -488,3 +488,3 @@ ]

path: field_path,
original_data: mutation,
// original_data: mutation,
additional_info: {

@@ -508,3 +508,3 @@ given_character_count,

path: field_path,
original_data: mutation,
// original_data: mutation,
additional_info: {

@@ -524,3 +524,3 @@ given_decimals,

path: field_path,
original_data: mutation,
// original_data: mutation,
additional_info: {

@@ -544,3 +544,3 @@ given_decimals,

path: field_path,
original_data: mutation,
// original_data: mutation,
},

@@ -569,3 +569,3 @@ ]

path: field_path,
original_data: mutation,
// original_data: mutation,
additional_info: {

@@ -617,3 +617,3 @@ required_data_type,

path: [...record_path, required_field],
original_data: mutation,
// original_data: mutation,
},

@@ -676,3 +676,3 @@ ]

// // path: [...record_path, '$operation'],
// // original_data: mutation,
// // // original_data: mutation,
// // additional_info: {

@@ -715,3 +715,3 @@ // // parent_entity,

// path: record_path,
// original_data: mutation,
// // original_data: mutation,
// // stack_trace: new Error().stack,

@@ -718,0 +718,0 @@ // additional_info: {

@@ -19,3 +19,3 @@ import { expect } from 'chai'

const sql = format(json_to_sql(json))
const goal = format(`SELECT a FROM b`)
const goal = format(`SELECT a FROM \`b\``)

@@ -32,6 +32,17 @@ expect(sql).to.equal(goal)

const sql = format(json_to_sql(json))
const goal = format('WHERE (a) = (b)')
const goal = format('WHERE a = b')
expect(sql).to.equal(goal)
})
test('handles selecting functions', () => {
const json = {
$select: [{ $as: ['SUM(views)', 'total_views'] }],
$from: 'posts',
}
const sql = format(json_to_sql(json))
const goal = format('SELECT SUM(views) AS total_views FROM \`posts\`')
expect(sql).to.equal(goal)
})
test("'$not' command works", () => {

@@ -45,3 +56,3 @@ const json = {

const sql = format(json_to_sql(json))
const goal = format('(a) NOT IN ((1), (2))')
const goal = format('a NOT IN (1, 2)')

@@ -69,3 +80,3 @@ expect(sql).to.equal(goal)

const sql = format(json_to_sql(json))
const goal = format('((a) IS NOT NULL) AND ((a) IS NOT NULL)')
const goal = format('(a IS NOT NULL) AND (a IS NOT NULL)')

@@ -83,3 +94,3 @@ expect(sql).to.equal(goal)

const sql = format(json_to_sql(json))
const goal = format('((id), (parent_id)) = ((1), (2))')
const goal = format('(id, parent_id) = (1, 2)')

@@ -99,3 +110,3 @@ expect(sql).to.equal(goal)

const sql = format(json_to_sql(json))
const goal = format('((id) != (1)) AND ((parent_id) IS NOT NULL)')
const goal = format('(id != 1) AND (parent_id IS NOT NULL)')

@@ -152,3 +163,3 @@ expect(sql).to.equal(goal)

const sql = format(json_to_sql(json))
const goal = format(`IF ((1) = (1), "yes", "no")`)
const goal = format(`IF (1 = 1, "yes", "no")`)
expect(sql).to.equal(goal)

@@ -177,3 +188,3 @@ })

const sql = format(json_to_sql(json))
const goal = format('(a) IN ((1), (2))')
const goal = format('a IN (1, 2)')

@@ -195,5 +206,3 @@ expect(sql).to.equal(goal)

const sql = format(json_to_sql(json))
const goal = format(
"((a), (b)) IN (((1), ('c')), ((COALESCE(null, 2)), (3)))"
)
const goal = format("(a, b) IN ((1, 'c'), (COALESCE(null, 2), 3))")

@@ -219,3 +228,3 @@ expect(sql).to.equal(goal)

const sql = format(json_to_sql(json))
const goal = format('items.sku')
const goal = format('`items`.`sku`')

@@ -242,8 +251,8 @@ expect(sql).to.equal(goal)

HAVING
(SELECT
*
FROM
reviews
WHERE
(listing_id) = (0)) >= (4)`)
(SELECT
*
FROM
\`reviews\`
WHERE
listing_id = 0) >= 4`)

@@ -305,3 +314,3 @@ expect(sql).to.equal(goal)

const goal = format(`
ALTER TABLE my_table (
ALTER TABLE \`my_table\` (
ADD id INT,

@@ -464,3 +473,3 @@ DROP id,

const goal = format(`
ALTER TABLE my_table (
ALTER TABLE \`my_table\` (
ADD INDEX invisible (label) INVISIBLE COMMENT "invis"

@@ -485,3 +494,3 @@ )`)

const goal = format(`
ALTER TABLE my_table (
ALTER TABLE \`my_table\` (
ADD CONSTRAINT \`uq_ind\` UNIQUE (label)

@@ -506,3 +515,3 @@ )`)

const goal = format(`
ALTER TABLE my_table (
ALTER TABLE \`my_table\` (
ADD FULLTEXT INDEX ft (size, label)

@@ -523,3 +532,3 @@ )`)

const goal = format(`
CREATE INDEX \`my_index\` ON my_table (field1, field2)
CREATE INDEX \`my_index\` ON \`my_table\` (field1, field2)
`)

@@ -543,3 +552,3 @@

const goal = format(`
ALTER TABLE my_table (
ALTER TABLE \`my_table\` (
ADD CONSTRAINT \`primary\` PRIMARY KEY (id)

@@ -588,7 +597,7 @@ )`)

const goal = format(`
ALTER TABLE my_table (
ADD FOREIGN KEY (parent_id) REFERENCES parents (id),
ADD CONSTRAINT \`my_foreign_key\` FOREIGN KEY (parent_id) REFERENCES parents (id)
ALTER TABLE \`my_table\` (
ADD FOREIGN KEY (parent_id) REFERENCES \`parents\` (id),
ADD CONSTRAINT \`my_foreign_key\` FOREIGN KEY (parent_id) REFERENCES \`parents\` (id)
ON DELETE CASCADE ON UPDATE RESTRICT,
ADD FOREIGN KEY (parent_id) REFERENCES parents (id)
ADD FOREIGN KEY (parent_id) REFERENCES \`parents\` (id)
ON DELETE NO ACTION ON UPDATE SET NULL

@@ -595,0 +604,0 @@ )`)

@@ -310,6 +310,6 @@ /**

$select: args => `SELECT ${args.join(', ')}`,
$as: args => `(${args[0]}) AS ${args[1]}`,
$entity: args => `${args}`,
$field: args => `.${args}`,
$from: args => `FROM ${args}`,
$as: args => `${wrap_if_subquery(args[0])} AS ${args[1]}`,
$entity: args => `${escape_field(args)}`,
$field: args => `.${escape_field(args)}`,
$from: args => `FROM ${escape_field(args)}`,
$where: args => `WHERE ${args}`,

@@ -326,3 +326,3 @@ $group_by: args => `GROUP BY ${args.join(', ')}`,

const left_arg_string = Array.isArray(left_arg)
? left_arg.map(val => `(${val})`).join(', ')
? `(${left_arg.map(val => `${wrap_if_subquery(val)}`).join(', ')})`
: left_arg

@@ -334,4 +334,6 @@ const not_string = nested_under_odd_nots(path) ? ' NOT' : ''

Array.isArray(val)
? `(${val.map(el => `(${el})`).join(', ')})`
: `(${val})`
? `(${val
.map(el => wrap_if_subquery(el))
.join(', ')})`
: wrap_if_subquery(val)
)

@@ -341,3 +343,5 @@ .join(', ')

return `(${left_arg_string})${not_string} IN (${right_arg_string})`
return `${wrap_if_subquery(
left_arg_string
)}${not_string} IN (${right_arg_string})`
},

@@ -357,8 +361,8 @@ $and: (args, path) => {

is_sql_null(right_val)
? `(${left_val}) IS${
? `${wrap_if_subquery(left_val)} IS${
nested_under_odd_nots(path) ? ' NOT' : ''
} NULL`
: `(${left_val}) ${
: `${wrap_if_subquery(left_val)} ${
nested_under_odd_nots(path) ? '!' : ''
}= (${right_val})`
}= ${wrap_if_subquery(right_val)}`

@@ -375,5 +379,7 @@ const [left_arg, right_arg] = args

} else {
return `(${left_arg.map(val => `(${val})`).join(', ')}) ${
return `(${left_arg
.map(val => wrap_if_subquery(val))
.join(', ')}) ${
nested_under_odd_nots(path) ? '!' : ''
}= (${right_arg.map(val => `(${val})`).join(', ')})`
}= (${right_arg.map(val => wrap_if_subquery(val)).join(', ')})`
}

@@ -386,9 +392,17 @@ }

$gt: (args, path) =>
`(${args[0]}) ${nested_under_odd_nots(path) ? '<=' : '>'} (${args[1]})`,
`${wrap_if_subquery(args[0])} ${
nested_under_odd_nots(path) ? '<=' : '>'
} ${wrap_if_subquery(args[1])}`,
$lt: (args, path) =>
`(${args[0]}) ${nested_under_odd_nots(path) ? '>=' : '<'} (${args[1]})`,
`${wrap_if_subquery(args[0])} ${
nested_under_odd_nots(path) ? '>=' : '<'
} ${wrap_if_subquery(args[1])}`,
$gte: (args, path) =>
`(${args[0]}) ${nested_under_odd_nots(path) ? '<' : '>='} (${args[1]})`,
`${wrap_if_subquery(args[0])} ${
nested_under_odd_nots(path) ? '<' : '>='
} ${wrap_if_subquery(args[1])}`,
$lte: (args, path) =>
`(${args[0]}) ${nested_under_odd_nots(path) ? '>' : '<='} (${args[1]})`,
`${wrap_if_subquery(args[0])} ${
nested_under_odd_nots(path) ? '>' : '<='
} ${wrap_if_subquery(args[1])}`,
$exists: (args, path) =>

@@ -402,5 +416,5 @@ `${nested_under_odd_nots(path) ? 'NOT ' : ''}EXISTS (${args})`,

// } LIKE '%${search_value}%'`
return `(${args[0]})${
return `${wrap_if_subquery(args[0])}${
nested_under_odd_nots(path) ? ' NOT' : ''
} LIKE (${args[1]})`
} LIKE ${wrap_if_subquery(args[1])}`
},

@@ -428,3 +442,3 @@ $not: args => args, // not logic is different depending on the children, so the children handle it

// alter
$alter_table: table_name => `ALTER TABLE ${table_name}`,
$alter_table: table_name => `ALTER TABLE \`${table_name}\``,
// definitions

@@ -522,2 +536,12 @@ $definitions: args => (args?.length ? `(${args.join(', ')})` : ''),

/**
* Only wrap SELECT ... statments with (), since sqlite doesnt support wrapping primitive values like
* numbers in (), I think its interpreting them as tuples when you do that
*/
const wrap_if_subquery = (val: string) =>
val?.startsWith?.('SELECT') ? `(${val})` : val
const escape_field = val =>
typeof val === 'string' && !['*'].includes(val) ? `\`${val}\`` : val
const is_sql_null = val => {

@@ -524,0 +548,0 @@ const is_regular_null = val === null

@@ -49,2 +49,17 @@ import { GlobalTestMutation } from '../../test_data/global_test_schema'

}
{
// supports nesting with double map (not sure why, but double nested map can cause intellisense to fail)
const t = {
posts: [
{
title: 'test',
likes: [].map(el => ({
posts: [].map(el => ({
})),
})),
},
],
} as const satisfies GlobalTestMutation
}
}

@@ -12,38 +12,19 @@ import { GlobalTestSchema } from '../../test_data/global_test_schema'

export type OrmaMutation<Schema extends OrmaSchema> =
| {
readonly [Entity in GetAllEntities<Schema>]?: readonly MutationRecord<
Schema,
Entity,
// we only need to do this on the top level, since after the highest entity everything will have an operation,
// either directly provided or through cascading from the highest entity
true
>[]
}
| ({
readonly [Entity in GetAllEntities<Schema>]?: readonly MutationRecord<
Schema,
Entity,
false
>[]
} & {
readonly $operation?: Operation
})
export type OrmaMutation<Schema extends OrmaSchema> = {
readonly [Entity in GetAllEntities<Schema>]?: readonly MutationRecord<
Schema,
Entity
>[]
} & OperationObj
type MutationRecord<
Schema extends OrmaSchema,
Entity extends GetAllEntities<Schema>,
RequireOperation extends boolean
Entity extends GetAllEntities<Schema>
> = FieldsObj<Schema, Entity> &
OperationObj<RequireOperation> &
OperationObj &
ForeignKeyFieldsObj<Schema, Entity, GetAllEdges<Schema, Entity>>
type OperationObj<RequireOperation extends boolean> =
RequireOperation extends true
? {
readonly $operation: Operation
}
: {
readonly $operation?: Operation
}
type OperationObj = {
readonly $operation?: Operation
}

@@ -56,4 +37,4 @@ type Operation = 'create' | 'update' | 'delete' | 'upsert'

> = {
readonly // baseline for regular props
[Field in GetFields<Schema, Entity>]?:
// baseline for regular props
readonly [Field in GetFields<Schema, Entity>]?:
| FieldType<Schema, Entity, Field>

@@ -87,4 +68,3 @@ // primary or foreign keys can have guids

Schema,
Field,
false
Field
>[]

@@ -91,0 +71,0 @@ }

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