diff --git a/backend/database/core.ts b/backend/database/core.ts index 874fa826..5f6b9fce 100644 --- a/backend/database/core.ts +++ b/backend/database/core.ts @@ -11,6 +11,7 @@ import { Field, FieldTypeEnum, RawValue, + Schema, SchemaMap, TargetField, } from '../../schemas/types'; @@ -92,7 +93,7 @@ export default class DatabaseCore extends DatabaseBase { async migrate() { for (const schemaName in this.schemaMap) { - const schema = this.schemaMap[schemaName]; + const schema = this.schemaMap[schemaName] as Schema; if (schema.isSingle) { continue; } @@ -109,7 +110,7 @@ export default class DatabaseCore extends DatabaseBase { } async exists(schemaName: string, name?: string): Promise { - const schema = this.schemaMap[schemaName]; + const schema = this.schemaMap[schemaName] as Schema; if (schema.isSingle) { return this.#singleExists(schemaName); } @@ -134,7 +135,7 @@ export default class DatabaseCore extends DatabaseBase { fieldValueMap: FieldValueMap ): Promise { // insert parent - if (this.schemaMap[schemaName].isSingle) { + if (this.schemaMap[schemaName]!.isSingle) { await this.#updateSingleValues(schemaName, fieldValueMap); } else { await this.#insertOne(schemaName, fieldValueMap); @@ -150,7 +151,7 @@ export default class DatabaseCore extends DatabaseBase { name: string = '', fields?: string | string[] ): Promise { - const schema = this.schemaMap[schemaName]; + const schema = this.schemaMap[schemaName] as Schema; if (!schema.isSingle && !name) { throw new ValueError('name is mandatory'); } @@ -204,7 +205,7 @@ export default class DatabaseCore extends DatabaseBase { schemaName: string, options: GetAllOptions = {} ): Promise { - const schema = this.schemaMap[schemaName]; + const schema = this.schemaMap[schemaName] as Schema; const hasCreated = !!schema.fields.find((f) => f.fieldname === 'created'); const { fields = ['name', ...(schema.keywordFields ?? [])], @@ -279,7 +280,7 @@ export default class DatabaseCore extends DatabaseBase { async update(schemaName: string, fieldValueMap: FieldValueMap) { // update parent - if (this.schemaMap[schemaName].isSingle) { + if (this.schemaMap[schemaName]!.isSingle) { await this.#updateSingleValues(schemaName, fieldValueMap); } else { await this.#updateOne(schemaName, fieldValueMap); @@ -290,7 +291,7 @@ export default class DatabaseCore extends DatabaseBase { } async delete(schemaName: string, name: string) { - const schema = this.schemaMap[schemaName]; + const schema = this.schemaMap[schemaName] as Schema; if (schema.isSingle) { await this.#deleteSingle(schemaName, name); return; @@ -462,7 +463,7 @@ export default class DatabaseCore extends DatabaseBase { async #getColumnDiff(schemaName: string): Promise { const tableColumns = await this.#getTableColumns(schemaName); - const validFields = this.schemaMap[schemaName].fields; + const validFields = this.schemaMap[schemaName]!.fields; const diff: ColumnDiff = { added: [], removed: [] }; for (const field of validFields) { @@ -485,7 +486,7 @@ export default class DatabaseCore extends DatabaseBase { async #getNewForeignKeys(schemaName: string): Promise { const foreignKeys = await this.#getForeignKeys(schemaName); const newForeignKeys: Field[] = []; - const schema = this.schemaMap[schemaName]; + const schema = this.schemaMap[schemaName] as Schema; for (const field of schema.fields) { if ( field.fieldtype === 'Link' && @@ -534,7 +535,7 @@ export default class DatabaseCore extends DatabaseBase { (field as TargetField).target ) { const targetSchemaName = (field as TargetField).target as string; - const schema = this.schemaMap[targetSchemaName]; + const schema = this.schemaMap[targetSchemaName] as Schema; table .foreign(field.fieldname) .references('name') @@ -568,7 +569,7 @@ export default class DatabaseCore extends DatabaseBase { async #createTable(schemaName: string, tableName?: string) { tableName ??= schemaName; - const fields = this.schemaMap[schemaName].fields; + const fields = this.schemaMap[schemaName]!.fields; return await this.#runCreateTableQuery(tableName, fields); } @@ -587,15 +588,15 @@ export default class DatabaseCore extends DatabaseBase { .select('fieldname') ).map(({ fieldname }) => fieldname); - return this.schemaMap[singleSchemaName].fields - .map(({ fieldname, default: value }) => ({ + return this.schemaMap[singleSchemaName]!.fields.map( + ({ fieldname, default: value }) => ({ fieldname, value: value as RawValue | undefined, - })) - .filter( - ({ fieldname, value }) => - !existingFields.includes(fieldname) && value !== undefined - ); + }) + ).filter( + ({ fieldname, value }) => + !existingFields.includes(fieldname) && value !== undefined + ); } async #deleteOne(schemaName: string, name: string) { @@ -710,7 +711,7 @@ export default class DatabaseCore extends DatabaseBase { } // Non Table Fields - const fields = this.schemaMap[schemaName].fields.filter( + const fields = this.schemaMap[schemaName]!.fields.filter( (f) => f.fieldtype !== FieldTypeEnum.Table ); @@ -726,7 +727,7 @@ export default class DatabaseCore extends DatabaseBase { singleSchemaName: string, fieldValueMap: FieldValueMap ) { - const fields = this.schemaMap[singleSchemaName].fields; + const fields = this.schemaMap[singleSchemaName]!.fields; for (const field of fields) { const value = fieldValueMap[field.fieldname] as RawValue | undefined; @@ -779,7 +780,7 @@ export default class DatabaseCore extends DatabaseBase { async #initializeSingles() { const singleSchemaNames = Object.keys(this.schemaMap).filter( - (n) => this.schemaMap[n].isSingle + (n) => this.schemaMap[n]!.isSingle ); for (const schemaName of singleSchemaNames) { @@ -788,7 +789,7 @@ export default class DatabaseCore extends DatabaseBase { continue; } - const fields = this.schemaMap[schemaName].fields; + const fields = this.schemaMap[schemaName]!.fields; if (fields.every((f) => f.default === undefined)) { continue; } @@ -815,7 +816,7 @@ export default class DatabaseCore extends DatabaseBase { async #updateOne(schemaName: string, fieldValueMap: FieldValueMap) { const updateMap = { ...fieldValueMap }; delete updateMap.name; - const schema = this.schemaMap[schemaName]; + const schema = this.schemaMap[schemaName] as Schema; for (const { fieldname, fieldtype } of schema.fields) { if (fieldtype !== FieldTypeEnum.Table) { continue; @@ -868,7 +869,7 @@ export default class DatabaseCore extends DatabaseBase { } #getTableFields(schemaName: string): TargetField[] { - return this.schemaMap[schemaName].fields.filter( + return this.schemaMap[schemaName]!.fields.filter( (f) => f.fieldtype === FieldTypeEnum.Table ) as TargetField[]; } diff --git a/backend/database/tests/testCore.spec.ts b/backend/database/tests/testCore.spec.ts index c91dd2e1..c4c27bdf 100644 --- a/backend/database/tests/testCore.spec.ts +++ b/backend/database/tests/testCore.spec.ts @@ -1,6 +1,6 @@ import * as assert from 'assert'; import 'mocha'; -import { FieldTypeEnum, RawValue } from 'schemas/types'; +import { FieldTypeEnum, RawValue, Schema } from 'schemas/types'; import { getMapFromList, getValueMapFromList, sleep } from 'utils'; import { getDefaultMetaFieldValueMap, sqliteTypeMap } from '../../helpers'; import DatabaseCore from '../core'; @@ -72,7 +72,7 @@ describe('DatabaseCore: Migrate and Check Db', function () { specify('Post Migrate TableInfo', async function () { await db.migrate(); for (const schemaName in schemaMap) { - const schema = schemaMap[schemaName]; + const schema = schemaMap[schemaName] as Schema; const fieldMap = getMapFromList(schema.fields, 'fieldname'); const columns: SqliteTableInfo[] = await db.knex!.raw( 'pragma table_info(??)', @@ -176,7 +176,7 @@ describe('DatabaseCore: CRUD', function () { 'select * from SingleValue' ); const defaultMap = getValueMapFromList( - schemaMap.SystemSettings.fields, + (schemaMap.SystemSettings as Schema).fields, 'fieldname', 'default' ); diff --git a/frappe/core/docHandler.ts b/frappe/core/docHandler.ts index ecdfdbae..299c79d6 100644 --- a/frappe/core/docHandler.ts +++ b/frappe/core/docHandler.ts @@ -1,25 +1,15 @@ -import { Field, Model } from '@/types/model'; import Doc from 'frappe/model/doc'; -import Meta from 'frappe/model/meta'; -import { getDuplicates, getRandomString } from 'frappe/utils'; +import { DocMap, ModelMap } from 'frappe/model/types'; +import { getRandomString } from 'frappe/utils'; import Observable from 'frappe/utils/observable'; import { Frappe } from '..'; -import { DocValue } from './types'; - -type DocMap = Record; -type MetaMap = Record; -interface DocData { - doctype: string; - name?: string; - [key: string]: unknown; -} +import { DocValue, DocValueMap } from './types'; export class DocHandler { frappe: Frappe; singles: DocMap = {}; - metaCache: MetaMap = {}; - docs?: Observable; - models: Record = {}; + docs: Observable = new Observable(); + models: ModelMap = {}; constructor(frappe: Frappe) { this.frappe = frappe; @@ -27,124 +17,80 @@ export class DocHandler { init() { this.models = {}; - this.metaCache = {}; this.docs = new Observable(); } - registerModels(models: Record) { - for (const doctype in models) { - const metaDefinition = models[doctype]; - if (!metaDefinition.name) { - throw new Error(`Name is mandatory for ${doctype}`); - } - - if (metaDefinition.name !== doctype) { - throw new Error( - `Model name mismatch for ${doctype}: ${metaDefinition.name}` - ); - } - - const fieldnames = (metaDefinition.fields || []) - .map((df) => df.fieldname) - .sort(); - - const duplicateFieldnames = getDuplicates(fieldnames); - if (duplicateFieldnames.length > 0) { - throw new Error( - `Duplicate fields in ${doctype}: ${duplicateFieldnames.join(', ')}` - ); - } - - this.models[doctype] = metaDefinition; + registerModels(models: ModelMap) { + for (const schemaName in models) { + this.models[schemaName] = models[schemaName]; } } - getModels(filterFunction: (name: Model) => boolean): Model[] { - const models: Model[] = []; - for (const doctype in this.models) { - models.push(this.models[doctype]!); - } - return filterFunction ? models.filter(filterFunction) : models; - } - /** * Cache operations */ addToCache(doc: Doc) { - if (!this.docs) return; - - // add to `docs` cache - const name = doc.name as string | undefined; - const doctype = doc.doctype as string | undefined; - - if (!doctype || !name) { + if (!this.docs) { return; } - if (!this.docs[doctype]) { - this.docs[doctype] = {}; + // add to `docs` cache + const name = doc.name; + const schemaName = doc.schemaName; + + if (!name) { + return; } - (this.docs[doctype] as DocMap)[name] = doc; + if (!this.docs[schemaName]) { + this.docs[schemaName] = {}; + } + + (this.docs[schemaName] as DocMap)[name] = doc; // singles available as first level objects too - if (doctype === doc.name) { + if (schemaName === doc.name) { this.singles[name] = doc; } - // propogate change to `docs` + // propagate change to `docs` doc.on('change', (params: unknown) => { this.docs!.trigger('change', params); }); } - removeFromCache(doctype: string, name: string) { - const docMap = this.docs?.[doctype] as DocMap | undefined; - const doc = docMap?.[name]; + removeFromCache(schemaName: string, name: string) { + const docMap = this.docs[schemaName] as DocMap | undefined; + delete docMap?.[name]; + } - if (doc) { - delete docMap[name]; - } else { - console.warn(`Document ${doctype} ${name} does not exist`); + getFromCache(schemaName: string, name: string): Doc | undefined { + const docMap = this.docs[schemaName] as DocMap | undefined; + return docMap?.[name]; + } + + getCachedValue( + schemaName: string, + name: string, + fieldname: string + ): DocValue | Doc[] | undefined { + const docMap = this.docs[schemaName] as DocMap; + const doc = docMap[name]; + if (doc === undefined) { + return; } + + return doc.get(fieldname); } - getDocFromCache(schemaName: string, name: string): Doc | undefined { + isDirty(schemaName: string, name: string): boolean { const doc = (this.docs?.[schemaName] as DocMap)?.[name]; - return doc; - } - - isDirty(doctype: string, name: string) { - const doc = (this.docs?.[doctype] as DocMap)?.[name]; if (doc === undefined) { return false; } - return !!doc._dirty; - } - - /** - * Meta Operations - */ - - getMeta(doctype: string): Meta { - const meta = this.metaCache[doctype]; - if (meta) { - return meta; - } - - const model = this.models?.[doctype]; - if (!model) { - throw new Error(`${doctype} is not a registered doctype`); - } - - this.metaCache[doctype] = new this.frappe.Meta!(model); - return this.metaCache[doctype]!; - } - - createMeta(fields: Field[]) { - return new this.frappe.Meta!({ isCustom: 1, fields }); + return doc.dirty; } /** @@ -152,73 +98,47 @@ export class DocHandler { */ async getDoc( - doctype: string, + schemaName: string, name: string, options = { skipDocumentCache: false } ) { - let doc = null; + let doc: Doc | undefined; if (!options?.skipDocumentCache) { - doc = this.getDocFromCache(doctype, name); + doc = this.getFromCache(schemaName, name); } if (doc) { return doc; } - const DocClass = this.getDocumentClass(doctype); - doc = new DocClass({ - doctype: doctype, - name: name, - }); - + doc = this.getNewDoc(schemaName, { name }); await doc.load(); this.addToCache(doc); return doc; } - getDocumentClass(doctype: string): typeof Doc { - const meta = this.getMeta(doctype); - let documentClass = this.frappe.Document!; - if (meta && meta.documentClass) { - documentClass = meta.documentClass as typeof Doc; + getModel(schemaName: string): typeof Doc { + const Model = this.models[schemaName]; + if (Model === undefined) { + return Doc; } - return documentClass; + return Model; } - async getSingle(doctype: string) { - return await this.getDoc(doctype, doctype); + async getSingle(schemaName: string) { + return await this.getDoc(schemaName, schemaName); } - async getDuplicate(doc: Doc) { - const doctype = doc.doctype as string; - const newDoc = await this.getEmptyDoc(doctype); - const meta = this.getMeta(doctype); - - const fields = meta.getValidFields() as Field[]; - - for (const field of fields) { - if (['name', 'submitted'].includes(field.fieldname)) { - continue; - } - - newDoc[field.fieldname] = doc[field.fieldname]; - if (field.fieldtype === 'Table') { - const value = (doc[field.fieldname] as DocData[]) || []; - newDoc[field.fieldname] = value.map((d) => { - const childData = Object.assign({}, d); - childData.name = ''; - return childData; - }); - } - } + async getDuplicate(doc: Doc): Promise { + const newDoc = await doc.duplicate(false); + delete newDoc.name; return newDoc; } - getEmptyDoc(doctype: string, cacheDoc: boolean = true): Doc { - const doc = this.getNewDoc({ doctype }); - doc._notInserted = true; + getEmptyDoc(schemaName: string, cacheDoc: boolean = true): Doc { + const doc = this.getNewDoc(schemaName); doc.name = getRandomString(); if (cacheDoc) { @@ -228,34 +148,33 @@ export class DocHandler { return doc; } - getNewDoc(data: DocData): Doc { - const DocClass = this.getDocumentClass(data.doctype); - const doc = new DocClass(data); + getNewDoc(schemaName: string, data: DocValueMap = {}): Doc { + const Model = this.getModel(schemaName); + const schema = this.frappe.schemaMap[schemaName]; + if (schema === undefined) { + throw new Error(`Schema not found for ${schemaName}`); + } + + const doc = new Model(schema, data); doc.setDefaults(); return doc; } - async syncDoc(data: DocData) { - let doc; - const { doctype, name } = data; - if (!doctype || !name) { + async syncDoc(schemaName: string, data: DocValueMap) { + const name = data.name as string | undefined; + if (name === undefined) { return; } - const docExists = await this.frappe.db.exists(doctype, name); - if (docExists) { - doc = await this.getDoc(doctype, name); - Object.assign(doc, data); - await doc.update(); - } else { - doc = this.getNewDoc(data); - await doc.insert(); + const docExists = await this.frappe.db.exists(schemaName, name); + if (!docExists) { + const doc = this.getNewDoc(schemaName, data); + await doc.insert; + return; } - } - getCachedValue( - schemaName: string, - name: string, - fieldname: string - ): DocValue {} + const doc = await this.getDoc(schemaName, name); + await doc.setMultiple(data); + await doc.update(); + } } diff --git a/frappe/index.ts b/frappe/index.ts index e998d74a..e490927d 100644 --- a/frappe/index.ts +++ b/frappe/index.ts @@ -1,10 +1,11 @@ import { ErrorLog } from '@/errorHandling'; -import Doc from 'frappe/model/doc'; import { getMoneyMaker, MoneyMaker } from 'pesa'; import { markRaw } from 'vue'; import { AuthHandler } from './core/authHandler'; import { DatabaseHandler } from './core/dbHandler'; import { DocHandler } from './core/docHandler'; +import { ModelMap } from './model/types'; +import coreModels from './models'; import { DEFAULT_DISPLAY_PRECISION, DEFAULT_INTERNAL_PRECISION, @@ -13,6 +14,14 @@ import * as errors from './utils/errors'; import { format } from './utils/format'; import { t, T } from './utils/translation'; +/** + * Terminology + * - Schema: object that defines shape of the data in the database + * - Model: the controller class that extends the Doc class or the Doc + * class itself. + * - Doc: instance of a Model, i.e. what has the data. + */ + export class Frappe { t = t; T = T; @@ -28,8 +37,6 @@ export class Frappe { doc: DocHandler; db: DatabaseHandler; - Doc?: typeof Doc; - _initialized: boolean = false; errorLog?: ErrorLog[]; @@ -38,8 +45,9 @@ export class Frappe { constructor() { this.auth = new AuthHandler(this); - this.doc = new DocHandler(this); this.db = new DatabaseHandler(this); + this.doc = new DocHandler(this); + this.pesa = getMoneyMaker({ currency: 'XXX', precision: DEFAULT_INTERNAL_PRECISION, @@ -60,13 +68,17 @@ export class Frappe { return this.doc.models; } - async initializeAndRegister(customModels = {}, force = false) { + get schemaMap() { + return this.db.schemaMap; + } + + async initializeAndRegister( + customModels: ModelMap = {}, + force: boolean = false + ) { await this.init(force); - this.Doc = (await import('frappe/model/doc')).default; - - const coreModels = await import('frappe/models'); - this.doc.registerModels(coreModels.default as Record); + this.doc.registerModels(coreModels as ModelMap); this.doc.registerModels(customModels); } diff --git a/frappe/model/doc.ts b/frappe/model/doc.ts index 17327e63..ddab7470 100644 --- a/frappe/model/doc.ts +++ b/frappe/model/doc.ts @@ -78,6 +78,10 @@ export default class Doc extends Observable { ) as TargetField[]; } + get dirty() { + return this._dirty; + } + _setInitialValues(data: DocValueMap) { for (const fieldname in data) { const value = data[fieldname]; @@ -222,7 +226,7 @@ export default class Doc extends Observable { } const childSchemaName = this.fieldMap[fieldname] as TargetField; - const schema = frappe.db.schemaMap[childSchemaName.target]; + const schema = frappe.db.schemaMap[childSchemaName.target] as Schema; const childDoc = new Doc(schema, data as DocValueMap); childDoc.setDefaults(); return childDoc; @@ -417,13 +421,13 @@ export default class Doc extends Observable { (this.modified as Date) !== (currentDoc.modified as Date) ) { throw new Conflict( - frappe.t`Document ${this.doctype} ${this.name} has been modified after loading` + frappe.t`Document ${this.schemaName} ${this.name} has been modified after loading` ); } if (this.submitted && !this.schema.isSubmittable) { throw new ValidationError( - frappe.t`Document type ${this.doctype} is not submittable` + frappe.t`Document type ${this.schemaName} is not submittable` ); } @@ -651,7 +655,7 @@ export default class Doc extends Observable { return frappe.doc.getCachedValue(schemaName, name, fieldname); } - async duplicate() { + async duplicate(shouldInsert: boolean = true): Promise { const updateMap: DocValueMap = {}; const docValueMap = this.getValidDict(); const fieldnames = this.schema.fields.map((f) => f.fieldname); @@ -680,7 +684,12 @@ export default class Doc extends Observable { const doc = frappe.doc.getEmptyDoc(this.schemaName, false); await doc.setMultiple(updateMap); - await doc.insert(); + + if (shouldInsert) { + await doc.insert(); + } + + return doc; } formulas: FormulaMap = {}; diff --git a/frappe/model/types.ts b/frappe/model/types.ts index ecac74cd..894905e1 100644 --- a/frappe/model/types.ts +++ b/frappe/model/types.ts @@ -27,5 +27,7 @@ export type DependsOnMap = Record /** * Should add this for hidden too - */ + +export type ModelMap = Record< string, typeof Doc | undefined> +export type DocMap = Record; \ No newline at end of file diff --git a/schemas/index.ts b/schemas/index.ts index 158279d0..ccd3c31d 100644 --- a/schemas/index.ts +++ b/schemas/index.ts @@ -31,7 +31,7 @@ function deepFreeze(schemaMap: SchemaMap) { Object.freeze(schemaMap[schemaName][key]); } - for (const field of schemaMap[schemaName].fields ?? []) { + for (const field of schemaMap[schemaName]?.fields ?? []) { Object.freeze(field); } } @@ -47,7 +47,7 @@ export function addMetaFields(schemaMap: SchemaMap): SchemaMap { const submittableTree = getCombined(tree, metaSchemaMap.submittable); for (const name in schemaMap) { - const schema = schemaMap[name]; + const schema = schemaMap[name] as Schema; if (schema.isSingle) { continue; } @@ -71,7 +71,7 @@ export function addMetaFields(schemaMap: SchemaMap): SchemaMap { function addNameField(schemaMap: SchemaMap) { for (const name in schemaMap) { - const schema = schemaMap[name]; + const schema = schemaMap[name] as Schema; if (schema.isSingle) { continue; } @@ -104,7 +104,7 @@ function getAppSchemas(countryCode: string): SchemaMap { export function cleanSchemas(schemaMap: SchemaMap): SchemaMap { for (const name in schemaMap) { - const schema = schemaMap[name]; + const schema = schemaMap[name] as Schema; if (schema.isAbstract && !schema.extends) { delete schemaMap[name]; continue; diff --git a/schemas/tests/testSchemaBuilder.spec.ts b/schemas/tests/testSchemaBuilder.spec.ts index 98e08a56..bb7dc403 100644 --- a/schemas/tests/testSchemaBuilder.spec.ts +++ b/schemas/tests/testSchemaBuilder.spec.ts @@ -86,7 +86,7 @@ describe('Schema Builder', function () { ); describe('Abstract Combined Schemas', function () { specify('Meta Properties', function () { - assert.strictEqual(abstractCombined.Customer.extends, undefined); + assert.strictEqual(abstractCombined.Customer!.extends, undefined); }); specify('Abstract Schema Existance', function () { @@ -94,11 +94,11 @@ describe('Schema Builder', function () { }); specify('Field Counts', function () { - assert.strictEqual(abstractCombined.Customer.fields?.length, 10); + assert.strictEqual(abstractCombined.Customer!.fields?.length, 10); }); specify('Quick Edit Field Counts', function () { - assert.strictEqual(abstractCombined.Customer.quickEditFields?.length, 7); + assert.strictEqual(abstractCombined.Customer!.quickEditFields?.length, 7); }); specify('Schema Equality with App Schemas', function () { @@ -127,7 +127,7 @@ describe('Schema Builder', function () { assert.strictEqual( everyFieldExists( regionalSchemaMap.Party.quickEditFields ?? [], - abstractCombined.Customer + abstractCombined.Customer! ), true ); @@ -152,14 +152,14 @@ describe('Schema Builder', function () { describe('Final Schemas', function () { specify('Schema Field Existance', function () { assert.strictEqual( - everyFieldExists(baseFieldNames, finalSchemas.Customer), + everyFieldExists(baseFieldNames, finalSchemas.Customer!), true ); assert.strictEqual( someFieldExists( subtract(allFieldNames, baseFieldNames), - finalSchemas.Customer + finalSchemas.Customer! ), false ); @@ -167,7 +167,7 @@ describe('Schema Builder', function () { assert.strictEqual( everyFieldExists( [...baseFieldNames, ...submittableFieldNames], - finalSchemas.JournalEntry + finalSchemas.JournalEntry! ), true ); @@ -175,20 +175,20 @@ describe('Schema Builder', function () { assert.strictEqual( someFieldExists( subtract(allFieldNames, baseFieldNames, submittableFieldNames), - finalSchemas.JournalEntry + finalSchemas.JournalEntry! ), false ); assert.strictEqual( - everyFieldExists(childFieldNames, finalSchemas.JournalEntryAccount), + everyFieldExists(childFieldNames, finalSchemas.JournalEntryAccount!), true ); assert.strictEqual( someFieldExists( subtract(allFieldNames, childFieldNames), - finalSchemas.JournalEntryAccount + finalSchemas.JournalEntryAccount! ), false ); @@ -196,7 +196,7 @@ describe('Schema Builder', function () { assert.strictEqual( everyFieldExists( [...treeFieldNames, ...baseFieldNames], - finalSchemas.Account + finalSchemas.Account! ), true ); @@ -204,7 +204,7 @@ describe('Schema Builder', function () { assert.strictEqual( someFieldExists( subtract(allFieldNames, treeFieldNames, baseFieldNames), - finalSchemas.Account + finalSchemas.Account! ), false ); diff --git a/schemas/types.ts b/schemas/types.ts index 5fd297c0..072f9dcd 100644 --- a/schemas/types.ts +++ b/schemas/types.ts @@ -128,5 +128,5 @@ export interface Schema { export interface SchemaStub extends Partial { name: string; } -export type SchemaMap = Record; +export type SchemaMap = Record; export type SchemaStubMap = Record;