Skip to content
Open
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
29 changes: 28 additions & 1 deletion docs/languages/TypeScript.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,34 @@ Here are all the supported presets and the libraries they use for converting to

#### Generate marshalling and unmarshalling functions

Using the preset `TS_COMMON_PRESET` with the option `marshalling` to `true`, renders two function for the class models. One which convert the model to JSON and another which convert the model from JSON to an instance of the class.
Using the preset `TS_COMMON_PRESET` with the option `marshalling` to `true`, renders four methods for class models:

| Method | Description |
|--------|-------------|
| `toJson(): Record<string, unknown>` | Converts the instance to a plain JSON-serializable object |
| `marshal(): string` | Converts the instance to a JSON string (calls `JSON.stringify(this.toJson())`) |
| `static fromJson(obj: Record<string, unknown>): ClassName` | Creates an instance from a plain JSON object |
| `static unmarshal(json: string \| object): ClassName` | Creates an instance from a JSON string or object (calls `fromJson()` internally) |

**When to use each method:**

- Use `toJson()`/`fromJson()` when working with objects directly (e.g., API responses already parsed, or when you need to manipulate the data before serialization)
- Use `marshal()`/`unmarshal()` when working with JSON strings

**Example:**

```typescript
// Create an instance
const meeting = new Meeting({ email: 'test@example.com', createdAt: new Date() });

// Object conversion
const obj = meeting.toJson(); // Returns plain object
const fromObj = Meeting.fromJson(obj); // Creates instance from object

// String serialization
const str = meeting.marshal(); // Returns JSON string
const fromStr = Meeting.unmarshal(str); // Creates instance from string
```

