parse-server-schema-manager
Version:
Parse server schema manager
269 lines • 26.6 kB
JavaScript
;
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 __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.manageSchema = exports.getAllSchemas = exports.diffingCLP = exports.diffingIndexes = exports.diffingFields = void 0;
const object_1 = require("../object");
const sync_1 = require("./sync");
const node_1 = __importDefault(require("parse/node"));
const checkSecondProperties = ['type'];
const checkOptions = ['targetClass', 'required', 'defaultValue'];
const diffingFields = (obj1, obj2, schemaOptions) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
let add = {};
let remove = {};
let change = {};
for (let key in obj2) {
if ((_a = schemaOptions === null || schemaOptions === void 0 ? void 0 : schemaOptions.ignoreAttributes) === null || _a === void 0 ? void 0 : _a.includes(key))
continue;
if (!obj1[key])
add[key] = obj2[key];
else {
const obj1Field = obj1[key];
const obj2Field = obj2[key];
for (const prop of checkSecondProperties) {
if (prop in obj1Field && prop in obj2Field) {
if ((obj1Field === null || obj1Field === void 0 ? void 0 : obj1Field[prop]) !== (obj2Field === null || obj2Field === void 0 ? void 0 : obj2Field[prop])) {
change[key] = (_b = change[key]) !== null && _b !== void 0 ? _b : [];
change[key].push(`${prop}: ${obj1Field[prop]} -> ${obj2Field[prop]}`);
}
}
}
for (let pr of checkSecondProperties) {
if ((obj1Field === null || obj1Field === void 0 ? void 0 : obj1Field[pr]) !== (obj2Field === null || obj2Field === void 0 ? void 0 : obj2Field[pr])) {
change[key] = (_c = change[key]) !== null && _c !== void 0 ? _c : [];
change[key].push(`${pr}: ${obj1Field[pr]} -> ${obj2Field[pr]}`);
}
}
for (let pr of checkOptions)
if (!(0, object_1.checkSame)(obj1Field === null || obj1Field === void 0 ? void 0 : obj1Field[pr], obj2Field === null || obj2Field === void 0 ? void 0 : obj2Field[pr])) {
if (pr === 'required' &&
((_d = obj1[key]) === null || _d === void 0 ? void 0 : _d[pr]) === false &&
!((_e = obj2[key]) === null || _e === void 0 ? void 0 : _e[pr]))
continue;
if (pr === 'defaultValue' &&
((_f = obj1[key]) === null || _f === void 0 ? void 0 : _f[pr]) === false &&
!((_g = obj2[key]) === null || _g === void 0 ? void 0 : _g[pr]))
continue;
change[key] = (_h = change[key]) !== null && _h !== void 0 ? _h : [];
change[key].push(`${pr}: ${JSON.stringify(obj1Field[pr])} -> ${JSON.stringify(obj2Field === null || obj2Field === void 0 ? void 0 : obj2Field[pr])}`);
}
}
}
for (let key in obj1) {
if ((_j = schemaOptions === null || schemaOptions === void 0 ? void 0 : schemaOptions.ignoreAttributes) === null || _j === void 0 ? void 0 : _j.includes(key))
continue;
if (!obj2[key])
remove[key] = obj1[key];
}
const output = {};
if (Object.keys(add).length)
output.add = add;
if (Object.keys(remove).length)
output.remove = remove;
if (Object.keys(change).length)
output.change = change;
return output;
};
exports.diffingFields = diffingFields;
const diffingIndexes = (obj1, obj2) => {
const change = {};
const add = {};
const remove = {};
for (let key in obj1)
if (!obj2[key])
remove[key] = obj1[key];
for (let key in obj2) {
if (!obj1[key]) {
add[key] = obj2[key];
continue;
}
const allKeys = [
...new Set([...Object.keys(obj1[key]), ...Object.keys(obj2[key])]),
];
if (allKeys.some((key2) => { var _a, _b; return !(0, object_1.checkSame)((_a = obj1[key]) === null || _a === void 0 ? void 0 : _a[key2], (_b = obj2[key]) === null || _b === void 0 ? void 0 : _b[key2]); })) {
change[key] = {
from: obj1[key],
to: obj2[key],
};
}
}
const output = {};
if (Object.keys(add).length)
output.add = add;
if (Object.keys(remove).length)
output.remove = remove;
if (Object.keys(change).length)
output.change = change;
return output;
};
exports.diffingIndexes = diffingIndexes;
const diffingCLP = (obj1, obj2) => {
const change = {};
for (let key in obj2) {
const allKeys = [...Object.keys(obj1[key])];
if (allKeys.some((key2) => { var _a, _b; return !(0, object_1.checkSame)((_a = obj1[key]) === null || _a === void 0 ? void 0 : _a[key2], (_b = obj2[key]) === null || _b === void 0 ? void 0 : _b[key2]); })) {
change[key] = {
from: obj1[key],
to: obj2[key],
};
}
}
return change;
};
exports.diffingCLP = diffingCLP;
const sanitizeSchemaParts = (parts) => {
return Object.assign({
fields: true,
indexes: true,
classLevelPermissions: true,
}, parts);
};
const sanitizeSchemaOptions = (outputOptions) => {
return Object.assign({
ignoreClasses: ['_Session'],
ignoreAttributes: [
'ACL',
'password',
'authData',
'emailVerified',
'email',
],
}, outputOptions);
};
const wait = (t) => new Promise((r) => setTimeout(r, t));
const getAllParseSchema = () => __awaiter(void 0, void 0, void 0, function* () {
return yield node_1.default.Schema.all();
});
const getAllSchemas = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (parts = {}, outputOptions = {}) {
var _a;
const schemaParts = sanitizeSchemaParts(parts);
const options = sanitizeSchemaOptions(outputOptions);
const { ignoreClasses, ignoreAttributes } = options;
const list = yield getAllParseSchema();
const clone = structuredClone(list).filter((c) => !ignoreClasses.includes(c.className));
const returnList = [];
for (let cls of clone) {
let obj = { className: cls.className, fields: {} };
if (schemaParts.fields) {
obj.fields = cls.fields;
for (let atr of ignoreAttributes !== null && ignoreAttributes !== void 0 ? ignoreAttributes : [])
if ((_a = obj.fields) === null || _a === void 0 ? void 0 : _a[atr])
delete obj.fields[atr];
}
if (schemaParts.indexes)
obj.indexes = cls.indexes;
if (schemaParts.classLevelPermissions)
obj.classLevelPermissions = cls.classLevelPermissions;
returnList.push(obj);
}
return returnList;
});
exports.getAllSchemas = getAllSchemas;
const diffSchemaChanges = (existingSchema, schema, part, schemaOptions) => {
var _a;
const change = {};
for (let cls of schema) {
const className = cls.className;
if ((_a = schemaOptions === null || schemaOptions === void 0 ? void 0 : schemaOptions.ignoreClasses) === null || _a === void 0 ? void 0 : _a.includes(className))
continue;
const existingCls = existingSchema.find((c) => c.className === className);
if (!(existingCls === null || existingCls === void 0 ? void 0 : existingCls.fields) || !cls.fields)
continue;
const diff = part === 'fields'
? (0, exports.diffingFields)(existingCls.fields, cls.fields, schemaOptions)
: part === 'indexes'
? (0, exports.diffingIndexes)(existingCls.indexes, cls.indexes)
: (0, exports.diffingCLP)(existingCls.classLevelPermissions, cls.classLevelPermissions);
if (Object.keys(diff).length)
change[className] = diff;
}
return change;
};
const addRemoveSchemaChanges = (existingSchema, schema, schemaOptions) => {
var _a, _b;
const add = {};
const remove = {};
for (let cls of schema) {
const className = cls.className;
if ((_a = schemaOptions === null || schemaOptions === void 0 ? void 0 : schemaOptions.ignoreClasses) === null || _a === void 0 ? void 0 : _a.includes(className))
continue;
const existingCls = existingSchema.find((c) => c.className === className);
if (existingCls)
continue;
add[className] = cls;
}
for (let cls of existingSchema) {
const className = cls.className;
if ((_b = schemaOptions === null || schemaOptions === void 0 ? void 0 : schemaOptions.ignoreClasses) === null || _b === void 0 ? void 0 : _b.includes(className))
continue;
const newCls = schema.find((c) => c.className === className);
if (newCls)
continue;
remove[className] = cls;
}
const output = {};
if (Object.keys(add).length)
output.add = add;
if (Object.keys(remove).length)
output.remove = remove;
return output;
};
const manageSchema = (schema_1, _a, ...args_1) => __awaiter(void 0, [schema_1, _a, ...args_1], void 0, function* (schema, { commit = false, remove = false, purge = false }, actionParts = {}, schemaOptions = {}) {
var _b, _c, _d, _e, _f, _g;
const schemaParts = sanitizeSchemaParts(actionParts);
const options = sanitizeSchemaOptions(schemaOptions);
const existingSchema = yield (0, exports.getAllSchemas)(actionParts, options);
const addRemove = addRemoveSchemaChanges(existingSchema, schema, options);
const changesDiff = {};
for (let key in schemaParts)
if (schemaParts[key])
changesDiff[key] = diffSchemaChanges(existingSchema, schema, key, options);
let log = 'Nothing changed!';
if (commit) {
for (let key in (_b = addRemove.add) !== null && _b !== void 0 ? _b : {})
yield (0, sync_1.syncSchemaWithObject)(key, (_c = addRemove.add) === null || _c === void 0 ? void 0 : _c[key], options.ignoreAttributes);
let keysToSync = new Set();
for (let classKey in (_d = changesDiff.fields) !== null && _d !== void 0 ? _d : {})
keysToSync.add(classKey);
for (let classKey in (_e = changesDiff.indexes) !== null && _e !== void 0 ? _e : {})
keysToSync.add(classKey);
keysToSync = [...keysToSync];
for (let key of keysToSync) {
const cls = schema.find((t) => t.className === key);
yield (0, sync_1.syncSchemaWithObject)(key, cls, options.ignoreAttributes);
}
log = 'Schema synced!';
}
if (remove)
for (let key in (_f = addRemove.remove) !== null && _f !== void 0 ? _f : {}) {
const mySchema = new node_1.default.Schema(key);
if (purge)
yield mySchema.purge();
yield mySchema.delete();
log = 'Schema synced!';
}
const output = Object.assign(Object.assign({}, addRemove), { log });
if (Object.keys(changesDiff).length) {
let tempChanges = {};
for (let key in changesDiff) {
if (Object.keys((_g = changesDiff[key]) !== null && _g !== void 0 ? _g : {}).length)
tempChanges[key] = changesDiff[key];
}
if (Object.keys(tempChanges).length)
output.changes = tempChanges;
}
return output;
});
exports.manageSchema = manageSchema;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Z1bmN0aW9ucy9zY2hlbWEvc2NoZW1hLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQUNBLHNDQUFvQztBQUNwQyxpQ0FBNEM7QUFDNUMsc0RBQStCO0FBRS9CLE1BQU0scUJBQXFCLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUV2QyxNQUFNLFlBQVksR0FBRyxDQUFDLGFBQWEsRUFBRSxVQUFVLEVBQUUsY0FBYyxDQUFDLENBQUM7QUFjMUQsTUFBTSxhQUFhLEdBQUcsQ0FDM0IsSUFBaUIsRUFDakIsSUFBaUIsRUFDakIsYUFBa0MsRUFDaEIsRUFBRTs7SUFDcEIsSUFBSSxHQUFHLEdBQWdCLEVBQUUsQ0FBQztJQUMxQixJQUFJLE1BQU0sR0FBZ0IsRUFBRSxDQUFDO0lBQzdCLElBQUksTUFBTSxHQUFrQyxFQUFFLENBQUM7SUFDL0MsS0FBSyxJQUFJLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUNyQixJQUFJLE1BQUEsYUFBYSxhQUFiLGFBQWEsdUJBQWIsYUFBYSxDQUFFLGdCQUFnQiwwQ0FBRSxRQUFRLENBQUMsR0FBRyxDQUFDO1lBQUUsU0FBUztRQUU3RCxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztZQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDaEMsQ0FBQztZQUNKLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQXdCLENBQUM7WUFDbkQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBd0IsQ0FBQztZQUVuRCxLQUFLLE1BQU0sSUFBSSxJQUFJLHFCQUFxQixFQUFFLENBQUM7Z0JBQ3pDLElBQUksSUFBSSxJQUFJLFNBQVMsSUFBSSxJQUFJLElBQUksU0FBUyxFQUFFLENBQUM7b0JBQzNDLElBQUksQ0FBQSxTQUFTLGFBQVQs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