2019-04-18 00:50:03 +00:00
|
|
|
import * as crypto from 'crypto';
|
2021-07-22 23:04:56 +00:00
|
|
|
|
2021-05-12 06:35:00 +00:00
|
|
|
import { database as db } from '../common/database';
|
2018-06-25 17:42:50 +00:00
|
|
|
import type { BaseModel } from './index';
|
2016-09-21 20:32:45 +00:00
|
|
|
|
2016-11-22 19:42:10 +00:00
|
|
|
export const name = 'Environment';
|
2016-10-02 20:57:00 +00:00
|
|
|
export const type = 'Environment';
|
|
|
|
export const prefix = 'env';
|
2017-03-23 22:10:42 +00:00
|
|
|
export const canDuplicate = true;
|
2021-05-12 06:35:00 +00:00
|
|
|
export const canSync = true;
|
2017-10-31 18:05:35 +00:00
|
|
|
|
2021-05-12 06:35:00 +00:00
|
|
|
interface BaseEnvironment {
|
|
|
|
name: string;
|
|
|
|
data: Record<string, any>;
|
|
|
|
dataPropertyOrder: Record<string, any> | null;
|
|
|
|
color: string | null;
|
|
|
|
metaSortKey: number;
|
2017-10-31 18:05:35 +00:00
|
|
|
// For sync control
|
2021-05-12 06:35:00 +00:00
|
|
|
isPrivate: boolean;
|
|
|
|
}
|
2017-09-25 21:32:58 +00:00
|
|
|
|
|
|
|
export type Environment = BaseModel & BaseEnvironment;
|
|
|
|
|
2021-06-16 19:19:00 +00:00
|
|
|
export const isEnvironment = (model: Pick<BaseModel, 'type'>): model is Environment => (
|
|
|
|
model.type === type
|
|
|
|
);
|
|
|
|
|
2018-06-25 17:42:50 +00:00
|
|
|
export function init() {
|
2016-11-10 01:15:27 +00:00
|
|
|
return {
|
2016-10-02 20:57:00 +00:00
|
|
|
name: 'New Environment',
|
|
|
|
data: {},
|
2019-05-29 20:10:48 +00:00
|
|
|
dataPropertyOrder: null,
|
2017-06-27 21:44:23 +00:00
|
|
|
color: null,
|
2018-06-07 17:55:28 +00:00
|
|
|
isPrivate: false,
|
2018-12-12 17:36:11 +00:00
|
|
|
metaSortKey: Date.now(),
|
2017-03-03 20:09:08 +00:00
|
|
|
};
|
2016-10-02 20:57:00 +00:00
|
|
|
}
|
|
|
|
|
2021-05-12 06:35:00 +00:00
|
|
|
export function migrate(doc: Environment) {
|
2016-11-22 19:42:10 +00:00
|
|
|
return doc;
|
|
|
|
}
|
|
|
|
|
2021-05-12 06:35:00 +00:00
|
|
|
export function create(patch: Partial<Environment> = {}) {
|
2016-09-21 20:32:45 +00:00
|
|
|
if (!patch.parentId) {
|
2018-10-17 16:42:33 +00:00
|
|
|
throw new Error(`New Environment missing \`parentId\`: ${JSON.stringify(patch)}`);
|
2016-09-21 20:32:45 +00:00
|
|
|
}
|
|
|
|
|
2021-05-12 06:35:00 +00:00
|
|
|
return db.docCreate<Environment>(type, patch);
|
2016-10-02 20:57:00 +00:00
|
|
|
}
|
2016-09-21 20:32:45 +00:00
|
|
|
|
2021-05-12 06:35:00 +00:00
|
|
|
export function update(environment: Environment, patch: Partial<Environment>) {
|
2016-09-21 20:32:45 +00:00
|
|
|
return db.docUpdate(environment, patch);
|
2016-10-02 20:57:00 +00:00
|
|
|
}
|
2016-09-21 20:32:45 +00:00
|
|
|
|
2021-05-12 06:35:00 +00:00
|
|
|
export function findByParentId(parentId: string) {
|
|
|
|
return db.find<Environment>(
|
|
|
|
type,
|
|
|
|
{
|
|
|
|
parentId,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
metaSortKey: 1,
|
|
|
|
},
|
|
|
|
);
|
2016-10-02 20:57:00 +00:00
|
|
|
}
|
2016-09-21 20:32:45 +00:00
|
|
|
|
2021-06-22 20:45:30 +00:00
|
|
|
export async function getOrCreateForParentId(parentId: string) {
|
2021-05-12 06:35:00 +00:00
|
|
|
const environments = await db.find<Environment>(type, {
|
2021-06-22 20:45:30 +00:00
|
|
|
parentId,
|
2021-05-12 06:35:00 +00:00
|
|
|
});
|
2016-10-02 20:57:00 +00:00
|
|
|
|
2017-11-13 19:05:46 +00:00
|
|
|
if (!environments.length) {
|
2017-11-20 16:07:36 +00:00
|
|
|
return create({
|
2021-06-22 20:45:30 +00:00
|
|
|
parentId,
|
2018-12-12 17:36:11 +00:00
|
|
|
name: 'Base Environment',
|
2019-04-18 00:50:03 +00:00
|
|
|
// Deterministic base env ID. It helps reduce sync complexity since we won't have to
|
|
|
|
// de-duplicate environments.
|
2021-06-22 20:45:30 +00:00
|
|
|
_id: `${prefix}_${crypto.createHash('sha1').update(parentId).digest('hex')}`,
|
2017-03-03 20:09:08 +00:00
|
|
|
});
|
2016-10-02 20:57:00 +00:00
|
|
|
}
|
2017-03-30 18:52:07 +00:00
|
|
|
|
2017-11-13 19:05:46 +00:00
|
|
|
return environments[environments.length - 1];
|
2016-10-02 20:57:00 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 17:42:50 +00:00
|
|
|
export function getById(id: string): Promise<Environment | null> {
|
2016-10-02 20:57:00 +00:00
|
|
|
return db.get(type, id);
|
|
|
|
}
|
|
|
|
|
2021-06-22 20:45:30 +00:00
|
|
|
export function getByParentId(parentId: string): Promise<Environment | null> {
|
|
|
|
return db.getWhere<Environment>(type, { parentId });
|
|
|
|
}
|
|
|
|
|
2021-05-12 06:35:00 +00:00
|
|
|
export async function duplicate(environment: Environment) {
|
2019-10-07 18:43:34 +00:00
|
|
|
const name = `${environment.name} (Copy)`;
|
|
|
|
// Get sort key of next environment
|
2021-05-12 06:35:00 +00:00
|
|
|
const q = {
|
|
|
|
metaSortKey: {
|
|
|
|
$gt: environment.metaSortKey,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
// @ts-expect-error -- TSCONVERSION appears to be a genuine error
|
|
|
|
const [nextEnvironment] = await db.find<Environment>(type, q, { metaSortKey: 1 });
|
2019-10-07 18:43:34 +00:00
|
|
|
const nextSortKey = nextEnvironment ? nextEnvironment.metaSortKey : environment.metaSortKey + 100;
|
|
|
|
// Calculate new sort key
|
|
|
|
const metaSortKey = (environment.metaSortKey + nextSortKey) / 2;
|
2021-05-12 06:35:00 +00:00
|
|
|
return db.duplicate(environment, {
|
|
|
|
name,
|
|
|
|
metaSortKey,
|
|
|
|
});
|
2019-10-07 18:43:34 +00:00
|
|
|
}
|
|
|
|
|
2021-05-12 06:35:00 +00:00
|
|
|
export function remove(environment: Environment) {
|
2016-09-21 20:32:45 +00:00
|
|
|
return db.remove(environment);
|
2016-10-02 20:57:00 +00:00
|
|
|
}
|
2016-09-21 20:32:45 +00:00
|
|
|
|
2021-05-12 06:35:00 +00:00
|
|
|
export function all() {
|
|
|
|
return db.all<Environment>(type);
|
2016-10-02 20:57:00 +00:00
|
|
|
}
|