Skip to content
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
27 changes: 27 additions & 0 deletions docs/migrations/version-5-to-6.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,33 @@ const models = await generator.generateCompleteModels(schema, {

The generated Python code behavior remains unchanged - all imports will continue to use the explicit style.

## Typescript
### Date formats now generate `Date` instead of `string`

In Modelina v5, OpenAPI schema fields with type `string` and formats such as
`date-time`, `date`, or `time` were generated as `string` in TypeScript models.

Starting from v6, these formats are now mapped to the native `Date` type.

This is a **breaking change** and may require updates in consumer code.

#### What changed

**Before (v5):**
```ts
sentAt?: string;
```

**After(v6):**
```ts
sentAt?: Date;
```
#### Migration notes

- Update TypeScript type annotations that previously expected `string`
- Ensure any custom serialization or parsing logic handles `Date` objects
- Update mocks, tests, and fixtures that rely on string values for date fields

## AsyncAPI

### Improved schema naming strategy
Expand Down
4 changes: 0 additions & 4 deletions examples/integrate-with-next/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ exports[`Jest Snapshot testing suite Matches DOM Snapshot 1`] = `
class LightMeasured {
private _id?: number;
private _lumens?: number;
private _sentAt?: string;
private _sentAt?: Date;
private _additionalProperties?: Map<string, any>;

constructor(input: {
id?: number,
lumens?: number,
sentAt?: string,
sentAt?: Date,
additionalProperties?: Map<string, any>,
}) {
this._id = input.id;
Expand All @@ -50,8 +50,8 @@ class LightMeasured {
get lumens(): number | undefined { return this._lumens; }
set lumens(lumens: number | undefined) { this._lumens = lumens; }

get sentAt(): string | undefined { return this._sentAt; }
set sentAt(sentAt: string | undefined) { this._sentAt = sentAt; }
get sentAt(): Date | undefined { return this._sentAt; }
set sentAt(sentAt: Date | undefined) { this._sentAt = sentAt; }

get additionalProperties(): Map<string, any> | undefined { return this._additionalProperties; }
set additionalProperties(additionalProperties: Map<string, any> | undefined) { this._additionalProperties = additionalProperties; }
Expand All @@ -77,12 +77,12 @@ export { LightMeasured };

class TurnOn {
private _id?: number;
private _sentAt?: string;
private _sentAt?: Date;
private _additionalProperties?: Map<string, any>;

constructor(input: {
id?: number,
sentAt?: string,
sentAt?: Date,
additionalProperties?: Map<string, any>,
}) {
this._id = input.id;
Expand All @@ -93,8 +93,8 @@ class TurnOn {
get id(): number | undefined { return this._id; }
set id(id: number | undefined) { this._id = id; }

get sentAt(): string | undefined { return this._sentAt; }
set sentAt(sentAt: string | undefined) { this._sentAt = sentAt; }
get sentAt(): Date | undefined { return this._sentAt; }
set sentAt(sentAt: Date | undefined) { this._sentAt = sentAt; }

get additionalProperties(): Map<string, any> | undefined { return this._additionalProperties; }
set additionalProperties(additionalProperties: Map<string, any> | undefined) { this._additionalProperties = additionalProperties; }
Expand Down
21 changes: 21 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"dependencies": {
"@apidevtools/json-schema-ref-parser": "^11.1.0",
"@apidevtools/swagger-parser": "^10.1.0",
"@asyncapi/modelina": "^5.10.1",
"@asyncapi/multi-parser": "^2.2.0",
"@asyncapi/parser": "^3.4.0",
"alterschema": "^1.1.2",
Expand Down
4 changes: 4 additions & 0 deletions src/generators/typescript/TypeScriptConstrainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ export const TypeScriptDefaultTypeMapping: TypeScriptTypeMapping = {
return applyNullable(constrainedModel, 'number');
},
String({ constrainedModel }): string {
const format = constrainedModel?.options?.format;
if (format === 'date-time' || format === 'date' || format === 'time') {
return applyNullable(constrainedModel, 'Date');
}
return applyNullable(constrainedModel, 'string');
},
Boolean({ constrainedModel }): string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,15 @@ Array [
private _specversion: string;
private _reservedType: CloudEventType.DOG = CloudEventType.DOG;
private _dataschema?: string;
private _time?: string;
private _time?: Date;
private _additionalProperties?: Map<string, any>;

constructor(input: {
id: string,
source: string,
specversion: string,
dataschema?: string,
time?: string,
time?: Date,
additionalProperties?: Map<string, any>,
}) {
this._id = input.id;
Expand All @@ -130,8 +130,8 @@ Array [
get dataschema(): string | undefined { return this._dataschema; }
set dataschema(dataschema: string | undefined) { this._dataschema = dataschema; }

get time(): string | undefined { return this._time; }
set time(time: string | undefined) { this._time = time; }
get time(): Date | undefined { return this._time; }
set time(time: Date | undefined) { this._time = time; }

get additionalProperties(): Map<string, any> | undefined { return this._additionalProperties; }
set additionalProperties(additionalProperties: Map<string, any> | undefined) { this._additionalProperties = additionalProperties; }
Expand All @@ -146,15 +146,15 @@ Array [
private _specversion: string;
private _reservedType: CloudEventType.CAT = CloudEventType.CAT;
private _dataschema?: string;
private _time?: string;
private _time?: Date;
private _additionalProperties?: Map<string, any>;

constructor(input: {
id: string,
source: string,
specversion: string,
dataschema?: string,
time?: string,
time?: Date,
additionalProperties?: Map<string, any>,
}) {
this._id = input.id;
Expand All @@ -179,8 +179,8 @@ Array [
get dataschema(): string | undefined { return this._dataschema; }
set dataschema(dataschema: string | undefined) { this._dataschema = dataschema; }

get time(): string | undefined { return this._time; }
set time(time: string | undefined) { this._time = time; }
get time(): Date | undefined { return this._time; }
set time(time: Date | undefined) { this._time = time; }

get additionalProperties(): Map<string, any> | undefined { return this._additionalProperties; }
set additionalProperties(additionalProperties: Map<string, any> | undefined) { this._additionalProperties = additionalProperties; }
Expand Down Expand Up @@ -377,13 +377,13 @@ Array [
"class ReservedEvent {
private _id: string;
private _action?: Action;
private _eventTime?: string;
private _eventTime?: Date;
private _additionalProperties?: Map<string, any>;

constructor(input: {
id: string,
action?: Action,
eventTime?: string,
eventTime?: Date,
additionalProperties?: Map<string, any>,
}) {
this._id = input.id;
Expand All @@ -398,8 +398,8 @@ Array [
get action(): Action | undefined { return this._action; }
set action(action: Action | undefined) { this._action = action; }

get eventTime(): string | undefined { return this._eventTime; }
set eventTime(eventTime: string | undefined) { this._eventTime = eventTime; }
get eventTime(): Date | undefined { return this._eventTime; }
set eventTime(eventTime: Date | undefined) { this._eventTime = eventTime; }

get additionalProperties(): Map<string, any> | undefined { return this._additionalProperties; }
set additionalProperties(additionalProperties: Map<string, any> | undefined) { this._additionalProperties = additionalProperties; }
Expand Down
4 changes: 4 additions & 0 deletions test/runtime/generic-input-all.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
"string_type": {
"type": "string"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"number_type": {
"type": "number"
},
Expand Down
10 changes: 6 additions & 4 deletions test/runtime/runtime-typescript/test/Marshalling.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ describe('Marshalling', () => {
test: 'test'
});
const testObject = new TestObject({
stringType: 'test',
createdAt: new Date('2023-01-01T10:00:00Z'),
stringType: 'test',
numberType: 1,
booleanType: true,
arrayType: [1, 'test'],
Expand All @@ -18,12 +19,13 @@ describe('Marshalling', () => {
additionalProperties: new Map(Object.entries({"test": "test"})),
enumType: EnumType.CURLYLEFT_QUOTATION_TEST_QUOTATION_COLON_2_CURLYRIGHT,
tupleType: ['test', 1],
unionType: 'test'
unionType: 'test',
});
test('be able to serialize model', () => {
const serialized = testObject.marshal();
expect(serialized).toEqual("{\"string_type\": \"test\",\"number_type\": 1,\"boolean_type\": true,\"union_type\": \"test\",\"array_type\": [1,\"test\"],\"tuple_type\": [\"test\",1],\"object_type\": {\"test\": \"test\"},\"dictionary_type\": {},\"enum_type\": \"{\\\"test\\\":2}\",\"test\": \"test\"}");
});
expect(serialized).toEqual(
"{\"string_type\": \"test\",\"createdAt\": \"2023-01-01T10:00:00.000Z\",\"number_type\": 1,\"boolean_type\": true,\"union_type\": \"test\",\"array_type\": [1,\"test\"],\"tuple_type\": [\"test\",1],\"object_type\": {\"test\": \"test\"},\"dictionary_type\": {},\"enum_type\": \"{\\\"test\\\":2}\",\"test\": \"test\"}"
);});
test('be able to serialize model and turning it back to a model with the same values', () => {
const serialized = testObject.marshal();
const newAddress = TestObject.unmarshal(serialized);
Expand Down