diff --git a/src/index.ts b/src/index.ts index d36ef3f..daf22fb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -109,10 +109,13 @@ export {SchemaOutputTransformer} from './schema/output/transformer'; export {SchemaVerifyFlags} from './schema/verify/flags'; export {SchemaVerifyInit} from './schema/verify/init'; export {SchemaVerifyValue} from './schema/verify/value'; -export {simpleOutputTransform} from './transform/verified'; export {Statement} from './statement'; export {Tracer} from './tracer'; export {TracerInit} from './tracer/init'; +export {Transformed} from './transformed'; +export {transformVerified} from './transform/verified'; +export {transformVerifiedArray} from './transform/verified/array'; +export {transformVerifiedField} from './transform/verified/field'; export {valueTypeLabel} from './value/type/label'; export {Verified} from './verified'; export {VerifiedArray} from './verified/array'; @@ -133,5 +136,3 @@ export {verifyBigInt} from './verify/big/int'; export {verifyBoolean} from './verify/boolean'; export {verifyStringId} from './verify/string/id'; export {verifyUrl} from './verify/url'; -export {transformVerifiedArray} from './transform/verified/array'; -export {transformVerifiedMap} from './transform/verified/map'; diff --git a/src/transform/verified.ts b/src/transform/verified.ts index 678845e..f2cc3a2 100644 --- a/src/transform/verified.ts +++ b/src/transform/verified.ts @@ -26,9 +26,9 @@ import {Fate} from '@toreda/fate'; import {Log} from '@toreda/log'; import {schemaError} from '../schema/error'; -import {type Verified} from '../verified'; import {type VerifiedMap} from '../verified/map'; -import {type VerifiedArray} from '../verified/array'; +import {Transformed} from '../transformed'; +import {transformVerifiedField} from './verified/field'; /** * Default transformer when one isn't provided to a schema. Expects a @@ -38,8 +38,8 @@ import {type VerifiedArray} from '../verified/array'; * * @category Schema – Transform Output */ -export async function transformVerified( - input: DataT | VerifiedMap | VerifiedArray, +export async function transformVerified( + input: VerifiedMap, base: Log ): Promise> { const fate = new Fate(); @@ -55,26 +55,16 @@ export async function transformVerified( } try { - const verified: Verified = {}; + const transformed: Transformed = {}; for (const [id, field] of input) { - if (Array.isArray(field)) { - verified[id] = []; - for (const item of field) { - } + const result = await transformVerifiedField(id, field, log); + if (result.ok()) { + transformed[id] = result.data; } else { - if (field instanceof Map) { - const result = await transformVerified(field, base); - if (result.ok()) { - verified[id] = result.data; - } else { - log.error(`Error in schema output transform ${id}: ${result.errorCode()}`); - verified[id] = null; - // TODO: Need tracer here for detailed path info. - } - } else { - verified[id] = field; - } + log.error(`Error in schema output transform ${id}: ${result.errorCode()}`); + fate.setErrorCode(result.errorCode()); + break; } } @@ -84,7 +74,7 @@ export async function transformVerified( return fate; } - fate.data = verified as TransformedT; + fate.data = transformed as TransformedT; fate.setSuccess(true); } catch (e: unknown) { diff --git a/src/transform/verified/array.ts b/src/transform/verified/array.ts deleted file mode 100644 index 3a47cc8..0000000 --- a/src/transform/verified/array.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {Fate} from '@toreda/fate'; -import {type VerifiedArray} from '../../verified/array'; - -export async function transformVerifiedArray( - input: VerifiedArray -): Promise> { - const fate = new Fate({ - data: [] - }); - - return fate; -} diff --git a/src/transform/verified/field.ts b/src/transform/verified/field.ts index d77bf07..5048ddf 100644 --- a/src/transform/verified/field.ts +++ b/src/transform/verified/field.ts @@ -1,25 +1,83 @@ +/** + * MIT License + * + * Copyright (c) 2019 - 2024 Toreda, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + import {Fate} from '@toreda/fate'; import {type VerifiedMap} from '../../verified/map'; import {type VerifiedArray} from '../../verified/array'; +import {type Transformed} from '../../transformed'; +import {Log} from '@toreda/log'; -export async function transformVerifiedField( +/** + * Default transformer when one isn't provided to a schema. Expects a + * string -> primitive map and produces a simple object of the same mapping. + * @param id + * @param data + * @param base + * + * @category Schema – Transform Output + */ +export async function transformVerifiedField( id: string, - data: DataT | VerifiedMap | VerifiedArray + data: DataT | VerifiedMap | VerifiedArray, + base: Log ): Promise> { - const fate = new Fate(); + const fate = new Fate(); + const log = base.makeLog(`${id}`); if (Array.isArray(data)) { - fate.data = []; + const results: TransformedT[] = []; for (const item of data) { - const result = await transformVerifiedField('xxxx', item); + const result = await transformVerifiedField('xxxx', item, log); if (result.ok()) { - fate.data.push(result.data); + results.push(result.data as any); } else { + log.error(`Error in schema output transform ${id}: ${result.errorCode()}`); + fate.setErrorCode(result.errorCode()); + break; } } + fate.data = results; } else if (data instanceof Map) { + const transformed = {} as Transformed; for (const [id, field] of data) { + const result = await transformVerifiedField(id, field, log); + if (result.ok()) { + transformed[id] = result.data; + } else { + transformed[id] = null; + } } + + fate.data = transformed as TransformedT; + } else { + // HACK: Should not rely on any. Defeats the purpose of type checking. + fate.data = data as any; + } + + if (!fate.errorCode()) { + fate.setSuccess(true); } return fate; diff --git a/src/transformed.ts b/src/transformed.ts new file mode 100644 index 0000000..6940653 --- /dev/null +++ b/src/transformed.ts @@ -0,0 +1,31 @@ +/** + * MIT License + * + * Copyright (c) 2019 - 2024 Toreda, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +/** + * @category Schema + */ +export interface Transformed { + [k: string]: unknown; +} diff --git a/tests/schema/recursive.spec.ts b/tests/schema/recursive.spec.ts index 9370596..90cc99a 100644 --- a/tests/schema/recursive.spec.ts +++ b/tests/schema/recursive.spec.ts @@ -204,15 +204,15 @@ describe('Schema - Recursive Parsing', () => { expect(result.data?.subSchemas).toHaveLength(2); const resultSubA = result.data?.subSchemas![0]; - expect(resultSubA).toEqual({}); const resultSubB = result.data?.subSchemas![1]; + expect(resultSubB).toBeDefined(); expect(resultSubA?.int2b).toBe(intSample1); expect(resultSubA?.str2b).toBe(strSample1); - expect(resultSubB?.int2b).toBe(intSample1); - expect(resultSubB?.str2b).toBe(strSample1); + expect(resultSubB?.int2b).toBe(intSample2); + expect(resultSubB?.str2b).toBe(strSample2); }); }); });