// @flow import * as crypto from 'crypto'; import * as db from '../common/database'; import type { BaseModel } from './index'; import type { Workspace } from './workspace'; export const name = 'Environment'; export const type = 'Environment'; export const prefix = 'env'; export const canDuplicate = true; export const canSync = true; type BaseEnvironment = { name: string, data: Object, dataPropertyOrder: Object | null, color: string | null, metaSortKey: number, // For sync control isPrivate: boolean, }; export type Environment = BaseModel & BaseEnvironment; export function init() { return { name: 'New Environment', data: {}, dataPropertyOrder: null, color: null, isPrivate: false, metaSortKey: Date.now(), }; } export function migrate(doc: Environment): Environment { return doc; } export function create(patch: $Shape = {}): Promise { if (!patch.parentId) { throw new Error(`New Environment missing \`parentId\`: ${JSON.stringify(patch)}`); } return db.docCreate(type, patch); } export function update(environment: Environment, patch: $Shape): Promise { return db.docUpdate(environment, patch); } export function findByParentId(parentId: string): Promise> { return db.find(type, { parentId }, { metaSortKey: 1 }); } export async function getOrCreateForWorkspaceId(workspaceId: string): Promise { const environments = await db.find(type, { parentId: workspaceId }); if (!environments.length) { return create({ parentId: workspaceId, name: 'Base Environment', // Deterministic base env ID. It helps reduce sync complexity since we won't have to // de-duplicate environments. _id: `${prefix}_${crypto .createHash('sha1') .update(workspaceId) .digest('hex')}`, }); } return environments[environments.length - 1]; } export async function getOrCreateForWorkspace(workspace: Workspace): Promise { return getOrCreateForWorkspaceId(workspace._id); } export function getById(id: string): Promise { return db.get(type, id); } export async function duplicate(environment: Environment): Promise { const name = `${environment.name} (Copy)`; // Get sort key of next environment const q = { metaSortKey: { $gt: environment.metaSortKey } }; const [nextEnvironment] = await db.find(type, q, { metaSortKey: 1 }); const nextSortKey = nextEnvironment ? nextEnvironment.metaSortKey : environment.metaSortKey + 100; // Calculate new sort key const metaSortKey = (environment.metaSortKey + nextSortKey) / 2; return db.duplicate(environment, { name, metaSortKey }); } export function remove(environment: Environment): Promise { return db.remove(environment); } export function all(): Promise> { return db.all(type); }