Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JNG-5921 fix identifier issues #80

Merged
merged 1 commit into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
/**
* Utility Interface to use in places where we are not interested in a Stored object's data, only
* it's `__signedIdentifier`.
* Utility interface used for
* - mapped elements received from the backend
* - ui unmapped element discrimination which is mandatory in case an element is inside an iterable visual element such as tables.
*/
export interface JudoIdentifiable<T> {
export interface JudoTechnicalIdentifiable {
__identifier?: string;
}

/**
* Utility Interface to use in places where we are not interested in a Stored object's data, only
* it's `__signedIdentifier`. This identifier may change on the backend based on what operations are triggered on it,
* or it's containing parent.
*/
export interface JudoIdentifiable<T> extends JudoTechnicalIdentifiable {
__signedIdentifier: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ export interface SerializerUtil {
}

export interface Serializer<T> {
serialize(instance: T, cleanup?: boolean): any;
serialize(instance: T): any;
deserialize(data: any): T;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { type JudoStored } from './JudoStored';

export const draftIdentifierPrefix = 'draft:';

export const applyStoredMembers = (result: JudoStored<any>, instance: JudoStored<any>, cleanup = false): void => {
export const applyStoredMembers = (result: JudoStored<any>, instance: JudoStored<any>): void => {
if (typeof instance.__deleteable === 'boolean') {
result.__deleteable = instance.__deleteable;
}
Expand All @@ -18,7 +18,7 @@ export const applyStoredMembers = (result: JudoStored<any>, instance: JudoStored
if (typeof instance.__entityType === 'string') {
result.__entityType = instance.__entityType;
}
if (typeof instance.__identifier === 'string' && (!cleanup || !instance.__identifier.startsWith(draftIdentifierPrefix))) {
if (typeof instance.__identifier === 'string' && !instance.__identifier.startsWith(draftIdentifierPrefix)) {
result.__identifier = instance.__identifier;
}
if (typeof instance.__signedIdentifier === 'string') {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{{> fragment.header.hbs }}

import type { JudoStored } from '../common';
import type { JudoStored, JudoTechnicalIdentifiable } from '../common';
{{# each (getImportTokens application.actor classType) as | token | }}
import { {{ @key }} } from './{{ token }}';
{{/ each }}

export interface {{ classDataName classType '' }} {
export interface {{ classDataName classType '' }} extends JudoTechnicalIdentifiable {
__identifier?: string;
{{# each classType.attributes as | attribute | }}
{{ attribute.name }}{{# if attribute.isRequired }}: {{ else }}?: null | {{/ if}}{{ typescriptType attribute.dataType }};
{{/ each }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function serialize{{ classDataName classType "QueryCustomizer" }}(queryCu
const { lastItem, ...seekRest } = _seek;
result._seek = { ...seekRest };
if (lastItem) {
result._seek.lastItem = serializer.serialize(lastItem as {{ classDataName classType "Stored" }}, true);
result._seek.lastItem = serializer.serialize(lastItem as {{ classDataName classType "Stored" }});
}
}
return result;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{{> fragment.header.hbs }}

import { v4 as uuidv4 } from 'uuid';
import type { JudoStored, Serializer, SerializerUtil } from '../common';
import { applyStoredMembers } from '../common/utils';
import { applyStoredMembers, draftIdentifierPrefix } from '../common/utils';
import type { {{ classDataName classType '' }}, {{ classDataName classType 'Stored' }} } from '../model/{{ classDataName classType '' }}';
{{# each (getRelatedClasses classType) as |classType| }}
import { {{ classDataName classType 'Serializer' }} } from './{{ classDataName classType 'Serializer' }}';
Expand All @@ -24,8 +25,8 @@ export class {{ classDataName classType 'Stored' }}Serializer implements Seriali
this.normalSerializer = new {{ classDataName classType 'Serializer' }}();
}

serialize(instance: {{ classDataName classType 'Stored' }}, cleanup = false): any {
return this.normalSerializer.serialize(instance, cleanup);
serialize(instance: {{ classDataName classType 'Stored' }}): any {
return this.normalSerializer.serialize(instance);
}

deserialize(data: any = {}): {{ classDataName classType 'Stored' }} {
Expand All @@ -47,7 +48,7 @@ export class {{ classDataName classType 'Serializer' }} implements Serializer<{{
return {{ classDataName classType '' }}Serializer._instance;
}

serialize(instance: {{ classDataName classType '' }}, cleanup = false): any {
serialize(instance: {{ classDataName classType '' }}): any {
const result: any = {};
{{# each classType.attributes as |attribute| }}
if (instance.{{ attribute.name }} !== undefined) {
Expand All @@ -57,15 +58,15 @@ export class {{ classDataName classType 'Serializer' }} implements Serializer<{{
{{# each classType.relations as |relation| }}
{{# if relation.isCollection }}
if (Array.isArray(instance.{{ relation.name }})) {
result.{{ relation.name }} = instance.{{ relation.name }}.map(r => {{ classDataName relation.target 'Serializer' }}.getInstance().serialize(r, cleanup));
result.{{ relation.name }} = instance.{{ relation.name }}.map(r => {{ classDataName relation.target 'Serializer' }}.getInstance().serialize(r));
}
{{ else }}
if (instance.{{ relation.name }} !== undefined) {
result.{{ relation.name }} = {{# if relation.isOptional }}instance.{{ relation.name }} === null ? null : {{/ if }}{{ classDataName relation.target 'Serializer' }}.getInstance().serialize(instance.{{ relation.name }}, cleanup);
result.{{ relation.name }} = {{# if relation.isOptional }}instance.{{ relation.name }} === null ? null : {{/ if }}{{ classDataName relation.target 'Serializer' }}.getInstance().serialize(instance.{{ relation.name }});
}
{{/ if }}
{{/ each }}
applyStoredMembers(result, instance as unknown as JudoStored<any>, true);
applyStoredMembers(result, instance as unknown as JudoStored<any>);
return result;
}

Expand All @@ -88,6 +89,10 @@ export class {{ classDataName classType 'Serializer' }} implements Serializer<{{
{{/ if }}
{{/ each }}
applyStoredMembers(result, instance as unknown as JudoStored<any>);
if (!result.__identifier) {
result.__identifier = `${draftIdentifierPrefix}${uuidv4()}`;
}

return result as {{ classDataName classType '' }};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ private readonly {{ firstToLower imp }}StoredSerializer = {{ imp }}StoredSeriali
*/
async update(target: {{ classDataName classType "Stored" }}, queryCustomizer?: CommandQueryCustomizer): Promise<JudoRestResponse<{{ classDataName classType "Stored" }}>> {
const path = '{{ restPath classType '/~update' '' '' }}';
const input = this.{{ firstToLower (classDataName classType "StoredSerializer") }}.serialize(target, true);
const input = this.{{ firstToLower (classDataName classType "StoredSerializer") }}.serialize(target);
const { data, ...rest } = await this.axios.post(this.getPathForActor(path), input, {
headers: {
[X_JUDO_SIGNED_IDENTIFIER]: target.__signedIdentifier!,
Expand All @@ -95,7 +95,7 @@ private readonly {{ firstToLower imp }}StoredSerializer = {{ imp }}StoredSeriali
*/
async validateUpdate(target: {{ classDataName classType "Stored" }}): Promise<JudoRestResponse<{{ classDataName classType "Stored" }}>> {
const path = '{{ restPath classType '/~validate' '' '' }}';
const input = this.{{ firstToLower (classDataName classType "StoredSerializer") }}.serialize(target, true);
const input = this.{{ firstToLower (classDataName classType "StoredSerializer") }}.serialize(target);
const { data, ...rest } = await this.axios.post(this.getPathForActor(path), input, {
headers: {
[X_JUDO_SIGNED_IDENTIFIER]: target.__signedIdentifier!,
Expand Down Expand Up @@ -126,7 +126,7 @@ private readonly {{ firstToLower imp }}StoredSerializer = {{ imp }}StoredSeriali
*/
async create{{ firstToUpper relation.name }}(owner: {{ classDataName classType "Stored" }}, target: {{ classDataName relation.target "" }}, queryCustomizer?: CommandQueryCustomizer): Promise<JudoRestResponse<{{ classDataName relation.target "Stored" }}>> {
const path = '{{ restPath classType "/~update/" relation.name "/~create" }}';
const input = this.{{ firstToLower (classDataName relation.target "Serializer") }}.serialize(target, true);
const input = this.{{ firstToLower (classDataName relation.target "Serializer") }}.serialize(target);
const { data, ...rest } = await this.axios.post(this.getPathForActor(path), input, {
headers: {
[X_JUDO_SIGNED_IDENTIFIER]: owner.__signedIdentifier!,
Expand All @@ -145,7 +145,7 @@ private readonly {{ firstToLower imp }}StoredSerializer = {{ imp }}StoredSeriali
*/
async validateCreate{{ firstToUpper relation.name }}(owner: {{ classDataName classType "Stored" }}, target: {{ classDataName relation.target "" }}): Promise<JudoRestResponse<{{ classDataName relation.target "" }}>> {
const path = '{{ restPath classType "/~update/" relation.name "/~validate" }}';
const input = this.{{ firstToLower (classDataName relation.target "Serializer") }}.serialize(target, true);
const input = this.{{ firstToLower (classDataName relation.target "Serializer") }}.serialize(target);
const { data, ...rest } = await this.axios.post(this.getPathForActor(path), input, {
headers: {
[X_JUDO_SIGNED_IDENTIFIER]: owner.__signedIdentifier!,
Expand Down Expand Up @@ -186,7 +186,7 @@ private readonly {{ firstToLower imp }}StoredSerializer = {{ imp }}StoredSeriali
*/
async getRangeFor{{ firstToUpper relation.name }}(owner?: {{ classDataName classType "Stored" }}, queryCustomizer?:{{ classDataName relation.target "QueryCustomizer" }}, headers?: Record<string, string>): Promise<JudoRestResponse<Array<{{ classDataName relation.target "Stored" }}>>> {
const path = '{{ restPath classType "/" relation.name "/~range" }}';
const input = owner ? this.{{ firstToLower (classDataName classType "StoredSerializer") }}.serialize(owner, true) : {};
const input = owner ? this.{{ firstToLower (classDataName classType "StoredSerializer") }}.serialize(owner) : {};
const { data, ...rest } = await this.axios.post(this.getPathForActor(path), { owner: input, queryCustomizer: serialize{{ classDataName relation.target "QueryCustomizer" }}(queryCustomizer) ?? {} }, headers ? { headers } : undefined);
return {
...rest,
Expand All @@ -201,9 +201,9 @@ private readonly {{ firstToLower imp }}StoredSerializer = {{ imp }}StoredSeriali
async set{{ firstToUpper relation.name }}(owner: {{ classDataName classType "Stored" }}, selected:{{# if relation.isCollection }}Array<{{/ if }}{{ classDataName relation.target "Stored" }}{{# if relation.isCollection }}>{{/ if }}): Promise<JudoRestResponse<void>> {
const path = '{{ restPath classType "/~update/" relation.name "/~set" }}';
{{# if relation.isCollection }}
const input = selected.map(s => this.{{ firstToLower (classDataName relation.target "StoredSerializer") }}.serialize(s, true));
const input = selected.map(s => this.{{ firstToLower (classDataName relation.target "StoredSerializer") }}.serialize(s));
{{ else }}
const input = this.{{ firstToLower (classDataName relation.target "StoredSerializer") }}.serialize(selected, true);
const input = this.{{ firstToLower (classDataName relation.target "StoredSerializer") }}.serialize(selected);
{{/ if }}
return this.axios.post(this.getPathForActor(path), input, {
headers: {
Expand Down Expand Up @@ -233,7 +233,7 @@ private readonly {{ firstToLower imp }}StoredSerializer = {{ imp }}StoredSeriali
*/
async add{{ firstToUpper relation.name }}(owner: {{ classDataName classType "Stored" }}, selected: Array<{{ classDataName relation.target "Stored" }}>): Promise<JudoRestResponse<void>> {
const path = '{{ restPath classType "/~update/" relation.name "/~add" }}';
const input = selected.map(s => this.{{ firstToLower (classDataName relation.target "StoredSerializer") }}.serialize(s, true));
const input = selected.map(s => this.{{ firstToLower (classDataName relation.target "StoredSerializer") }}.serialize(s));
return this.axios.post(this.getPathForActor(path), input, {
headers: {
[X_JUDO_SIGNED_IDENTIFIER]: owner.__signedIdentifier!,
Expand All @@ -248,7 +248,7 @@ private readonly {{ firstToLower imp }}StoredSerializer = {{ imp }}StoredSeriali
*/
async remove{{ firstToUpper relation.name }}(owner: {{ classDataName classType "Stored" }}, selected: Array<{{ classDataName relation.target "Stored" }}>): Promise<JudoRestResponse<void>> {
const path = '{{ restPath classType "/~update/" relation.name "/~remove" }}';
const input = selected.map(s => this.{{ firstToLower (classDataName relation.target "StoredSerializer") }}.serialize(s, true));
const input = selected.map(s => this.{{ firstToLower (classDataName relation.target "StoredSerializer") }}.serialize(s));
return this.axios.post(this.getPathForActor(path), input, {
headers: {
[X_JUDO_SIGNED_IDENTIFIER]: owner.__signedIdentifier!,
Expand Down Expand Up @@ -279,7 +279,7 @@ private readonly {{ firstToLower imp }}StoredSerializer = {{ imp }}StoredSeriali
async {{ operation.name }}For{{ firstToUpper relation.name }}({{# if operation.isMapped }}owner: {{ classDataName relation.target "Stored" }}{{/ if }}{{# if operation.input }}{{# if operation.isMapped }},{{/ if }}target:{{ classDataName operation.input.target "Stored" }}{{/ if }}): Promise<JudoRestResponse<{{# if operation.output }}{{ classDataName operation.output.target "Stored" }}{{ else }}void{{/ if }}>> {
const path = '{{ operationRestPath relation.target operation '' }}';
{{# if operation.input }}
const input = target ? this.{{ firstToLower (classDataName operation.input.target "StoredSerializer") }}.serialize(target, true) : null;
const input = target ? this.{{ firstToLower (classDataName operation.input.target "StoredSerializer") }}.serialize(target) : null;
{{/ if }}
const { data, ...rest } = await this.axios.post(this.getPathForActor(path){{# if operation.input }}, input{{ else }}, undefined{{/ if }}{{# if operation.isMapped }}, {
headers: {
Expand Down Expand Up @@ -315,7 +315,7 @@ private readonly {{ firstToLower imp }}StoredSerializer = {{ imp }}StoredSeriali
*/
async getRangeOn{{ firstToUpper operation.name }}For{{ firstToUpper relation.name }}(owner?: {{ classDataName relation.target "Stored" }}, queryCustomizer?:{{ classDataName operation.input.target "QueryCustomizer" }}, headers?: Record<string, string>): Promise<JudoRestResponse<Array<{{ classDataName operation.input.target "Stored" }}>>> {
const path = '{{ operationRestPath relation.target operation '/~range' }}';
const input = owner ? this.{{ firstToLower (classDataName relation.target "StoredSerializer") }}.serialize(owner, true) : {};
const input = owner ? this.{{ firstToLower (classDataName relation.target "StoredSerializer") }}.serialize(owner) : {};
const { data, ...rest } = await this.axios.post(this.getPathForActor(path), { owner: input, queryCustomizer: serialize{{ classDataName operation.input.target "QueryCustomizer" }}(queryCustomizer) ?? {} }, headers ? { headers } : undefined);
return {
...rest,
Expand All @@ -334,7 +334,7 @@ private readonly {{ firstToLower imp }}StoredSerializer = {{ imp }}StoredSeriali
async {{ operation.name }}({{# if operation.isMapped }}owner: {{ classDataName classType "Stored" }}{{/ if }}{{# if operation.input }}{{# if operation.isMapped }},{{/ if }}target:{{ classDataName operation.input.target "" }}{{/ if }}): Promise<JudoRestResponse<{{# if operation.output }}{{ classDataName operation.output.target "Stored" }}{{ else }}void{{/ if }}>> {
const path = '{{ operationRestPath classType operation '' }}';
{{# if operation.input }}
const input = target ? this.{{ firstToLower (classDataName operation.input.target "Serializer") }}.serialize(target, true) : null;
const input = target ? this.{{ firstToLower (classDataName operation.input.target "Serializer") }}.serialize(target) : null;
{{/ if }}
const { data, ...rest } = await this.axios.post(this.getPathForActor(path){{# if operation.input }}, input{{ else }}, undefined{{/ if }}{{# if operation.isMapped }}, {
headers: {
Expand Down Expand Up @@ -369,7 +369,7 @@ private readonly {{ firstToLower imp }}StoredSerializer = {{ imp }}StoredSeriali
*/
async getRangeOn{{ firstToUpper operation.name }}For{{ firstToUpper relation.name }}(owner?: {{ classDataName operation.input.target "Stored" }}, queryCustomizer?:{{ classDataName relation.target "QueryCustomizer" }}, headers?: Record<string, string>): Promise<JudoRestResponse<Array<{{ classDataName relation.target "Stored" }}>>> {
const path = '{{ restPath operation.input.target "/" relation.name "/~range" }}';
const input = owner ? this.{{ firstToLower (classDataName operation.input.target "StoredSerializer") }}.serialize(owner, true) : {};
const input = owner ? this.{{ firstToLower (classDataName operation.input.target "StoredSerializer") }}.serialize(owner) : {};
const { data, ...rest } = await this.axios.post(this.getPathForActor(path), { owner: input, queryCustomizer: serialize{{ classDataName relation.target "QueryCustomizer" }}(queryCustomizer) ?? {} }, headers ? { headers } : undefined);
return {
...rest,
Expand All @@ -385,7 +385,7 @@ private readonly {{ firstToLower imp }}StoredSerializer = {{ imp }}StoredSeriali
*/
async getRangeOn{{ firstToUpper operation.name }}(owner?: {{ classDataName classType "Stored" }}, queryCustomizer?:{{ classDataName operation.input.target "QueryCustomizer" }}, headers?: Record<string, string>): Promise<JudoRestResponse<Array<{{ classDataName operation.input.target "Stored" }}>>> {
const path = '{{ operationRestPath classType operation '/~range' }}';
const input = owner ? this.{{ firstToLower (classDataName classType "StoredSerializer") }}.serialize(owner, true) : {};
const input = owner ? this.{{ firstToLower (classDataName classType "StoredSerializer") }}.serialize(owner) : {};
const { data, ...rest } = await this.axios.post(this.getPathForActor(path), { owner: input, queryCustomizer: serialize{{ classDataName operation.input.target "QueryCustomizer" }}(queryCustomizer) ?? {} }, headers ? { headers } : undefined);
return {
...rest,
Expand Down
Loading
Loading