horiuchi / dtsgenerator Goto Github PK
View Code? Open in Web Editor NEWTypeScript d.ts file generate from JSON Schema file
TypeScript d.ts file generate from JSON Schema file
The searchAllSubSchema
function skips registering schemas for these instances:
requestBody:
$ref: '#/components/requestBodies/MyRequestBody'
responses:
200:
$ref: '#/components/responses/MyRequestBody'
The reason is that setSubIdToRequestBody
and setSubIdToResponseV3
only proceed to setSubId if the content
property exists. https://github.com/horiuchi/dtsgenerator/blob/master/src/core/jsonSchema.ts#L270
Easy fix though. :)
id
field accept the URL format and Path only format.id
field is resolved by against the most immediate parent scope.via: http://json-schema.org/latest/json-schema-core.html#anchor27
I've got a couple of files. Each file is a schema, but there are references to schema in another files.
I expect that if all files are on input togheter than generator can resolve cross references, but it seem doesn't work. It doesn't care about files/dependency order.
Is it supported? If not any idea to achieve this?.
These are two example files:
{
"id" :"ApiBaseObject",
"$schema": "http://json-schema.org/draft-03/schema",
"type": "object",
"description": "ApiBaseObject of a record",
"properties": {
"first" : {"type" : "string"}
}
}
{
"id" :"ApiMetadata",
"$schema": "http://json-schema.org/draft-03/schema",
"type": "object",
"description": "Metadata of a record",
"properties": {
"serverOperation" : {
"type" : "string",
"enum" : ["I","U","D"],
"javaEnumNames" : ["INSERT","UPDATE","DELETE"]
},
"test" : {"$ref" : "ApiBaseObject" }
}
}
Hello,
is it possible to generate source files which use single quotes instead of double quotes? This would be nice to have to have the generated code uniform with the written code.
🚨 You need to enable Continuous Integration on all branches of this repository. 🚨
To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because we are using your CI build statuses to figure out when to notify you about breaking changes.
Since we did not receive a CI status on the greenkeeper/initial
branch, we assume that you still need to configure it.
If you have already set up a CI for this repository, you might need to check your configuration. Make sure it will run on all new branches. If you don’t want it to run on every branch, you can whitelist branches starting with greenkeeper/
.
We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.
標準入力からの入力にも対応する。
Object, Array 共に受け取れるようにする。
Testing against the JSONAPI schema, I received the bug below against version 0.4.0.
To recreate, run this command: curl jsonapi.org/schema | dtsgen
{ '$schema': 'http://json-schema.org/draft-04/schema#',
title: 'JSON API Schema',
description: 'This is a schema for responses in the JSON API format. For more, see http://jsonapi.org',
oneOf:
[ { '$ref': '#/definitions/success' },
{ '$ref': '#/definitions/failure' },
{ '$ref': '#/definitions/info' } ],
definitions:
{ success:
{ type: 'object',
required: [Object],
properties: [Object],
additionalProperties: false },
failure:
{ type: 'object',
required: [Object],
properties: [Object],
additionalProperties: false },
info:
{ type: 'object',
required: [Object],
properties: [Object],
additionalProperties: false },
meta:
{ description: 'Non-standard meta-information that can not be represented as an attribute or relationship.',
type: 'object',
additionalProperties: true },
data:
{ description: 'The document\'s "primary data" is a representation of the resource or collection of resources targeted by a request.',
oneOf: [Object] },
resource:
{ description: '"Resource objects" appear in a JSON API document to represent resources.',
type: 'object',
required: [Object],
properties: [Object],
additionalProperties: false },
links:
{ description: 'A resource object **MAY** contain references to other resource objects ("relationships"). Relationships may be to-one or to-many. Relationships can be specified by including a member in a resource\'s links object.',
type: 'object',
properties: [Object],
additionalProperties: true },
link:
{ description: 'A link **MUST** be represented as either: a string containing the link\'s URL or a link object.',
oneOf: [Object] },
attributes:
{ description: 'Members of the attributes object ("attributes") represent information about the resource object in which it\'s defined.',
type: 'object',
patternProperties: [Object],
additionalProperties: false },
relationships:
{ description: 'Members of the relationships object ("relationships") represent references from the resource object in which it\'s defined to other resource objects.',
type: 'object',
patternProperties: [Object],
additionalProperties: false },
relationshipToOne:
{ description: 'References to other resource objects in a to-one ("relationship"). Relationships can be specified by including a member in a resource\'s links object.',
anyOf: [Object] },
relationshipToMany:
{ description: 'An array of objects each containing "type" and "id" members for to-many relationships.',
type: 'array',
items: [Object],
uniqueItems: true },
empty:
{ description: 'Describes an empty to-one relationship.',
type: 'null' },
linkage:
{ description: 'The "type" and "id" to non-empty members.',
type: 'object',
required: [Object],
properties: [Object],
additionalProperties: false },
pagination: { type: 'object', properties: [Object] },
jsonapi:
{ description: 'An object describing the server\'s implementation',
type: 'object',
properties: [Object],
additionalProperties: false },
error:
{ type: 'object',
properties: [Object],
additionalProperties: false } } }
/home/ianks/.nvm/versions/node/v5.8.0/lib/node_modules/dtsgenerator/src/generator.js:11
throw new Error('id is not found.');
^
Error: id is not found.
at new Generator (/home/ianks/.nvm/versions/node/v5.8.0/lib/node_modules/dtsgenerator/src/generator.js:11:19)
at Function.Generator.add (/home/ianks/.nvm/versions/node/v5.8.0/lib/node_modules/dtsgenerator/src/generator.js:50:17)
at /home/ianks/.nvm/versions/node/v5.8.0/lib/node_modules/dtsgenerator/src/index.js:12:20
at Array.forEach (native)
at dtsgenerator (/home/ianks/.nvm/versions/node/v5.8.0/lib/node_modules/dtsgenerator/src/index.js:11:13)
at processGenerate (/home/ianks/.nvm/versions/node/v5.8.0/lib/node_modules/dtsgenerator/src/cli.js:62:18)
at Socket.<anonymous> (/home/ianks/.nvm/versions/node/v5.8.0/lib/node_modules/dtsgenerator/src/cli.js:40:9)
at emitNone (events.js:85:20)
at Socket.emit (events.js:179:7)
at endReadableNT (_stream_readable.js:913:12)
When using the package at version 0.9.3, we get a Error: Cannot find module '../src/cli'
error. This is because cli.ts
is present, but not cli.js
.
Was the package pushed prior to transpilation?
Do you have motivation to support emit Operations for OpenAPI version 3.0?
null
type support (breaking change)
--v1
flag to input parameterI don't need namespaces because:
So, I want to get a file composing only export interface
by command option.
P.S.
How do we use --header
option? I guess that use for comment. But I can't have confidence in that.
When the schema contains non-string examples, the generator crashes with error:
TypeError: example.split is not a function
example schema:
{
"modelYear": {
"type": "string",
"example": 2013
}
}
dtsgen throws error for http://adaptivecards.io/schemas/adaptive-card.json
The $ref targets root is not found: #/definitions/AdaptiveCarD
Official guideline says that:
Do not use "I" as a prefix for interface names.
https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#names
I think dtsgenerator also should follow the convention. Thanks.
Under the right circumstances, using allOf
in a "derived" schema to inherit properties of a "base" schema will result in that base schema interface being emitted with the same properties as the derived schema interface.
Those circumstances are:
properties
property (e.g. it only inherits properties but does not define its own).The issue is due to utils.mergeSchema(), where it uses the base schema properties array if the extended schema does not have its own, meaning that two schemas are now sharing the same array. When properties (of other base schemas) are later merged into that array, those properties are now reflected in that original base schema.
Here is a test that exposes the issue:
it ('should include allOf schemas', async () => {
const baseSchema: JsonSchemaOrg.Schema = {
id: 'http://test/zzz/allOf/base',
type: 'object',
properties: {
id: {
type: 'string',
},
},
required: ['id'],
};
const extendedSchema: JsonSchemaOrg.Schema = {
id: 'http://test/zzz/allOf/extended',
type: 'object',
allOf: [
{ $ref: '/zzz/allOf/base' },
],
properties: {
value: {
type: 'number',
},
},
required: ['value'],
};
const separateSchema: JsonSchemaOrg.Schema = {
id: 'http://test/separate',
type: 'object',
properties: {
message: {
type: 'string',
},
},
required: ['message'],
};
const combinedSchema: JsonSchemaOrg.Schema = {
id: 'http://test/combined',
type: 'object',
allOf: [
{ $ref: '/zzz/allOf/base' },
{ $ref: '/zzz/allOf/extended' },
{ $ref: '/separate' },
],
};
const result = await dtsgenerator([baseSchema, extendedSchema, separateSchema, combinedSchema]);
const expected = `declare namespace Test {
export interface Combined {
id: string;
value: number;
message: string;
}
export interface Separate {
message: string;
}
namespace Zzz {
namespace AllOf {
export interface Base {
id: string;
}
export interface Extended {
value: number;
id: string;
}
}
}
}
`;
assert.equal(result, expected, result);
});
Here is the result of that test:
+ expected - actual
namespace Zzz {
namespace AllOf {
export interface Base {
id: string;
- value: number;
- message: string;
}
export interface Extended {
value: number;
id: string;
- message: string;
}
}
}
}
According to documentation https://swagger.io/docs/specification/using-ref/#syntax, it is possible to specify definitions in other file.
I have 2 files
Is it possible to import $ref from other file?
Current Open APIs Spec is in version 3.0.1
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md
Would you support that?
FYI: https://www.openapis.org/news/blogs/2016/10/tdc-structural-improvements-explaining-30-spec-part-2
Interfaces in namespace Components.Schema
has descriptions on them from the OpenAPI spec.
This is not the case for interfaces in namespace Paths
.
This would be very useful and specially for QueryParameters.
Would be great to be able to generate actual enums.
Right now, we get:
interface Foo {
status: 'ended' | 'active' | 'paused';
}
But would be awesome to get:
enum FooStatus {
'ended' = 'ended',
'active' = 'active',
'paused' = 'paused',
}
interface Foo {
status: FooStatus;
}
And would be even more awesome, if it was possible to filter it before output, so that it can be (optionally) corrected to:
enum FooStatus {
'ENDED' = 'ended',
'ACTIVE' = 'active',
'PAUSED' = 'paused',
}
Thanks!
It'd be great to be able to filter the property names and rename them too.
Our API returns snake_case
property names, but JS/TS world is mostly operating in camelCase
.
I'd like to be able to convert these before output.
Thanks.
eg:
dtsgen -o test.d.ts --url http://json.schemastore.org/eslintrc
/**
* Disallow the use of undeclared variables unless mentioned in /*global */ comments
*/
"no-undef"?: Rule;
"/* global */" will break parsing
Hi,
I tried dstgen on those jsonschema and it didn't output anything, no even an error; any idea ?
Thanks.
I tried to run npx dtsgenerator --url https://storage.googleapis.com/cognitedata-api-docs/openapi.0.5.json
and it failed with Error: The $ref targets root is not found: https://storage.googleapis.com/cognitedata-api-docs/api-acls-0.8.4s.json#/components/schemas/cogniteCapability
.
I also ran Swagger-CLI: npx swagger-cli validate https://storage.googleapis.com/cognitedata-api-docs/openapi.0.5.json
which stated that the spec is valid.
Can you bring back the --prefix
option? We use I-prefixed interfaces throughout the app and changing them all is difficult if we want to migrate to dtsgenerator v1.
TypeScript's guideline to avoid "I" as a prefix is limited to TypeScript development itself, not to the community. See https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines
dtsgen won't work since upgrading to typescript 1.7:
dtsgen --out dist/common/schemas.d.ts common/models/**/*.json
{ name: 'auditLog',
base: 'PersistedModel',
strict: false,
idInjection: true,
options: { validateUpsert: true },
uiOptions: { editable: false },
type: 'object',
properties:
{ date: { type: 'date', required: true },
userId: { type: 'number', required: false },
request: { type: 'object', properties: [Object] } },
validations: [],
relations: {},
acls: [],
methods: [] }
/usr/local/lib/node_modules/dtsgenerator/node_modules/asyncblock/lib/flow_fiber.js:26
this._fiber.run(task);
^
Error: id is not found.
at new Generator (/usr/local/lib/node_modules/dtsgenerator/lib/generator.js:11:19)
at Function.Generator.add (/usr/local/lib/node_modules/dtsgenerator/lib/generator.js:51:17)
at /usr/local/lib/node_modules/dtsgenerator/lib/index.js:13:20
at Array.forEach (native)
at dtsgenerator (/usr/local/lib/node_modules/dtsgenerator/lib/index.js:12:13)
at /usr/local/lib/node_modules/dtsgenerator/lib/cli.js:25:22
at fiberContents (/usr/local/lib/node_modules/dtsgenerator/node_modules/asyncblock/lib/asyncblock.js:112:26)
=== Pre-asyncblock stack ===
Error
at module.exports (/usr/local/lib/node_modules/dtsgenerator/node_modules/asyncblock/lib/asyncblock.js:34:15)
at processGenerate (/usr/local/lib/node_modules/dtsgenerator/lib/cli.js:19:5)
at Object.<anonymous> (/usr/local/lib/node_modules/dtsgenerator/lib/cli.js:16:5)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object.<anonymous> (/usr/local/lib/node_modules/dtsgenerator/bin/dtsgen:3:1)
To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:
.travis.yml
package.json
files, so that was left aloneIf you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.
Greenkeeper has checked the engines
key in any package.json
file, the .nvmrc
file, and the .travis.yml
file, if present.
engines
was only updated if it defined a single version, not a range..nvmrc
was updated to Node.js 10.travis.yml
was only changed if there was a root-level node_js
that didn’t already include Node.js 10, such as node
or lts/*
. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.For many simpler .travis.yml
configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
🚨 You need to enable Continuous Integration on Greenkeeper branches of this repository. 🚨
To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.
Since we didn’t receive a CI status on the greenkeeper/initial
branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.
If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/
.
Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please click the 'fix repo' button on account.greenkeeper.io.
Hi,
I'm new to typescript and json-schema and I would like to know which one is the more complete. I want to use the most complete one as base in order to generate the other one. At first glance I would think json-schema is more complete and polyvalent than typescript.
Could someone confirm this?
An idea: it would be great to be able to be bidirectionnal.
Thanks for your response and for your work on this project.
We'd like to ignore filename extensions in the generated type names, as the extensions we use for our schema files add noise to the generated types.
Would you be happy with this change if I raised a PR? If so, what strategy would you like me to take? As the references are meant to be URIs (or part thereof) I take it this change may not make sense for all use-cases.
https://github.com/horiuchi/dtsgenerator/blob/master/test/schemaid_test.ts#L26
For exampe: http://x.y.z/rootschema.json
=> XYZ.RootschemaJson
test(new SchemaId('http://x.y.z/rootschema.json#', []), 'http://x.y.z/rootschema.json#', true, 'http://x.y.z/rootschema.json#', false, [], ['XYZ', 'RootschemaJson']);
We're using JSON Schema to describe payloads (e.g., request/response/stream bodies) across our messaging oriented middleware. We make use of some tools, like jsonschema2pojo, to generate DTOs in Java. We hope to use this library to do the same for TypeScript.
Our existing DTOs sometimes contain relative references to other schemas, e.g., RatesRequest.dto.yaml
may contain a reference "$ref": "CurrencyPair.dto.yaml"
. We also generate service clients etc. from other yaml files. We use the extension of the file to differentiate the different declarations, e.g., services are described in *.service.yaml
files.
I have looked at a few different ways to work with json-schema in TypeScript, and dtsgenerator seems to be the closest to what I am looking for, and produces nicely formatted and structured typescript definitions. The issue I have is with tuples, for example:
{
"$id": "https://example.com/test.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": [
{"type": "number"},
{"type": "string"}
]
}
This generates:
declare namespace ExampleCom {
export type TestJson = [number, string] | [number, string, any];
}
Which is too permissive, what I really want is:
declare namespace ExampleCom {
export type TestJson = [number, string];
}
Could dtsgenerator be extended to support maxItems
for this use case, or is there another way to achieve what I want?
Using the --url flag to fetch the JSON, the cli works. Specifying a local file, does not.
$ DEBUG=dtsgen dtsgen res.json --out types.d.ts
dtsgen parse schema: schemaId=[undefined], url=[undefined]. +0ms
dtsgen generate d.ts. +4ms
dtsgen resolve reference: reference schema count=0. +3ms
dtsgen TypeId list: +1ms
dtsgen SchemaId list: +0ms
dtsgen Reference list: +0ms
Error: There is no id in the input schema(s)
at JsonSchemaParser.createHierarchicalMap (C:\Users\wie\AppData\Roaming\npm\node_modules\dtsgenerator\src\jsonSchemaParser.js:299:23)
at JsonSchemaParser._callee$ (C:\Users\wie\AppData\Roaming\npm\node_modules\dtsgenerator\src\jsonSchemaParser.js:278:44)
at tryCatch (C:\Users\wie\AppData\Roaming\npm\node_modules\dtsgenerator\node_modules\regenerator-runtime\runtime.js:64:40)
at Generator.invoke [as _invoke] (C:\Users\wie\AppData\Roaming\npm\node_modules\dtsgenerator\node_modules\regenerator-runtime\runtime.js:299:22)
at Generator.prototype.(anonymous function) [as next] (C:\Users\wie\AppData\Roaming\npm\node_modules\dtsgenerator\node_modules\regenerator-runtime\runtime.js:116:21)
at fulfilled (C:\Users\wie\AppData\Roaming\npm\node_modules\dtsgenerator\src\jsonSchemaParser.js:15:32)
Hi,
I'm on windows with npm 3.5.3 and node 4.2.5 but I can't install this package I have the following error:
npm ERR! [email protected] install: 'node build.js || nodejs build.js'
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script 'node build.js || nodejs build.js'.
If I run:
dtsgen --out types.d.ts src/Schema.json
I get the message "Error: id is not found.". What does it mean?
(dtsgenerator 0.7.1)
Using the id referencing technique you outlined in #10 the following schema produces duplicate/confusing TS definitions. I've tried a variety of different ways to $ref the types but no success. My goal is to spit out a .d.ts that contains 3 interface definitions, one each for Batch, Transaction, and Line respectively. What I get instead is output that blends/duplicates portions of the top level and has self-referencing properties. Do I have something wrong in my format or is this a bug with $ref handling?
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "NetSuite Invoice JSON Schema",
"description": "This JSON Schema represents the Invoice object payload that will be passed to NetSuite from Acumatica.",
"id": "/Batch",
"type": "object",
"properties": {
"invProcessedAmt": {
"title": "Invoice Processed Amount",
"description": "The total currency amount of Invoices to processed.",
"type": "number"
},
"invProcessedCount": {
"title": "Invoice Processed Amount",
"description": "The total quantities Invoices to processed.",
"type": "number"
},
"cmProcessedAmt": {
"title": "Credit Memo Processed Amount",
"description": "The total currency amount of Credit Memos to be processed.",
"type": "number"
},
"cmProcessedCount": {
"title": "Credit Memo Processed Amount",
"description": "The total currency amount of Credit Memos to be processed.",
"type": "number"
},
"correlationid": {
"type": "string"
},
"data": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "/Transaction#"
}
},
"Documents": {
"title": "Document List",
"description": "This is list of remotely stored electronic documents related to Invoices and Credit Memos. ",
"type": "array",
"minItems": 1,
"maxItems": 3,
"uniqueItems": true,
"items": [
{
"title": "Documents",
"description": "This is an object that contains properties related to Invoice and Credit Memo documents stored remotely.",
"type": "object",
"properties": {
"fileName": {
"title": "File Name",
"description": "This is the name of the Invoice or Credit Memo file.",
"type": "string"
},
"fileId": {
"title": "File Id",
"description": "This is the GUID of the file.",
"type": "string"
},
"docType": {
"title": "Doc Type",
"description": "This is the electronic document type.",
"type": "string",
"enum": [
"Summary",
"Detail"
]
}
},
"required": [
"fileName",
"fileId",
"docType"
]
}
],
"additionalItems": false
}
},
"required": [
"invProcessedAmt",
"invProcessedCount",
"cmProcessedAmt",
"cmProcessedCount",
"correlationId",
"data"
],
"definitions": {
"transaction": {
"id": "/Transaction",
"type": "object",
"properties": {
"trantype": {
"title": "Transaction Type",
"description": "This is the Type of Transaction being sent from Acumatica.",
"type": "string",
"enum": [
"Invoice",
"Credit Memo"
]
},
"custbody_acumatica_batch_id": {
"title": "Acumatica Batch Number",
"description": "This is the Invoice Batch Id assigned by Acumatica.",
"type": "string"
},
"tranid": {
"title": "Transaction Number",
"description": "This is the Invoice or Credit Memo Id passed from Acumatica.",
"type": "string"
},
"entitiy": {
"title": "Customer",
"description": "This is the Customer related to the Invoice or Credit Memo.",
"type": "string"
},
"trandate": {
"title": "Date",
"description": "This is the date of the Invoice.",
"type": "string"
},
"refNum": {
"title": "Ref No.",
"description": "This applies to Credit Memos only -- it is a reference to the Invoice to which the Credit Memo is applied to.",
"type": "string"
},
"memo": {
"title": "Memo",
"type": "string"
},
"items": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "/Line#"
}
}
},
"required": [
"trantype",
"custbody_acumatica_batch_id",
"tranid",
"entitiy",
"trandate",
"memo",
"items",
"Documents"
],
"definitions": {
"line": {
"id": "/Line",
"title": "Invoice or Credit Memo Line Items",
"description": "This is an object that contains properties related to Invoice and Credit Memo line items.",
"type": "object",
"properties": {
"item": {
"title": "Product Id",
"description": "This is the Item Name (not the Id) of each Invoice line",
"type": "string"
},
"quantity": {
"title": "Units",
"description": "This is the Quantity of Items on each Invoice line.",
"type": "integer"
},
"rate": {
"title": "Unit Price",
"description": "This is the Unit Price of the Item on each Invoice line.",
"type": "number"
},
"amount": {
"title": "Amount",
"description": "This is the amount of eachthe Item on each Invoice line.",
"type": "number"
},
"istaxable": {
"title": "Taxable",
"description": "This boolean field scpecifies whether taxes will be applied to an Invoice line.",
"type": "boolean"
},
"taxcode": {
"title": "Tax Code",
"type": "string"
},
"taxrate1": {
"title": "Tax Rate",
"description": "This is the tax percentage of each Invoice line.",
"type": "number"
}
},
"required": [
"item",
"quantity",
"rate",
"amount",
"istaxable",
"taxcode",
"taxrate1"
]
}
}
}
}
}
Hello! I think a recent change may have introduced an old bug about non-string examples. The particular code is here:
dtsgenerator/src/writeProcessor.ts
Lines 91 to 93 in 553cb94
When we do the split, we use toString
to support non-string examples. However, we then pass the non-stringified example
value into protectComment
, which attempts to call replace
on it. This function doesn't exist, so we get this error:
TypeError: str.replace is not a function
at WriteProcessor.protectComment (...\node_modules\dtsgenerator\src\writeProcessor.js:71:20)
at WriteProcessor.outputJSDoc (...\node_modules\dtsgenerator\src\writeProcessor.js:88:55)
at TypeDefinition.generateType (...\node_modules\dtsgenerator\src\typeDefinition.js:113:17)
at TypeDefinition.doProcess (...\node_modules\dtsgenerator\src\typeDefinition.js:48:14)
Adding a type on spec
might help prevent this problem, by declaring example
as string | number
instead of its current any
.
Thank you!
I use this lib primarily for server-side consumption, so my controllers can have types for request bodies and query params.
dtsgenerator
marks interface keys as optional (?
) when the schema does not mark them as required, which makes sense from the client-side perspective, but from the server-side, if the attribute has a default value the generated TS interface should not consider the key as optional.
My solution to date is to use a wrapper script that dives into the Definition schemas (Swagger v2) and sets keys as required if they have a default set, before throwing the spec into dtsgenerator
.
async function main() {
const spec = JSON.parse(fs.readFileSync(swaggerPath, { encoding: "utf-8" }));
for (const schema of Object.values(spec.definitions)) {
fixDefaults(schema);
}
const result = await dtsGenerator({
contents: [spec],
namespaceName: "MyAPI",
});
fs.writeFileSync(outPath, result, { encoding: "utf-8" });
}
function fixDefaults(schema) {
if (!schema.properties) {
return;
}
if (!schema.required) {
schema.required = [];
}
for (const [k, subSchema] of Object.entries(schema.properties)) {
if ("default" in subSchema && !schema.required.includes(k)) {
schema.required.push(k);
}
if (subSchema.type === "object") {
fixDefaults(subSchema);
}
}
}
I thought I would open this as an issue instead of a PR to see if this feature has any buyin.
It would mean adding an optional arg, called something?, and the implementation would need to be smarter than my workaround since determining if an attribute has a default varies from JSON Schema/Swagger/OpenAPI.
Thanks for this, this is awesome.
I do run into the following issue. The following (swagger/open api) schema crashes dtsgenerator:
{
"swagger": "2.0",
"definitions": {
"Zipcode": {
"type": "object",
"properties": {
"odd/even": {
"type": "string",
"enum": [
"odd",
"even"
]
}
}
}
}
}
Cmd: dtsgen test.json
Expected result: typescript definitions
Actual result: Error with stacktrace:
$ dtsgen test.json
TypeError: Cannot read property 'id' of undefined
at getId (/usr/lib/node_modules/dtsgenerator/dist/core/jsonSchema.js:45:19)
at Object.getSubSchema (/usr/lib/node_modules/dtsgenerator/dist/core/jsonSchema.js:24:21)
at DtsGenerator.normalizeContent (/usr/lib/node_modules/dtsgenerator/dist/core/dtsGenerator.js:79:35)
at DtsGenerator.generateProperties (/usr/lib/node_modules/dtsgenerator/dist/core/dtsGenerator.js:152:39)
at DtsGenerator.generateTypeModel (/usr/lib/node_modules/dtsgenerator/dist/core/dtsGenerator.js:128:14)
at DtsGenerator.walkSchema (/usr/lib/node_modules/dtsgenerator/dist/core/dtsGenerator.js:69:29)
at DtsGenerator.walk (/usr/lib/node_modules/dtsgenerator/dist/core/dtsGenerator.js:43:26)
at DtsGenerator.walk (/usr/lib/node_modules/dtsgenerator/dist/core/dtsGenerator.js:48:26)
at DtsGenerator.<anonymous> (/usr/lib/node_modules/dtsgenerator/dist/core/dtsGenerator.js:26:30)
at step (/usr/lib/node_modules/dtsgenerator/node_modules/tslib/tslib.js:133:27)
Is it possible to set a custom namespace?
Hello.
Is it possible to add strictNullTypes
option to generate source files friendly to typescript strictNullCheck option instead of optional properties? This would be really useful for projects which uses this typescript option.
When running dtsgen -o types.d.ts < openapi.yaml
, the emitted file contains a namespace based on the JSON path to the schemas, namely
declare namespace Definitions { ... }
Unfortunately, when one converts the file from OpenAPI 2.0 to OpenAPI 3.0, the location of the schemas is now in components schemas and the output is
declare namespace Components {
namespace Schemas {
I'd like the output to be independent of the JSON path where the schemas are found, as these names are really unrelated to the API itself; they are merely artifacts of the OpenAPI specification and layout.
I propose adding a --namespace <namespace>
option in the CLI, so one could do
dtsgen -o petstore.d.ts --namespace PetStore << petstore.yaml
to get
declare namespace PetStore { ... }
If you like, I can submit a PR to support this. It also allows one to use --namespace ~none~
so the emitted types are not in a namespace at all.
Hi,
This is more a suggestion/question than a bug. Enums are converted to union types like so:
status: 'active' | 'ended' | 'preparing';
This works well. However, I recently stumbled upon large enums and a sonar tslint rule that only allows for three union type members:
https://github.com/SonarSource/SonarTS/blob/master/sonarts-core/docs/rules/max-union-size.md
Sonar implies it is a better practice to define types than using union types. So that the example becomes:
type statusType = 'active' | 'ended' | 'preparing';
status: statusType;
I like the general idea, because the enum suddenly becomes reusable.
What do you think?
dtsgenerator creates some really great definitions. I'm having some issues with the $ref
implementation requiring a top-level id
.
OpenAPI defines the $ref
: using the URL of the current document as the base URI
. Setting the $ref
value to match a dtsgenerator-only-syntax matching an id:
causes trouble using this with any other OpenAPI software.
The base cause is that this is not valid a OpenAPI v3 schema. IE running it through something like swagger-parser will fail validation.
Consider this structure:
src/
- api.yaml
|-- components/
|---- models/
|------ Auth.yaml
|---- responses/
|------ Response.yaml
Assume that:
Api.yaml
has a $ref
to Response.yaml
and Auth.yaml
Response.yaml
has a $ref
to Auth.yaml
.If I set the id:
's and ref:
's to /Auth.yaml
and /Response.yaml
, it will work with dtsgenerator.
However, this will fail OpenAPI validation (id:
property not valid, and eg. /Auth.yaml
not found on disk.) and make this schema unusable with most other Open API packages.
If I set the $ref
to the follow the proper spec:
Api.yaml
:
./components/responses/Response.yaml
,./components/models/Auth.yaml
Response.yaml
:
../models/Auth.yaml
Then it will follow the spec and work with most other packages, but fail with dtsgenerator. There is no way to match the id:
property, since Auth.yaml
is referenced from two different places.
I'm sure there is a good reason why id
is required - but is there no way to use this package using the spec-defined implementation of $ref
? Or a workaround? Or am I doing something wrong?
Thanks for the great work!
Take the following example spec that contains 2 definitions: resource and createResource. Resource both defines its own _embedded property and inherits _embedded from createResource.
_embedded is the same in both cases except for the description.
swagger: '2.0'
info:
title: Example
version: 0.1.0
paths:
/tasks:
get:
summary: Return a collection of tasks
operationId: getTasks
responses:
'200':
description: OK
definitions:
resource:
allOf:
- $ref: '#/definitions/createResource'
properties:
_embedded:
description: >-
Test Description
type: object
createResource:
properties:
_embedded:
description: >-
Other Description
type: object
Note the generated output below:
declare namespace Definitions {
export interface CreateResource {
/**
* Other Description
*/
_embedded?: {};
}
export interface Resource {
/**
* Other Description // Expect this to be Test Description
*/
_embedded?: {};
}
}
Swagger editor shows the 2 resources with different descriptions, but the generated code has them with the same. This example uses Description to demo the issue, the issue is not limited to the Description field.
This OpenAPI 3 spec (JSON): https://drive.google.com/file/d/1VYU0B7-mJl_8S50vOiHCM65B7ljE3y64/view?usp=sharing fails with Error: The $ref target is not exists: #/components/schemas/Group/properties/capabilities/items/oneOf/7/properties/rawAcl/properties/scope/properties/all
which exists in the spec.
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.