Comparing version 1.0.24 to 1.0.28
"use strict"; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) | ||
to[j] = from[i]; | ||
return to; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.extract_subpaths = void 0; | ||
var helpers_1 = require("./helpers"); | ||
const helpers_1 = require("./helpers"); | ||
/** | ||
@@ -33,7 +12,5 @@ * | ||
*/ | ||
var extract_subpaths = function (template_path, obj) { | ||
var subpaths = []; | ||
var get_subpaths_recursive = function (path_template, obj, recursion_depth, current_path) { | ||
if (recursion_depth === void 0) { recursion_depth = 0; } | ||
if (current_path === void 0) { current_path = []; } | ||
const extract_subpaths = (template_path, obj) => { | ||
let subpaths = []; | ||
const get_subpaths_recursive = (path_template, obj, recursion_depth = 0, current_path = []) => { | ||
if (recursion_depth === path_template.length) { | ||
@@ -44,8 +21,6 @@ subpaths.push(current_path); | ||
(helpers_1.deep_get(current_path, obj) || []) | ||
.forEach(function (el, i) { | ||
return get_subpaths_recursive(path_template, obj, recursion_depth + 1, __spreadArray(__spreadArray([], __read(current_path)), [i])); | ||
}); | ||
.forEach((el, i) => get_subpaths_recursive(path_template, obj, recursion_depth + 1, [...current_path, i])); | ||
} | ||
else { | ||
get_subpaths_recursive(path_template, obj, recursion_depth + 1, __spreadArray(__spreadArray([], __read(current_path)), [path_template[recursion_depth]])); | ||
get_subpaths_recursive(path_template, obj, recursion_depth + 1, [...current_path, path_template[recursion_depth]]); | ||
} | ||
@@ -52,0 +27,0 @@ }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var chai_1 = require("chai"); | ||
var mocha_1 = require("mocha"); | ||
var extract_subpaths_1 = require("./extract_subpaths"); | ||
mocha_1.describe('Extract subpaths', function () { | ||
mocha_1.test('Extracts subpaths from arrays', function () { | ||
var products = [{ | ||
const chai_1 = require("chai"); | ||
const mocha_1 = require("mocha"); | ||
const extract_subpaths_1 = require("./extract_subpaths"); | ||
mocha_1.describe('Extract subpaths', () => { | ||
mocha_1.test('Extracts subpaths from arrays', () => { | ||
const products = [{ | ||
id: 1, | ||
@@ -23,4 +23,4 @@ title: 'Phone', | ||
}]; | ||
var template_path = [0, 'variants', 0]; | ||
var goal = [ | ||
const template_path = [0, 'variants', 0]; | ||
const goal = [ | ||
[0, 'variants', 0], | ||
@@ -31,5 +31,5 @@ [1, 'variants', 0], | ||
]; | ||
var subpaths = extract_subpaths_1.extract_subpaths(template_path, products); | ||
const subpaths = extract_subpaths_1.extract_subpaths(template_path, products); | ||
chai_1.expect(subpaths).to.deep.equal(goal); | ||
}); | ||
}); |
"use strict"; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) | ||
to[j] = from[i]; | ||
return to; | ||
}; | ||
var __values = (this && this.__values) || function(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.clone = exports.deep_for_each = exports.deep_map = exports.deep_get = exports.deep_set = exports.last = exports.drop = exports.type = void 0; | ||
var type = function (value) { | ||
const type = (value) => { | ||
return value === null | ||
@@ -44,24 +12,24 @@ ? 'Null' | ||
exports.type = type; | ||
var drop = function (num, arr) { return arr.slice(0, -num); }; | ||
const drop = (num, arr) => arr.slice(0, -num); | ||
exports.drop = drop; | ||
var last = function (array) { return array[array.length - 1]; }; | ||
const last = (array) => array[array.length - 1]; | ||
exports.last = last; | ||
var deep_set = function (path_array, value, obj) { | ||
const deep_set = (path_array, value, obj) => { | ||
if (path_array.length === 0) | ||
return obj; | ||
var pointer = obj; | ||
for (var i = 0; i < path_array.length; i++) { | ||
var path_el = path_array[i]; | ||
var next_path_el = i !== path_array.length - 1 | ||
let pointer = obj; | ||
for (let i = 0; i < path_array.length; i++) { | ||
const path_el = path_array[i]; | ||
const next_path_el = i !== path_array.length - 1 | ||
? path_array[i + 1] | ||
: undefined; | ||
var next_el_default = exports.type(next_path_el) === 'Number' | ||
const next_el_default = exports.type(next_path_el) === 'Number' | ||
? [] | ||
: {}; | ||
var is_array = Array.isArray(pointer); | ||
var is_object = exports.type(pointer) === 'Object'; | ||
const is_array = Array.isArray(pointer); | ||
const is_object = exports.type(pointer) === 'Object'; | ||
// if (is_array && type(path_el) !== 'Number') { | ||
// throw new Error('Trying to path into an array without a number index') | ||
// } | ||
var contains_path_el = is_array ? path_el < pointer.length | ||
const contains_path_el = is_array ? path_el < pointer.length | ||
: is_object ? path_el in pointer | ||
@@ -71,9 +39,9 @@ : false; | ||
if (is_array) { | ||
var items_to_add = new Array(Number(path_el) - pointer.length).map(function (el) { return undefined; }); | ||
pointer.push.apply(pointer, __spreadArray([], __read(items_to_add))); | ||
const items_to_add = new Array(Number(path_el) - pointer.length).map(el => undefined); | ||
pointer.push(...items_to_add); | ||
} | ||
pointer[path_el] = next_el_default; | ||
} | ||
var child_type = exports.type(pointer[path_el]); | ||
var child_is_primitive = child_type !== 'Object' && child_type !== 'Array'; | ||
const child_type = exports.type(pointer[path_el]); | ||
const child_is_primitive = child_type !== 'Object' && child_type !== 'Array'; | ||
if (!contains_path_el || child_is_primitive) { | ||
@@ -89,32 +57,20 @@ pointer[path_el] = next_el_default; | ||
exports.deep_set = deep_set; | ||
var deep_get = function (path_array, obj, default_value) { | ||
var e_1, _a; | ||
if (default_value === void 0) { default_value = undefined; } | ||
var pointer = obj; | ||
try { | ||
for (var path_array_1 = __values(path_array), path_array_1_1 = path_array_1.next(); !path_array_1_1.done; path_array_1_1 = path_array_1.next()) { | ||
var path_el = path_array_1_1.value; | ||
var is_array = Array.isArray(pointer); | ||
var is_object = exports.type(pointer) === 'Object'; | ||
// if (is_array && type(path_el) !== 'Number') { | ||
// throw new Error('Trying to path into an array without a number index') | ||
// } | ||
var contains_path_el = is_array ? path_el < pointer.length | ||
: is_object ? path_el in pointer | ||
: false; | ||
if (contains_path_el) { | ||
pointer = pointer[path_el]; | ||
continue; | ||
} | ||
else { | ||
return default_value; | ||
} | ||
const deep_get = (path_array, obj, default_value = undefined) => { | ||
let pointer = obj; | ||
for (const path_el of path_array) { | ||
const is_array = Array.isArray(pointer); | ||
const is_object = exports.type(pointer) === 'Object'; | ||
// if (is_array && type(path_el) !== 'Number') { | ||
// throw new Error('Trying to path into an array without a number index') | ||
// } | ||
const contains_path_el = is_array ? path_el < pointer.length | ||
: is_object ? path_el in pointer | ||
: false; | ||
if (contains_path_el) { | ||
pointer = pointer[path_el]; | ||
continue; | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (path_array_1_1 && !path_array_1_1.done && (_a = path_array_1.return)) _a.call(path_array_1); | ||
else { | ||
return default_value; | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
@@ -130,9 +86,8 @@ return pointer; | ||
*/ | ||
var deep_map = function (item, processor, current_path) { | ||
if (current_path === void 0) { current_path = []; } | ||
var mapped_item; | ||
const deep_map = (item, processor, current_path = []) => { | ||
let mapped_item; | ||
if (Array.isArray(item)) { | ||
mapped_item = item.map(function (el, i) { | ||
var new_path = __spreadArray(__spreadArray([], __read(current_path)), [i]); | ||
var subitem = exports.deep_map(el, processor, new_path); | ||
mapped_item = item.map((el, i) => { | ||
const new_path = [...current_path, i]; | ||
const subitem = exports.deep_map(el, processor, new_path); | ||
return subitem; | ||
@@ -142,5 +97,5 @@ }); | ||
else if (typeof item === 'object') { | ||
mapped_item = Object.keys(item).reduce(function (acc, key) { | ||
var new_path = __spreadArray(__spreadArray([], __read(current_path)), [key]); | ||
var subitem = exports.deep_map(item[key], processor, new_path); | ||
mapped_item = Object.keys(item).reduce((acc, key) => { | ||
const new_path = [...current_path, key]; | ||
const subitem = exports.deep_map(item[key], processor, new_path); | ||
acc[key] = subitem; | ||
@@ -166,11 +121,10 @@ return acc; | ||
*/ | ||
var deep_for_each = function (item, processor, current_path) { | ||
if (current_path === void 0) { current_path = []; } | ||
var is_object = typeof item === 'object' && !Array.isArray(item); | ||
var is_array = typeof item === 'object' && Array.isArray(item); | ||
var is_primitive = !is_object && !is_array; | ||
const deep_for_each = (item, processor, current_path = []) => { | ||
const is_object = typeof item === 'object' && !Array.isArray(item); | ||
const is_array = typeof item === 'object' && Array.isArray(item); | ||
const is_primitive = !is_object && !is_array; | ||
if (is_object) { | ||
processor(item, current_path); | ||
for (var prop in item) { | ||
exports.deep_for_each(item[prop], processor, __spreadArray(__spreadArray([], __read(current_path)), [prop])); | ||
for (const prop in item) { | ||
exports.deep_for_each(item[prop], processor, [...current_path, prop]); | ||
} | ||
@@ -180,4 +134,4 @@ } | ||
processor(item, current_path); | ||
item.forEach(function (el, i) { | ||
exports.deep_for_each(el, processor, __spreadArray(__spreadArray([], __read(current_path)), [i])); | ||
item.forEach((el, i) => { | ||
exports.deep_for_each(el, processor, [...current_path, i]); | ||
}); | ||
@@ -203,3 +157,3 @@ } | ||
*/ | ||
var clone = function (obj) { | ||
const clone = (obj) => { | ||
if (typeof obj == 'function') { | ||
@@ -206,0 +160,0 @@ return obj; |
"use strict"; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) | ||
to[j] = from[i]; | ||
return to; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -36,4 +15,3 @@ exports.lir_join = void 0; | ||
*/ | ||
var lir_join = function (left_list, inner_list, right_list, left_fn, inner_fn, right_fn) { | ||
var _a, _b; | ||
const lir_join = (left_list, inner_list, right_list, left_fn, inner_fn, right_fn) => { | ||
// Safety check called once per invocation | ||
@@ -50,6 +28,6 @@ if (!Array.isArray(left_list)) | ||
throw new Error('Inner function must be a function'); | ||
var memory = {}; | ||
for (var i = 0; i < left_list.length; i++) { | ||
var left_list_el = left_list[i]; | ||
var left_list_val = left_fn(left_list_el); | ||
let memory = {}; | ||
for (let i = 0; i < left_list.length; i++) { | ||
const left_list_el = left_list[i]; | ||
const left_list_val = left_fn(left_list_el); | ||
if (!memory[left_list_val]) | ||
@@ -59,5 +37,5 @@ memory[left_list_val] = { left: [], right: [] }; | ||
} | ||
for (var i = 0; i < right_list.length; i++) { | ||
var right_list_el = right_list[i]; | ||
var right_list_val = right_fn(right_list_el); | ||
for (let i = 0; i < right_list.length; i++) { | ||
const right_list_el = right_list[i]; | ||
const right_list_val = right_fn(right_list_el); | ||
if (!memory[right_list_val]) | ||
@@ -67,8 +45,8 @@ memory[right_list_val] = { left: [], right: [] }; | ||
} | ||
var output = { left: [], inner: inner_list, right: [] }; | ||
var keys = Object.keys(memory); | ||
for (var i = 0; i < keys.length; i++) { | ||
var key = keys[i]; | ||
let output = { left: [], inner: inner_list, right: [] }; | ||
const keys = Object.keys(memory); | ||
for (let i = 0; i < keys.length; i++) { | ||
const key = keys[i]; | ||
if (memory[key].left.length > 0 && memory[key].right.length === 0) { | ||
(_a = output.left).push.apply(_a, __spreadArray([], __read(memory[key].left))); | ||
output.left.push(...memory[key].left); | ||
} | ||
@@ -79,3 +57,3 @@ if (memory[key].left.length > 0 && memory[key].right.length > 0) { | ||
if (memory[key].left.length === 0 && memory[key].right.length > 0) { | ||
(_b = output.right).push.apply(_b, __spreadArray([], __read(memory[key].right))); | ||
output.right.push(...memory[key].right); | ||
} | ||
@@ -82,0 +60,0 @@ } |
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) | ||
to[j] = from[i]; | ||
return to; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var chai_1 = require("chai"); | ||
var mocha_1 = require("mocha"); | ||
var extract_subpaths_1 = require("./extract_subpaths"); | ||
var helpers_1 = require("./helpers"); | ||
var lir_join_1 = require("./lir_join"); | ||
var push_path_1 = require("./push_path"); | ||
mocha_1.describe('lir_join', function () { | ||
mocha_1.test('Merges flat lists', function () { | ||
var products = [{ id: 1, title: 'Laptop' }]; | ||
var product_in_stores = [{ product_id: 1, store_id: 1 }]; | ||
var goal = [{ | ||
const chai_1 = require("chai"); | ||
const mocha_1 = require("mocha"); | ||
const extract_subpaths_1 = require("./extract_subpaths"); | ||
const helpers_1 = require("./helpers"); | ||
const lir_join_1 = require("./lir_join"); | ||
const push_path_1 = require("./push_path"); | ||
mocha_1.describe('lir_join', () => { | ||
mocha_1.test('Merges flat lists', () => { | ||
const products = [{ id: 1, title: 'Laptop' }]; | ||
const product_in_stores = [{ product_id: 1, store_id: 1 }]; | ||
const goal = [{ | ||
id: 1, title: 'Laptop', | ||
product_in_stores: [{ product_id: 1, store_id: 1 }] | ||
}]; | ||
var _a = lir_join_1.lir_join(products, [], product_in_stores, function (el) { return el.id; }, function (l, i, r) { i.push(__assign(__assign({}, l[0]), { product_in_stores: r })); return i; }, function (el) { return el.product_id; }), left = _a.left, inner = _a.inner, right = _a.right; | ||
const { left, inner, right } = lir_join_1.lir_join(products, [], product_in_stores, el => el.id, (l, i, r) => { i.push(Object.assign(Object.assign({}, l[0]), { product_in_stores: r })); return i; }, el => el.product_id); | ||
chai_1.expect(left).to.deep.equal([]); | ||
@@ -54,10 +22,10 @@ chai_1.expect(inner).to.deep.equal(goal); | ||
}); | ||
mocha_1.test('Nests many entities to one location (right to left)', function () { | ||
var products = [{ id: 1, title: 'Laptop' }]; | ||
var product_in_stores = [{ product_id: 1, store_id: 1 }, { product_id: 1, store_id: 2 }]; | ||
var goal = [{ | ||
mocha_1.test('Nests many entities to one location (right to left)', () => { | ||
const products = [{ id: 1, title: 'Laptop' }]; | ||
const product_in_stores = [{ product_id: 1, store_id: 1 }, { product_id: 1, store_id: 2 }]; | ||
const goal = [{ | ||
id: 1, title: 'Laptop', | ||
product_in_stores: [{ product_id: 1, store_id: 1 }, { product_id: 1, store_id: 2 }] | ||
}]; | ||
var _a = lir_join_1.lir_join(products, [], product_in_stores, function (el) { return el.id; }, function (l, i, r) { i.push(__assign(__assign({}, l[0]), { product_in_stores: r })); return i; }, function (el) { return el.product_id; }), left = _a.left, inner = _a.inner, right = _a.right; | ||
const { left, inner, right } = lir_join_1.lir_join(products, [], product_in_stores, el => el.id, (l, i, r) => { i.push(Object.assign(Object.assign({}, l[0]), { product_in_stores: r })); return i; }, el => el.product_id); | ||
chai_1.expect(left).to.deep.equal([]); | ||
@@ -67,10 +35,10 @@ chai_1.expect(inner).to.deep.equal(goal); | ||
}); | ||
mocha_1.test('Nests many entities to one location (left to right)', function () { | ||
var products = [{ id: 1, title: 'Laptop' }]; | ||
var product_in_stores = [{ product_id: 1, store_id: 1 }, { product_id: 1, store_id: 2 }]; | ||
var goal = [{ | ||
mocha_1.test('Nests many entities to one location (left to right)', () => { | ||
const products = [{ id: 1, title: 'Laptop' }]; | ||
const product_in_stores = [{ product_id: 1, store_id: 1 }, { product_id: 1, store_id: 2 }]; | ||
const goal = [{ | ||
id: 1, title: 'Laptop', | ||
product_in_stores: [{ product_id: 1, store_id: 1 }, { product_id: 1, store_id: 2 }] | ||
}]; | ||
var _a = lir_join_1.lir_join(product_in_stores, [], products, function (el) { return el.product_id; }, function (l, i, r) { i.push(__assign(__assign({}, r[0]), { product_in_stores: l })); return i; }, function (el) { return el.id; }), left = _a.left, inner = _a.inner, right = _a.right; | ||
const { left, inner, right } = lir_join_1.lir_join(product_in_stores, [], products, el => el.product_id, (l, i, r) => { i.push(Object.assign(Object.assign({}, r[0]), { product_in_stores: l })); return i; }, el => el.id); | ||
chai_1.expect(left).to.deep.equal([]); | ||
@@ -80,3 +48,3 @@ chai_1.expect(inner).to.deep.equal(goal); | ||
}); | ||
mocha_1.test('Deeply nests', function () { | ||
mocha_1.test('Deeply nests', () => { | ||
// This is a deep nest because images are going on the variant which is on the product | ||
@@ -87,3 +55,3 @@ // The example includes a scenario with multiple images on a variant | ||
// Setup | ||
var products = [{ | ||
const products = [{ | ||
id: 1, | ||
@@ -103,3 +71,3 @@ title: 'Phone', | ||
}]; | ||
var images = [ | ||
const images = [ | ||
{ id: 111, variant_id: 11, bucket_url: 'http://www.phone.jpg' }, | ||
@@ -111,3 +79,3 @@ { id: 222, variant_id: 22, bucket_url: 'http://www.tbgreen.jpg' }, | ||
]; | ||
var goal = [{ | ||
const goal = [{ | ||
id: 1, | ||
@@ -135,20 +103,20 @@ title: 'Phone', | ||
}]; | ||
var _a = lir_join_1.lir_join(extract_subpaths_1.extract_subpaths([0, 'variants', 0], products), products, images, function (left_el) { return helpers_1.deep_get(__spreadArray(__spreadArray([], __read(left_el)), ['id']), products); }, function (l, i, r) { | ||
const { left, inner, right } = lir_join_1.lir_join(extract_subpaths_1.extract_subpaths([0, 'variants', 0], products), products, images, (left_el) => helpers_1.deep_get([...left_el, 'id'], products), (l, i, r) => { | ||
// for each image, mutate inner | ||
// placing the element at correct subpath with images appended to path | ||
r.forEach(function (right_adjacent) { return push_path_1.push_path(__spreadArray(__spreadArray([], __read(l[0])), ['images']), right_adjacent, i); }); | ||
r.forEach(right_adjacent => push_path_1.push_path([...l[0], 'images'], right_adjacent, i)); | ||
return i; | ||
}, function (el) { return el.variant_id; }), left = _a.left, inner = _a.inner, right = _a.right; | ||
chai_1.expect(left.map(function (left_el) { return helpers_1.deep_get(left_el, products); })).to.deep.equal([{ id: 44, sku: 'tssu1-pink' }]); | ||
}, el => el.variant_id); | ||
chai_1.expect(left.map(left_el => helpers_1.deep_get(left_el, products))).to.deep.equal([{ id: 44, sku: 'tssu1-pink' }]); | ||
chai_1.expect(inner).to.deep.equal(goal); | ||
chai_1.expect(right).to.deep.equal([{ id: 555, variant_id: 55, bucket_url: 'http://www.stray.purple.jpg' }]); | ||
}); | ||
mocha_1.test('Accepts undefined as if it was a string', function () { | ||
mocha_1.test('Accepts undefined as if it was a string', () => { | ||
// obj[undefined] in js is the same as obj['undefined'] | ||
var list1 = [1, 2, 3]; | ||
var list2 = [2, 4, 6, undefined]; | ||
var _a = lir_join_1.lir_join(list1, [], list2, function (el) { return el; }, function (l, i, r) { | ||
const list1 = [1, 2, 3]; | ||
const list2 = [2, 4, 6, undefined]; | ||
const { left, inner, right } = lir_join_1.lir_join(list1, [], list2, el => el, (l, i, r) => { | ||
i.push(l[0]); | ||
return i; | ||
}, function (el) { return el; }), left = _a.left, inner = _a.inner, right = _a.right; | ||
}, el => el); | ||
chai_1.expect(left).to.deep.equal([1, 3]); | ||
@@ -158,7 +126,7 @@ chai_1.expect(inner).to.deep.equal([2]); | ||
}); | ||
mocha_1.test('Accepts undefined as if it was a string in object', function () { | ||
mocha_1.test('Accepts undefined as if it was a string in object', () => { | ||
// obj[undefined] in js is the same as obj['undefined'] | ||
var original = [{ id: 6, quantity: 1, reason: 'customer' }]; | ||
var modified = [{ quantity: 1, reason: 'customer' }]; | ||
var _a = lir_join_1.lir_join(original, [], modified, function (x) { return x.id; }, function (l, i, r) { | ||
const original = [{ id: 6, quantity: 1, reason: 'customer' }]; | ||
const modified = [{ quantity: 1, reason: 'customer' }]; | ||
const { left, inner, right } = lir_join_1.lir_join(original, [], modified, x => x.id, (l, i, r) => { | ||
// if (l.length !== 1 || r.length !== 1) throw new Error('You must not have arrays where id is same across more than one entry eg [{id:2},{id:2}]') | ||
@@ -172,3 +140,3 @@ // const left_obj = l[0] | ||
return i; | ||
}, function (x) { return x.id; }), left = _a.left, inner = _a.inner, right = _a.right; | ||
}, x => x.id); | ||
chai_1.expect(left).to.deep.equal(original); | ||
@@ -179,10 +147,10 @@ chai_1.expect(inner).to.deep.equal([]); | ||
mocha_1.test.skip('preserves order of elements in array'); | ||
mocha_1.test.skip('Nests multiple entities', function () { | ||
var variants = [{ id: 1, sku: 'mysku1' }]; | ||
var variant_in_stores = [{ variant_id: 1, price: 19.99 }]; | ||
var images = [{ variant_id: 1, bucket_url: 'http:...' }]; | ||
mocha_1.test.skip('Nests multiple entities', () => { | ||
const variants = [{ id: 1, sku: 'mysku1' }]; | ||
const variant_in_stores = [{ variant_id: 1, price: 19.99 }]; | ||
const images = [{ variant_id: 1, bucket_url: 'http:...' }]; | ||
}); | ||
mocha_1.test.skip('Flips nests deeply', function () { | ||
var orders = []; | ||
var boxes = []; | ||
mocha_1.test.skip('Flips nests deeply', () => { | ||
const orders = []; | ||
const boxes = []; | ||
// chain prop it | ||
@@ -193,9 +161,9 @@ // weld it | ||
}); | ||
mocha_1.test.skip('Merges lists', function () { | ||
var products1 = [{ id: 1, title: 'title1' }, { id: 2, title: 'title2' }]; | ||
var products2 = [{ id: 2, title: 'title22' }, { id: 3, title: 'title3' }]; | ||
mocha_1.test.skip('Merges lists', () => { | ||
const products1 = [{ id: 1, title: 'title1' }, { id: 2, title: 'title2' }]; | ||
const products2 = [{ id: 2, title: 'title22' }, { id: 3, title: 'title3' }]; | ||
// should get a list with 1, 2 (merged) and 3 | ||
}); | ||
mocha_1.test.skip('Handle more than 126,000 remainder in a list', function () { | ||
mocha_1.test.skip('Handle more than 126,000 remainder in a list', () => { | ||
}); | ||
}); |
"use strict"; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) | ||
to[j] = from[i]; | ||
return to; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.nester = void 0; | ||
var extract_subpaths_1 = require("./extract_subpaths"); | ||
var helpers_1 = require("./helpers"); | ||
var lir_join_1 = require("./lir_join"); | ||
var push_path_1 = require("./push_path"); | ||
const extract_subpaths_1 = require("./extract_subpaths"); | ||
const helpers_1 = require("./helpers"); | ||
const lir_join_1 = require("./lir_join"); | ||
const push_path_1 = require("./push_path"); | ||
/** | ||
@@ -33,28 +12,25 @@ * @param data Takes a list of nest path and nest data pairs ordered by acceptable insert order | ||
*/ | ||
var nester = function (data, edges) { | ||
const nester = (data, edges) => { | ||
// Requires that data is sorted so that later elements are equal or deeper in json tree | ||
var result = {}; | ||
var _loop_1 = function (i) { | ||
var _a = __read(data[i], 2), pth = _a[0], list = _a[1]; | ||
var array_mode = helpers_1.last(pth) === 0; | ||
var path = array_mode ? helpers_1.drop(1, pth) : pth; | ||
let result = {}; | ||
for (let i = 0; i < data.length; i++) { | ||
const [pth, list] = data[i]; | ||
const array_mode = helpers_1.last(pth) === 0; | ||
const path = array_mode ? helpers_1.drop(1, pth) : pth; | ||
if (!edges[i]) | ||
helpers_1.deep_set(path, list, result); | ||
else { | ||
var left_list = extract_subpaths_1.extract_subpaths(helpers_1.drop(1, path), result); | ||
var _b = lir_join_1.lir_join(left_list, result, list, function (el) { return helpers_1.deep_get(__spreadArray(__spreadArray([], __read(el)), [edges[i][0]]), result); }, function (l, i, r) { | ||
r.forEach(function (right_adjacent) { | ||
const left_list = extract_subpaths_1.extract_subpaths(helpers_1.drop(1, path), result); | ||
const { left, inner, right } = lir_join_1.lir_join(left_list, result, list, (el) => helpers_1.deep_get([...el, edges[i][0]], result), (l, i, r) => { | ||
r.forEach(right_adjacent => { | ||
if (array_mode) { | ||
push_path_1.push_path(__spreadArray(__spreadArray([], __read(l[0])), [helpers_1.last(path)]), right_adjacent, i); | ||
push_path_1.push_path([...l[0], helpers_1.last(path)], right_adjacent, i); | ||
} | ||
else { | ||
helpers_1.deep_set(__spreadArray(__spreadArray([], __read(l[0])), [helpers_1.last(path)]), right_adjacent, i); | ||
helpers_1.deep_set([...l[0], helpers_1.last(path)], right_adjacent, i); | ||
} | ||
}); | ||
return i; | ||
}, function (el) { return el[edges[i][1]]; }), left = _b.left, inner = _b.inner, right = _b.right; | ||
}, el => el[edges[i][1]]); | ||
} | ||
}; | ||
for (var i = 0; i < data.length; i++) { | ||
_loop_1(i); | ||
} | ||
@@ -61,0 +37,0 @@ return result; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var chai_1 = require("chai"); | ||
var mocha_1 = require("mocha"); | ||
var nester_1 = require("./nester"); | ||
mocha_1.describe('nester', function () { | ||
mocha_1.test('basic deep nesting', function () { return __awaiter(void 0, void 0, void 0, function () { | ||
var data, edges, goal, result; | ||
return __generator(this, function (_a) { | ||
data = [ | ||
[['vendors', 0], [{ id: 1 }, { id: 2 }]], | ||
[['vendors', 0, 'products', 0], [{ id: 1, vendor_id: 2 }]], | ||
[['vendors', 0, 'products', 0, 'images', 0], [{ product_id: 1 }, { product_id: 1 }]] | ||
]; | ||
edges = [ | ||
null, | ||
['id', 'vendor_id'], | ||
['id', 'product_id'] | ||
]; | ||
goal = { | ||
vendors: [{ | ||
id: 1 | ||
}, { | ||
id: 2, | ||
products: [{ | ||
id: 1, | ||
vendor_id: 2, | ||
images: [{ | ||
product_id: 1 | ||
}, { | ||
product_id: 1 | ||
}] | ||
}] | ||
}] | ||
}; | ||
result = nester_1.nester(data, edges); | ||
chai_1.expect(result).to.deep.equal(goal); | ||
return [2 /*return*/]; | ||
}); | ||
}); }); | ||
mocha_1.test('handles entities with no children', function () { return __awaiter(void 0, void 0, void 0, function () { | ||
var data, edges, goal, result; | ||
return __generator(this, function (_a) { | ||
data = [ | ||
[['vendors', 0], [{ id: 1 }]], | ||
[['images', 0], [{ id: 1 }]], | ||
[['vendors', 0, 'products', 0], [{ id: 1, vendor_id: 1 }, { id: 2, vendor_id: 1 }]], | ||
]; | ||
edges = [ | ||
null, | ||
null, | ||
['id', 'vendor_id'] | ||
]; | ||
goal = { | ||
images: [{ | ||
id: 1 | ||
}], | ||
vendors: [{ | ||
id: 1, | ||
products: [{ | ||
id: 1, | ||
vendor_id: 1 | ||
}, { | ||
id: 2, | ||
vendor_id: 1 | ||
}] | ||
}] | ||
}; | ||
result = nester_1.nester(data, edges); | ||
chai_1.expect(result).to.deep.equal(goal); | ||
return [2 /*return*/]; | ||
}); | ||
}); }); | ||
mocha_1.test('handles sibling nesting', function () { return __awaiter(void 0, void 0, void 0, function () { | ||
var data, edges, goal, result; | ||
return __generator(this, function (_a) { | ||
data = [ | ||
[['vendors', 0], [{ id: 1 }]], | ||
[['images', 0], [{ id: 1 }]], | ||
[['images', 0, 'child_images', 0], [{ id: 1, image_id: 1 }, { id: 2, image_id: 1 }]], | ||
[['vendors', 0, 'products', 0], [{ id: 1, vendor_id: 1 }, { id: 2, vendor_id: 1 }]], | ||
]; | ||
edges = [ | ||
null, | ||
null, | ||
['id', 'image_id'], | ||
['id', 'vendor_id'] | ||
]; | ||
goal = { | ||
images: [{ | ||
id: 1, | ||
child_images: [{ | ||
id: 1, | ||
image_id: 1 | ||
}, { | ||
id: 2, | ||
image_id: 1 | ||
}] | ||
}], | ||
vendors: [{ | ||
id: 1, | ||
products: [{ | ||
id: 1, | ||
vendor_id: 1 | ||
}, { | ||
id: 2, | ||
vendor_id: 1 | ||
}] | ||
}] | ||
}; | ||
result = nester_1.nester(data, edges); | ||
chai_1.expect(result).to.deep.equal(goal); | ||
return [2 /*return*/]; | ||
}); | ||
}); }); | ||
mocha_1.test('object nesting', function () { | ||
var data = [ | ||
const chai_1 = require("chai"); | ||
const mocha_1 = require("mocha"); | ||
const nester_1 = require("./nester"); | ||
mocha_1.describe('nester', () => { | ||
mocha_1.test('basic deep nesting', async () => { | ||
const data = [ | ||
[['vendors', 0], [{ id: 1 }, { id: 2 }]], | ||
[['vendors', 0, 'products', 0], [{ id: 1, vendor_id: 2 }]], | ||
[['vendors', 0, 'products', 0, 'images', 0], [{ product_id: 1 }, { product_id: 1 }]] | ||
]; | ||
const edges = [ | ||
null, | ||
['id', 'vendor_id'], | ||
['id', 'product_id'] | ||
]; | ||
const goal = { | ||
vendors: [{ | ||
id: 1 | ||
}, { | ||
id: 2, | ||
products: [{ | ||
id: 1, | ||
vendor_id: 2, | ||
images: [{ | ||
product_id: 1 | ||
}, { | ||
product_id: 1 | ||
}] | ||
}] | ||
}] | ||
}; | ||
let result = nester_1.nester(data, edges); | ||
chai_1.expect(result).to.deep.equal(goal); | ||
}); | ||
mocha_1.test('handles entities with no children', async () => { | ||
const data = [ | ||
[['vendors', 0], [{ id: 1 }]], | ||
[['images', 0], [{ id: 1 }]], | ||
[['vendors', 0, 'products', 0], [{ id: 1, vendor_id: 1 }, { id: 2, vendor_id: 1 }]], | ||
]; | ||
const edges = [ | ||
null, | ||
null, | ||
['id', 'vendor_id'] | ||
]; | ||
const goal = { | ||
images: [{ | ||
id: 1 | ||
}], | ||
vendors: [{ | ||
id: 1, | ||
products: [{ | ||
id: 1, | ||
vendor_id: 1 | ||
}, { | ||
id: 2, | ||
vendor_id: 1 | ||
}] | ||
}] | ||
}; | ||
let result = nester_1.nester(data, edges); | ||
chai_1.expect(result).to.deep.equal(goal); | ||
}); | ||
mocha_1.test('handles sibling nesting', async () => { | ||
const data = [ | ||
[['vendors', 0], [{ id: 1 }]], | ||
[['images', 0], [{ id: 1 }]], | ||
[['images', 0, 'child_images', 0], [{ id: 1, image_id: 1 }, { id: 2, image_id: 1 }]], | ||
[['vendors', 0, 'products', 0], [{ id: 1, vendor_id: 1 }, { id: 2, vendor_id: 1 }]], | ||
]; | ||
const edges = [ | ||
null, | ||
null, | ||
['id', 'image_id'], | ||
['id', 'vendor_id'] | ||
]; | ||
const goal = { | ||
images: [{ | ||
id: 1, | ||
child_images: [{ | ||
id: 1, | ||
image_id: 1 | ||
}, { | ||
id: 2, | ||
image_id: 1 | ||
}] | ||
}], | ||
vendors: [{ | ||
id: 1, | ||
products: [{ | ||
id: 1, | ||
vendor_id: 1 | ||
}, { | ||
id: 2, | ||
vendor_id: 1 | ||
}] | ||
}] | ||
}; | ||
let result = nester_1.nester(data, edges); | ||
chai_1.expect(result).to.deep.equal(goal); | ||
}); | ||
mocha_1.test('object nesting', () => { | ||
const data = [ | ||
[['vendors', 0], [{ id: 1 }, { id: 2 }]], | ||
[['vendors', 0, 'products'], [{ id: 1, vendor_id: 2 }]], | ||
]; | ||
var edges = [ | ||
const edges = [ | ||
null, | ||
['id', 'vendor_id'] | ||
]; | ||
var goal = { | ||
const goal = { | ||
vendors: [{ | ||
@@ -172,3 +124,3 @@ id: 1 | ||
}; | ||
var result = nester_1.nester(data, edges); | ||
let result = nester_1.nester(data, edges); | ||
// let result = {} | ||
@@ -182,56 +134,53 @@ // for (let i = 0; i < 10000; i++) { | ||
}); | ||
mocha_1.test.skip('breadth speed test', function () { return __awaiter(void 0, void 0, void 0, function () { | ||
var vendors, products, images, data, edges, goal, result; | ||
return __generator(this, function (_a) { | ||
vendors = new Array(100).fill(undefined).map(function (_, i) { return ({ | ||
id: Math.random() * 1000000000000000 | ||
}); }); | ||
products = vendors.flatMap(function (vendor, i) { | ||
return new Array(100).fill(undefined).map(function (_, i) { return ({ | ||
id: Math.random() * 1000000000000000, | ||
vendor_id: vendor.id | ||
}); }); | ||
}); | ||
console.log('generated products'); | ||
images = products.flatMap(function (product, i) { | ||
return new Array(100).fill(undefined).map(function (_, i) { return ({ | ||
id: Math.random() * 1000000000000000, | ||
product_id: product.id | ||
}); }); | ||
}); | ||
data = [ | ||
[['vendors'], vendors], | ||
[['vendors', 0, 'products'], products], | ||
[['vendors', 0, 'products', 0, 'images'], images] | ||
]; | ||
edges = [ | ||
{ from_entity: 'vendors', from_field: 'id', to_entity: 'products', to_field: 'vendor_id' }, | ||
{ from_entity: 'products', from_field: 'id', to_entity: 'images', to_field: 'product_id' }, | ||
]; | ||
goal = { | ||
vendors: [{ | ||
id: 1 | ||
}, { | ||
id: 2, | ||
products: [{ | ||
id: 1, | ||
vendor_id: 2, | ||
images: [{ | ||
product_id: 1 | ||
}, { | ||
product_id: 1 | ||
}] | ||
}] | ||
}] | ||
}; | ||
console.time('t'); | ||
result = {}; | ||
// for (let i = 0; i < 10000; i++) { | ||
result = nester_1.nester(data, edges); | ||
// } | ||
console.timeEnd('t'); | ||
console.log('done'); | ||
return [2 /*return*/]; | ||
mocha_1.test.skip('breadth speed test', async () => { | ||
const vendors = new Array(100).fill(undefined).map((_, i) => ({ | ||
id: Math.random() * 1000000000000000 | ||
})); | ||
const products = vendors.flatMap((vendor, i) => { | ||
return new Array(100).fill(undefined).map((_, i) => ({ | ||
id: Math.random() * 1000000000000000, | ||
vendor_id: vendor.id | ||
})); | ||
}); | ||
}); }); | ||
console.log('generated products'); | ||
const images = products.flatMap((product, i) => { | ||
return new Array(100).fill(undefined).map((_, i) => ({ | ||
id: Math.random() * 1000000000000000, | ||
product_id: product.id | ||
})); | ||
}); | ||
const data = [ | ||
[['vendors'], vendors], | ||
[['vendors', 0, 'products'], products], | ||
[['vendors', 0, 'products', 0, 'images'], images] | ||
]; | ||
const edges = [ | ||
{ from_entity: 'vendors', from_field: 'id', to_entity: 'products', to_field: 'vendor_id' }, | ||
{ from_entity: 'products', from_field: 'id', to_entity: 'images', to_field: 'product_id' }, | ||
]; | ||
const goal = { | ||
vendors: [{ | ||
id: 1 | ||
}, { | ||
id: 2, | ||
products: [{ | ||
id: 1, | ||
vendor_id: 2, | ||
images: [{ | ||
product_id: 1 | ||
}, { | ||
product_id: 1 | ||
}] | ||
}] | ||
}] | ||
}; | ||
console.time('t'); | ||
let result = {}; | ||
// for (let i = 0; i < 10000; i++) { | ||
result = nester_1.nester(data, edges); | ||
// } | ||
console.timeEnd('t'); | ||
console.log('done'); | ||
// expect(result).to.deep.equal(goal) | ||
}); | ||
}); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.push_path = void 0; | ||
var helpers_1 = require("./helpers"); | ||
const helpers_1 = require("./helpers"); | ||
/** | ||
* Push values to arrays which are deeply nested | ||
*/ | ||
var push_path = function (path_to_arr, val, obj) { | ||
var current_value = helpers_1.deep_get(path_to_arr, obj, null); | ||
const push_path = (path_to_arr, val, obj) => { | ||
const current_value = helpers_1.deep_get(path_to_arr, obj, null); | ||
if (!Array.isArray(current_value)) { | ||
@@ -11,0 +11,0 @@ helpers_1.deep_set(path_to_arr, [val], obj); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var chai_1 = require("chai"); | ||
var mocha_1 = require("mocha"); | ||
var push_path_1 = require("./push_path"); | ||
mocha_1.describe('push_path', function () { | ||
mocha_1.test('Creates [] when nothing at path', function () { | ||
var obj = { my: { nested: {} } }; | ||
const chai_1 = require("chai"); | ||
const mocha_1 = require("mocha"); | ||
const push_path_1 = require("./push_path"); | ||
mocha_1.describe('push_path', () => { | ||
mocha_1.test('Creates [] when nothing at path', () => { | ||
let obj = { my: { nested: {} } }; | ||
push_path_1.push_path(['my', 'nested', 'arr'], 'my_val', obj); | ||
chai_1.expect(obj).to.deep.equal({ my: { nested: { arr: ['my_val'] } } }); | ||
}); | ||
mocha_1.test('Pushes to array when something is at path', function () { | ||
var obj = { my: { nested: { arr: [1] } } }; | ||
mocha_1.test('Pushes to array when something is at path', () => { | ||
let obj = { my: { nested: { arr: [1] } } }; | ||
push_path_1.push_path(['my', 'nested', 'arr'], 2, obj); | ||
@@ -15,0 +15,0 @@ chai_1.expect(obj).to.deep.equal({ my: { nested: { arr: [1, 2] } } }); |
@@ -6,34 +6,2 @@ "use strict"; | ||
*/ | ||
var __values = (this && this.__values) || function(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) | ||
to[j] = from[i]; | ||
return to; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -44,3 +12,3 @@ exports.field_exists = exports.get_unique_fields = exports.get_primary_keys = exports.is_parent_entity = exports.get_edge_path = exports.get_direct_edge = exports.get_direct_edges = exports.is_reserved_keyword = exports.get_all_edges = exports.get_child_edges = exports.reverse_edge = exports.get_parent_edges = exports.get_field_names = exports.get_entity_names = void 0; | ||
*/ | ||
var get_entity_names = function (orma_schema) { | ||
const get_entity_names = (orma_schema) => { | ||
return Object.keys(orma_schema); | ||
@@ -52,3 +20,3 @@ }; | ||
*/ | ||
var get_field_names = function (entity_name, orma_schema) { | ||
const get_field_names = (entity_name, orma_schema) => { | ||
var _a; | ||
@@ -66,6 +34,6 @@ return Object.keys((_a = orma_schema[entity_name]) !== null && _a !== void 0 ? _a : {}); | ||
*/ | ||
var get_parent_edges = function (entity_name, orma_schema) { | ||
const get_parent_edges = (entity_name, orma_schema) => { | ||
var _a; | ||
var fields_schema = (_a = orma_schema[entity_name]) !== null && _a !== void 0 ? _a : {}; | ||
var parent_edges = Object.keys(fields_schema).flatMap(function (field_name) { | ||
const fields_schema = (_a = orma_schema[entity_name]) !== null && _a !== void 0 ? _a : {}; | ||
const parent_edges = Object.keys(fields_schema).flatMap(field_name => { | ||
var _a, _b; | ||
@@ -75,8 +43,8 @@ if (exports.is_reserved_keyword(field_name)) { | ||
} | ||
var field_schema = ((_a = fields_schema[field_name]) !== null && _a !== void 0 ? _a : {}); | ||
var parent_entity_name = Object.keys((_b = field_schema.references) !== null && _b !== void 0 ? _b : {})[0]; | ||
const field_schema = ((_a = fields_schema[field_name]) !== null && _a !== void 0 ? _a : {}); | ||
const parent_entity_name = Object.keys((_b = field_schema.references) !== null && _b !== void 0 ? _b : {})[0]; | ||
if (!parent_entity_name) { | ||
return []; | ||
} | ||
var parent_field_name = Object.keys(field_schema.references[parent_entity_name])[0]; | ||
const parent_field_name = Object.keys(field_schema.references[parent_entity_name])[0]; | ||
return [{ | ||
@@ -95,3 +63,3 @@ from_entity: entity_name, | ||
*/ | ||
var reverse_edge = function (edge) { return ({ | ||
const reverse_edge = (edge) => ({ | ||
from_entity: edge.to_entity, | ||
@@ -101,44 +69,23 @@ from_field: edge.to_field, | ||
to_field: edge.from_field | ||
}); }; | ||
}); | ||
exports.reverse_edge = reverse_edge; | ||
// we use a map because it can take objects as keys (they are compared by reference) | ||
var child_edges_cache_by_schema = new Map(); | ||
const child_edges_cache_by_schema = new Map(); | ||
// a helper method, having all the child edges in a single cache object helps it be memoized | ||
var get_child_edges_cache = function (orma_schema) { | ||
var e_1, _a, e_2, _b; | ||
const get_child_edges_cache = (orma_schema) => { | ||
if (child_edges_cache_by_schema.has(orma_schema)) { | ||
return child_edges_cache_by_schema.get(orma_schema); | ||
} | ||
var entity_names = exports.get_entity_names(orma_schema); | ||
var cache = {}; | ||
try { | ||
for (var entity_names_1 = __values(entity_names), entity_names_1_1 = entity_names_1.next(); !entity_names_1_1.done; entity_names_1_1 = entity_names_1.next()) { | ||
var entity_name = entity_names_1_1.value; | ||
var parent_edges = exports.get_parent_edges(entity_name, orma_schema); | ||
var child_edges = parent_edges.map(exports.reverse_edge); | ||
try { | ||
for (var child_edges_1 = (e_2 = void 0, __values(child_edges)), child_edges_1_1 = child_edges_1.next(); !child_edges_1_1.done; child_edges_1_1 = child_edges_1.next()) { | ||
var child_edge = child_edges_1_1.value; | ||
if (!cache[child_edge.from_entity]) { | ||
cache[child_edge.from_entity] = []; | ||
} | ||
cache[child_edge.from_entity].push(child_edge); | ||
} | ||
const entity_names = exports.get_entity_names(orma_schema); | ||
const cache = {}; | ||
for (const entity_name of entity_names) { | ||
const parent_edges = exports.get_parent_edges(entity_name, orma_schema); | ||
const child_edges = parent_edges.map(exports.reverse_edge); | ||
for (const child_edge of child_edges) { | ||
if (!cache[child_edge.from_entity]) { | ||
cache[child_edge.from_entity] = []; | ||
} | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
finally { | ||
try { | ||
if (child_edges_1_1 && !child_edges_1_1.done && (_b = child_edges_1.return)) _b.call(child_edges_1); | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
} | ||
cache[child_edge.from_entity].push(child_edge); | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (entity_names_1_1 && !entity_names_1_1.done && (_a = entity_names_1.return)) _a.call(entity_names_1); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
// now cache has keys of each entity name, with the value being an array of the child edges, with no duplicates | ||
@@ -151,5 +98,5 @@ child_edges_cache_by_schema.set(orma_schema, cache); | ||
*/ | ||
var get_child_edges = function (entity_name, orma_schema) { | ||
const get_child_edges = (entity_name, orma_schema) => { | ||
var _a; | ||
var child_edges_cache = get_child_edges_cache(orma_schema); | ||
const child_edges_cache = get_child_edges_cache(orma_schema); | ||
return (_a = child_edges_cache[entity_name]) !== null && _a !== void 0 ? _a : []; | ||
@@ -161,6 +108,6 @@ }; | ||
*/ | ||
var get_all_edges = function (entity_name, orma_schema) { | ||
var parent_edges = exports.get_parent_edges(entity_name, orma_schema); | ||
var child_edges = exports.get_child_edges(entity_name, orma_schema); | ||
return __spreadArray(__spreadArray([], __read(parent_edges)), __read(child_edges)); | ||
const get_all_edges = (entity_name, orma_schema) => { | ||
const parent_edges = exports.get_parent_edges(entity_name, orma_schema); | ||
const child_edges = exports.get_child_edges(entity_name, orma_schema); | ||
return [...parent_edges, ...child_edges]; | ||
}; | ||
@@ -171,12 +118,10 @@ exports.get_all_edges = get_all_edges; | ||
*/ | ||
var is_reserved_keyword = function (keyword) { | ||
return typeof keyword === 'string' | ||
&& keyword[0] === '$'; | ||
}; | ||
const is_reserved_keyword = (keyword) => typeof keyword === 'string' | ||
&& keyword[0] === '$'; | ||
exports.is_reserved_keyword = is_reserved_keyword; | ||
/* gets possible parent or child edges between two tables that are immediate child/parent or parent/child | ||
*/ | ||
var get_direct_edges = function (from_entity, to_entity, orma_schema) { | ||
var possible_edges = exports.get_all_edges(from_entity, orma_schema); | ||
var edges = possible_edges.filter(function (el) { return el.to_entity === to_entity; }); | ||
const get_direct_edges = (from_entity, to_entity, orma_schema) => { | ||
const possible_edges = exports.get_all_edges(from_entity, orma_schema); | ||
const edges = possible_edges.filter(el => el.to_entity === to_entity); | ||
return edges; | ||
@@ -188,6 +133,6 @@ }; | ||
*/ | ||
var get_direct_edge = function (from_entity, to_entity, orma_schema) { | ||
var edges = exports.get_direct_edges(from_entity, to_entity, orma_schema); | ||
const get_direct_edge = (from_entity, to_entity, orma_schema) => { | ||
const edges = exports.get_direct_edges(from_entity, to_entity, orma_schema); | ||
if (edges.length !== 1) { | ||
throw Error("Did not find exactly one edge from " + from_entity + " to " + to_entity); | ||
throw Error(`Did not find exactly one edge from ${from_entity} to ${to_entity}`); | ||
} | ||
@@ -203,7 +148,7 @@ return edges[0]; | ||
*/ | ||
var get_edge_path = function (entities, orma_schema) { | ||
const get_edge_path = (entities, orma_schema) => { | ||
if (entities.length <= 1) { | ||
return []; | ||
} | ||
var edge_path = entities.flatMap(function (entity, i) { | ||
const edge_path = entities.flatMap((entity, i) => { | ||
if (i === 0) { | ||
@@ -217,5 +162,5 @@ // if (tables.length === 1) { | ||
} | ||
var from_entity = entities[i - 1]; | ||
var to_entity = entities[i]; | ||
var edge = exports.get_direct_edge(from_entity, to_entity, orma_schema); | ||
const from_entity = entities[i - 1]; | ||
const to_entity = entities[i]; | ||
const edge = exports.get_direct_edge(from_entity, to_entity, orma_schema); | ||
return edge; | ||
@@ -229,5 +174,5 @@ }); | ||
*/ | ||
var is_parent_entity = function (entity1, entity2, orma_schema) { | ||
var edges = exports.get_child_edges(entity1, orma_schema); | ||
return edges.some(function (edge) { return edge.to_entity === entity2; }); | ||
const is_parent_entity = (entity1, entity2, orma_schema) => { | ||
const edges = exports.get_child_edges(entity1, orma_schema); | ||
return edges.some(edge => edge.to_entity === entity2); | ||
}; | ||
@@ -238,6 +183,6 @@ exports.is_parent_entity = is_parent_entity; | ||
*/ | ||
var get_primary_keys = function (entity_name, orma_schema) { | ||
var fields = exports.get_field_names(entity_name, orma_schema); | ||
var primary_key_fields = fields.filter(function (field) { | ||
var field_schema = orma_schema[entity_name][field]; | ||
const get_primary_keys = (entity_name, orma_schema) => { | ||
const fields = exports.get_field_names(entity_name, orma_schema); | ||
const primary_key_fields = fields.filter((field) => { | ||
const field_schema = orma_schema[entity_name][field]; | ||
if (typeof field_schema === 'string') { | ||
@@ -254,6 +199,6 @@ return false; | ||
*/ | ||
var get_unique_fields = function (entity_name, orma_schema) { | ||
var fields = exports.get_field_names(entity_name, orma_schema); | ||
var unique_fields = fields.filter(function (field) { | ||
var field_schema = orma_schema[entity_name][field]; | ||
const get_unique_fields = (entity_name, orma_schema) => { | ||
const fields = exports.get_field_names(entity_name, orma_schema); | ||
const unique_fields = fields.filter((field) => { | ||
const field_schema = orma_schema[entity_name][field]; | ||
if (typeof field_schema === 'string') { | ||
@@ -267,3 +212,3 @@ return false; | ||
exports.get_unique_fields = get_unique_fields; | ||
var field_exists = function (entity, field, schema) { | ||
const field_exists = (entity, field, schema) => { | ||
var _a; | ||
@@ -270,0 +215,0 @@ return (_a = schema[entity]) === null || _a === void 0 ? void 0 : _a[field]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var chai_1 = require("chai"); | ||
var mocha_1 = require("mocha"); | ||
var schema_helpers_1 = require("./schema_helpers"); | ||
mocha_1.describe('schema_helpers', function () { | ||
mocha_1.describe('get_entity_names', function () { | ||
mocha_1.test('gets entity names', function () { | ||
var orma_schema = { | ||
const chai_1 = require("chai"); | ||
const mocha_1 = require("mocha"); | ||
const schema_helpers_1 = require("./schema_helpers"); | ||
mocha_1.describe('schema_helpers', () => { | ||
mocha_1.describe('get_entity_names', () => { | ||
mocha_1.test('gets entity names', () => { | ||
const orma_schema = { | ||
vendors: {}, | ||
products: {} | ||
}; | ||
var entity_names = schema_helpers_1.get_entity_names(orma_schema); | ||
const entity_names = schema_helpers_1.get_entity_names(orma_schema); | ||
chai_1.expect(entity_names.sort()).to.deep.equal(['vendors', 'products'].sort()); | ||
}); | ||
}); | ||
mocha_1.describe('get_field_names', function () { | ||
mocha_1.test('gets field names', function () { | ||
var orma_schema = { | ||
mocha_1.describe('get_field_names', () => { | ||
mocha_1.test('gets field names', () => { | ||
const orma_schema = { | ||
vendors: {}, | ||
@@ -26,9 +26,9 @@ products: { | ||
}; | ||
var field_names = schema_helpers_1.get_field_names('products', orma_schema); | ||
const field_names = schema_helpers_1.get_field_names('products', orma_schema); | ||
chai_1.expect(field_names.sort()).to.deep.equal(['id', 'title'].sort()); | ||
}); | ||
}); | ||
mocha_1.describe('get_parent_edges', function () { | ||
mocha_1.test('gets parent edges', function () { | ||
var orma_schema = { | ||
mocha_1.describe('get_parent_edges', () => { | ||
mocha_1.test('gets parent edges', () => { | ||
const orma_schema = { | ||
vendors: { | ||
@@ -48,4 +48,4 @@ id: {} | ||
}; | ||
var parent_edges = schema_helpers_1.get_parent_edges('products', orma_schema); | ||
var goal = [ | ||
const parent_edges = schema_helpers_1.get_parent_edges('products', orma_schema); | ||
const goal = [ | ||
{ from_entity: 'products', from_field: 'vendor_id', to_entity: 'vendors', to_field: 'id' } | ||
@@ -56,5 +56,5 @@ ]; | ||
}); | ||
mocha_1.describe('get_child_edges', function () { | ||
mocha_1.test('gets child edges', function () { | ||
var orma_schema = { | ||
mocha_1.describe('get_child_edges', () => { | ||
mocha_1.test('gets child edges', () => { | ||
const orma_schema = { | ||
vendors: { | ||
@@ -74,4 +74,4 @@ id: {} | ||
}; | ||
var parent_edges = schema_helpers_1.get_child_edges('vendors', orma_schema); | ||
var goal = [ | ||
const parent_edges = schema_helpers_1.get_child_edges('vendors', orma_schema); | ||
const goal = [ | ||
{ from_entity: 'vendors', from_field: 'id', to_entity: 'products', to_field: 'vendor_id' } | ||
@@ -82,5 +82,5 @@ ]; | ||
}); | ||
mocha_1.describe('get_all_edges', function () { | ||
mocha_1.test('gets all edges', function () { | ||
var orma_schema = { | ||
mocha_1.describe('get_all_edges', () => { | ||
mocha_1.test('gets all edges', () => { | ||
const orma_schema = { | ||
vendors: { | ||
@@ -109,4 +109,4 @@ id: {} | ||
}; | ||
var all_edges = schema_helpers_1.get_all_edges('products', orma_schema); | ||
var goal = [ | ||
const all_edges = schema_helpers_1.get_all_edges('products', orma_schema); | ||
const goal = [ | ||
{ from_entity: 'products', from_field: 'vendor_id', to_entity: 'vendors', to_field: 'id' }, | ||
@@ -113,0 +113,0 @@ { from_entity: 'products', from_field: 'id', to_entity: 'images', to_field: 'product_id' } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.stable_sort = void 0; | ||
var stable_sort = function (arr, compare) { return arr | ||
.map(function (item, index) { return ({ item: item, index: index }); }) | ||
.sort(function (a, b) { return compare(a.item, b.item) || a.index - b.index; }) | ||
.map(function (_a) { | ||
var item = _a.item; | ||
return item; | ||
}); }; | ||
const stable_sort = (arr, compare) => arr | ||
.map((item, index) => ({ item, index })) | ||
.sort((a, b) => compare(a.item, b.item) || a.index - b.index) | ||
.map(({ item }) => item); | ||
exports.stable_sort = stable_sort; |
"use strict"; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -27,11 +11,11 @@ exports.countInDegrees = exports.toposort = void 0; | ||
*/ | ||
var toposort = function (dag) { | ||
var indegrees = exports.countInDegrees(dag); | ||
var sorted = []; | ||
var roots = getRoots(indegrees); | ||
var _loop_1 = function () { | ||
const toposort = (dag) => { | ||
const indegrees = exports.countInDegrees(dag); | ||
const sorted = []; | ||
let roots = getRoots(indegrees); | ||
while (roots.length) { | ||
sorted.push(roots); | ||
var newRoots = []; | ||
roots.forEach(function (root) { | ||
dag[root].forEach(function (dependent) { | ||
const newRoots = []; | ||
roots.forEach(root => { | ||
dag[root].forEach(dependent => { | ||
indegrees[dependent]--; | ||
@@ -44,5 +28,2 @@ if (indegrees[dependent] === 0) { | ||
roots = newRoots; | ||
}; | ||
while (roots.length) { | ||
_loop_1(); | ||
} | ||
@@ -55,8 +36,7 @@ if (getNonRoots(indegrees).length) { | ||
exports.toposort = toposort; | ||
var countInDegrees = function (dag) { | ||
var counts = {}; | ||
Object.entries(dag).forEach(function (_a) { | ||
var _b = __read(_a, 2), vx = _b[0], dependents = _b[1]; | ||
const countInDegrees = dag => { | ||
const counts = {}; | ||
Object.entries(dag).forEach(([vx, dependents]) => { | ||
counts[vx] = counts[vx] || 0; | ||
dependents.forEach(function (dependent) { | ||
dependents.forEach(dependent => { | ||
counts[dependent] = counts[dependent] || 0; | ||
@@ -69,14 +49,6 @@ counts[dependent]++; | ||
exports.countInDegrees = countInDegrees; | ||
var filterByDegree = function (predicate) { return function (counts) { | ||
return Object.entries(counts) | ||
.filter(function (_a) { | ||
var _b = __read(_a, 2), _ = _b[0], deg = _b[1]; | ||
return predicate(deg); | ||
}) | ||
.map(function (_a) { | ||
var _b = __read(_a, 2), id = _b[0], _ = _b[1]; | ||
return id; | ||
}); | ||
}; }; | ||
var getRoots = filterByDegree(function (deg) { return deg === 0; }); | ||
var getNonRoots = filterByDegree(function (deg) { return deg !== 0; }); | ||
const filterByDegree = predicate => counts => Object.entries(counts) | ||
.filter(([_, deg]) => predicate(deg)) | ||
.map(([id, _]) => id); | ||
const getRoots = filterByDegree(deg => deg === 0); | ||
const getNonRoots = filterByDegree(deg => deg !== 0); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var toposort_1 = require("./toposort"); | ||
var chai_1 = require("chai"); | ||
var mocha_1 = require("mocha"); | ||
mocha_1.describe('toposort', function () { | ||
mocha_1.it('toposorts an empty graph', function () { | ||
const toposort_1 = require("./toposort"); | ||
const chai_1 = require("chai"); | ||
const mocha_1 = require("mocha"); | ||
mocha_1.describe('toposort', () => { | ||
mocha_1.it('toposorts an empty graph', () => { | ||
chai_1.expect(toposort_1.toposort({})).to.deep.equal([]); | ||
}); | ||
mocha_1.it('toposorts a simple DAG', function () { | ||
mocha_1.it('toposorts a simple DAG', () => { | ||
chai_1.expect(toposort_1.toposort({ | ||
@@ -17,3 +17,3 @@ a: ['b'], | ||
}); | ||
mocha_1.it('toposorts a richer DAG', function () { | ||
mocha_1.it('toposorts a richer DAG', () => { | ||
chai_1.expect(toposort_1.toposort({ | ||
@@ -25,4 +25,4 @@ a: ['c'], | ||
}); | ||
mocha_1.it('toposorts a complex DAG', function () { | ||
var result = toposort_1.toposort({ | ||
mocha_1.it('toposorts a complex DAG', () => { | ||
const result = toposort_1.toposort({ | ||
a: ['c', 'f'], | ||
@@ -46,4 +46,4 @@ b: ['d', 'e'], | ||
}); | ||
mocha_1.it('errors on a small cyclic graph', function () { | ||
var dg = { | ||
mocha_1.it('errors on a small cyclic graph', () => { | ||
const dg = { | ||
a: ['b'], | ||
@@ -53,3 +53,3 @@ b: ['a'], | ||
}; | ||
var sortCyclicGraph = function () { | ||
const sortCyclicGraph = () => { | ||
toposort_1.toposort(dg); | ||
@@ -59,4 +59,4 @@ }; | ||
}); | ||
mocha_1.it('errors on a larger cyclic graph', function () { | ||
var dg = { | ||
mocha_1.it('errors on a larger cyclic graph', () => { | ||
const dg = { | ||
a: ['b', 'c'], | ||
@@ -68,3 +68,3 @@ b: ['c'], | ||
}; | ||
var sortCyclicGraph = function () { | ||
const sortCyclicGraph = () => { | ||
toposort_1.toposort(dg); | ||
@@ -74,8 +74,8 @@ }; | ||
}); | ||
mocha_1.it('counts in-degrees for an empty DAG', function () { | ||
var DAG = {}; | ||
mocha_1.it('counts in-degrees for an empty DAG', () => { | ||
const DAG = {}; | ||
chai_1.expect(toposort_1.countInDegrees(DAG)).to.deep.equal({}); | ||
}); | ||
mocha_1.it('counts in-degrees for a small DAG', function () { | ||
var DAG = { | ||
mocha_1.it('counts in-degrees for a small DAG', () => { | ||
const DAG = { | ||
a: ['b'], | ||
@@ -89,4 +89,4 @@ b: [], | ||
}); | ||
mocha_1.it('counts in-degrees for a medium DAG', function () { | ||
var DAG = { | ||
mocha_1.it('counts in-degrees for a medium DAG', () => { | ||
const DAG = { | ||
a: ['b', 'c'], | ||
@@ -104,4 +104,4 @@ b: ['c'], | ||
}); | ||
mocha_1.it('counts in-degrees for a bigger DAG', function () { | ||
var DAG = { | ||
mocha_1.it('counts in-degrees for a bigger DAG', () => { | ||
const DAG = { | ||
a: ['c', 'f'], | ||
@@ -108,0 +108,0 @@ b: ['d', 'e'], |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.orma_query = exports.introspector = void 0; | ||
var introspector_1 = require("./introspector/introspector"); | ||
var query_1 = require("./query/query"); | ||
const introspector_1 = require("./introspector/introspector"); | ||
const query_1 = require("./query/query"); | ||
exports.introspector = introspector_1.introspector; | ||
exports.orma_query = query_1.orma_query; |
@@ -6,68 +6,5 @@ "use strict"; | ||
*/ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __values = (this && this.__values) || function(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.introspector = exports.generate_field_schema = exports.generate_database_schema = exports.get_introspect_sqls = void 0; | ||
var helpers_1 = require("../helpers/helpers"); | ||
const helpers_1 = require("../helpers/helpers"); | ||
/** | ||
@@ -77,7 +14,31 @@ * Gets a list of sql strings to collect introspector data for the given database | ||
*/ | ||
var get_introspect_sqls = function (database_name) { | ||
var query_strings = [ | ||
"SELECT \n table_name, \n table_comment \n FROM INFORMATION_SCHEMA.TABLES \n WHERE table_schema='" + database_name + "'", | ||
"SELECT \n column_name, \n table_name,\n data_type,\n column_type,\n column_key,\n is_nullable,\n numeric_precision,\n numeric_scale,\n character_maximum_length,\n column_default,\n column_comment\n FROM information_schema.COLUMNS \n WHERE table_schema = '" + database_name + "'", | ||
"SELECT \n table_name, \n column_name,\n referenced_table_name,\n referenced_column_name,\n constraint_name\n FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE\n WHERE REFERENCED_TABLE_SCHEMA = '" + database_name + "'" | ||
const get_introspect_sqls = (database_name) => { | ||
const query_strings = [ | ||
`SELECT | ||
table_name, | ||
table_comment | ||
FROM INFORMATION_SCHEMA.TABLES | ||
WHERE table_schema='${database_name}'`, | ||
`SELECT | ||
column_name, | ||
table_name, | ||
data_type, | ||
column_type, | ||
column_key, | ||
is_nullable, | ||
numeric_precision, | ||
numeric_scale, | ||
character_maximum_length, | ||
column_default, | ||
column_comment | ||
FROM information_schema.COLUMNS | ||
WHERE table_schema = '${database_name}'`, | ||
`SELECT | ||
table_name, | ||
column_name, | ||
referenced_table_name, | ||
referenced_column_name, | ||
constraint_name | ||
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE | ||
WHERE REFERENCED_TABLE_SCHEMA = '${database_name}'` | ||
]; | ||
@@ -111,59 +72,28 @@ return query_strings; | ||
*/ | ||
var generate_database_schema = function (mysql_tables, mysql_columns, mysql_foreign_keys) { | ||
var e_1, _a, e_2, _b, e_3, _c; | ||
var database_schema = {}; | ||
try { | ||
for (var mysql_tables_1 = __values(mysql_tables), mysql_tables_1_1 = mysql_tables_1.next(); !mysql_tables_1_1.done; mysql_tables_1_1 = mysql_tables_1.next()) { | ||
var mysql_table = mysql_tables_1_1.value; | ||
database_schema[mysql_table.table_name] = { | ||
$comment: mysql_table.table_comment | ||
}; | ||
} | ||
const generate_database_schema = (mysql_tables, mysql_columns, mysql_foreign_keys) => { | ||
const database_schema = {}; | ||
for (const mysql_table of mysql_tables) { | ||
database_schema[mysql_table.table_name] = { | ||
$comment: mysql_table.table_comment | ||
}; | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (mysql_tables_1_1 && !mysql_tables_1_1.done && (_a = mysql_tables_1.return)) _a.call(mysql_tables_1); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
for (const mysql_column of mysql_columns) { | ||
const field_schema = exports.generate_field_schema(mysql_column); | ||
database_schema[mysql_column.table_name][mysql_column.column_name] = field_schema; | ||
} | ||
try { | ||
for (var mysql_columns_1 = __values(mysql_columns), mysql_columns_1_1 = mysql_columns_1.next(); !mysql_columns_1_1.done; mysql_columns_1_1 = mysql_columns_1.next()) { | ||
var mysql_column = mysql_columns_1_1.value; | ||
var field_schema = exports.generate_field_schema(mysql_column); | ||
database_schema[mysql_column.table_name][mysql_column.column_name] = field_schema; | ||
} | ||
for (const mysql_foreign_key of mysql_foreign_keys) { | ||
const { table_name, column_name, referenced_table_name, referenced_column_name, constraint_name } = mysql_foreign_key; | ||
const reference_path = [ | ||
table_name, | ||
column_name, | ||
'references', | ||
referenced_table_name, | ||
referenced_column_name | ||
]; | ||
helpers_1.deep_set(reference_path, {}, database_schema); | ||
} | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
finally { | ||
try { | ||
if (mysql_columns_1_1 && !mysql_columns_1_1.done && (_b = mysql_columns_1.return)) _b.call(mysql_columns_1); | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
} | ||
try { | ||
for (var mysql_foreign_keys_1 = __values(mysql_foreign_keys), mysql_foreign_keys_1_1 = mysql_foreign_keys_1.next(); !mysql_foreign_keys_1_1.done; mysql_foreign_keys_1_1 = mysql_foreign_keys_1.next()) { | ||
var mysql_foreign_key = mysql_foreign_keys_1_1.value; | ||
var table_name = mysql_foreign_key.table_name, column_name = mysql_foreign_key.column_name, referenced_table_name = mysql_foreign_key.referenced_table_name, referenced_column_name = mysql_foreign_key.referenced_column_name, constraint_name = mysql_foreign_key.constraint_name; | ||
var reference_path = [ | ||
table_name, | ||
column_name, | ||
'references', | ||
referenced_table_name, | ||
referenced_column_name | ||
]; | ||
helpers_1.deep_set(reference_path, {}, database_schema); | ||
} | ||
} | ||
catch (e_3_1) { e_3 = { error: e_3_1 }; } | ||
finally { | ||
try { | ||
if (mysql_foreign_keys_1_1 && !mysql_foreign_keys_1_1.done && (_c = mysql_foreign_keys_1.return)) _c.call(mysql_foreign_keys_1); | ||
} | ||
finally { if (e_3) throw e_3.error; } | ||
} | ||
return database_schema; | ||
}; | ||
exports.generate_database_schema = generate_database_schema; | ||
var mysql_to_simple_types = { | ||
const mysql_to_simple_types = { | ||
bigint: 'number', | ||
@@ -199,7 +129,7 @@ binary: 'string', | ||
}; | ||
var generate_field_schema = function (mysql_column) { | ||
var table_name = mysql_column.table_name, column_name = mysql_column.column_name, ordinal_position = mysql_column.ordinal_position, column_default = mysql_column.column_default, is_nullable = mysql_column.is_nullable, data_type = mysql_column.data_type, character_maximum_length = mysql_column.character_maximum_length, numeric_precision = mysql_column.numeric_precision, numeric_scale = mysql_column.numeric_scale, datetime_precision = mysql_column.datetime_precision, column_key = mysql_column.column_key, extra = mysql_column.extra, generation_expression = mysql_column.generation_expression, column_comment = mysql_column.column_comment; | ||
var field_schema = { | ||
const generate_field_schema = (mysql_column) => { | ||
const { table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, numeric_precision, numeric_scale, datetime_precision, column_key, extra, generation_expression, column_comment } = mysql_column; | ||
const field_schema = { | ||
data_type: mysql_to_simple_types[data_type], | ||
ordinal_position: ordinal_position | ||
ordinal_position | ||
}; | ||
@@ -246,26 +176,14 @@ // indices | ||
exports.generate_field_schema = generate_field_schema; | ||
var introspector = function (db, fn) { return __awaiter(void 0, void 0, void 0, function () { | ||
var sql_strings, _a, mysql_tables, mysql_columns, mysql_foreign_keys, transform_keys_to_lower, orma_schema; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
sql_strings = exports.get_introspect_sqls(db); | ||
return [4 /*yield*/, fn(sql_strings) | ||
// TODO: to be removed when orma lowercase bug fixed | ||
]; | ||
case 1: | ||
_a = __read.apply(void 0, [_b.sent() | ||
// TODO: to be removed when orma lowercase bug fixed | ||
, 3]), mysql_tables = _a[0], mysql_columns = _a[1], mysql_foreign_keys = _a[2]; | ||
transform_keys_to_lower = function (obj) { | ||
return Object.entries(obj).reduce(function (acc, val) { | ||
acc[val[0].toLowerCase()] = val[1]; | ||
return acc; | ||
}, {}); | ||
}; | ||
orma_schema = exports.generate_database_schema(mysql_tables.map(transform_keys_to_lower), mysql_columns.map(transform_keys_to_lower), mysql_foreign_keys.map(transform_keys_to_lower)); | ||
return [2 /*return*/, orma_schema]; | ||
} | ||
}); | ||
}); }; | ||
const introspector = async (db, fn) => { | ||
const sql_strings = exports.get_introspect_sqls(db); | ||
// @ts-ignore | ||
const [mysql_tables, mysql_columns, mysql_foreign_keys] = await fn(sql_strings); | ||
// TODO: to be removed when orma lowercase bug fixed | ||
const transform_keys_to_lower = obj => Object.entries(obj).reduce((acc, val) => { | ||
acc[val[0].toLowerCase()] = val[1]; | ||
return acc; | ||
}, {}); | ||
const orma_schema = exports.generate_database_schema(mysql_tables.map(transform_keys_to_lower), mysql_columns.map(transform_keys_to_lower), mysql_foreign_keys.map(transform_keys_to_lower)); | ||
return orma_schema; | ||
}; | ||
exports.introspector = introspector; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var chai_1 = require("chai"); | ||
var mocha_1 = require("mocha"); | ||
var helpers_1 = require("../helpers/helpers"); | ||
var introspector_1 = require("./introspector"); | ||
mocha_1.describe('introspector', function () { | ||
mocha_1.test('introspect sqls are string', function () { | ||
var introspect_sqls = introspector_1.get_introspect_sqls('international'); | ||
const chai_1 = require("chai"); | ||
const mocha_1 = require("mocha"); | ||
const helpers_1 = require("../helpers/helpers"); | ||
const introspector_1 = require("./introspector"); | ||
mocha_1.describe('introspector', () => { | ||
mocha_1.test('introspect sqls are string', () => { | ||
const introspect_sqls = introspector_1.get_introspect_sqls('international'); | ||
chai_1.expect(introspect_sqls.length).to.equal(3); | ||
chai_1.expect(helpers_1.type(introspect_sqls[0])).to.equal('String'); | ||
}); | ||
mocha_1.test('primary key field schema', function () { | ||
var mysql_column = { | ||
mocha_1.test('primary key field schema', () => { | ||
const mysql_column = { | ||
table_name: 'users', | ||
@@ -23,3 +23,3 @@ column_name: 'id', | ||
}; | ||
var field_schema = introspector_1.generate_field_schema(mysql_column); | ||
const field_schema = introspector_1.generate_field_schema(mysql_column); | ||
chai_1.expect(field_schema).to.deep.equal({ | ||
@@ -35,4 +35,4 @@ data_type: 'number', | ||
}); | ||
mocha_1.test('unique key field schema', function () { | ||
var mysql_column = { | ||
mocha_1.test('unique key field schema', () => { | ||
const mysql_column = { | ||
table_name: 'users', | ||
@@ -45,3 +45,3 @@ column_name: 'username', | ||
}; | ||
var field_schema = introspector_1.generate_field_schema(mysql_column); | ||
const field_schema = introspector_1.generate_field_schema(mysql_column); | ||
chai_1.expect(field_schema).to.deep.equal({ | ||
@@ -55,4 +55,4 @@ data_type: 'string', | ||
}); | ||
mocha_1.test('decimal precision field schema', function () { | ||
var mysql_column = { | ||
mocha_1.test('decimal precision field schema', () => { | ||
const mysql_column = { | ||
table_name: 'users', | ||
@@ -66,3 +66,3 @@ column_name: 'rating', | ||
}; | ||
var field_schema = introspector_1.generate_field_schema(mysql_column); | ||
const field_schema = introspector_1.generate_field_schema(mysql_column); | ||
chai_1.expect(field_schema).to.deep.equal({ | ||
@@ -76,4 +76,4 @@ data_type: 'number', | ||
}); | ||
mocha_1.test('entity relationships', function () { | ||
var mysql_tables = [ | ||
mocha_1.test('entity relationships', () => { | ||
const mysql_tables = [ | ||
{ | ||
@@ -88,3 +88,3 @@ table_name: 'users', | ||
]; | ||
var mysql_columns = [ | ||
const mysql_columns = [ | ||
{ | ||
@@ -103,3 +103,3 @@ table_name: 'users', | ||
]; | ||
var mysql_foreign_keys = [ | ||
const mysql_foreign_keys = [ | ||
{ | ||
@@ -113,3 +113,3 @@ table_name: 'posts', | ||
]; | ||
var database_schema = introspector_1.generate_database_schema(mysql_tables, mysql_columns, mysql_foreign_keys); | ||
const database_schema = introspector_1.generate_database_schema(mysql_tables, mysql_columns, mysql_foreign_keys); | ||
chai_1.expect(database_schema).to.deep.equal({ | ||
@@ -116,0 +116,0 @@ posts: { |
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __values = (this && this.__values) || function(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) | ||
to[j] = from[i]; | ||
return to; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.get_mutate_plan = exports.get_command_jsons = exports.orma_mutate = void 0; | ||
var helpers_1 = require("../helpers/helpers"); | ||
var schema_helpers_1 = require("../helpers/schema_helpers"); | ||
var toposort_1 = require("../helpers/toposort"); | ||
var query_1 = require("../query/query"); | ||
const helpers_1 = require("../helpers/helpers"); | ||
const schema_helpers_1 = require("../helpers/schema_helpers"); | ||
const toposort_1 = require("../helpers/toposort"); | ||
const query_1 = require("../query/query"); | ||
// TODO: comment explaining how to set up mutation functions and what needs to be returned (need to return generated values) | ||
var orma_mutate = function (mutation, mutate_functions, orma_schema) { return __awaiter(void 0, void 0, void 0, function () { | ||
var mutate_plan, mutation_result, mutate_plan_1, mutate_plan_1_1, tier, e_1_1; | ||
var e_1, _a; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
mutate_plan = exports.get_mutate_plan(mutation, orma_schema); | ||
mutation_result = helpers_1.clone(mutation); | ||
_b.label = 1; | ||
case 1: | ||
_b.trys.push([1, 6, 7, 8]); | ||
mutate_plan_1 = __values(mutate_plan), mutate_plan_1_1 = mutate_plan_1.next(); | ||
_b.label = 2; | ||
case 2: | ||
if (!!mutate_plan_1_1.done) return [3 /*break*/, 5]; | ||
tier = mutate_plan_1_1.value; | ||
return [4 /*yield*/, Promise.all(tier.map(function (_a) { | ||
var operation = _a.operation, paths = _a.paths; | ||
var command_jsons = exports.get_command_jsons(operation, paths, mutation_result, orma_schema); | ||
var command_sqls = command_jsons.map(function (command_json) { return query_1.json_to_sql(command_jsons); }); | ||
var mutate_function = mutate_functions[operation]; | ||
var results = mutate_function(command_sqls, command_jsons); | ||
paths.forEach(function (path, i) { | ||
helpers_1.deep_set(path, results[i], mutation_result); | ||
}); | ||
}))]; | ||
case 3: | ||
_b.sent(); | ||
_b.label = 4; | ||
case 4: | ||
mutate_plan_1_1 = mutate_plan_1.next(); | ||
return [3 /*break*/, 2]; | ||
case 5: return [3 /*break*/, 8]; | ||
case 6: | ||
e_1_1 = _b.sent(); | ||
e_1 = { error: e_1_1 }; | ||
return [3 /*break*/, 8]; | ||
case 7: | ||
try { | ||
if (mutate_plan_1_1 && !mutate_plan_1_1.done && (_a = mutate_plan_1.return)) _a.call(mutate_plan_1); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
return [7 /*endfinally*/]; | ||
case 8: return [2 /*return*/, mutation_result]; | ||
} | ||
}); | ||
}); }; | ||
const orma_mutate = async (mutation, mutate_functions, orma_schema) => { | ||
const mutate_plan = exports.get_mutate_plan(mutation, orma_schema); | ||
const mutation_result = helpers_1.clone(mutation); | ||
for (const tier of mutate_plan) { | ||
await Promise.all(tier.map(({ operation, paths }) => { | ||
const command_jsons = exports.get_command_jsons(operation, paths, mutation_result, orma_schema); | ||
const command_sqls = command_jsons.map(command_json => query_1.json_to_sql(command_jsons)); | ||
const mutate_function = mutate_functions[operation]; | ||
const results = mutate_function(command_sqls, command_jsons); | ||
paths.forEach((path, i) => { | ||
helpers_1.deep_set(path, results[i], mutation_result); | ||
}); | ||
})); | ||
} | ||
return mutation_result; | ||
}; | ||
exports.orma_mutate = orma_mutate; | ||
@@ -160,3 +50,3 @@ /* | ||
*/ | ||
var get_command_jsons = function (operation, paths, mutation, orma_schema) { | ||
const get_command_jsons = (operation, paths, mutation, orma_schema) => { | ||
if (operation === 'update') { | ||
@@ -171,22 +61,22 @@ return get_update_jsons(paths, mutation, orma_schema); | ||
} | ||
throw new Error("Unknown operation " + operation); | ||
throw new Error(`Unknown operation ${operation}`); | ||
}; | ||
exports.get_command_jsons = get_command_jsons; | ||
var get_update_jsons = function (paths, mutation, orma_schema) { | ||
const get_update_jsons = (paths, mutation, orma_schema) => { | ||
if (paths.length === 0) { | ||
return []; | ||
} | ||
var entity_name = path_to_entity_name(paths[0]); | ||
var jsons = paths.map(function (path) { | ||
var record = helpers_1.deep_get(path, mutation); | ||
var identifying_keys = get_identifying_keys(entity_name, record, orma_schema); | ||
const entity_name = path_to_entity_name(paths[0]); | ||
const jsons = paths.map(path => { | ||
const record = helpers_1.deep_get(path, mutation); | ||
const identifying_keys = get_identifying_keys(entity_name, record, orma_schema); | ||
throw_identifying_key_errors('update', identifying_keys, path, mutation); | ||
var where = generate_record_where_clause(identifying_keys, record); | ||
var keys_to_set = Object.keys(record) | ||
.filter(function (key) { return !identifying_keys.includes(key); }) | ||
.filter(function (key) { return typeof (record[key]) !== 'object'; }) | ||
.filter(function (key) { return !schema_helpers_1.is_reserved_keyword(key); }); | ||
const where = generate_record_where_clause(identifying_keys, record); | ||
const keys_to_set = Object.keys(record) | ||
.filter(key => !identifying_keys.includes(key)) | ||
.filter(key => typeof (record[key]) !== 'object') | ||
.filter(key => !schema_helpers_1.is_reserved_keyword(key)); | ||
return { | ||
$update: entity_name, | ||
$set: keys_to_set.map(function (key) { return [key, record[key]]; }), | ||
$set: keys_to_set.map(key => [key, record[key]]), | ||
$where: where | ||
@@ -197,12 +87,12 @@ }; | ||
}; | ||
var get_delete_jsons = function (paths, mutation, orma_schema) { | ||
const get_delete_jsons = (paths, mutation, orma_schema) => { | ||
if (paths.length === 0) { | ||
return []; | ||
} | ||
var entity_name = path_to_entity_name(paths[0]); | ||
var jsons = paths.map(function (path) { | ||
var record = helpers_1.deep_get(path, mutation); | ||
var identifying_keys = get_identifying_keys(entity_name, record, orma_schema); | ||
const entity_name = path_to_entity_name(paths[0]); | ||
const jsons = paths.map(path => { | ||
const record = helpers_1.deep_get(path, mutation); | ||
const identifying_keys = get_identifying_keys(entity_name, record, orma_schema); | ||
throw_identifying_key_errors('delete', identifying_keys, path, mutation); | ||
var where = generate_record_where_clause(identifying_keys, record); | ||
const where = generate_record_where_clause(identifying_keys, record); | ||
return { | ||
@@ -215,35 +105,24 @@ $delete_from: entity_name, | ||
}; | ||
var get_create_jsons = function (paths, mutation, orma_schema) { | ||
const get_create_jsons = (paths, mutation, orma_schema) => { | ||
if (paths.length === 0) { | ||
return []; | ||
} | ||
var entity_name = path_to_entity_name(paths[0]); | ||
var records = paths.map(function (path) { return helpers_1.deep_get(path, mutation); }); | ||
const entity_name = path_to_entity_name(paths[0]); | ||
const records = paths.map(path => helpers_1.deep_get(path, mutation)); | ||
// get insert keys by combining the keys from all records | ||
var insert_keys = paths.reduce(function (acc, path, i) { | ||
var record = records[i]; | ||
var keys_to_insert = Object.keys(record) | ||
.filter(function (key) { return typeof (record[key]) !== 'object'; }) | ||
.filter(function (key) { return !schema_helpers_1.is_reserved_keyword(key); }); | ||
keys_to_insert.forEach(function (key) { return acc.add(key); }); | ||
const insert_keys = paths.reduce((acc, path, i) => { | ||
const record = records[i]; | ||
const keys_to_insert = Object.keys(record) | ||
.filter(key => typeof (record[key]) !== 'object') | ||
.filter(key => !schema_helpers_1.is_reserved_keyword(key)); | ||
keys_to_insert.forEach(key => acc.add(key)); | ||
return acc; | ||
}, new Set()); | ||
var values = paths.map(function (path, i) { | ||
var e_2, _a; | ||
var _b; | ||
var record = records[i]; | ||
var record_values = []; | ||
try { | ||
for (var insert_keys_1 = __values(insert_keys), insert_keys_1_1 = insert_keys_1.next(); !insert_keys_1_1.done; insert_keys_1_1 = insert_keys_1.next()) { | ||
var key = insert_keys_1_1.value; | ||
record_values.push((_b = record[key]) !== null && _b !== void 0 ? _b : null); | ||
} | ||
const values = paths.map((path, i) => { | ||
var _a; | ||
const record = records[i]; | ||
const record_values = []; | ||
for (const key of insert_keys) { | ||
record_values.push((_a = record[key]) !== null && _a !== void 0 ? _a : null); | ||
} | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
finally { | ||
try { | ||
if (insert_keys_1_1 && !insert_keys_1_1.done && (_a = insert_keys_1.return)) _a.call(insert_keys_1); | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
} | ||
return record_values; | ||
@@ -256,7 +135,7 @@ }); | ||
}; | ||
var generate_record_where_clause = function (identifying_keys, record) { | ||
var where_clauses = identifying_keys.map(function (key) { return ({ | ||
const generate_record_where_clause = (identifying_keys, record) => { | ||
const where_clauses = identifying_keys.map(key => ({ | ||
$eq: [key, record[key]] | ||
}); }); | ||
var where = where_clauses.length > 1 ? { | ||
})); | ||
const where = where_clauses.length > 1 ? { | ||
and: where_clauses | ||
@@ -266,9 +145,9 @@ } : where_clauses === null || where_clauses === void 0 ? void 0 : where_clauses[0]; | ||
}; | ||
var inject_foreign_keys = function (entity_name, orma_schema, insert_keys) { | ||
const inject_foreign_keys = (entity_name, orma_schema, insert_keys) => { | ||
// when creating an entity, all foreign keys must be present. These can be taken from the user input | ||
var edges_to_parents = schema_helpers_1.get_parent_edges(entity_name, orma_schema); | ||
var foreign_keys_to_parent = edges_to_parents.map(function (edge) { return edge.from_field; }); | ||
foreign_keys_to_parent.forEach(function (key) { return insert_keys.add(key); }); | ||
const edges_to_parents = schema_helpers_1.get_parent_edges(entity_name, orma_schema); | ||
const foreign_keys_to_parent = edges_to_parents.map(edge => edge.from_field); | ||
foreign_keys_to_parent.forEach(key => insert_keys.add(key)); | ||
}; | ||
var get_parent_path = function (path) { | ||
const get_parent_path = (path) => { | ||
return typeof helpers_1.last(path) === 'number' | ||
@@ -278,3 +157,3 @@ ? path.slice(0, path.length - 2) | ||
}; | ||
var path_to_entity_name = function (path) { | ||
const path_to_entity_name = (path) => { | ||
return typeof helpers_1.last(path) === 'number' | ||
@@ -284,10 +163,10 @@ ? path[path.length - 2] | ||
}; | ||
var get_identifying_keys = function (entity_name, record, orma_schema) { | ||
var primary_keys = schema_helpers_1.get_primary_keys(entity_name, orma_schema); | ||
var has_primary_keys = primary_keys.every(function (primary_key) { return record[primary_key]; }); | ||
const get_identifying_keys = (entity_name, record, orma_schema) => { | ||
const primary_keys = schema_helpers_1.get_primary_keys(entity_name, orma_schema); | ||
const has_primary_keys = primary_keys.every(primary_key => record[primary_key]); | ||
if (has_primary_keys && primary_keys.length > 0) { | ||
return primary_keys; | ||
} | ||
var unique_keys = schema_helpers_1.get_unique_fields(entity_name, orma_schema); | ||
var included_unique_keys = unique_keys.filter(function (unique_key) { return record[unique_key]; }); | ||
const unique_keys = schema_helpers_1.get_unique_fields(entity_name, orma_schema); | ||
const included_unique_keys = unique_keys.filter(unique_key => record[unique_key]); | ||
if (included_unique_keys.length === 1) { // if there are 2 or more unique keys, we cant use them since it would be ambiguous which we choose | ||
@@ -298,6 +177,6 @@ return included_unique_keys; | ||
}; | ||
var throw_identifying_key_errors = function (operation, identifying_keys, path, mutation) { | ||
const throw_identifying_key_errors = (operation, identifying_keys, path, mutation) => { | ||
if (!identifying_keys || identifying_keys.length === 0) { | ||
throw { | ||
message: "Could not find primary keys or unique keys in record to " + operation, | ||
message: `Could not find primary keys or unique keys in record to ${operation}`, | ||
path: path, | ||
@@ -312,3 +191,3 @@ original_data: mutation, | ||
}; | ||
var get_mutate_plan = function (mutation, orma_schema) { | ||
const get_mutate_plan = (mutation, orma_schema) => { | ||
/* | ||
@@ -368,8 +247,8 @@ This function is an algorithm that wont make sense without an explanation. The idea is to generate a mutate plan | ||
*/ | ||
var paths_by_route = {}; | ||
const paths_by_route = {}; | ||
// construct a directed acyclic graph reflecting the parent/child relationships of the routes | ||
// we use sets because we need to quickly add items to the graph while avoiding duplicates | ||
// (one will be added per row in the mutation, so its important that this is O(1)) | ||
var route_graph = {}; | ||
helpers_1.deep_for_each(mutation, function (value, path) { | ||
const route_graph = {}; | ||
helpers_1.deep_for_each(mutation, (value, path) => { | ||
var _a; | ||
@@ -380,12 +259,12 @@ if (typeof value !== 'object' || Array.isArray(value) || path.length === 0) { | ||
// use the closest ancestor with an $operation as the current $operation. This handles operation inheritance | ||
var operation = path | ||
.map(function (el, i) { return path.slice(0, path.length - i); }) | ||
.map(function (path_slice) { return helpers_1.deep_get(__spreadArray(__spreadArray([], __read(path_slice)), ['$operation']), mutation); }) | ||
.find(function (el) { return typeof el === 'string'; }); | ||
const operation = path | ||
.map((el, i) => path.slice(0, path.length - i)) | ||
.map(path_slice => helpers_1.deep_get([...path_slice, '$operation'], mutation)) | ||
.find((el) => typeof el === 'string'); | ||
if (!operation) { | ||
throw new Error("Could not find an inherited operation for " + JSON.stringify(path)); | ||
throw new Error(`Could not find an inherited operation for ${JSON.stringify(path)}`); | ||
} | ||
var path_template = path.map(function (el) { return typeof el === 'number' ? 0 : el; }); | ||
var route = __spreadArray([operation], __read(path_template)); | ||
var route_string = JSON.stringify(route); | ||
const path_template = path.map(el => typeof el === 'number' ? 0 : el); | ||
const route = [operation, ...path_template]; | ||
const route_string = JSON.stringify(route); | ||
// add path to paths_by_route | ||
@@ -400,3 +279,3 @@ if (!paths_by_route[route_string]) { | ||
} | ||
var higher_path = typeof helpers_1.last(path) === 'number' | ||
const higher_path = typeof helpers_1.last(path) === 'number' | ||
? path.slice(0, path.length - 2) // need to remove the entity name and index template (the number 0) | ||
@@ -408,20 +287,20 @@ : path.slice(0, path.length - 1); // only remove the entity name | ||
// if higher row does not have $operation, it inherits the same operation as the current row | ||
var higher_operation = (_a = helpers_1.deep_get(__spreadArray(__spreadArray([], __read(higher_path)), ['$operation']), mutation)) !== null && _a !== void 0 ? _a : operation; | ||
var higher_path_template = typeof helpers_1.last(path_template) === 'number' | ||
const higher_operation = (_a = helpers_1.deep_get([...higher_path, '$operation'], mutation)) !== null && _a !== void 0 ? _a : operation; | ||
const higher_path_template = typeof helpers_1.last(path_template) === 'number' | ||
? path_template.slice(0, path_template.length - 2) // need to remove the entity name and index template (the number 0) | ||
: path_template.slice(0, path_template.length - 1); // only remove the entity name | ||
var higher_route = __spreadArray([higher_operation], __read(higher_path_template)); | ||
var higher_route_string = JSON.stringify(higher_route); | ||
const higher_route = [higher_operation, ...higher_path_template]; | ||
const higher_route_string = JSON.stringify(higher_route); | ||
if (!route_graph[higher_route_string]) { | ||
route_graph[higher_route_string] = new Set(); | ||
} | ||
var entity = typeof helpers_1.last(path) === 'number' | ||
const entity = typeof helpers_1.last(path) === 'number' | ||
? path[path.length - 2] | ||
: helpers_1.last(path); | ||
var higher_entity = typeof helpers_1.last(higher_path) === 'number' | ||
const higher_entity = typeof helpers_1.last(higher_path) === 'number' | ||
? higher_path[higher_path.length - 2] | ||
: helpers_1.last(higher_path); | ||
var higher_entity_is_parent = schema_helpers_1.is_parent_entity(higher_entity, entity, orma_schema); // in cases of self-referenced entities, this will return true. So they will be processed in regular order (top -> bottom for creates, bottom -> top for deletes) | ||
var parent_route_string = higher_entity_is_parent ? higher_route_string : route_string; // regular nesting | ||
var child_route_string = higher_entity_is_parent ? route_string : higher_route_string; // reverse nesting | ||
const higher_entity_is_parent = schema_helpers_1.is_parent_entity(higher_entity, entity, orma_schema); // in cases of self-referenced entities, this will return true. So they will be processed in regular order (top -> bottom for creates, bottom -> top for deletes) | ||
const parent_route_string = higher_entity_is_parent ? higher_route_string : route_string; // regular nesting | ||
const child_route_string = higher_entity_is_parent ? route_string : higher_route_string; // reverse nesting | ||
if (operation === higher_operation) { | ||
@@ -439,13 +318,10 @@ if (operation === 'create') { | ||
// convert sets into arrays for toposort | ||
var toposort_graph = Object.keys(route_graph).reduce(function (acc, key) { | ||
var _a; | ||
return __assign(__assign({}, acc), (_a = {}, _a[key] = __spreadArray([], __read(route_graph[key])), _a)); | ||
const toposort_graph = Object.keys(route_graph).reduce((acc, key) => { | ||
return Object.assign(Object.assign({}, acc), { [key]: [...route_graph[key]] }); | ||
}, {}); | ||
var topological_ordering = toposort_1.toposort(toposort_graph); | ||
var mutate_plan = topological_ordering.map(function (route_strings) { | ||
return route_strings.map(function (route_string) { return ({ | ||
operation: JSON.parse(route_string)[0], | ||
paths: paths_by_route[route_string] | ||
}); }); | ||
}); | ||
const topological_ordering = toposort_1.toposort(toposort_graph); | ||
const mutate_plan = topological_ordering.map(route_strings => route_strings.map(route_string => ({ | ||
operation: JSON.parse(route_string)[0], | ||
paths: paths_by_route[route_string] | ||
}))); | ||
return mutate_plan; | ||
@@ -452,0 +328,0 @@ }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var chai_1 = require("chai"); | ||
var mocha_1 = require("mocha"); | ||
var mutate_1 = require("./mutate"); | ||
mocha_1.describe('mutate', function () { | ||
var orma_schema = { | ||
const chai_1 = require("chai"); | ||
const mocha_1 = require("mocha"); | ||
const mutate_1 = require("./mutate"); | ||
mocha_1.describe('mutate', () => { | ||
const orma_schema = { | ||
grandparents: { | ||
@@ -50,5 +50,5 @@ id: { | ||
}; | ||
mocha_1.describe('get_mutate_plan', function () { | ||
mocha_1.test('simple mutation', function () { | ||
var mutation = { | ||
mocha_1.describe('get_mutate_plan', () => { | ||
mocha_1.test('simple mutation', () => { | ||
const mutation = { | ||
parents: [{ | ||
@@ -63,4 +63,4 @@ $operation: 'create', | ||
}; | ||
var mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
var goal = [ | ||
const mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
const goal = [ | ||
[{ operation: 'create', paths: [['parents', 0]] }], | ||
@@ -71,4 +71,4 @@ [{ operation: 'create', paths: [['parents', 0, 'children', 0], ['parents', 0, 'children', 1]] }] | ||
}); | ||
mocha_1.test('respects operation precedence', function () { | ||
var mutation = { | ||
mocha_1.test('respects operation precedence', () => { | ||
const mutation = { | ||
parents: [{ | ||
@@ -82,4 +82,4 @@ $operation: 'delete', | ||
}; | ||
var mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
var goal = [ | ||
const mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
const goal = [ | ||
[ | ||
@@ -93,4 +93,4 @@ { operation: 'delete', paths: [['parents', 0]] }, | ||
}); | ||
mocha_1.test('respects topological ordering for create', function () { | ||
var mutation = { | ||
mocha_1.test('respects topological ordering for create', () => { | ||
const mutation = { | ||
parents: [{ | ||
@@ -103,4 +103,4 @@ $operation: 'create', | ||
}; | ||
var mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
var goal = [ | ||
const mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
const goal = [ | ||
[{ operation: 'create', paths: [['parents', 0]] }], | ||
@@ -111,4 +111,4 @@ [{ operation: 'create', paths: [['parents', 0, 'children', 0]] }] | ||
}); | ||
mocha_1.test('respects topological ordering for update', function () { | ||
var mutation = { | ||
mocha_1.test('respects topological ordering for update', () => { | ||
const mutation = { | ||
parents: [{ | ||
@@ -121,5 +121,5 @@ $operation: 'update', | ||
}; | ||
var mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
const mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
// update order is not guaranteed | ||
var goal = [ | ||
const goal = [ | ||
[ | ||
@@ -132,4 +132,4 @@ { operation: 'update', paths: [['parents', 0]] }, | ||
}); | ||
mocha_1.test('respects topological ordering for delete', function () { | ||
var mutation = { | ||
mocha_1.test('respects topological ordering for delete', () => { | ||
const mutation = { | ||
parents: [{ | ||
@@ -142,4 +142,4 @@ $operation: 'delete', | ||
}; | ||
var mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
var goal = [ | ||
const mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
const goal = [ | ||
[{ operation: 'delete', paths: [['parents', 0, 'children', 0]] }], | ||
@@ -150,4 +150,4 @@ [{ operation: 'delete', paths: [['parents', 0]] }], | ||
}); | ||
mocha_1.test('handles mixed operation requests', function () { | ||
var mutation = { | ||
mocha_1.test('handles mixed operation requests', () => { | ||
const mutation = { | ||
grandparents: [{ | ||
@@ -168,4 +168,4 @@ $operation: 'update', | ||
}; | ||
var mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
var goal = [ | ||
const mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
const goal = [ | ||
[ | ||
@@ -182,4 +182,4 @@ { operation: 'update', paths: [['grandparents', 0]] }, | ||
}); | ||
mocha_1.test('handles entity with no children', function () { | ||
var mutation = { | ||
mocha_1.test('handles entity with no children', () => { | ||
const mutation = { | ||
parents: [{ | ||
@@ -189,4 +189,4 @@ $operation: 'update', | ||
}; | ||
var mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
var goal = [ | ||
const mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
const goal = [ | ||
[{ operation: 'update', paths: [['parents', 0]] }] | ||
@@ -196,4 +196,4 @@ ]; | ||
}); | ||
mocha_1.test('handles reverse nesting', function () { | ||
var mutation = { | ||
mocha_1.test('handles reverse nesting', () => { | ||
const mutation = { | ||
children: [{ | ||
@@ -206,4 +206,4 @@ $operation: 'create', | ||
}; | ||
var mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
var goal = [ | ||
const mutate_plan = mutate_1.get_mutate_plan(mutation, orma_schema); | ||
const goal = [ | ||
[{ operation: 'create', paths: [['children', 0, 'parents', 0]] }], | ||
@@ -215,5 +215,5 @@ [{ operation: 'create', paths: [['children', 0]] }] | ||
}); | ||
mocha_1.describe('get_command_jsons', function () { | ||
mocha_1.test('update/delete by id', function () { | ||
var mutation = { | ||
mocha_1.describe('get_command_jsons', () => { | ||
mocha_1.test('update/delete by id', () => { | ||
const mutation = { | ||
grandparents: [{ | ||
@@ -225,4 +225,4 @@ $operation: 'update', | ||
}; | ||
var result = mutate_1.get_command_jsons('update', [['grandparents', 0]], mutation, orma_schema); | ||
var goal = [{ | ||
const result = mutate_1.get_command_jsons('update', [['grandparents', 0]], mutation, orma_schema); | ||
const goal = [{ | ||
$update: 'grandparents', | ||
@@ -236,4 +236,4 @@ $set: [['quantity', 2]], | ||
}); | ||
mocha_1.test('foreign key has precedence over unique', function () { | ||
var mutation = { | ||
mocha_1.test('foreign key has precedence over unique', () => { | ||
const mutation = { | ||
parents: [{ | ||
@@ -244,4 +244,4 @@ id: 1, | ||
}; | ||
var result = mutate_1.get_command_jsons('update', [['parents', 0]], mutation, orma_schema); | ||
var goal = [{ | ||
const result = mutate_1.get_command_jsons('update', [['parents', 0]], mutation, orma_schema); | ||
const goal = [{ | ||
$update: 'parents', | ||
@@ -255,4 +255,4 @@ $set: [['unique1', 'john']], | ||
}); | ||
mocha_1.test('update/delete by unique', function () { | ||
var mutation = { | ||
mocha_1.test('update/delete by unique', () => { | ||
const mutation = { | ||
parents: [{ | ||
@@ -263,4 +263,4 @@ unique1: 'john', | ||
}; | ||
var result = mutate_1.get_command_jsons('update', [['parents', 0]], mutation, orma_schema); | ||
var goal = [{ | ||
const result = mutate_1.get_command_jsons('update', [['parents', 0]], mutation, orma_schema); | ||
const goal = [{ | ||
$update: 'parents', | ||
@@ -274,4 +274,4 @@ $set: [['quantity', 5]], | ||
}); | ||
mocha_1.test('throws on no update key', function () { | ||
var mutation = { | ||
mocha_1.test('throws on no update key', () => { | ||
const mutation = { | ||
parents: [{ | ||
@@ -282,3 +282,3 @@ quantity: 5 | ||
try { | ||
var result = mutate_1.get_command_jsons('update', [['parents', 0]], mutation, orma_schema); | ||
const result = mutate_1.get_command_jsons('update', [['parents', 0]], mutation, orma_schema); | ||
chai_1.expect('should have thrown an error').to.equal(true); | ||
@@ -288,4 +288,4 @@ } | ||
}); | ||
mocha_1.test('throws on multiple unique update keys', function () { | ||
var mutation = { | ||
mocha_1.test('throws on multiple unique update keys', () => { | ||
const mutation = { | ||
parents: [{ | ||
@@ -298,3 +298,3 @@ unique1: 'test', | ||
try { | ||
var result = mutate_1.get_command_jsons('update', [['parents', 0]], mutation, orma_schema); | ||
const result = mutate_1.get_command_jsons('update', [['parents', 0]], mutation, orma_schema); | ||
chai_1.expect('should have thrown an error').to.equal(true); | ||
@@ -304,4 +304,4 @@ } | ||
}); | ||
mocha_1.test('handles compound primary key', function () { | ||
var mutation = { | ||
mocha_1.test('handles compound primary key', () => { | ||
const mutation = { | ||
children: [{ | ||
@@ -313,4 +313,4 @@ id1: 4, | ||
}; | ||
var result = mutate_1.get_command_jsons('update', [['children', 0]], mutation, orma_schema); | ||
var goal = [{ | ||
const result = mutate_1.get_command_jsons('update', [['children', 0]], mutation, orma_schema); | ||
const goal = [{ | ||
$update: 'children', | ||
@@ -328,4 +328,4 @@ $set: [['parent_id', 6]], | ||
}); | ||
mocha_1.test('handles deletes', function () { | ||
var mutation = { | ||
mocha_1.test('handles deletes', () => { | ||
const mutation = { | ||
parents: [{ | ||
@@ -335,4 +335,4 @@ id: 4 | ||
}; | ||
var result = mutate_1.get_command_jsons('delete', [['parents', 0]], mutation, orma_schema); | ||
var goal = [{ | ||
const result = mutate_1.get_command_jsons('delete', [['parents', 0]], mutation, orma_schema); | ||
const goal = [{ | ||
$delete_from: 'parents', | ||
@@ -339,0 +339,0 @@ $where: { |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.stop_profiler = exports.start_profiler = void 0; | ||
var inspector = require('inspector'); | ||
var util = require('util'); | ||
var session = new inspector.Session(); | ||
const inspector = require('inspector'); | ||
const util = require('util'); | ||
let session = new inspector.Session(); | ||
session.connect(); | ||
var post = util.promisify(session.post.bind(session)); | ||
var fs = require('fs'); | ||
var write_file = util.promisify(fs.writeFile); | ||
var profiler_running = false; | ||
var start_profiler = function () { return __awaiter(void 0, void 0, void 0, function () { | ||
var er_1; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (profiler_running) { | ||
throw new Error('Profiler already running, try again later'); | ||
} | ||
profiler_running = true; | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 4, , 5]); | ||
return [4 /*yield*/, post('Profiler.enable')]; | ||
case 2: | ||
_a.sent(); | ||
return [4 /*yield*/, post('Profiler.start')]; | ||
case 3: | ||
_a.sent(); | ||
return [3 /*break*/, 5]; | ||
case 4: | ||
er_1 = _a.sent(); | ||
console.error('Profiler error:', er_1); | ||
return [3 /*break*/, 5]; | ||
case 5: return [2 /*return*/]; | ||
} | ||
}); | ||
}); }; | ||
let post = util.promisify(session.post.bind(session)); | ||
const fs = require('fs'); | ||
let write_file = util.promisify(fs.writeFile); | ||
let profiler_running = false; | ||
const start_profiler = async () => { | ||
if (profiler_running) { | ||
throw new Error('Profiler already running, try again later'); | ||
} | ||
profiler_running = true; | ||
try { | ||
await post('Profiler.enable'); | ||
await post('Profiler.start'); | ||
} | ||
catch (er) { | ||
console.error('Profiler error:', er); | ||
} | ||
}; | ||
exports.start_profiler = start_profiler; | ||
var stop_profiler = function () { return __awaiter(void 0, void 0, void 0, function () { | ||
var profile, file_name, er_2; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 3, 4, 6]); | ||
return [4 /*yield*/, post('Profiler.stop')]; | ||
case 1: | ||
profile = (_a.sent()).profile; | ||
file_name = "profile_" + Date.now() + ".cpuprofile"; | ||
return [4 /*yield*/, write_file(file_name, JSON.stringify(profile))]; | ||
case 2: | ||
_a.sent(); | ||
console.error('Profile written to', file_name); | ||
return [3 /*break*/, 6]; | ||
case 3: | ||
er_2 = _a.sent(); | ||
console.error('Profiler error:', er_2); | ||
return [3 /*break*/, 6]; | ||
case 4: return [4 /*yield*/, post('Profiler.disable')]; | ||
case 5: | ||
_a.sent(); | ||
profiler_running = false; | ||
return [7 /*endfinally*/]; | ||
case 6: return [2 /*return*/]; | ||
} | ||
}); | ||
}); }; | ||
const stop_profiler = async () => { | ||
try { | ||
const profile = (await post('Profiler.stop')).profile; | ||
let file_name = `profile_${Date.now()}.cpuprofile`; | ||
await write_file(file_name, JSON.stringify(profile)); | ||
console.error('Profile written to', file_name); | ||
} | ||
catch (er) { | ||
console.error('Profiler error:', er); | ||
} | ||
finally { | ||
await post('Profiler.disable'); | ||
profiler_running = false; | ||
} | ||
}; | ||
exports.stop_profiler = stop_profiler; |
@@ -91,31 +91,28 @@ "use strict"; | ||
*/ | ||
var parse_json_query = function (expression, command_parsers, command_joiner, throw_on_unknown, ancestors) { | ||
if (throw_on_unknown === void 0) { throw_on_unknown = true; } | ||
if (ancestors === void 0) { ancestors = []; } | ||
const parse_json_query = (expression, command_parsers, command_joiner, throw_on_unknown = true, ancestors = []) => { | ||
if (type(expression) === 'Object') { | ||
var commands = keys(expression).sort(function (key1, key2) { | ||
var i1 = indexOf(key1, command_order); | ||
var i2 = indexOf(key2, command_order); | ||
const commands = keys(expression).sort((key1, key2) => { | ||
const i1 = indexOf(key1, command_order); | ||
const i2 = indexOf(key2, command_order); | ||
return i1 - i2; | ||
}); | ||
var parsed_commands = commands.map(function (command) { | ||
var _a; | ||
var command_path = append(command, ancestors); | ||
var args = expression[command]; | ||
var parse_arg = function (arg) { return exports.parse_json_query(arg, command_parsers, command_joiner, throw_on_unknown, command_path); }; | ||
var parsed_args = type(args) === 'Array' | ||
const parsed_commands = commands.map(command => { | ||
const command_path = append(command, ancestors); | ||
const args = expression[command]; | ||
const parse_arg = arg => exports.parse_json_query(arg, command_parsers, command_joiner, throw_on_unknown, command_path); | ||
const parsed_args = type(args) === 'Array' | ||
? args.map(parse_arg) | ||
: parse_arg(args); | ||
var command_parser = find_command_parser(command_path, command_parsers); | ||
const command_parser = find_command_parser(command_path, command_parsers); | ||
if (command_parser === undefined) { | ||
if (throw_on_unknown) { | ||
throw Error("Cannot find command parser for " + command); | ||
throw Error(`Cannot find command parser for ${command}`); | ||
} | ||
else { | ||
return _a = {}, | ||
_a[command] = parsed_args, | ||
_a; | ||
return { | ||
[command]: parsed_args | ||
}; | ||
} | ||
} | ||
var parsed_command = type(command_parser) === 'Function' | ||
const parsed_command = type(command_parser) === 'Function' | ||
? command_parser(parsed_args, command_path) | ||
@@ -132,5 +129,4 @@ : parsed_args; | ||
exports.parse_json_query = parse_json_query; | ||
var json_to_sql = function (expression, pretty) { | ||
if (pretty === void 0) { pretty = false; } | ||
var parsed = exports.parse_json_query(expression, sql_command_parsers, join(' ')); | ||
const json_to_sql = (expression, pretty = false) => { | ||
const parsed = exports.parse_json_query(expression, sql_command_parsers, join(' ')); | ||
if (pretty) { | ||
@@ -137,0 +133,0 @@ return sqlFormatter.format(parsed); |
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) | ||
to[j] = from[i]; | ||
return to; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.read_query_schema = exports.get_query_schema = exports.get_relevant_diff_functions = void 0; | ||
// @ts-nocheck | ||
var mysql_1 = require("mysql"); | ||
var ramda_1 = require("ramda"); | ||
var helpers_1 = require("../helpers"); | ||
var query_schema_diffs_1 = require("../no3rd/query_schema_diffs"); | ||
var traversal2_1 = require("../traversal2"); | ||
var _generated_table_info_1 = require("../../generated/_generated_table_info"); | ||
var memoize = require('memoizee'); | ||
var Joi = require('joi'); | ||
var get_relevant_diff_functions = function (is_meta, table_name, master_diff) { | ||
var table_names = traversal2_1.get_all_table_names(_generated_table_info_1.table_info); | ||
var matching_diff_pairs = ramda_1.keys(master_diff).flatMap(function (key) { | ||
var key_is_meta, key_table, key_field; | ||
var split_key = key.split('/'); | ||
var is_formatted_root = split_key.length === 2 | ||
const mysql_1 = require("mysql"); | ||
const ramda_1 = require("ramda"); | ||
const helpers_1 = require("../helpers"); | ||
const query_schema_diffs_1 = require("../no3rd/query_schema_diffs"); | ||
const traversal2_1 = require("../traversal2"); | ||
const _generated_table_info_1 = require("../../generated/_generated_table_info"); | ||
const memoize = require('memoizee'); | ||
const Joi = require('joi'); | ||
const get_relevant_diff_functions = (is_meta, table_name, master_diff) => { | ||
const table_names = traversal2_1.get_all_table_names(_generated_table_info_1.table_info); | ||
const matching_diff_pairs = ramda_1.keys(master_diff).flatMap(key => { | ||
let key_is_meta, key_table, key_field; | ||
const split_key = key.split('/'); | ||
const is_formatted_root = split_key.length === 2 | ||
&& split_key[0] === '' | ||
&& split_key[1] !== 'meta' | ||
&& !ramda_1.includes(split_key[1], table_names); | ||
var is_formatted_meta = split_key.length === 3 | ||
const is_formatted_meta = split_key.length === 3 | ||
&& split_key[0] === 'meta' | ||
@@ -71,3 +39,3 @@ && ramda_1.includes(split_key[1], table_names) | ||
} | ||
var diff = function (schema) { return master_diff[key](schema); }; | ||
const diff = schema => master_diff[key](schema); | ||
if (key_is_meta === is_meta && key_table === table_name) { | ||
@@ -80,44 +48,41 @@ return [[key_field, diff]]; | ||
}); | ||
var diffs_object = ramda_1.fromPairs(matching_diff_pairs); | ||
const diffs_object = ramda_1.fromPairs(matching_diff_pairs); | ||
return diffs_object; | ||
}; | ||
exports.get_relevant_diff_functions = get_relevant_diff_functions; | ||
var get_meta_schema = function () { | ||
var _a; | ||
var table_names = traversal2_1.get_all_table_names(_generated_table_info_1.table_info); | ||
var table_schemas = table_names.map(function (table_name) { | ||
var _a; | ||
var diffs_by_key = exports.get_relevant_diff_functions(true, table_name, query_schema_diffs_1.default); | ||
var key_schemas = ramda_1.keys(diffs_by_key).map(function (key) { return diffs_by_key[key](); }); | ||
var table_schema = (_a = Joi.object()).keys.apply(_a, __spreadArray([], __read(key_schemas))); | ||
const get_meta_schema = () => { | ||
const table_names = traversal2_1.get_all_table_names(_generated_table_info_1.table_info); | ||
const table_schemas = table_names.map(table_name => { | ||
const diffs_by_key = exports.get_relevant_diff_functions(true, table_name, query_schema_diffs_1.default); | ||
const key_schemas = ramda_1.keys(diffs_by_key).map(key => diffs_by_key[key]()); | ||
const table_schema = Joi.object().keys(...key_schemas); | ||
return table_schema; | ||
}); | ||
var table_schema_fields = ramda_1.zipObj(table_names, table_schemas); | ||
var meta_schema = (_a = Joi.object().keys(__assign({}, table_schema_fields))).xor.apply(_a, __spreadArray([], __read(table_names))); | ||
const table_schema_fields = ramda_1.zipObj(table_names, table_schemas); | ||
const meta_schema = Joi.object().keys(Object.assign({}, table_schema_fields)).xor(...table_names); | ||
return table_schemas; | ||
}; | ||
var get_select_schema = function (table_name) { | ||
var _a; | ||
var column_names = traversal2_1.get_column_names(table_name, _generated_table_info_1.table_info); | ||
var aggregate_columns = [ | ||
const get_select_schema = table_name => { | ||
const column_names = traversal2_1.get_column_names(table_name, _generated_table_info_1.table_info); | ||
const aggregate_columns = [ | ||
Joi.object().keys({ | ||
sum: Joi.valid.apply(Joi, __spreadArray([], __read(column_names))).required() | ||
sum: Joi.valid(...column_names).required() | ||
}) | ||
]; | ||
// if group by is provided, we can only select from the grouped column, or from aggregate columns | ||
var column_schema = Joi.when('...group_by', { | ||
const column_schema = Joi.when('...group_by', { | ||
switch: [ | ||
{ | ||
is: Joi.array().required(), | ||
then: Joi.alternatives.apply(Joi, __spreadArray(__spreadArray([Joi.in('...group_by')], __read(aggregate_columns)), [Joi.valid('*')])).required() | ||
then: Joi.alternatives(Joi.in('...group_by'), ...aggregate_columns, Joi.valid('*')).required() | ||
}, { | ||
is: Joi.alternatives(Joi.string().required(), Joi.number().required()).required(), | ||
then: Joi.alternatives.apply(Joi, __spreadArray(__spreadArray([Joi.ref('...group_by')], __read(aggregate_columns)), [Joi.valid('*')])).required() | ||
then: Joi.alternatives(Joi.ref('...group_by'), ...aggregate_columns, Joi.valid('*')).required() | ||
} | ||
], | ||
otherwise: (_a = Joi | ||
.valid.apply(Joi, __spreadArray([], __read(column_names)))) | ||
.valid.apply(_a, __spreadArray([], __read(aggregate_columns))).required() | ||
otherwise: Joi | ||
.valid(...column_names) | ||
.valid(...aggregate_columns).required() | ||
}); | ||
var schema = [ | ||
const schema = [ | ||
Joi.array().items(column_schema).min(1).required(), | ||
@@ -130,63 +95,61 @@ column_schema, | ||
// returns a regex that is only valid for the given items separated by dots | ||
var get_delimited_list_regex = function (valid_options, delimiter) { | ||
var item_regex = valid_options.map(helpers_1.escapeRegex).join('|'); | ||
var list_regex = "^(" + item_regex + ")(" + helpers_1.escapeRegex(delimiter) + "(" + item_regex + "))*$"; | ||
const get_delimited_list_regex = (valid_options, delimiter) => { | ||
const item_regex = valid_options.map(helpers_1.escapeRegex).join('|'); | ||
const list_regex = `^(${item_regex})(${helpers_1.escapeRegex(delimiter)}(${item_regex}))*$`; | ||
return RegExp(list_regex); | ||
}; | ||
// returns a regex that is valid if each dot separated item is either the parent or child of the item before it | ||
var get_invalid_table_relation_regex = function (table_infos) { | ||
var table_names = traversal2_1.get_all_table_names(table_infos); | ||
var table_checks = table_names.map(function (table_name) { | ||
var child_tables = traversal2_1.get_possible_child_edges(table_name, table_infos) | ||
const get_invalid_table_relation_regex = (table_infos) => { | ||
const table_names = traversal2_1.get_all_table_names(table_infos); | ||
const table_checks = table_names.map(table_name => { | ||
const child_tables = traversal2_1.get_possible_child_edges(table_name, table_infos) | ||
.concat(traversal2_1.get_possible_parent_edges(table_name, table_infos)) | ||
.map(ramda_1.prop('to_table')); | ||
var child_tables_regex = child_tables | ||
.map(function (child) { return "(" + helpers_1.escapeRegex(child) + ")"; }) | ||
const child_tables_regex = child_tables | ||
.map(child => `(${helpers_1.escapeRegex(child)})`) | ||
// .concat('$') // end of string is considered a valid child. If there are no children, this is the only valid child, since nothing can come next | ||
.join('|'); | ||
return "((^|\\.)" + helpers_1.escapeRegex(table_name) + "\\.(?!" + child_tables_regex + "))"; // matches the table name followed by something that is not a child | ||
return `((^|\\.)${helpers_1.escapeRegex(table_name)}\\.(?!${child_tables_regex}))`; // matches the table name followed by something that is not a child | ||
}); | ||
var regex_str = table_checks.join('|'); | ||
const regex_str = table_checks.join('|'); | ||
return RegExp(regex_str); | ||
}; | ||
// returns a regex that passes if the string starts with a table name that is either a parent or child of the supplied table_name | ||
var get_starts_with_connected_table_regex = function (table_name, table_infos) { | ||
var connected_tables = traversal2_1.get_possible_child_edges(table_name, table_infos) | ||
const get_starts_with_connected_table_regex = (table_name, table_infos) => { | ||
const connected_tables = traversal2_1.get_possible_child_edges(table_name, table_infos) | ||
.concat(traversal2_1.get_possible_parent_edges(table_name, table_infos)) | ||
.map(ramda_1.prop('to_table')); | ||
var connected_tables_regex = connected_tables | ||
.map(function (child) { return "(" + helpers_1.escapeRegex(child) + ")"; }) | ||
const connected_tables_regex = connected_tables | ||
.map(child => `(${helpers_1.escapeRegex(child)})`) | ||
.join('|'); | ||
return RegExp("^(" + connected_tables_regex + ")"); | ||
return RegExp(`^(${connected_tables_regex})`); | ||
}; | ||
var get_where_schema = function (table_name, is_having_clause) { | ||
var _a, _b, _c, _d; | ||
if (is_having_clause === void 0) { is_having_clause = false; } | ||
var column_names = traversal2_1.get_column_names(table_name, _generated_table_info_1.table_info); | ||
var aggregate_column_names = column_names.map(function (column_name) { return "sum_" + column_name; }); | ||
var column_schema = is_having_clause | ||
? (_a = Joi.string()).valid.apply(_a, __spreadArray([], __read(column_names))).required() | ||
: (_b = (_c = Joi.string()).valid.apply(_c, __spreadArray([], __read(column_names)))).valid.apply(_b, __spreadArray([], __read(aggregate_column_names))).required(); | ||
var user_value_schema = Joi.alternatives(Joi.string(), Joi.number()).required().custom(function (val, helpers) { | ||
const get_where_schema = (table_name, is_having_clause = false) => { | ||
const column_names = traversal2_1.get_column_names(table_name, _generated_table_info_1.table_info); | ||
const aggregate_column_names = column_names.map(column_name => `sum_${column_name}`); | ||
const column_schema = is_having_clause | ||
? Joi.string().valid(...column_names).required() | ||
: Joi.string().valid(...column_names).valid(...aggregate_column_names).required(); | ||
const user_value_schema = Joi.alternatives(Joi.string(), Joi.number()).required().custom((val, helpers) => { | ||
return mysql_1.escape(val); | ||
}); | ||
var operation_schema = Joi.array().ordered(column_schema, user_value_schema); | ||
var table_names = traversal2_1.get_all_table_names(_generated_table_info_1.table_info); | ||
var route_table_regex = get_delimited_list_regex(table_names, '.'); | ||
var invalid_table_relation_regex = get_invalid_table_relation_regex(_generated_table_info_1.table_info); | ||
var starts_with_connected_table_regex = get_starts_with_connected_table_regex(table_name, _generated_table_info_1.table_info); | ||
var any_route_schema = Joi.string() | ||
const operation_schema = Joi.array().ordered(column_schema, user_value_schema); | ||
const table_names = traversal2_1.get_all_table_names(_generated_table_info_1.table_info); | ||
const route_table_regex = get_delimited_list_regex(table_names, '.'); | ||
const invalid_table_relation_regex = get_invalid_table_relation_regex(_generated_table_info_1.table_info); | ||
const starts_with_connected_table_regex = get_starts_with_connected_table_regex(table_name, _generated_table_info_1.table_info); | ||
const any_route_schema = Joi.string() | ||
.regex(route_table_regex, { name: 'has only valid table names' }) | ||
.regex(invalid_table_relation_regex, { invert: true, name: 'has only connected tables together' }) | ||
.regex(starts_with_connected_table_regex, { name: "starts with child or parent of " + table_name }); | ||
var any_where_schema = Joi.when('', { | ||
switch: table_names.map(function (child_table) { return ({ | ||
is: Joi.string().regex(RegExp("(\\.|^)" + child_table + "$")).required(), | ||
.regex(starts_with_connected_table_regex, { name: `starts with child or parent of ${table_name}` }); | ||
const any_where_schema = Joi.when('', { | ||
switch: table_names.map(child_table => ({ | ||
is: Joi.string().regex(RegExp(`(\\.|^)${child_table}$`)).required(), | ||
then: Joi.link('/' + child_table + '.where') | ||
}); }), | ||
})), | ||
otherwise: Joi.forbidden() | ||
}); | ||
var this_schema = Joi.link('/' + table_name + '.where'); | ||
var schema_obj = { | ||
eq: Joi.array().ordered(column_schema, Joi.alternatives(Joi.string(), Joi.number(), Joi.allow(null)).required().custom(function (val, helpers) { | ||
const this_schema = Joi.link('/' + table_name + '.where'); | ||
const schema_obj = { | ||
eq: Joi.array().ordered(column_schema, Joi.alternatives(Joi.string(), Joi.number(), Joi.allow(null)).required().custom((val, helpers) => { | ||
return mysql_1.escape(val); | ||
@@ -207,35 +170,33 @@ })), | ||
}; | ||
var schema = (_d = Joi.object().keys(schema_obj)) | ||
.xor.apply(_d, __spreadArray([], __read(ramda_1.keys(schema_obj)))); | ||
const schema = Joi.object().keys(schema_obj) | ||
.xor(...ramda_1.keys(schema_obj)); | ||
return schema; | ||
}; | ||
var get_group_by_schema = function (table_name) { | ||
var column_names = traversal2_1.get_column_names(table_name, _generated_table_info_1.table_info); | ||
var term_schema = Joi.valid.apply(Joi, __spreadArray([], __read(column_names))).required(); | ||
const get_group_by_schema = table_name => { | ||
const column_names = traversal2_1.get_column_names(table_name, _generated_table_info_1.table_info); | ||
const term_schema = Joi.valid(...column_names).required(); | ||
return Joi.alternatives(Joi.array().items(term_schema).min(1).required(), term_schema); | ||
}; | ||
var get_order_by_schema = function (table_name) { | ||
var column_names = traversal2_1.get_column_names(table_name, _generated_table_info_1.table_info); | ||
var term_schema = Joi.alternatives(Joi.valid.apply(Joi, __spreadArray([], __read(column_names))), Joi.object().keys({ | ||
asc: Joi.valid.apply(Joi, __spreadArray([], __read(column_names))), | ||
desc: Joi.valid.apply(Joi, __spreadArray([], __read(column_names))), | ||
const get_order_by_schema = table_name => { | ||
const column_names = traversal2_1.get_column_names(table_name, _generated_table_info_1.table_info); | ||
const term_schema = Joi.alternatives(Joi.valid(...column_names), Joi.object().keys({ | ||
asc: Joi.valid(...column_names), | ||
desc: Joi.valid(...column_names), | ||
}).xor('asc', 'desc')).required(); | ||
return Joi.alternatives(Joi.array().items(term_schema).min(1).required(), term_schema); | ||
}; | ||
var get_query_schema = function (master_diff) { | ||
var _a; | ||
var table_names = traversal2_1.get_all_table_names(_generated_table_info_1.table_info); | ||
var table_schemas = table_names.map(function (table_name) { | ||
var child_tables = traversal2_1.get_child_tables(table_name, _generated_table_info_1.table_info); | ||
var parent_tables = traversal2_1.get_possible_parent_edges(table_name, _generated_table_info_1.table_info) | ||
const get_query_schema = (master_diff) => { | ||
const table_names = traversal2_1.get_all_table_names(_generated_table_info_1.table_info); | ||
const table_schemas = table_names.map(table_name => { | ||
const child_tables = traversal2_1.get_child_tables(table_name, _generated_table_info_1.table_info); | ||
const parent_tables = traversal2_1.get_possible_parent_edges(table_name, _generated_table_info_1.table_info) | ||
.map(ramda_1.prop('to_table')); | ||
var lower_tables = child_tables.concat(parent_tables); | ||
var lower_table_schemas = lower_tables.map(function (child_table) { | ||
var parent_foreign_keys = traversal2_1.get_edges(child_table, table_name, _generated_table_info_1.table_info) | ||
const lower_tables = child_tables.concat(parent_tables); | ||
const lower_table_schemas = lower_tables.map(child_table => { | ||
const parent_foreign_keys = traversal2_1.get_edges(child_table, table_name, _generated_table_info_1.table_info) | ||
.map(ramda_1.prop('to_key')); | ||
return Joi.when('group_by', { | ||
is: Joi.alternatives(Joi.forbidden(), // group by not supplied | ||
Joi.valid.apply(// group by not supplied | ||
Joi, __spreadArray([], __read(parent_foreign_keys))).required(), // group by is for child_table | ||
Joi.array().items(Joi.any(), Joi.valid.apply(Joi, __spreadArray([], __read(parent_foreign_keys))).required()) // group by is an array including child_table | ||
Joi.valid(...parent_foreign_keys).required(), // group by is for child_table | ||
Joi.array().items(Joi.any(), Joi.valid(...parent_foreign_keys).required()) // group by is an array including child_table | ||
), | ||
@@ -246,10 +207,10 @@ then: Joi.link('/' + child_table), | ||
}); | ||
var lower_schema_keys = ramda_1.zipObj(lower_tables, lower_table_schemas); | ||
var table_schema = Joi.object().keys(__assign({ select: get_select_schema(table_name), where: get_where_schema(table_name), having: get_where_schema(table_name), limit: Joi.number().integer().min(1), offset: Joi.number().integer().min(0), group_by: get_group_by_schema(table_name), order_by: get_order_by_schema(table_name) }, lower_schema_keys)); | ||
const lower_schema_keys = ramda_1.zipObj(lower_tables, lower_table_schemas); | ||
const table_schema = Joi.object().keys(Object.assign({ select: get_select_schema(table_name), where: get_where_schema(table_name), having: get_where_schema(table_name), limit: Joi.number().integer().min(1), offset: Joi.number().integer().min(0), group_by: get_group_by_schema(table_name), order_by: get_order_by_schema(table_name) }, lower_schema_keys)); | ||
return table_schema; | ||
}); | ||
var diffs_by_field = exports.get_relevant_diff_functions(false, '', master_diff); | ||
var new_field_names = ramda_1.keys(diffs_by_field); | ||
var new_field_schemas = new_field_names.map(function (field) { return diffs_by_field[field](); }); | ||
var query_schema = (_a = Joi.object().keys(__assign(__assign({}, ramda_1.zipObj(table_names, table_schemas)), ramda_1.zipObj(new_field_names, new_field_schemas)))).xor.apply(_a, __spreadArray([], __read(table_names))); | ||
const diffs_by_field = exports.get_relevant_diff_functions(false, '', master_diff); | ||
const new_field_names = ramda_1.keys(diffs_by_field); | ||
const new_field_schemas = new_field_names.map(field => diffs_by_field[field]()); | ||
const query_schema = Joi.object().keys(Object.assign(Object.assign({}, ramda_1.zipObj(table_names, table_schemas)), ramda_1.zipObj(new_field_names, new_field_schemas))).xor(...table_names); | ||
return query_schema; | ||
@@ -259,4 +220,4 @@ }; | ||
exports.read_query_schema = memoize(exports.get_query_schema); | ||
var a = { | ||
const a = { | ||
$asd: 1 | ||
}; |
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) | ||
to[j] = from[i]; | ||
return to; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.orma_query = exports.orma_nester = exports.convert_any_path_macro = exports.combine_where_clauses = exports.having_to_json_sql = exports.where_to_json_sql = exports.select_to_json_sql = exports.query_to_json_sql = exports.get_subquery_sql = exports.get_real_entity_name = exports.get_real_parent_name = exports.is_subquery = exports.get_query_plan = exports.json_to_sql = void 0; | ||
var helpers_1 = require("../helpers/helpers"); | ||
var nester_1 = require("../helpers/nester"); | ||
var schema_helpers_1 = require("../helpers/schema_helpers"); | ||
const helpers_1 = require("../helpers/helpers"); | ||
const nester_1 = require("../helpers/nester"); | ||
const schema_helpers_1 = require("../helpers/schema_helpers"); | ||
// this is a simple parser function, whatever comes in the json object is placed as-is in the output sql string. | ||
// more complicated rules (such as adding a 'from' clause, or adding group-by columns on select *) is handled while the query is still a json object | ||
var json_to_sql = function (expression, path) { | ||
if (path === void 0) { path = []; } | ||
const json_to_sql = (expression, path = []) => { | ||
// strings and other non-objects are returned as-is | ||
var is_object = typeof expression === 'object' && !Array.isArray(expression); | ||
const is_object = typeof expression === 'object' && !Array.isArray(expression); | ||
if (!is_object) { | ||
return expression; | ||
} | ||
var sorted_commands = Object.keys(expression).sort(function (command1, command2) { | ||
const sorted_commands = Object.keys(expression).sort((command1, command2) => { | ||
// unspecified commands go at the beginning | ||
var i1 = command_order[command1] || -1; | ||
var i2 = command_order[command2] || -1; | ||
const i1 = command_order[command1] || -1; | ||
const i2 = command_order[command2] || -1; | ||
return i1 - i2; | ||
}); | ||
var parsed_commands = sorted_commands.map(function (command) { | ||
const parsed_commands = sorted_commands.map(command => { | ||
if (expression[command] === undefined) { | ||
return ''; | ||
} | ||
var command_parser = sql_command_parsers[command]; | ||
const command_parser = sql_command_parsers[command]; | ||
if (!command_parser) { | ||
throw new Error("Cannot find command parser for " + command + "."); | ||
throw new Error(`Cannot find command parser for ${command}.`); | ||
} | ||
var args = expression[command]; | ||
var parsed_args = Array.isArray(args) | ||
? args.map(function (arg, i) { return exports.json_to_sql(arg, __spreadArray(__spreadArray([], __read(path)), [command, i])); }) | ||
: exports.json_to_sql(args, __spreadArray(__spreadArray([], __read(path)), [command])); | ||
const args = expression[command]; | ||
const parsed_args = Array.isArray(args) | ||
? args.map((arg, i) => exports.json_to_sql(arg, [...path, command, i])) | ||
: exports.json_to_sql(args, [...path, command]); | ||
return command_parser(parsed_args, path); | ||
}).filter(function (el) { return el !== ''; }); | ||
}).filter(el => el !== ''); | ||
return parsed_commands.join(' '); | ||
}; | ||
exports.json_to_sql = json_to_sql; | ||
var command_order = { | ||
const command_order = { | ||
$delete_from: -3, | ||
@@ -133,42 +64,42 @@ $update: -2, | ||
*/ | ||
var sql_command_parsers = { | ||
$select: function (args) { return "SELECT " + args.join(', '); }, | ||
$as: function (args) { return "(" + args[0] + ") AS " + args[1]; }, | ||
$from: function (args) { return "FROM " + args; }, | ||
$where: function (args) { return "WHERE " + args; }, | ||
$having: function (args) { return "HAVING " + args; }, | ||
$in: function (args, path) { return "" + args[0] + (helpers_1.last(path) === '$not' ? ' NOT' : '') + " IN (" + args[1] + ")"; }, | ||
$group_by: function (args) { return "GROUP BY " + args.join(', '); }, | ||
$order_by: function (args) { return "ORDER BY " + args.join(', '); }, | ||
$asc: function (args) { return args + " ASC"; }, | ||
$desc: function (args) { return args + " DESC"; }, | ||
$and: function (args, path) { | ||
var res = "(" + args.join(') AND (') + ")"; | ||
return helpers_1.last(path) === '$not' ? "NOT (" + res + ")" : res; | ||
const sql_command_parsers = { | ||
$select: args => `SELECT ${args.join(', ')}`, | ||
$as: args => `(${args[0]}) AS ${args[1]}`, | ||
$from: args => `FROM ${args}`, | ||
$where: args => `WHERE ${args}`, | ||
$having: args => `HAVING ${args}`, | ||
$in: (args, path) => `${args[0]}${helpers_1.last(path) === '$not' ? ' NOT' : ''} IN (${args[1]})`, | ||
$group_by: args => `GROUP BY ${args.join(', ')}`, | ||
$order_by: args => `ORDER BY ${args.join(', ')}`, | ||
$asc: args => `${args} ASC`, | ||
$desc: args => `${args} DESC`, | ||
$and: (args, path) => { | ||
const res = `(${args.join(') AND (')})`; | ||
return helpers_1.last(path) === '$not' ? `NOT (${res})` : res; | ||
}, | ||
$or: function (args, path) { | ||
var res = "(" + args.join(') OR (') + ")"; | ||
return helpers_1.last(path) === '$not' ? "NOT (" + res + ")" : res; | ||
$or: (args, path) => { | ||
const res = `(${args.join(') OR (')})`; | ||
return helpers_1.last(path) === '$not' ? `NOT (${res})` : res; | ||
}, | ||
$any: function (args) { return "ANY (" + args + ")"; }, | ||
$all: function (args) { return "ALL (" + args + ")"; }, | ||
$eq: function (args, path) { return args[1] === null | ||
? "" + args[0] + (helpers_1.last(path) === '$not' ? ' NOT' : '') + " IS NULL" | ||
: args[0] + " " + (helpers_1.last(path) === '$not' ? '!' : '') + "= " + args[1]; }, | ||
$gt: function (args, path) { return args[0] + " " + (helpers_1.last(path) === '$not' ? '<=' : '>') + " " + args[1]; }, | ||
$lt: function (args, path) { return args[0] + " " + (helpers_1.last(path) === '$not' ? '>=' : '<') + " " + args[1]; }, | ||
$gte: function (args, path) { return args[0] + " " + (helpers_1.last(path) === '$not' ? '<' : '>=') + " " + args[1]; }, | ||
$lte: function (args, path) { return args[0] + " " + (helpers_1.last(path) === '$not' ? '>' : '<=') + " " + args[1]; }, | ||
$exists: function (args, path) { return (helpers_1.last(path) === '$not' ? 'NOT ' : '') + "EXISTS (" + args + ")"; }, | ||
$limit: function (args) { return "LIMIT " + args; }, | ||
$offset: function (args) { return "OFFSET " + args; }, | ||
$like: function (args, path) { | ||
var string_arg = args[1].toString(); | ||
var search_value = string_arg | ||
$any: args => `ANY (${args})`, | ||
$all: args => `ALL (${args})`, | ||
$eq: (args, path) => args[1] === null | ||
? `${args[0]}${helpers_1.last(path) === '$not' ? ' NOT' : ''} IS NULL` | ||
: `${args[0]} ${helpers_1.last(path) === '$not' ? '!' : ''}= ${args[1]}`, | ||
$gt: (args, path) => `${args[0]} ${helpers_1.last(path) === '$not' ? '<=' : '>'} ${args[1]}`, | ||
$lt: (args, path) => `${args[0]} ${helpers_1.last(path) === '$not' ? '>=' : '<'} ${args[1]}`, | ||
$gte: (args, path) => `${args[0]} ${helpers_1.last(path) === '$not' ? '<' : '>='} ${args[1]}`, | ||
$lte: (args, path) => `${args[0]} ${helpers_1.last(path) === '$not' ? '>' : '<='} ${args[1]}`, | ||
$exists: (args, path) => `${helpers_1.last(path) === '$not' ? 'NOT ' : ''}EXISTS (${args})`, | ||
$limit: args => `LIMIT ${args}`, | ||
$offset: args => `OFFSET ${args}`, | ||
$like: (args, path) => { | ||
const string_arg = args[1].toString(); | ||
const search_value = string_arg | ||
.replace(/^\'/, '') | ||
.replace(/\'$/, ''); // get rid of quotes if they were put there by escape() | ||
return "" + args[0] + (helpers_1.last(path) === '$not' ? ' NOT' : '') + " LIKE '%" + search_value + "%'"; | ||
return `${args[0]}${helpers_1.last(path) === '$not' ? ' NOT' : ''} LIKE '%${search_value}%'`; | ||
}, | ||
$not: function (args) { return args; }, | ||
$sum: function (args) { return "SUM(" + args + ")"; }, | ||
$not: args => args, | ||
$sum: args => `SUM(${args})`, | ||
// not: { | ||
@@ -185,18 +116,9 @@ // in: args => `${args[0]} NOT IN (${args[1]})`, | ||
// } | ||
$insert_into: function (_a) { | ||
var _b = __read(_a, 2), table_name = _b[0], _c = __read(_b[1]), columns = _c.slice(0); | ||
return "INSERT INTO " + table_name + " (" + columns.join(', ') + ")"; | ||
}, | ||
$values: function (values) { return "" + values.map(function (inner_values) { return "(" + inner_values.join(', ') + ")"; }).join(', '); }, | ||
$update: function (table_name) { return "" + table_name; }, | ||
$set: function () { | ||
var items = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
items[_i] = arguments[_i]; | ||
} | ||
return "" + items | ||
.map(function (column, value) { return column + " = " + value; }) | ||
.join(', '); | ||
}, | ||
$delete_from: function (table_name) { return "DELETE FROM " + table_name; } | ||
$insert_into: ([table_name, [...columns]]) => `INSERT INTO ${table_name} (${columns.join(', ')})`, | ||
$values: (values) => `${values.map(inner_values => `(${inner_values.join(', ')})`).join(', ')}`, | ||
$update: (table_name) => `${table_name}`, | ||
$set: (...items) => `${items | ||
.map((column, value) => `${column} = ${value}`) | ||
.join(', ')}`, | ||
$delete_from: (table_name) => `DELETE FROM ${table_name}` | ||
}; | ||
@@ -213,15 +135,14 @@ /* | ||
*/ | ||
var get_query_plan = function (query) { | ||
var query_plan = []; | ||
helpers_1.deep_for_each(query, function (value, path) { | ||
var _a; | ||
const get_query_plan = (query) => { | ||
const query_plan = []; | ||
helpers_1.deep_for_each(query, (value, path) => { | ||
if (typeof value === 'object') { | ||
var query_1 = value; | ||
var has_filter = '$where' in value || '$having' in value; | ||
var is_root = path.length === 0; | ||
var child_paths = Object.keys(value).map(function (child_key) { | ||
const query = value; | ||
const has_filter = '$where' in value || '$having' in value; | ||
const is_root = path.length === 0; | ||
const child_paths = Object.keys(value).map(child_key => { | ||
if (exports.is_subquery(value[child_key])) { | ||
return __spreadArray(__spreadArray([], __read(path)), [child_key]); | ||
return [...path, child_key]; | ||
} | ||
}).filter(function (el) { return el !== undefined; }); | ||
}).filter(el => el !== undefined); | ||
if (child_paths.length === 0) { | ||
@@ -235,3 +156,3 @@ return; // subquery with nothing else nested on | ||
else { | ||
(_a = helpers_1.last(query_plan)).push.apply(_a, __spreadArray([], __read(child_paths))); | ||
helpers_1.last(query_plan).push(...child_paths); | ||
} | ||
@@ -243,25 +164,25 @@ } | ||
exports.get_query_plan = get_query_plan; | ||
var is_subquery = function (subquery) { | ||
const is_subquery = (subquery) => { | ||
if (typeof subquery !== 'object' || Array.isArray(subquery)) { | ||
return false; | ||
} | ||
var subquery_keys = Object.keys(subquery); | ||
return subquery_keys.some(function (key) { return !schema_helpers_1.is_reserved_keyword(key); }) || subquery_keys.length === 0; | ||
const subquery_keys = Object.keys(subquery); | ||
return subquery_keys.some(key => !schema_helpers_1.is_reserved_keyword(key)) || subquery_keys.length === 0; | ||
}; | ||
exports.is_subquery = is_subquery; | ||
// This function will default to the from clause | ||
var get_real_parent_name = function (path, query) { | ||
const get_real_parent_name = (path, query) => { | ||
if (path.length < 2) | ||
return null; | ||
return helpers_1.deep_get(__spreadArray(__spreadArray([], __read(helpers_1.drop(1, path))), ['$from']), query, null) || path[path.length - 2]; | ||
return helpers_1.deep_get([...helpers_1.drop(1, path), '$from'], query, null) || path[path.length - 2]; | ||
}; | ||
exports.get_real_parent_name = get_real_parent_name; | ||
// This function will default to the from clause | ||
var get_real_entity_name = function (path, query) { | ||
return helpers_1.deep_get(__spreadArray(__spreadArray([], __read(path)), ['$from']), query, null) || helpers_1.last(path); | ||
const get_real_entity_name = (path, query) => { | ||
return helpers_1.deep_get([...path, '$from'], query, null) || helpers_1.last(path); | ||
}; | ||
exports.get_real_entity_name = get_real_entity_name; | ||
var get_subquery_sql = function (query, subquery_path, previous_results, orma_schema) { | ||
var json_sql = exports.query_to_json_sql(query, subquery_path, previous_results, orma_schema); | ||
var sql = exports.json_to_sql(json_sql); | ||
const get_subquery_sql = (query, subquery_path, previous_results, orma_schema) => { | ||
const json_sql = exports.query_to_json_sql(query, subquery_path, previous_results, orma_schema); | ||
const sql = exports.json_to_sql(json_sql); | ||
return sql; | ||
@@ -273,15 +194,14 @@ }; | ||
*/ | ||
var query_to_json_sql = function (query, subquery_path, previous_results, orma_schema) { | ||
const query_to_json_sql = (query, subquery_path, previous_results, orma_schema) => { | ||
var _a; | ||
var subquery = helpers_1.deep_get(subquery_path, query); | ||
var reserved_commands = Object.keys(subquery).filter(schema_helpers_1.is_reserved_keyword); | ||
var reserved_json = reserved_commands.reduce(function (previous, key) { | ||
var _a; | ||
return __assign(__assign({}, previous), (_a = {}, _a[key] = subquery[key], _a)); | ||
const subquery = helpers_1.deep_get(subquery_path, query); | ||
const reserved_commands = Object.keys(subquery).filter(schema_helpers_1.is_reserved_keyword); | ||
const reserved_json = reserved_commands.reduce((previous, key) => { | ||
return Object.assign(Object.assign({}, previous), { [key]: subquery[key] }); | ||
}, {}); | ||
var $select = exports.select_to_json_sql(query, subquery_path, orma_schema); | ||
var $from = (_a = subquery.$from) !== null && _a !== void 0 ? _a : helpers_1.last(subquery_path); | ||
var $where = exports.where_to_json_sql(query, subquery_path, previous_results, orma_schema); | ||
var $having = exports.having_to_json_sql(query, subquery_path, orma_schema); | ||
var json_sql = __assign({}, reserved_json); | ||
const $select = exports.select_to_json_sql(query, subquery_path, orma_schema); | ||
const $from = (_a = subquery.$from) !== null && _a !== void 0 ? _a : helpers_1.last(subquery_path); | ||
const $where = exports.where_to_json_sql(query, subquery_path, previous_results, orma_schema); | ||
const $having = exports.having_to_json_sql(query, subquery_path, orma_schema); | ||
const json_sql = Object.assign({}, reserved_json); | ||
if ($select) { | ||
@@ -302,7 +222,7 @@ json_sql.$select = $select; | ||
exports.query_to_json_sql = query_to_json_sql; | ||
var select_to_json_sql = function (query, subquery_path, orma_schema) { | ||
var subquery = helpers_1.deep_get(subquery_path, query); | ||
var entity_name = helpers_1.last(subquery_path); | ||
var $select = Object.keys(subquery) | ||
.flatMap(function (key) { | ||
const select_to_json_sql = (query, subquery_path, orma_schema) => { | ||
const subquery = helpers_1.deep_get(subquery_path, query); | ||
const entity_name = helpers_1.last(subquery_path); | ||
const $select = Object.keys(subquery) | ||
.flatMap(key => { | ||
var _a; | ||
@@ -322,5 +242,5 @@ if (schema_helpers_1.is_reserved_keyword(key)) { | ||
if (typeof subquery[key] === 'object' && exports.is_subquery(subquery[key])) { | ||
var lower_subquery = subquery[key]; | ||
var lower_subquery_entity = (_a = lower_subquery.$from) !== null && _a !== void 0 ? _a : key; | ||
var edge_to_lower_table = schema_helpers_1.get_direct_edge(entity_name, lower_subquery_entity, orma_schema); | ||
const lower_subquery = subquery[key]; | ||
const lower_subquery_entity = (_a = lower_subquery.$from) !== null && _a !== void 0 ? _a : key; | ||
const edge_to_lower_table = schema_helpers_1.get_direct_edge(entity_name, lower_subquery_entity, orma_schema); | ||
return edge_to_lower_table.from_field; | ||
@@ -331,22 +251,20 @@ } | ||
if (subquery_path.length > 1) { | ||
var higher_entity = subquery_path[subquery_path.length - 2]; | ||
var edge_to_higher_entity = schema_helpers_1.get_direct_edge(entity_name, higher_entity, orma_schema); | ||
const higher_entity = subquery_path[subquery_path.length - 2]; | ||
const edge_to_higher_entity = schema_helpers_1.get_direct_edge(entity_name, higher_entity, orma_schema); | ||
$select.push(edge_to_higher_entity.from_field); | ||
} | ||
return __spreadArray([], __read(new Set($select))); // unique values | ||
return [...new Set($select)]; // unique values | ||
}; | ||
exports.select_to_json_sql = select_to_json_sql; | ||
var where_to_json_sql = function (query, subquery_path, previous_results, orma_schema) { | ||
var subquery = helpers_1.deep_get(subquery_path, query); | ||
var $where = subquery.$where; | ||
var is_root_subquery = subquery_path.length <= 1; | ||
const where_to_json_sql = (query, subquery_path, previous_results, orma_schema) => { | ||
const subquery = helpers_1.deep_get(subquery_path, query); | ||
let $where = subquery.$where; | ||
const is_root_subquery = subquery_path.length <= 1; | ||
if (!is_root_subquery) { | ||
var nesting_ancestor_index = get_nesting_ancestor_index(query, subquery_path); | ||
var ancestor_path_1 = subquery_path.slice(0, nesting_ancestor_index + 1); | ||
var ancestor_rows = previous_results | ||
.filter(function (previous_result) { | ||
return previous_result[0].toString() === ancestor_path_1.toString(); | ||
}).map(function (previous_result) { return previous_result[1]; })[0]; | ||
var path_to_ancestor = subquery_path.slice(nesting_ancestor_index, Infinity).reverse(); | ||
var ancestor_where_clause = get_ancestor_where_clause(ancestor_rows, path_to_ancestor, orma_schema); | ||
const nesting_ancestor_index = get_nesting_ancestor_index(query, subquery_path); | ||
const ancestor_path = subquery_path.slice(0, nesting_ancestor_index + 1); | ||
const ancestor_rows = previous_results | ||
.filter(previous_result => previous_result[0].toString() === ancestor_path.toString()).map(previous_result => previous_result[1])[0]; | ||
const path_to_ancestor = subquery_path.slice(nesting_ancestor_index, Infinity).reverse(); | ||
const ancestor_where_clause = get_ancestor_where_clause(ancestor_rows, path_to_ancestor, orma_schema); | ||
$where = exports.combine_where_clauses($where, ancestor_where_clause, '$and'); | ||
@@ -357,5 +275,5 @@ } | ||
exports.where_to_json_sql = where_to_json_sql; | ||
var having_to_json_sql = function (query, subquery_path, orma_schema) { | ||
var subquery = helpers_1.deep_get(subquery_path, query); | ||
var $having = subquery.$having; | ||
const having_to_json_sql = (query, subquery_path, orma_schema) => { | ||
const subquery = helpers_1.deep_get(subquery_path, query); | ||
const $having = subquery.$having; | ||
return $having; | ||
@@ -367,4 +285,3 @@ }; | ||
*/ | ||
var combine_where_clauses = function (where1, where2, connective) { | ||
var _a, _b, _c, _d; | ||
const combine_where_clauses = (where1, where2, connective) => { | ||
if (!where1) { | ||
@@ -377,23 +294,23 @@ return where2; | ||
if (where1[connective] && where2[connective]) { | ||
var where1_items = where1[connective]; | ||
var where2_items = where2[connective]; | ||
return _a = {}, | ||
_a[connective] = __spreadArray(__spreadArray([], __read(where1_items)), __read(where2_items)), | ||
_a; | ||
const where1_items = where1[connective]; | ||
const where2_items = where2[connective]; | ||
return { | ||
[connective]: [...where1_items, ...where2_items] | ||
}; | ||
} | ||
if (where1[connective]) { | ||
var where1_items = where1[connective]; | ||
return _b = {}, | ||
_b[connective] = __spreadArray(__spreadArray([], __read(where1_items)), [where2]), | ||
_b; | ||
const where1_items = where1[connective]; | ||
return { | ||
[connective]: [...where1_items, where2] | ||
}; | ||
} | ||
if (where2[connective]) { | ||
var where2_items = where2[connective]; | ||
return _c = {}, | ||
_c[connective] = __spreadArray([where1], __read(where2_items)), | ||
_c; | ||
const where2_items = where2[connective]; | ||
return { | ||
[connective]: [where1, ...where2_items] | ||
}; | ||
} | ||
return _d = {}, | ||
_d[connective] = [where1, where2], | ||
_d; | ||
return { | ||
[connective]: [where1, where2] | ||
}; | ||
}; | ||
@@ -420,14 +337,14 @@ exports.combine_where_clauses = combine_where_clauses; | ||
*/ | ||
var convert_any_path_macro = function (where, root_entity, is_having, orma_schema) { | ||
const convert_any_path_macro = (where, root_entity, is_having, orma_schema) => { | ||
if (!where) { | ||
return where; | ||
} | ||
var processor = function (value, path) { | ||
const processor = (value, path) => { | ||
var _a; | ||
if (typeof value === 'object' && '$any' in value) { | ||
var _b = __read(value.$any, 2), any_path = _b[0], subquery = _b[1]; | ||
var previous_entities = path.flatMap(function (path_el, i) { | ||
const [any_path, subquery] = value.$any; | ||
const previous_entities = path.flatMap((path_el, i) => { | ||
if (path_el === '$any') { | ||
var path_segment = path.slice(0, i + 1); | ||
var previous_any = helpers_1.deep_get(path_segment, where); | ||
const path_segment = path.slice(0, i + 1); | ||
const previous_any = helpers_1.deep_get(path_segment, where); | ||
return helpers_1.last(previous_any[0]); | ||
@@ -439,14 +356,12 @@ } | ||
}); | ||
var current_entity = (_a = helpers_1.last(previous_entities)) !== null && _a !== void 0 ? _a : root_entity; | ||
var full_path = [current_entity].concat(any_path); | ||
var edge_path = schema_helpers_1.get_edge_path(full_path, orma_schema).reverse(); | ||
var query = edge_path.reduce(function (acc, edge) { | ||
var _a; | ||
const current_entity = (_a = helpers_1.last(previous_entities)) !== null && _a !== void 0 ? _a : root_entity; | ||
const full_path = [current_entity].concat(any_path); | ||
const edge_path = schema_helpers_1.get_edge_path(full_path, orma_schema).reverse(); | ||
const query = edge_path.reduce((acc, edge) => { | ||
return { | ||
$in: [edge.from_field, (_a = { | ||
$select: [edge.to_field], | ||
$from: edge.to_entity | ||
}, | ||
_a[is_having ? '$having' : '$where'] = acc, | ||
_a)] | ||
$in: [edge.from_field, { | ||
$select: [edge.to_field], | ||
$from: edge.to_entity, | ||
[is_having ? '$having' : '$where']: acc | ||
}] | ||
}; | ||
@@ -473,6 +388,6 @@ }, subquery); | ||
*/ | ||
var get_nesting_ancestor_index = function (query, subquery_path) { | ||
for (var i = subquery_path.length - 1; i >= 0; i--) { | ||
var subpath = subquery_path.slice(0, i + 1); | ||
var subquery = helpers_1.deep_get(subpath, query); | ||
const get_nesting_ancestor_index = (query, subquery_path) => { | ||
for (let i = subquery_path.length - 1; i >= 0; i--) { | ||
const subpath = subquery_path.slice(0, i + 1); | ||
const subquery = helpers_1.deep_get(subpath, query); | ||
if ('$where' in subquery || '$having' in subquery) { | ||
@@ -490,12 +405,12 @@ return i; | ||
*/ | ||
var get_ancestor_where_clause = function (ancestor_rows, path_to_ancestor, orma_schema) { | ||
var ancestor_name = helpers_1.last(path_to_ancestor); | ||
var table_under_ancestor = path_to_ancestor[path_to_ancestor.length - 2]; | ||
var last_edge_to_ancestor = schema_helpers_1.get_direct_edge(table_under_ancestor, ancestor_name, orma_schema); | ||
const get_ancestor_where_clause = (ancestor_rows, path_to_ancestor, orma_schema) => { | ||
const ancestor_name = helpers_1.last(path_to_ancestor); | ||
const table_under_ancestor = path_to_ancestor[path_to_ancestor.length - 2]; | ||
const last_edge_to_ancestor = schema_helpers_1.get_direct_edge(table_under_ancestor, ancestor_name, orma_schema); | ||
if (ancestor_rows === undefined || ancestor_rows.length === 0) { | ||
throw Error("No ancestor rows provided for " + ancestor_name); | ||
throw Error(`No ancestor rows provided for ${ancestor_name}`); | ||
} | ||
var ancestor_linking_key_values = ancestor_rows.map(function (row) { return row[last_edge_to_ancestor.to_field]; }); | ||
var any_path = path_to_ancestor.slice(1, path_to_ancestor.length - 1); | ||
var ancestor_query = exports.convert_any_path_macro({ | ||
const ancestor_linking_key_values = ancestor_rows.map(row => row[last_edge_to_ancestor.to_field]); | ||
const any_path = path_to_ancestor.slice(1, path_to_ancestor.length - 1); | ||
const ancestor_query = exports.convert_any_path_macro({ | ||
$any: [any_path, { | ||
@@ -507,15 +422,15 @@ $in: [last_edge_to_ancestor.from_field, ancestor_linking_key_values] | ||
}; | ||
var orma_nester = function (results, orma_schema) { | ||
const orma_nester = (results, orma_schema) => { | ||
// get data in the right format for the nester | ||
var edges = results.map(function (result) { | ||
var path = result[0]; | ||
var entity = helpers_1.last(path); | ||
var higher_entity = path[path.length - 2]; | ||
var edge = schema_helpers_1.get_direct_edge(higher_entity, entity, orma_schema); | ||
const edges = results.map(result => { | ||
const path = result[0]; | ||
const entity = helpers_1.last(path); | ||
const higher_entity = path[path.length - 2]; | ||
const edge = schema_helpers_1.get_direct_edge(higher_entity, entity, orma_schema); | ||
return [edge.from_field, edge.to_field]; | ||
}); | ||
var data = results.map(function (result) { | ||
var path = result[0]; | ||
var rows = result[1]; | ||
return [path.flatMap(function (path_el) { return [path_el, 0]; }), rows]; // all array nesting for now | ||
const data = results.map(result => { | ||
const path = result[0]; | ||
const rows = result[1]; | ||
return [path.flatMap(path_el => [path_el, 0]), rows]; // all array nesting for now | ||
}); | ||
@@ -526,55 +441,27 @@ return nester_1.nester(data, edges); | ||
// export const orma_query = async <schema>(raw_query: validate_query<schema>, orma_schema: validate_orma_schema<schema>, query_function: (sql_string: string) => Promise<Record<string, unknown>[]>) => { | ||
var orma_query = function (raw_query, orma_schema, query_function) { return __awaiter(void 0, void 0, void 0, function () { | ||
var query, query_plan, results, _loop_1, i, output; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
query = helpers_1.clone(raw_query) // clone query so we can apply macros without mutating user input | ||
; | ||
query_plan = exports.get_query_plan(query); | ||
results = []; | ||
_loop_1 = function (i) { | ||
var paths, sql_strings, output_1; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
paths = query_plan[i]; | ||
sql_strings = paths.map(function (path) { | ||
// apply macros | ||
var where = helpers_1.deep_get(__spreadArray(__spreadArray([], __read(path)), ['$where']), query); | ||
var macrod_where = exports.convert_any_path_macro(where, helpers_1.last(path), false, orma_schema); | ||
helpers_1.deep_set(__spreadArray(__spreadArray([], __read(path)), ['$where']), macrod_where, query); | ||
var having = helpers_1.deep_get(__spreadArray(__spreadArray([], __read(path)), ['$having']), query); | ||
var macrod_having = exports.convert_any_path_macro(having, helpers_1.last(path), false, orma_schema); | ||
helpers_1.deep_set(__spreadArray(__spreadArray([], __read(path)), ['$having']), macrod_having, query); | ||
return exports.get_subquery_sql(query, path, results, orma_schema); | ||
}); | ||
return [4 /*yield*/, query_function(sql_strings) | ||
// Combine outputs | ||
]; | ||
case 1: | ||
output_1 = _b.sent(); | ||
// Combine outputs | ||
sql_strings.forEach(function (_, i) { return results.push([paths[i], output_1[i]]); }); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}; | ||
i = 0; | ||
_a.label = 1; | ||
case 1: | ||
if (!(i < query_plan.length)) return [3 /*break*/, 4]; | ||
return [5 /*yield**/, _loop_1(i)]; | ||
case 2: | ||
_a.sent(); | ||
_a.label = 3; | ||
case 3: | ||
i++; | ||
return [3 /*break*/, 1]; | ||
case 4: | ||
output = exports.orma_nester(results, orma_schema); | ||
return [2 /*return*/, output]; | ||
} | ||
}); | ||
}); }; | ||
const orma_query = async (raw_query, orma_schema, query_function) => { | ||
const query = helpers_1.clone(raw_query); // clone query so we can apply macros without mutating user input | ||
const query_plan = exports.get_query_plan(query); | ||
let results = []; | ||
// Sequential for query plan | ||
for (let i = 0; i < query_plan.length; i++) { | ||
const paths = query_plan[i]; | ||
const sql_strings = paths.map(path => { | ||
// apply macros | ||
const where = helpers_1.deep_get([...path, '$where'], query); | ||
const macrod_where = exports.convert_any_path_macro(where, helpers_1.last(path), false, orma_schema); | ||
helpers_1.deep_set([...path, '$where'], macrod_where, query); | ||
const having = helpers_1.deep_get([...path, '$having'], query); | ||
const macrod_having = exports.convert_any_path_macro(having, helpers_1.last(path), false, orma_schema); | ||
helpers_1.deep_set([...path, '$having'], macrod_having, query); | ||
return exports.get_subquery_sql(query, path, results, orma_schema); | ||
}); | ||
// Promise.all for each element in query plan | ||
const output = await query_function(sql_strings); | ||
// Combine outputs | ||
sql_strings.forEach((_, i) => results.push([paths[i], output[i]])); | ||
} | ||
const output = exports.orma_nester(results, orma_schema); | ||
return output; | ||
}; | ||
exports.orma_query = orma_query; | ||
@@ -581,0 +468,0 @@ // ///-------------type-fest--------------- |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var chai_1 = require("chai"); | ||
var mocha_1 = require("mocha"); | ||
var sql_formatter_1 = require("sql-formatter"); | ||
var query_1 = require("./query"); | ||
mocha_1.describe('query', function () { | ||
var orma_schema = { | ||
const chai_1 = require("chai"); | ||
const mocha_1 = require("mocha"); | ||
const sql_formatter_1 = require("sql-formatter"); | ||
const query_1 = require("./query"); | ||
mocha_1.describe('query', () => { | ||
const orma_schema = { | ||
products: { | ||
@@ -42,14 +42,14 @@ id: {}, | ||
}; | ||
mocha_1.describe('json_to_sql', function () { | ||
mocha_1.test('joins commands', function () { | ||
var json = { | ||
mocha_1.describe('json_to_sql', () => { | ||
mocha_1.test('joins commands', () => { | ||
const json = { | ||
$select: ['a'], | ||
$from: 'b' | ||
}; | ||
var sql = sql_formatter_1.format(query_1.json_to_sql(json)); | ||
var goal = sql_formatter_1.format("SELECT a FROM b"); | ||
const sql = sql_formatter_1.format(query_1.json_to_sql(json)); | ||
const goal = sql_formatter_1.format(`SELECT a FROM b`); | ||
chai_1.expect(sql).to.equal(goal); | ||
}); | ||
mocha_1.test('nested command work', function () { | ||
var json = { | ||
mocha_1.test('nested command work', () => { | ||
const json = { | ||
$where: { | ||
@@ -59,8 +59,8 @@ $eq: ['a', 'b'] | ||
}; | ||
var sql = sql_formatter_1.format(query_1.json_to_sql(json)); | ||
var goal = sql_formatter_1.format('WHERE a = b'); | ||
const sql = sql_formatter_1.format(query_1.json_to_sql(json)); | ||
const goal = sql_formatter_1.format('WHERE a = b'); | ||
chai_1.expect(sql).to.equal(goal); | ||
}); | ||
mocha_1.test("'not' command works", function () { | ||
var json = { | ||
mocha_1.test("'not' command works", () => { | ||
const json = { | ||
$not: { | ||
@@ -70,18 +70,18 @@ $in: ['a', [1, 2]] | ||
}; | ||
var sql = sql_formatter_1.format(query_1.json_to_sql(json)); | ||
var goal = sql_formatter_1.format('a NOT IN (1, 2)'); | ||
const sql = sql_formatter_1.format(query_1.json_to_sql(json)); | ||
const goal = sql_formatter_1.format('a NOT IN (1, 2)'); | ||
chai_1.expect(sql).to.equal(goal); | ||
}); | ||
mocha_1.test('ignores undefined properties', function () { | ||
var json = { | ||
mocha_1.test('ignores undefined properties', () => { | ||
const json = { | ||
$having: undefined | ||
}; | ||
var sql = sql_formatter_1.format(query_1.json_to_sql(json)); | ||
var goal = sql_formatter_1.format(''); | ||
const sql = sql_formatter_1.format(query_1.json_to_sql(json)); | ||
const goal = sql_formatter_1.format(''); | ||
chai_1.expect(sql).to.equal(goal); | ||
}); | ||
}); | ||
mocha_1.describe('get_query_plan', function () { | ||
mocha_1.test('splits by $where clause and $having', function () { | ||
var query = { | ||
mocha_1.describe('get_query_plan', () => { | ||
mocha_1.test('splits by $where clause and $having', () => { | ||
const query = { | ||
vendors: { | ||
@@ -102,5 +102,5 @@ products: { | ||
}; | ||
var result = query_1.get_query_plan(query); | ||
const result = query_1.get_query_plan(query); | ||
// the split happens at variants because it has a where clause | ||
var goal = [ | ||
const goal = [ | ||
[['vendors'], ['vendors', 'products']], | ||
@@ -115,4 +115,4 @@ [ | ||
}); | ||
mocha_1.test('handles multiple top level props', function () { | ||
var query = { | ||
mocha_1.test('handles multiple top level props', () => { | ||
const query = { | ||
vendors: { | ||
@@ -125,9 +125,9 @@ id: true | ||
}; | ||
var result = query_1.get_query_plan(query); | ||
const result = query_1.get_query_plan(query); | ||
// the split happens at variants because it has a where clause | ||
var goal = [[['vendors'], ['products']]]; | ||
const goal = [[['vendors'], ['products']]]; | ||
chai_1.expect(result).to.deep.equal(goal); | ||
}); | ||
mocha_1.test('handles renamed queries', function () { | ||
var query = { | ||
mocha_1.test('handles renamed queries', () => { | ||
const query = { | ||
my_products: { | ||
@@ -138,11 +138,11 @@ $from: 'products', | ||
}; | ||
var result = query_1.get_query_plan(query); | ||
const result = query_1.get_query_plan(query); | ||
// the split happens at variants because it has a where clause | ||
var goal = [[['my_products']]]; | ||
const goal = [[['my_products']]]; | ||
chai_1.expect(result).to.deep.equal(goal); | ||
}); | ||
}); | ||
mocha_1.describe('is_subquery', function () { | ||
mocha_1.test('is subquery', function () { | ||
var result = query_1.is_subquery({ | ||
mocha_1.describe('is_subquery', () => { | ||
mocha_1.test('is subquery', () => { | ||
const result = query_1.is_subquery({ | ||
$from: 'products', | ||
@@ -153,4 +153,4 @@ id: {} | ||
}); | ||
mocha_1.test('not subquery', function () { | ||
var result = query_1.is_subquery({ | ||
mocha_1.test('not subquery', () => { | ||
const result = query_1.is_subquery({ | ||
$from: 'products' | ||
@@ -161,5 +161,5 @@ }); | ||
}); | ||
mocha_1.describe('convert_any_clauses', function () { | ||
mocha_1.test('multiple any clauses', function () { | ||
var where = { | ||
mocha_1.describe('convert_any_clauses', () => { | ||
mocha_1.test('multiple any clauses', () => { | ||
const where = { | ||
$and: [ | ||
@@ -184,4 +184,4 @@ { | ||
}; | ||
var converted_where = query_1.convert_any_path_macro(where, 'products', false, orma_schema); | ||
var goal = { | ||
const converted_where = query_1.convert_any_path_macro(where, 'products', false, orma_schema); | ||
const goal = { | ||
$and: [ | ||
@@ -216,4 +216,4 @@ { | ||
}); | ||
mocha_1.test('deep any path', function () { | ||
var where = { | ||
mocha_1.test('deep any path', () => { | ||
const where = { | ||
$any: [ | ||
@@ -226,4 +226,4 @@ ['images', 'image_urls'], | ||
}; | ||
var converted_where = query_1.convert_any_path_macro(where, 'products', false, orma_schema); | ||
var goal = { | ||
const converted_where = query_1.convert_any_path_macro(where, 'products', false, orma_schema); | ||
const goal = { | ||
$in: [ | ||
@@ -251,4 +251,4 @@ 'id', | ||
}); | ||
mocha_1.test('nested anys', function () { | ||
var where = { | ||
mocha_1.test('nested anys', () => { | ||
const where = { | ||
$any: [ | ||
@@ -266,4 +266,4 @@ ['images'], | ||
}; | ||
var converted_where = query_1.convert_any_path_macro(where, 'products', false, orma_schema); | ||
var goal = { | ||
const converted_where = query_1.convert_any_path_macro(where, 'products', false, orma_schema); | ||
const goal = { | ||
$in: [ | ||
@@ -291,4 +291,4 @@ 'id', | ||
}); | ||
mocha_1.test('uses having', function () { | ||
var where = { | ||
mocha_1.test('uses having', () => { | ||
const where = { | ||
$any: [ | ||
@@ -301,4 +301,4 @@ ['images'], | ||
}; | ||
var converted_where = query_1.convert_any_path_macro(where, 'products', true, orma_schema); | ||
var goal = { | ||
const converted_where = query_1.convert_any_path_macro(where, 'products', true, orma_schema); | ||
const goal = { | ||
$in: [ | ||
@@ -318,5 +318,5 @@ 'id', | ||
}); | ||
mocha_1.describe('query_to_json_sql', function () { | ||
mocha_1.test('handles selects/handles root', function () { | ||
var query = { | ||
mocha_1.describe('query_to_json_sql', () => { | ||
mocha_1.test('handles selects/handles root', () => { | ||
const query = { | ||
products: { | ||
@@ -330,4 +330,4 @@ id: true, | ||
}; | ||
var json_sql = query_1.query_to_json_sql(query, ['products'], [], {}); | ||
var goal = { | ||
const json_sql = query_1.query_to_json_sql(query, ['products'], [], {}); | ||
const goal = { | ||
$select: [ | ||
@@ -342,4 +342,4 @@ 'id', | ||
}); | ||
mocha_1.test('handles root nesting', function () { | ||
var query = { | ||
mocha_1.test('handles root nesting', () => { | ||
const query = { | ||
products: { | ||
@@ -353,5 +353,5 @@ id: true, | ||
}; | ||
var previous_results = [[['products'], [{ id: 1 }, { id: 2 }]]]; | ||
var json_sql = query_1.query_to_json_sql(query, ['products', 'images'], previous_results, orma_schema); | ||
var goal = { | ||
const previous_results = [[['products'], [{ id: 1 }, { id: 2 }]]]; | ||
const json_sql = query_1.query_to_json_sql(query, ['products', 'images'], previous_results, orma_schema); | ||
const goal = { | ||
$select: ['id', 'product_id'], | ||
@@ -365,5 +365,5 @@ $from: 'images', | ||
}); | ||
mocha_1.test('handles adding foreign keys', function () { | ||
mocha_1.test('handles adding foreign keys', () => { | ||
var _a; | ||
var query = { | ||
const query = { | ||
products: { | ||
@@ -373,11 +373,11 @@ images: { url: true } | ||
}; | ||
var previous_results = [[['products'], [{ id: 1 }, { id: 2 }]]]; | ||
var json_sql1 = query_1.query_to_json_sql(query, ['products'], previous_results, orma_schema); | ||
var goal1 = { | ||
const previous_results = [[['products'], [{ id: 1 }, { id: 2 }]]]; | ||
const json_sql1 = query_1.query_to_json_sql(query, ['products'], previous_results, orma_schema); | ||
const goal1 = { | ||
$select: ['id'], | ||
$from: 'products' | ||
}; | ||
var json_sql2 = query_1.query_to_json_sql(query, ['products', 'images'], previous_results, orma_schema); | ||
const json_sql2 = query_1.query_to_json_sql(query, ['products', 'images'], previous_results, orma_schema); | ||
(_a = json_sql2 === null || json_sql2 === void 0 ? void 0 : json_sql2.$select) === null || _a === void 0 ? void 0 : _a.sort(); | ||
var goal2 = { | ||
const goal2 = { | ||
$select: ['product_id', 'url'].sort(), | ||
@@ -392,5 +392,5 @@ $from: 'images', | ||
}); | ||
mocha_1.test('handles deep nesting', function () { | ||
mocha_1.test('handles deep nesting', () => { | ||
var _a; | ||
var query = { | ||
const query = { | ||
products: { | ||
@@ -404,6 +404,6 @@ images: { | ||
}; | ||
var previous_results = [[['products'], [{ id: 1 }, { id: 2 }]]]; | ||
var json_sql = query_1.query_to_json_sql(query, ['products', 'images', 'image_urls'], previous_results, orma_schema); | ||
const previous_results = [[['products'], [{ id: 1 }, { id: 2 }]]]; | ||
const json_sql = query_1.query_to_json_sql(query, ['products', 'images', 'image_urls'], previous_results, orma_schema); | ||
(_a = json_sql === null || json_sql === void 0 ? void 0 : json_sql.$select) === null || _a === void 0 ? void 0 : _a.sort(); | ||
var goal = { | ||
const goal = { | ||
$select: ['image_id', 'id'].sort(), | ||
@@ -426,4 +426,4 @@ $from: 'image_urls', | ||
}); | ||
mocha_1.test('handles nesting under where clause', function () { | ||
var query = { | ||
mocha_1.test('handles nesting under where clause', () => { | ||
const query = { | ||
products: { | ||
@@ -436,8 +436,8 @@ images: { | ||
}; | ||
var previous_results = [ | ||
const previous_results = [ | ||
[['products'], [{ id: 1 }, { id: 2 }]], | ||
[['products', 'images'], [{ id: 3 }]] | ||
]; | ||
var json_sql = query_1.query_to_json_sql(query, ['products', 'images', 'image_urls'], previous_results, orma_schema); | ||
var goal = { | ||
const json_sql = query_1.query_to_json_sql(query, ['products', 'images', 'image_urls'], previous_results, orma_schema); | ||
const goal = { | ||
$select: ['image_id'], | ||
@@ -451,4 +451,4 @@ $from: 'image_urls', | ||
}); | ||
mocha_1.test("respects 'from' clause", function () { | ||
var query = { | ||
mocha_1.test("respects 'from' clause", () => { | ||
const query = { | ||
my_products: { | ||
@@ -459,4 +459,4 @@ id: true, | ||
}; | ||
var json_sql = query_1.query_to_json_sql(query, ['my_products'], [], {}); | ||
var goal = { | ||
const json_sql = query_1.query_to_json_sql(query, ['my_products'], [], {}); | ||
const goal = { | ||
$select: ['id'], | ||
@@ -467,4 +467,4 @@ $from: 'products' | ||
}); | ||
mocha_1.test.skip("handles 'any' clause", function () { | ||
var query = { | ||
mocha_1.test.skip("handles 'any' clause", () => { | ||
const query = { | ||
$where: { | ||
@@ -475,32 +475,6 @@ $any: [] | ||
}; | ||
var json_sql = query_1.query_to_json_sql(query, ['products'], [], {}); | ||
var goal = {}; | ||
const json_sql = query_1.query_to_json_sql(query, ['products'], [], {}); | ||
const goal = {}; | ||
chai_1.expect(json_sql).to.deep.equal(goal); | ||
}); | ||
mocha_1.test('should not put where or having when not required', function () { | ||
var query = { | ||
calls: { | ||
id: true | ||
} | ||
}; | ||
var orma_schema = { | ||
calls: { | ||
$comment: '', | ||
id: { | ||
data_type: 'number', | ||
required: true, | ||
indexed: true, | ||
unique: true, | ||
primary_key: true, | ||
character_count: 10 | ||
} | ||
} | ||
}; | ||
var actual_query = ''; | ||
var test = query_1.orma_query(query, orma_schema, function (sql_strings) { | ||
actual_query = sql_strings[0]; | ||
return Promise.resolve([]); | ||
}); | ||
chai_1.expect(actual_query).to.deep.equal('SELECT id FROM calls'); | ||
}); | ||
}); | ||
@@ -507,0 +481,0 @@ }); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.validator = void 0; | ||
var helpers_1 = require("../helpers/helpers"); | ||
var schema_helpers_1 = require("../helpers/schema_helpers"); | ||
var query_1 = require("./query"); | ||
var validator = function (query, schema) { | ||
var errors = []; | ||
const helpers_1 = require("../helpers/helpers"); | ||
const schema_helpers_1 = require("../helpers/schema_helpers"); | ||
const query_1 = require("./query"); | ||
const validator = (query, schema) => { | ||
let errors = []; | ||
// Walk the query | ||
helpers_1.deep_for_each(query, function (val, path) { | ||
var is_boolean_resolver = val === true; | ||
var is_virtual_column_resolver = typeof val === 'object' && !query_1.is_subquery(val); | ||
var is_subquery_resolver = typeof val === 'object' && query_1.is_subquery(val); | ||
helpers_1.deep_for_each(query, (val, path) => { | ||
const is_boolean_resolver = val === true; | ||
const is_virtual_column_resolver = typeof val === 'object' && !query_1.is_subquery(val); | ||
const is_subquery_resolver = typeof val === 'object' && query_1.is_subquery(val); | ||
if (is_boolean_resolver) { | ||
var error = validate_field_exists(val, path, schema, query); | ||
const error = validate_field_exists(val, path, schema, query); | ||
if (error) | ||
@@ -20,8 +20,8 @@ errors.push(error); | ||
if (is_virtual_column_resolver) { | ||
var is_renamed_field = '$field' in val; | ||
var is_eq = '$eq' in val; | ||
const is_renamed_field = '$field' in val; | ||
const is_eq = '$eq' in val; | ||
if (is_renamed_field) { | ||
if (!is_exclusive_key('$field', val)) { | ||
var error = { | ||
message: "$field must be the only key when renaming a field", | ||
const error = { | ||
message: `$field must be the only key when renaming a field`, | ||
original_data: query, | ||
@@ -32,3 +32,3 @@ path: path | ||
} | ||
var error2 = ensure_field_exists(val, path, query, schema); | ||
const error2 = ensure_field_exists(val, path, query, schema); | ||
if (error2) | ||
@@ -39,18 +39,18 @@ errors.push(error2); | ||
if (!last_path_equals('$where', path)) { | ||
var error_1 = { | ||
message: "$eq can only be used in $where", | ||
const error = { | ||
message: `$eq can only be used in $where`, | ||
original_data: query, | ||
path: path, | ||
}; | ||
errors.push(error_1); | ||
errors.push(error); | ||
} | ||
if (!is_exclusive_key('$eq', val)) { | ||
var error_2 = { | ||
message: "$eq can only be used in $where", | ||
const error = { | ||
message: `$eq can only be used in $where`, | ||
original_data: query, | ||
path: path, | ||
}; | ||
errors.push(error_2); | ||
errors.push(error); | ||
} | ||
var error = ensure_valid_eq(val, path, query, schema); | ||
const error = ensure_valid_eq(val, path, query, schema); | ||
if (error) { | ||
@@ -62,3 +62,3 @@ errors.push(error); | ||
if (is_subquery_resolver) { | ||
var error = validate_edges(path, query, schema); | ||
const error = validate_edges(path, query, schema); | ||
if (error) | ||
@@ -75,9 +75,9 @@ errors.push(error); | ||
exports.validator = validator; | ||
var ensure_valid_eq = function (val, path, query, schema) { | ||
var args = val['$eq']; | ||
const ensure_valid_eq = (val, path, query, schema) => { | ||
const args = val['$eq']; | ||
if (!Array.isArray(args) || args.length !== 2) { | ||
var error = { | ||
message: "$eq must be an array of length 2", | ||
const error = { | ||
message: `$eq must be an array of length 2`, | ||
original_data: query, | ||
path: path, | ||
path, | ||
}; | ||
@@ -87,8 +87,8 @@ return error; | ||
// First val must be a valid column name | ||
var first_arg = args[0]; | ||
var parent_entity = query_1.get_real_parent_name(path, query); | ||
const first_arg = args[0]; | ||
const parent_entity = query_1.get_real_parent_name(path, query); | ||
if (typeof first_arg !== 'string' || !schema[parent_entity][first_arg]) { | ||
var error = { | ||
message: "First argument to $eq must be string and be a valid column name from " + parent_entity, | ||
path: path, | ||
const error = { | ||
message: `First argument to $eq must be string and be a valid column name from ${parent_entity}`, | ||
path, | ||
original_data: query | ||
@@ -100,17 +100,17 @@ }; | ||
}; | ||
var is_exclusive_key = function (key, obj) { | ||
const is_exclusive_key = (key, obj) => { | ||
return Object.keys(obj).length == 1 && Object.keys(obj)[0] === key; | ||
}; | ||
var last_path_equals = function (desired_key, path) { | ||
var is_valid = helpers_1.last(path) === desired_key; | ||
const last_path_equals = (desired_key, path) => { | ||
const is_valid = helpers_1.last(path) === desired_key; | ||
return is_valid; | ||
}; | ||
var validate_edges = function (path, query, schema) { | ||
const validate_edges = (path, query, schema) => { | ||
if (path.length > 1) { | ||
var parent_name = query_1.get_real_parent_name(path, query); | ||
var entity_name = query_1.get_real_entity_name(path, query); | ||
var direct_edges = schema_helpers_1.get_direct_edges(parent_name, entity_name, schema); | ||
const parent_name = query_1.get_real_parent_name(path, query); | ||
const entity_name = query_1.get_real_entity_name(path, query); | ||
const direct_edges = schema_helpers_1.get_direct_edges(parent_name, entity_name, schema); | ||
if (direct_edges.length === 0) { | ||
var error = { | ||
message: parent_name + " is not connected to " + entity_name + ".", | ||
const error = { | ||
message: `${parent_name} is not connected to ${entity_name}.`, | ||
path: path, | ||
@@ -123,8 +123,8 @@ original_data: query, | ||
}; | ||
var ensure_field_exists = function (val, path, query, schema) { | ||
var parent_entity = query_1.get_real_parent_name(path, query); | ||
var original_field = val['$field']; | ||
const ensure_field_exists = (val, path, query, schema) => { | ||
const parent_entity = query_1.get_real_parent_name(path, query); | ||
const original_field = val['$field']; | ||
if (typeof original_field !== 'string' || !schema[parent_entity][original_field]) { | ||
var error = { | ||
message: "$field must be a string which exists in " + parent_entity, | ||
const error = { | ||
message: `$field must be a string which exists in ${parent_entity}`, | ||
original_data: query, | ||
@@ -136,9 +136,9 @@ path: path | ||
}; | ||
var validate_field_exists = function (val, path, schema, query) { | ||
const validate_field_exists = (val, path, schema, query) => { | ||
// User is requesting a specific field be in the response | ||
var parent_entity = query_1.get_real_parent_name(path, query); | ||
var requested_field = helpers_1.last(path); | ||
const parent_entity = query_1.get_real_parent_name(path, query); | ||
const requested_field = helpers_1.last(path); | ||
if (!schema_helpers_1.field_exists(parent_entity, requested_field, schema)) { | ||
var error = { | ||
message: "Field " + requested_field + " does not exist on entity " + parent_entity, | ||
const error = { | ||
message: `Field ${requested_field} does not exist on entity ${parent_entity}`, | ||
path: path, | ||
@@ -145,0 +145,0 @@ original_data: query, |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var chai_1 = require("chai"); | ||
var mocha_1 = require("mocha"); | ||
var validate_query_1 = require("./validate_query"); | ||
var schema = { | ||
const chai_1 = require("chai"); | ||
const mocha_1 = require("mocha"); | ||
const validate_query_1 = require("./validate_query"); | ||
const schema = { | ||
grand_parent: { | ||
@@ -51,6 +51,6 @@ id: {}, | ||
*/ | ||
mocha_1.describe('validate_query.ts', function () { | ||
mocha_1.describe('boolean resolver', function () { | ||
mocha_1.test('validates boolean resolver column names', function () { | ||
var query = { | ||
mocha_1.describe('validate_query.ts', () => { | ||
mocha_1.describe('boolean resolver', () => { | ||
mocha_1.test('validates boolean resolver column names', () => { | ||
const query = { | ||
grand_parent: { | ||
@@ -68,3 +68,3 @@ id: true, | ||
}; | ||
var errors = validate_query_1.validator(query, schema); | ||
const errors = validate_query_1.validator(query, schema); | ||
chai_1.expect(errors.length).to.deep.equal(1); | ||
@@ -74,5 +74,5 @@ chai_1.expect(errors[0].path).to.deep.equal(['grand_parent', 'parent', 'child', 'child_column_oops']); | ||
}); | ||
mocha_1.describe('virtual columns', function () { | ||
mocha_1.test('validates $field virtual column', function () { | ||
var query = { | ||
mocha_1.describe('virtual columns', () => { | ||
mocha_1.test('validates $field virtual column', () => { | ||
const query = { | ||
parent: { | ||
@@ -83,3 +83,3 @@ custom_name: { $field: 'parent_column' }, | ||
}; | ||
var errors = validate_query_1.validator(query, schema); | ||
const errors = validate_query_1.validator(query, schema); | ||
chai_1.expect(errors[0].path).to.deep.equal(['parent', 'custom_name2']); | ||
@@ -89,5 +89,5 @@ chai_1.expect(errors.length).to.deep.equal(1); | ||
}); | ||
mocha_1.describe('subqueries', function () { | ||
mocha_1.test('validates the from clause', function () { | ||
var data = { | ||
mocha_1.describe('subqueries', () => { | ||
mocha_1.test('validates the from clause', () => { | ||
const data = { | ||
parent: { | ||
@@ -104,11 +104,9 @@ good: { | ||
}; | ||
var errors = validate_query_1.validator(data, schema); | ||
var from_clause_errors = errors.filter(function (err) { | ||
return JSON.stringify(err.path) === | ||
JSON.stringify(['parent', 'bad', 'id']); | ||
}); | ||
const errors = validate_query_1.validator(data, schema); | ||
const from_clause_errors = errors.filter(err => JSON.stringify(err.path) === | ||
JSON.stringify(['parent', 'bad', 'id'])); | ||
chai_1.expect(from_clause_errors.length).to.equal(1); | ||
}); | ||
mocha_1.test('validates subquery connections', function () { | ||
var data = { | ||
mocha_1.test('validates subquery connections', () => { | ||
const data = { | ||
grand_parent: { | ||
@@ -126,3 +124,3 @@ john: { | ||
}; | ||
var errors = validate_query_1.validator(data, schema); | ||
const errors = validate_query_1.validator(data, schema); | ||
chai_1.expect(errors.length).to.equal(1); | ||
@@ -132,5 +130,5 @@ chai_1.expect(errors[0].path).to.deep.equal(['grand_parent', 'john', 'child', 'grand_parent']); | ||
}); | ||
mocha_1.describe.skip('clauses', function () { | ||
mocha_1.test('Requires $eq to have valid field name', function () { | ||
var data = { | ||
mocha_1.describe.skip('clauses', () => { | ||
mocha_1.test('Requires $eq to have valid field name', () => { | ||
const data = { | ||
parent: { | ||
@@ -145,8 +143,8 @@ $where: { | ||
}; | ||
var errors = validate_query_1.validator(data, schema); | ||
const errors = validate_query_1.validator(data, schema); | ||
chai_1.expect(errors.length).to.equal(1); | ||
chai_1.expect(errors[0].path).to.deep.equal(['parent', '$where']); | ||
}); | ||
mocha_1.test('Lets $having have aliased fields', function () { | ||
var data = { | ||
mocha_1.test('Lets $having have aliased fields', () => { | ||
const data = { | ||
parent: { | ||
@@ -161,7 +159,7 @@ $having: { | ||
}; | ||
var errors = validate_query_1.validator(data, schema); | ||
const errors = validate_query_1.validator(data, schema); | ||
chai_1.expect(errors.length).to.equal(0); | ||
}); | ||
mocha_1.test('Lets operators have functions', function () { | ||
var data = { | ||
mocha_1.test('Lets operators have functions', () => { | ||
const data = { | ||
parent: { | ||
@@ -174,7 +172,7 @@ $where: { | ||
}; | ||
var errors = validate_query_1.validator(data, schema); | ||
const errors = validate_query_1.validator(data, schema); | ||
chai_1.expect(errors.length).to.equal(0); | ||
}); | ||
mocha_1.test('Lets operators have functions', function () { | ||
var data = { | ||
mocha_1.test('Lets operators have functions', () => { | ||
const data = { | ||
parent: { | ||
@@ -187,7 +185,7 @@ $where: { | ||
}; | ||
var errors = validate_query_1.validator(data, schema); | ||
const errors = validate_query_1.validator(data, schema); | ||
chai_1.expect(errors.length).to.equal(0); | ||
}); | ||
mocha_1.test('Lets $and', function () { | ||
var data = { | ||
mocha_1.test('Lets $and', () => { | ||
const data = { | ||
parent: { | ||
@@ -202,7 +200,7 @@ $where: { | ||
}; | ||
var errors = validate_query_1.validator(data, schema); | ||
const errors = validate_query_1.validator(data, schema); | ||
chai_1.expect(errors.length).to.equal(0); | ||
}); | ||
mocha_1.test('Changes scope for subqueries', function () { | ||
var data = { | ||
mocha_1.test('Changes scope for subqueries', () => { | ||
const data = { | ||
parent: { | ||
@@ -221,7 +219,7 @@ $where: { | ||
}; | ||
var errors = validate_query_1.validator(data, schema); | ||
const errors = validate_query_1.validator(data, schema); | ||
chai_1.expect(errors.length).to.equal(1); | ||
}); | ||
mocha_1.test('Requires subqueries to have valid fields', function () { | ||
var data = { | ||
mocha_1.test('Requires subqueries to have valid fields', () => { | ||
const data = { | ||
parent: { | ||
@@ -237,7 +235,7 @@ $where: { | ||
}; | ||
var errors = validate_query_1.validator(data, schema); | ||
const errors = validate_query_1.validator(data, schema); | ||
chai_1.expect(errors.length).to.equal(1); | ||
}); | ||
mocha_1.test('Requires subqueries to have valid fields', function () { | ||
var data = { | ||
mocha_1.test('Requires subqueries to have valid fields', () => { | ||
const data = { | ||
parent: { | ||
@@ -253,3 +251,3 @@ $where: { | ||
}; | ||
var errors = validate_query_1.validator(data, schema); | ||
const errors = validate_query_1.validator(data, schema); | ||
chai_1.expect(errors.length).to.equal(1); | ||
@@ -256,0 +254,0 @@ }); |
{ | ||
"name": "orma", | ||
"version": "1.0.24", | ||
"version": "1.0.28", | ||
"description": "A declarative relational syncronous orm", | ||
@@ -5,0 +5,0 @@ "main": "build/index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
213443
5176