Check out this [example out for a live demonstration](../../examples/typescript-generate-marshalling).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,34 @@ Array [
get email(): string | undefined { return this._email; }
set email(email: string | undefined) { this._email = email; }

public marshal() : string {
let json = '{'
public toJson(): Record<string, unknown> {
const json: Record<string, unknown> = {};
if(this.email !== undefined) {
json += \`\\"email\\": \${typeof this.email === 'number' || typeof this.email === 'boolean' ? this.email : JSON.stringify(this.email)},\`;
json[\\"email\\"] = this.email;
}

//Remove potential last comma
return \`\${json.charAt(json.length-1) === ',' ? json.slice(0, json.length-1) : json}}\`;
return json;
}

public static unmarshal(json: string | object): Test {
const obj = typeof json === \\"object\\" ? json : JSON.parse(json);
public marshal(): string {
return JSON.stringify(this.toJson());
}

public static fromJson(obj: Record<string, unknown>): Test {
const instance = new Test({} as any);

if (obj[\\"email\\"] !== undefined) {
instance.email = obj[\\"email\\"];
}


return instance;
}

public static unmarshal(json: string | object): Test {
const obj = typeof json === \\"object\\" ? json : JSON.parse(json);
return Test.fromJson(obj as Record<string, unknown>);
}
public async jsonbinSerialize(): Promise<Buffer>{
const jsonData = JSON.parse(this.marshal());
const jsonbinpackEncodedSchema = await jsonbinpack.compileSchema({\\"$schema\\":\\"https://json-schema.org/draft/2020-12/schema\\",\\"type\\":\\"object\\",\\"properties\\":{\\"email\\":{\\"format\\":\\"email\\",\\"type\\":\\"string\\",\\"x-modelgen-inferred-name\\":\\"email\\"}},\\"additionalProperties\\":false,\\"$id\\":\\"Test\\",\\"x-modelgen-inferred-name\\":\\"root\\"});
Expand Down
41 changes: 40 additions & 1 deletion examples/typescript-generate-marshalling/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,45 @@
# TypeScript Data Models with un/marshalling functionality

A basic example of how to use the un/marshalling functionality of the typescript class.
A basic example of how to use the un/marshalling functionality of the TypeScript class.

## Generated Methods

When `marshalling: true` is enabled, the following methods are generated:

### `toJson(): Record<string, unknown>`
Converts the instance to a plain JSON-serializable object. Useful when you need to work with the data as an object before serialization.

### `marshal(): string`
Converts the instance to a JSON string. Internally calls `JSON.stringify(this.toJson())`.

### `static fromJson(obj: Record<string, unknown>): ClassName`
Creates an instance from a plain JSON object. Useful when you receive data as an object (e.g., from an API response already parsed).

### `static unmarshal(json: string | object): ClassName`
Creates an instance from either a JSON string or object. For strings, it parses first then calls `fromJson()`. For objects, it directly calls `fromJson()`.

## Example Usage

```typescript
// Create an instance
const meeting = new Meeting({
email: 'test@example.com',
createdAt: new Date()
});

// Convert to plain object (for manipulation or custom serialization)
const jsonObject = meeting.toJson();
console.log(jsonObject); // { email: 'test@example.com', createdAt: '2023-01-01T00:00:00.000Z' }

// Convert to JSON string
const jsonString = meeting.marshal();

// Create from plain object
const fromObj = Meeting.fromJson(jsonObject);

// Create from JSON string
const fromString = Meeting.unmarshal(jsonString);
```

## How to run this example

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,45 +32,52 @@ Array [
get meetingTime(): string | undefined { return this._meetingTime; }
set meetingTime(meetingTime: string | undefined) { this._meetingTime = meetingTime; }

public marshal() : string {
let json = '{'
public toJson(): Record<string, unknown> {
const json: Record<string, unknown> = {};
if(this.email !== undefined) {
json += \`\\"email\\": \${typeof this.email === 'number' || typeof this.email === 'boolean' ? this.email : JSON.stringify(this.email)},\`;
json[\\"email\\"] = this.email;
}
if(this.createdAt !== undefined) {
json += \`\\"createdAt\\": \${typeof this.createdAt === 'number' || typeof this.createdAt === 'boolean' ? this.createdAt : JSON.stringify(this.createdAt)},\`;
json[\\"createdAt\\"] = this.createdAt;
}
if(this.meetingDate !== undefined) {
json += \`\\"meetingDate\\": \${typeof this.meetingDate === 'number' || typeof this.meetingDate === 'boolean' ? this.meetingDate : JSON.stringify(this.meetingDate)},\`;
json[\\"meetingDate\\"] = this.meetingDate;
}
if(this.meetingTime !== undefined) {
json += \`\\"meetingTime\\": \${typeof this.meetingTime === 'number' || typeof this.meetingTime === 'boolean' ? this.meetingTime : JSON.stringify(this.meetingTime)},\`;
json[\\"meetingTime\\"] = this.meetingTime;
}

//Remove potential last comma
return \`\${json.charAt(json.length-1) === ',' ? json.slice(0, json.length-1) : json}}\`;
return json;
}

public static unmarshal(json: string | object): Meeting {
const obj = typeof json === \\"object\\" ? json : JSON.parse(json);
public marshal(): string {
return JSON.stringify(this.toJson());
}

public static fromJson(obj: Record<string, unknown>): Meeting {
const instance = new Meeting({} as any);

if (obj[\\"email\\"] !== undefined) {
instance.email = obj[\\"email\\"];
}
if (obj[\\"createdAt\\"] !== undefined) {
instance.createdAt = obj[\\"createdAt\\"] == null ? undefined : new Date(obj[\\"createdAt\\"]);
instance.createdAt = obj[\\"createdAt\\"] == null ? undefined : new Date(obj[\\"createdAt\\"] as string);
}
if (obj[\\"meetingDate\\"] !== undefined) {
instance.meetingDate = obj[\\"meetingDate\\"] == null ? undefined : new Date(obj[\\"meetingDate\\"]);
instance.meetingDate = obj[\\"meetingDate\\"] == null ? undefined : new Date(obj[\\"meetingDate\\"] as string);
}
if (obj[\\"meetingTime\\"] !== undefined) {
instance.meetingTime = obj[\\"meetingTime\\"];
}


return instance;
}

public static unmarshal(json: string | object): Meeting {
const obj = typeof json === \\"object\\" ? json : JSON.parse(json);
return Meeting.fromJson(obj as Record<string, unknown>);
}
}",
]
`;
14 changes: 9 additions & 5 deletions src/generators/typescript/presets/CommonPreset.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { TypeScriptPreset } from '../TypeScriptPreset';
import renderExampleFunction from './utils/ExampleFunction';
import { renderUnmarshal } from './utils/UnmarshalFunction';
import { renderMarshal } from './utils/MarshalFunction';
import { renderFromJson, renderUnmarshal } from './utils/UnmarshalFunction';
import { renderMarshal, renderToJson } from './utils/MarshalFunction';

export interface TypeScriptCommonPresetOptions {
marshalling: boolean;
example: boolean;
}

/**
* Preset which adds `marshal`, `unmarshal`, `example` functions to class.
* Preset which adds `toJson`, `marshal`, `fromJson`, `unmarshal`, `example` functions to class.
*
* @implements {TypeScriptPreset}
*/
Expand All @@ -21,8 +21,12 @@
const blocks: string[] = [];

if (options.marshalling === true) {
blocks.push(renderMarshal({ renderer, model }));
blocks.push(renderUnmarshal({ renderer, model }));
blocks.push(
renderToJson({ renderer, model }),

Check failure on line 25 in src/generators/typescript/presets/CommonPreset.ts

View workflow job for this annotation

GitHub Actions / Test NodeJS PR - macos-latest

Delete `·`
renderMarshal(),
renderFromJson({ renderer, model }),
renderUnmarshal({ renderer, model })
);
}

if (options.example === true) {
Expand Down
Loading
Loading