nobrainr / morphism Goto Github PK
View Code? Open in Web Editor NEW⚡ Type-safe data transformer for JavaScript, TypeScript & Node.js.
Home Page: https://morphism-playground.now.sh/
License: MIT License
⚡ Type-safe data transformer for JavaScript, TypeScript & Node.js.
Home Page: https://morphism-playground.now.sh/
License: MIT License
Hi,
My destination argument passed to the schema, i can't be certain its an actual object, it could be undefined - it comes from a rest endpoint.
When i try to map it, it doesn't map anything. I am sure doing something wrong
getUserProfileExistsSchema(): Schema<UserProfileExistsDto, Responses.UserProfileResponse|undefined> {
const schema: Schema<UserProfileExistsDto, Responses.UserProfileResponse| undefined> = {
value: source => source?.backgroundColor !== undefined && source?.phrase !== undefined,
correlationId: () => this.correlationService.getCorrelationId()
}
return schema
}
The above is my schema on a method - the "source" could be undefined, i am using the safe navigation operator (?) - this is not the issue as i tested it.. In fact i am using the safe navigation operator throughout my code-base now :-)
Notice I am passing a union type for the source "Responses.UserProfileResponse | undefined"
Then to map i do the following
morphism.map(this.userProfileResponseSchema.getUserProfileExistsSchema(), userProfile)
if i pass userProfile as undefined, I get an empty object back.
What is the correct way of support this kind of functionality?
Thanks in advance
If I have a definition such as:
interface Grade = {
level: 'A'|'B'|'C'
note?: string
}
interface Student = {
name: string
grade?: Grade
}
interface StudentDocument = {
name: string,
grade_data?: {
level: 'A'|'B'|'C'
note?: string
}
}
const gradeSchema: StrictSchema<Grade> = {
level: 'level',
note: 'note'
}
const studentSchema: StrictSchema<Student, StudentDocument> = {
name: 'name',
grade: ({ grade_data }: any) => morphism(gradeSchema, grade_data),
}
Then the following function call will give:
morphism(studentSchema, { name: 'John Doe' })
{ name: 'John Doe',
grade: [Function] }
I can wrap this in something like:
grade: ({ grade_data }: any) => grade_data ? morphism(gradeSchema, grade_data) : null
However it would be nice if the morphism never resulted in a function even with missing values. What is the strategy when working with optional values?
The documentation is clear about how to grab a piece of data from a nested object. But what if you need the opposite: to construct a nested object from a piece of data?
interface source {
id: string;
}
interface target {
foo: {
id: string
}
}
I know I can use the function technique like this:
createSchema<target, source>({
foo: (i) => ({id: i.id}),
}
I'm wondering if there is a way to do this with a simple string argument though (which I, maybe falsely, assume to be faster)?
Hi,
I have noticed there is 2 ways of creating a strictSchema, I was wondering what the difference is ?
export const groupPackageSchema = createSchema<GraphQL.GroupPackage, Responses.IGroupRoot>({
groups: iteratee => morphism(groupSchema, iteratee._embedded.groups),
pageInfo: morphism(pageInfoSchema)
})
export const groupPackageSchema: StrictSchema<GraphQL.GroupPackage, Responses.IGroupRoot> = {
groups: iteratee => morphism(groupSchema, iteratee._embedded.groups),
pageInfo: morphism(pageInfoSchema)
}
I didn't see anything specific in the docs with regards to why we should use createSchema ?
Thanks in advance
// What we have
class Source {
public id!: number;
public ugly_field!: string;
}
// What we want
class Destination {
public id?: number;
public field!: string;
}
const source: Source = {
id: 1,
ugly_field: "field value",
};
const schema = { field: "ugly_field" };
const result = morphism<StrictSchema<Destination, Source>>(schema, source);
const h = result.constructor.name;
console.log(h);
Output
Object
{"field":"field value"}
To obtain the Destination object must use the plain schema and use Destination has last parameter on morphism
const result = morphism(schema, source, Destination);
Output
Destination
{"field":"field value"}
Last time, I was thinking about adding more real use cases to the documentation. According to npm, there is a certain amount of downloads, I was wondering how and for what do you use Morphism
Please share you usage or any relevant public link.
example: #33 (comment)
Hello,
I've been doing analysis of our Angular bundles and I found out that Morphism brings Lodash dependency. It results in increase of package bundle, because it is pulling whole Lodash package (cca 500KB).
Is it possible to get rid of lodash, or at least optimize it for tree-shaking?
Thanks,
Lukas
I just copied this example :
// What we have
interface Source {
ugly_field: string;
}
// What we want
interface Destination {
field: string;
}
const source: Source = {
ugly_field: 'field value'
};
// Destination and Source types are optional
morphism<Destination, Source>({ field: 'ugly_field' }, source);
// => {field: "field value"}
// Or
const sources = [source];
const schema: StrictSchema<Destination, Source> = { field: 'ugly_field' };
morphism<Destination, Source>(schema, sources);
// => [{field: "field value"}]
And I got the following error when applying morphism which is suppose to return an array :
Argument of type 'StrictSchema<Destination, Source>' is not assignable to parameter of type 'Destination'.
Types of property 'field' are incompatible.
Type 'string | string[] | ActionFunction<Destination, Source, string> | "ugly_field"[] | ActionSelector<Source, string>' is not assignable to type 'string'.
Type 'string[]' is not assignable to type 'string'.ts(2345)
Any tips on how to solve this problem ?
Is your feature request related to a problem? Please describe.
I'm trying to map a nested JSON object which I don't know what the possible attributes could be, there may be 1 or 20 in there with different keys/names.
For example if my source is:
{
"name": "test",
"stores": {
"gb": 123,
"de": 7126
}
}
Where there could be a number of possible "stores" and I want to re-map them and prefix a string to the key. So my target would be something like:
{
"name": "test",
"ids": {
"store_gb": 123,
"store_de": 7126,
}
}
Describe the solution you'd like
I'd like a dynamic way to iterate of each key/value pair in the object & then modify the key name so that it is mapped
Actually, this does not work because Morphism
does not apply the predicate function on the result from the aggregation.
Solution: Enable to apply the predicate fn
when an Array is given as a path to aggregate.
let data = {a:1 , b: { c: 2 }};
let rules = {
ac: {
path: ['a','b.c'],
fn: aggregate => {
expect(aggregate).to.eq({ a:1, b: {c:2} }); // but get aggregate 'undefined' instead
}
}
};
let res = morphism(rules, [data]);
I have made a simple repl.
On the console you can see that the output is an {Object} and not the {Destination} class.
Same output with webpack + babel
Hi,
I wonder if you can help, i am using an excellent mocking library here https://github.com/NagRock/ts-mockito
I have managed to spy on real objects for example fs, process etc .. without any issues but get an error here
on my test i do
import * as morphism from "morphism"
but i get cannot redefine morph
Any ideas what it could be ?
Hey,
Let's say this is the input :
{
a: {
b: 'c',
d: 'e',
},
f: {
b: 'f',
d: 'g',
}
}
Is it possible to transform this into :
{
k: [{
b: 'c'
}, {
b: 'f'
}]
}
I tried with this :
const firstSchema = {
b: 'b',
};
const secondSchema = {
k: {
path: ['a', 'f'],
fn: (data) => morphism(firstSchema, data),
},
};
I get this :
{
"k": {
"b": "c"
}
}
Thanks,
Describe the bug
It seems to be impossible to change types on the target schema. The value assumes the same type as the source.
To Reproduce
import { StrictSchema } from 'morphism'
interface SchemaSource {
foo: string
}
interface SchemaTarget {
foo: number
}
const schema: StrictSchema<SchemaTarget, SchemaSource> = {
foo: {
path: 'foo',
fn: (val) => {
return Number(val)
}
}
}
Expected behavior
Allow changing type on the target schema.
Screenshots
(property) foo: string | string[] | ((iteratee: SchemaSource, source: SchemaSource[], target: number) => number) | "foo"[] | ActionSelector<SchemaSource, SchemaTarget> | StrictSchema<...>
Type '{ path: string; fn: (val: any) => number; }' is not assignable to type 'string | string[] | ((iteratee: SchemaSource, source: SchemaSource[], target: number) => number) | "foo"[] | ActionSelector<SchemaSource, SchemaTarget> | StrictSchema<...>'.
Type '{ path: string; fn: (val: any) => number; }' is not assignable to type 'string'.ts(2322)
Untitled-1(8, 3): The expected type comes from property 'foo' which is declared here on type 'StrictSchema<SchemaTarget, SchemaSource>'
Additional context
❯ tsc -v
Version 3.6.4
"morphism": "1.12.2",
Hi!
I was wondering... does it work just for the browser, how we should use/require it in node?
Thanks!
Hi,
I wonder if you can help.
I have a Array of items but wish to return it flattened into items:, but it runs it multiple times.. I have placed a stackblitz at the end. I think I need to flatten but i didn't see an example.
The demo recreates what I am trying to do in production
// I get the following
/*
[
{
"items":{
"id":"123",
"name":"CompanyA"
}
},
{
"items":{
"id":"456",
"name":"CompanyB"
}
},
{
"items":{
"id":"2424",
"name":"CompanyC"
}
},
{
"items":{
"id":"111",
"name":"CompanyD"
}
}
]
*/
// but expect
/*
{
"items":[
{
"id":"123",
"name":"CompanyA"
},
{
"id":"456",
"name":"CompanyB"
},
{
"id":"2424",
"name":"CompanyC"
},
{
"id":"111",
"name":"CompanyD"
}
]
}
*/
I have created a stackblitz here that shows the issue
https://stackblitz.com/edit/morphism-single-source-to-complex-destination-1xms6b
Any ideas what I am doing wrong ?
If it helps, i am using Typescript but I doubt it makes a difference ?
Hi,
I have successfully managed to do a standard mapping with some help from here, thank you.
So my destination object is like so, the keygroups property is actuall an Array of keyGroup.
export type KeyGroupPackage = {
keyGroups?: Maybe<Array<Maybe<KeyGroup>>>;
pageInfo?: Maybe<PageInfo>;
};
I have the paginfo working, its just doing standard property matching - so no problems there. ( i placed the code below) But I can't get the array mapping to an array. My main schema that I run the morph
Here is my main command, to start the conversion.
morphism(keyGroupSchema, data)
export const packageSchema = createSchema<GraphQL.KeyGroupPackage, Responses.IKeyGroupRoot>({
keyGroups: morphism(keygroupSchema), /// THIS IS A PROBLEM.
pageInfo: morphism(paginationSchema)
})
The pageInfo works perfectly, I am placing the code below for the schema. But the keygroups does not. The keygroups is defined as an array on both source and destination.
I tried the following for the keygroup schema, which is defined above as morphism(keygroupSchema)
const keygroupSchema: StrictSchema<GraphQL.KeyGroup, Responses.IKeyGroup> = {
keyGroupId: "dddd"
}
The problem being is that both on the source and destination, the keygroups property is actually an array of keygroup.
An keygroup is like so
export type KeyGroup = {
keyGroupId: string;
name?: string;
}
I was hoping to use the interatee like below, but its expecting an array - so it doesn't work.
Pagination schema - works great :-)
const paginationSchema: StrictSchema<GraphQL.PageInfo, Responses.IKeyGroupRoot> = {
total: iteratee => iteratee.page.totalElements,
totalPages: iteratee => iteratee.page.totalPages,
page: iteratee => {
if (!isUndefined(iteratee.page.number)) {
return iteratee.page.number + 1
}
return 1
},
pageSize: iteratee => iteratee.page.size,
hasNextPage: iteratee => {
if (!isUndefined(iteratee.page.number) && !isUndefined(iteratee.page.totalPages)) {
return iteratee.page.number < iteratee.page.totalPages
}
return false
},
hasPreviousPage: iteratee => {
if (!isUndefined(iteratee.page.number)) {
return iteratee.page.number > 1
}
return false
}
}
Describe the bug
When using morphism inside the function with generic types - it could not assign SourceType to SourceFromSchema<StrictSchema<D, SourceType>>
To Reproduce
Steps to reproduce the behavior:
Just run this file with ts-node
locally. Also I commented specific error inside tranformWithGenerics
function
import {createSchema, morphism, StrictSchema} from 'morphism';
interface Target {
target: string;
}
interface Source {
source: string;
}
const source: Source = {
source: '123',
};
const map = {
target: 'source',
};
const schema = createSchema<Target, Source>(map);
const transformed = morphism(schema, source);
console.log('transformed:', transformed);
function transform(document: Source, m: StrictSchema<Target, Source>): Target {
return morphism(m, document);
}
const transformedWithFunction = transform(source, map);
console.log('transformedWithFunction:', transformedWithFunction);
function transformWithGenerics<T, S>(document: S, m: StrictSchema<T, S>): T {
return morphism(m, document);
// above line shows error:
// Overload 2 of 6, '(schema: StrictSchema<T, S>, data: SourceFromSchema<StrictSchema<T, S>>): DestinationFromSchema<StrictSchema<T, S>>', gave the following error.
// Argument of type 'S' is not assignable to parameter of type 'SourceFromSchema<StrictSchema<T, S>>'.
}
const transformedWithGenerics = transformWithGenerics<Target, Source>(source, map);
console.log('transformedWithGenerics:', transformedWithGenerics);
Expected behavior
I would expect it to properly work with generics, or am I missing something here?
Desktop (please complete the following information):
9.0.0
3.8.3
Is your feature request related to a problem? Please describe.
Morphism is unable to resolve promises in ActionFunction and ActionSelector and Type Promise is not allowed.
Describe the solution you'd like
Allow ActionFunction and ActionSelector to return a Promise that would later be resolvable by say a morphismasync method.
Example Schema
// Schema type removed to allow for group to be of type promise
const customerSchema = {
firstname: "firstname",
lastname: "lastname",
email: "email",
group: {
path: "group",
fn: async value => {
const res = await callSomeService(value);
return res.data;
}
}
};
Describe alternatives you've considered
Alternative solutions would be to map the data available with one morphism call then make any async requests desired then remap the data returned from those async requests.
Another solution would be to add a helper function like so.
async function resolvePromises(objectFromMorph) {
for (const key of Object.keys(objectFromMorph)) {
const value = objectFromMorph[key];
if (Promise.resolve(value) == value) {
console.log("Found Promise", value);
objectFromMorph[key] = await value;
}
}
return objectFromMorph;
}
const morphed = morphism(customerSchema, customer.data);
const customer = resolvePromises(morphed);
{
"sourceCustomerId": 39392,
"firstname": "somefirstname",
"lastname": "somelastname",
"email": "[email protected]",
"group": "Promise { <pending> }"
}
// After resolvePromises
{
"sourceCustomerId": 39392,
"firstname": "somefirstname",
"lastname": "somelastname",
"email": "[email protected]",
"group": "somegroup"
}
Additional context
Ideal implementation
const morphed = morphism(customerSchema, customer.data)
Current result, with unresolved promise
{
"firstname": "somefirstname",
"lastname": "somelastname",
"email": "[email protected]",
"group": "Promise { <pending> }"
}
Ideal result, with resolved promise
{
"firstname": "somefirstname",
"lastname": "somelastname",
"email": "[email protected]",
"group": "somegroup"
}
Provide a post processing step to remove some specific keys (like checking for null values). There is already the possibility to do it on undefined values, e.g: #52 (comment). The idea would be to extend this behaviour to any custom values.
See #35 (comment) as another suggestion
15.6.0
to 15.6.1
.This version is covered by your current version range and after updating it in your project the build failed.
now is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
The new version differs by 6 commits.
b22b378
15.6.1
e700ad7
Make sure to call secrets API only once (#2464)
85ccf59
Handle deployments rate limit (#2463)
094277c
Upgrade esm (#2458)
e5c7e2d
Handle cert errors in create-deployment (#2455)
3ee7bab
Prompt based DNS add command (#2450)
See the full diff
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
I am trying to implement morphism/DTO mapping concept in typescript.
I am trying to do source to destination mapping of a complex type object (i.e an object containing another object and arrays of object) in generic way using StrictSchema of morphism.
my interface is :
interface IFoo {
keyA: {
key1: number,
key2: number,
key3: [
{
key3A: string,
key3B: number
}
],
key4: string
},
keyB: string,
keyC: number,
keyD: {
key1: string,
key2: {
key2A: string
},
key3: string
},
keyE: string
}
const schema: StrictSchema<IFoo> =
{ keyA: {
key1: 'somepath',
key2: 'somepath',
key3: [
{
key3A: 'somepath',
key3B: 'somepath'
}
],
key4: 'somepath'
},
keyB: 'somepath',
keyC: 'somepath',
keyD: {
key1: 'somepath',
key2: {
key2A: 'somepath'
},
key3: 'somepath'
},
keyE: 'somepath'
};
const target = morphism(schema, someSourceObject);
Here, schema is the object-preserving map for my interface. I have added 'somepath' as a value for each key and I will replace this with some actual path from the actual source object.
but while doing so I am getting:
Error : The expected type comes from property 'keyA' which is declared here on type 'StrictSchema<IFoo, any>
So, First of all, can I preserve mapping in above scenarieo using morphism because I have not come accross any such examples using 'ScrictSchema'. If yes, then how?
Hi,
I'm trying to use the library to map the below source to a flat version
Source
{
"id": "2",
"type": "plan",
"name": "silver",
"pricings": [
{
"amount": {
"currency": "cad",
"value": 5.99
},
"interval": {
"type": 1,
"duration": 30
}
},
{
"amount": {
"currency": "cad",
"value": 9.99
},
"interval": {
"type": 2,
"duration": 90
}
}
]
}
Target
{
"id": "2",
"name": "silver",
"amount": {
"currency": "cad",
"value": 5.99
},
"interval": {
"type": 1,
"duration": 30
}
},
{
"id": "2",
"name": "silver",
"amount": {
"currency": "cad",
"value": 9.99
},
"interval": {
"type": 2,
"duration": 90
}
}
To achieve the above i'm using flatMap
function. I tried couple of ways using StrictSchema
const result = plans.flatMap(x => {
const plan = {
id: x.id,
name: x.name
}
return x.pricings.map(p => <Plan>{
...plan,
amount: p.amount,
interval: p.interval
});
});
Also, many times I need to do reverse mapping i.e. from Target to Source and for that I use reduce
function
As I'm planning to deprecate this feature in the version 2 of Morphism
, I was curious about the frequency of usage of this feature, and wether deprecating it would annoy more people than I would have thought of :)
undefined
branch failed. 🚨I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.
You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this 💪.
Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.
Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the undefined
branch. You can also manually restart the failed CI job that runs semantic-release.
If you are not sure how to resolve this, here is some links that can help you:
If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.
1.12.1
on branch next
cannot be published as it is out of range.Based on the releases published on other branches, only versions within the range >=2.0.0
can be published from branch next
.
The following commits are responsible for the invalid release:
Those commits should be moved to a valid branch with git merge or git cherry-pick and removed from branch next
with git revert or git reset.
A valid branch could be master
or next
.
See the workflow configuration documentation for more details.
Good luck with your project ✨
Your semantic-release bot 📦🚀
Unfortunately I can't find the answer I'm looking for in the documentation. Is there a way how I can map an array of objects like the example below? What must the scheme look like?
const object = {
persons: [
{
id: 1
name: "User 1"
},
{
id: 2
name: "User 2"
}
],
data: {
authors: [
{
id: 1
name: "User 1"
},
{
id: 2
name: "User 2"
}
],
}
};
const schema = {
};
morphism(schema, object);
I was trying to figure out if there is a way to get an equal object except for, let's say, only one property that I want to map, without having to explicitly write every property.
Thanks!
Planning a v2.0.0
for Morphism with those changes:
Tag Morphism Registry as deprecated (not so used?). Will be removed in v3
.
Runtime checks as https://github.com/gcanti/io-ts #84
Typescript support for nested paths https://github.com/bsalex/typed-path (#53)
Remove string dot notation access and replace with an array, better support for TypeScript
ActionAggregator
from schema support Provide a post processing step to remove some specfic keys (like checking for null
values). #85
DataViz for Schemas, per #47 (comment)
IE Support: #130
Please share any ideas or suggestions you would find valuable for a next version :)
master
branch failed. 🚨I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.
You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this 💪.
Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.
Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master
branch. You can also manually restart the failed CI job that runs semantic-release.
If you are not sure how to resolve this, here is some links that can help you:
If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.
An npm token must be created and set in the NPM_TOKEN
environment variable on your CI environment.
Please make sure to create an npm token and to set it in the NPM_TOKEN
environment variable on your CI environment. The token must allow to publish to the registry https://registry.npmjs.org/
.
Good luck with your project ✨
Your semantic-release bot 📦🚀
When using Register
with an invalid schema, exceptions are not thrown
Add defensive on Register
method when schema isNil=> throw new Error(`The schema must be an Object. Found ${schema}`);
Hello, I wanted to use your library but after install I've hit this issue:
import Morphism from 'morphism';
Could not find a declaration file for module 'morphism'. 'C:/project/node_modules/morphism/dist/morphism.js' implicitly has an 'any' type.
Try `npm install @types/morphism` if it exists or add a new declaration (.d.ts) file containing `declare module 'morphism';`
I was able to fix this issue with declare module 'morphism'
, but wouldn't be better solution to provide TypeScript declarations (typings?) directly inside package?
Best regards,
Lukas
morphism ^1.10.1
import Morphism, { morphism, StrictSchema } from "morphism";
// What we have
class Source {
public id!: number;
public ugly_field!: string;
}
// What we want
class Destination {
public id?: number;
public field!: string;
}
const source: Source = {
id: 1,
ugly_field: "field value"
};
const schema = { field: "ugly_field" };
const s: StrictSchema<Destination, Source> = schema;
Morphism.register(Destination, s);
const result = Morphism.map(Destination, source);
expect(result.id).toBeUndefined();
result.id === 1
When the target type is certain combinations of union types, I think when the unions share a property, the type of the ActionFunction breaks and no longer knows the types of the parameters.
** Reproduce **
const test = createSchema<{a:string} | {a:string; b:string},{c:string}>({
a: it => {} // Parameter 'it' implicitly has 'any' type
b: it => {} // here 'it' is the correct type
})
As you can see, it
should be of type {c:string}
, for the first property, but it is not. The other parameters are also any. If you remove a
from the second type, it works as expected.
Describe the bug
I'm trying to get a typed array, but typescript is warning when I specifying the destination type class on morphism(schema, source, Destination)
.
The error description:
Argument of type 'Destination[]' is not assignable to parameter of type 'Source'.
Type 'Destination[]' is missing the following properties from type 'Source': id, ugly_fieldts(2345)
Additional context
Environment: Nodejs
Ts version: 3.5.3
Screenshot code:
import { StrictSchema, morphism } from 'morphism';
class Source {
public id: number;
public ugly_field: string;
}
class Destination {
constructor(public id: number, public field: string) {}
}
const source = [new Destination(1, 'abc'), new Destination(1, 'def')];
const schema: StrictSchema<Destination, Source> = {
id: 'id',
field: 'ugly_field',
};
const result = morphism(schema, source, Destination);
Is there a way to unamp i.e. Morphism Object -> JSON String based on the schema ?
Can seem to mock the named export morphism
in my tests.
import { morphism } from 'morphism'
morphism = jest.fn()
This throws '"morphism" is read-only'
I want to be able to spy on morphism, to make sure function is being called.
Hello,
right now Schema
type is defined as:
export interface Schema {
/** `destinationProperty` is the name of the property of the target object you want to produce */
[destinationProperty: string]: ActionString | ActionFunction | ActionAggregator | ActionSelector;
}
What do you think about changing it to:
export interface Schema<Target> {
/** `destinationProperty` is the name of the property of the target object you want to produce */
[destinationProperty in keyof Target]: ActionString | ActionFunction | ActionAggregator | ActionSelector;
}
It will enforce you to map all fields in the target type, so you won't miss any of them by mistake.
I'm struggling to figure out how to understand morphism, possibly because I'm coming from AutoMapper.
For example, here's a simple AutoMapper configuration:
CreateMap<Setting, CreateOrUpdateSettingDto>();
CreateMap<CreateOrUpdateSettingDto, Setting>()
.ForMember(p => p.CreatedOn, p => p.Ignore())
.ForMember(p => p.ModifiedOn, p => p.Ignore())
.ForMember(p => p.CreatedBy, p => p.Ignore())
.ForMember(p => p.Version, p => p.Ignore())
.ForMember(p => p.ModifiedBy, p => p.Ignore())
.ForMember(p => p.Id, p => p.Ignore());
CreateMap<Setting, SettingDto>();
With that, I can easily map a Setting
to a CreateOrUpdateSettingDto
, a CreateOrUpdateSettingDto
to a Setting
, and a Setting
to a SettingDto
.
If I want to create a new object from another, it's as simple as:
var newSetting = _mapper.Map<Setting>(someCreateOrUpdateSettingDto);
Or I can map an existing object on top of another object:
_mapper.Map(someCreateOrUpdateSettingDto, someSetting);
Does morphism do the same thing? If so, can you help translate what I do in C# to morphism? The schema stuff is a little confusing to me.
Thanks!
I want to morph all items of an array to class objects using this package. The problem is that all generated class objects are the same: they all use the values of the last array item. I tried a couple of ways, but none seem to work. The only option that seems to work is resetting the mapper each time an item will be morphed.
Does anyone know what causes this issue or how it can be fixed?
class User {
constructor(firstName, lastName, phoneNumber) {
this.firstName = firstName;
this.lastName = lastName;
this.phoneNumber = phoneNumber;
this.city = null;
}
}
// Data source you want to map
const data = [{
firstName: 'John',
lastName: 'Smith',
address:
{
city: 'New York',
country: 'USA'
},
phoneNumber:
[
{
type: 'home',
number: '212 555-1234',
},
{
type: 'fax',
number: '646 555-4567',
},
],
},
{
firstName: 'James',
lastName: 'Bond',
address:
{
city: 'New York',
country: 'USA'
},
phoneNumber:
[
{
type: 'home',
number: '212 555-1234',
},
{
type: 'fax',
number: '646 555-4567',
},
],
}];
import Morphism from 'morphism';
const schema = {
city: 'adress.city',
phoneNumber: object => object.phoneNumber.filter(c => c.type === 'home')[0].number,
};
const mapUser = Morphism.register(User, schema);
console.log(Morphism.map(User, data));
// both objects have the values from last data object --> not correct!
console.log(mapUser(data));
// same problem
console.log(data.map(item => Morphism.map(User, item)));
// same problem
console.log(data.map((item) => { Morphism.setMapper(User, schema); return Morphism.map(User, item); }));
// this works correctly
Hi,
I have a json object, its not complex but what I want to end up, is a little difficult for me to understand how to do this. The standard JSON object (represented by a typescript interface) is this
{
"_embedded": {
"record": {
"name": "CompanyA",
"meta": {
"address": "6 some street",
"stateCountry: "NY, USA"
}
}
},
"pageData": {
"pagination" : {
"page": 1,
"totalPages": 1
}
}
}
I want to end up with the following, represented by a typescript class
export class Item {
name: string // this comes from __embedded/record/name
address: string // this comes from __embedded/record/meta/address
state: string // this comes from __embedded/meta/stateCountry (split by coma, FIRST part)
country: string // this comes from __embedded/meta/stateCountry (split by coma, SECOND part)
pagination : Pagination
}
export class Pagination {
page: number //this comes from __embedded/pageData/pagination/page
totalPages: number //this comes from __embedded/pageData/pagination/totalPages
hasNext: boolean // this uses the above 2 properties to work out if there is a nextPage, true/false
}
Any help really appreciated
Thanks
Question
I have been messing around with morphism for the past few weeks and thus far it has been a delight to use!
While using it to morph a array of object I encountered a scenario where I would like to remove a object from the array. Is this possible to do in a schema ?
Information
Schema
createSchema({
sku: orderItem => {
if (/* This sku looks good return it */) {
return orderItem.sku;
} else if (/** This sku is bad */) {
// we should remove this object
} else {
// Something else
}
},
// other data
});
Data
[
{
sku: 'goodsku',
// other data
},
{
sku: 'badsku'
// other data
}
]
Current Result
We set the value of sku to something like null and then loop through the array and remove all object that contain a sku: null
Current Result Data
[
{
sku: 'goodsku',
// other data
},
{
sku: 'null'
// other data
}
]
Ideal Result
Perhaps export a enum from morphism that signals this object should be removed. Perhaps this could be apart of #85?
Ideal Result Data
[
{
sku: 'goodsku',
// other data
}
]
Version
morphism: 1.12.0
How should I transform my const source.media
:
[
{
"type": "question",
"outlineIndex": 1
},
{
"type": "video",
"outlineIndex": 2
}
]
into:
"slides": [
{
"id": 1,
"template": "question",
},
{
"id": 2,
"template": "video",
}
]
I have been trying with (no luck):
const schema = {
code: "id",
name: "content.title",
groups: [
{
id: () => "scb",
name: () => "SCB",
description: () => "SCB Group",
slides: ({ media }) => (
{
id: media.outlineIndex
}
)
}
]
};
Thanks!
Describe the bug
In IE 11 file morphism.js throws "Invalid syntax (1,1715)"
To Reproduce
Steps to reproduce the behavior:
<script src="https://unpkg.com/morphism/dist/morphism.js"></script>
Expected behavior
Work like in other browsers
Additional context
If possible could you specify at least polyfills that are required for this library? I found out that its used: Promise, Map
Many thanks
Hi, I'm sorry if this has been explained somewhere, but I could not find it. I am in desperate need of a merge method for copying all the properties to destination and for the ones that are present in the schema, the mappings are applied.
In summary:
Copy properties from the source object to destination object by following the mapping defined by map object and you can have all the source objects, even if no mapping has been defined.
For example:
const source = {
_firstName: 'Mirza',
lastName:'Ta'
};
const schema = {
name: '_firstName'
};
morphism.merge(schema, source);
➡
{
"name": "Mirza",
lastName:'Ta'
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.