forbeslindesay / typescript-json-validator Goto Github PK
View Code? Open in Web Editor NEWAutomatically generate a validator using JSON Schema and AJV for any TypeScript type.
License: MIT License
Automatically generate a validator using JSON Schema and AJV for any TypeScript type.
License: MIT License
Currently disables tslint by default, I'm using eslint
Not a big deal, I can just add it to my eslintignore, but it'd be nice if I could pass in the header upon generation. Maybe I'm missing something?
Thanks!
It would be great to be able to specify a different output directory when generating a validator. Unless I've missed it, it looks like the CLI will always generate *.validator.ts
file alongside the input file. Moving the validator after the fact isn't a trivial task either, since the imports would potentially be incorrect.
I'm getting the following error when attempting to build a generated file with TypeScript:
error TS1202: Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead.
4 import Ajv = require('ajv');
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Found 1 error.
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
I just tried npx typescript-json-schema ./src/unified/schema.ts Spec > output.json
and it included it in the output.
See this thread about the incompatibility of the two features: https://www.reddit.com/r/typescript/comments/e9span/isolatedmodules_prevents_exporting_a_type_from_a/
It'd be nice to have a flag that simply causes these types to not be re-exported (I'm not totally sure why they are in the first place). Workaround is just to delete the line that re-exports, for example, with sed:
sed -i "/^export [{]/d" $file.validator.ts
Specifically, I want to name the type that typescript-json-validator uses so that in the error messages, I see the custom name I use rather than the name of the TypeScript interface in the source file.
The --useNamedExport
option currently doesn't appear to work, throwing an error with just the message "temp"
. I'm assuming this was a temporary thing that got left in, as the functionality appears to otherwise be implemented.
The last statement in the following code block contains the require
that is causing the issue. It could be fixed by adding an import
statement and than assigning that value to the ajv.addMetaSchema()
calll.
The generated file:
// generated by typescript-json-validator
import {inspect} from 'util';
import Ajv = require('ajv');
import ourReportfrom './ourReport';
export const ajv = new ajv({"allErrors":true,"coerceTypes":false,"format":"fast","nullable":true,"unicode":true,"uniqueItems":true,"useDefaults":true});
ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json'));
update:
The following error doesn't like the node_modeuls so the fix doesn't work. Not sure how to fix this yet.
TS6059: File ' _PACKAGE_PATH_\node_modules\ajv\lib\refs\json-schema-draft-06.json' is not under 'rootDir' ' _PACKAGE_PATH_/src'. 'rootDir' is expected to contain all source files.
update:
Temp work-around ->
/* eslint-disable @typescript-eslint/no-var-requires */
This script will currently fail if the incremental: true
flag is specified in a tsconfig.json
file.
/* tsconfig.json */
{
"compilerOptions": {
"target": "es2018",
"module": "es2015",
"moduleResolution": "Node",
"noImplicitAny": true,
"skipLibCheck": true,
"experimentalDecorators": false,
"jsx": "react-native",
"importHelpers": false,
"pretty": true,
"sourceMap": true,
"strict": true,
"esModuleInterop": true,
"outDir": "lib",
"forceConsistentCasingInFileNames": true,
"noEmitOnError": false,
"noErrorTruncation": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"declaration": false,
"lib": ["es2018"],
"incremental": true
},
"include": ["src"]
}
$ npx typescript-json-validator file.ts SomeOutput
Option '--incremental' can only be specified using tsconfig, emitting to single file or when option `--tsBuildInfoFile` is specified.
Did not expect generator to be null
Not able to create correct schema of the types.
type file: test.ts
export type test = {
a: string;
}
validator generated by npx typescript-json-validator --id test --collection test.ts
export const Schema = {
$id: 'test',
$schema: 'http://json-schema.org/draft-07/schema#',
definitions: {},
};
tried npx cross-env typescript-json-validator --id test --collection test.ts
as well but no luck
It would be nice if old issues are reviewed and removed.
Since there have been no commits for a while and there are a number of open PRs and issues I am wondering if this project is still maintained?
I'm seeing an issue that was supposedly fixed here #17
This issue is still occurring to me in version 2.4.2.
This is a part of the generated validator.
/* tslint:disable */
// generated by typescript-json-validator
import { inspect } from 'util';
import Ajv = require('ajv');
export const ajv = new Ajv({
allErrors: true,
coerceTypes: false,
format: 'fast',
nullable: true,
unicode: true,
uniqueItems: true,
useDefaults: true,
});
ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json'));
In the browser I'm getting
blueprint.model.validator.ts:6 Uncaught ReferenceError: Ajv is not defined
Changing import Ajv = require('ajv');
to const Ajv = require('ajv');
makes it work.
Also, interfaces are imported using default import even though the interface file has no default exports.
Hello,
is it possible to have a parameter to change the output filename ?
Thanks
Hi,
I'm not sure if it is an problem with this tool or with the gitlab runner.
I'm using the Gitlab pipe to build a node server. Since I added this validator, the pipe fails. Locally running the same commands as in the gitlab-ci.yml all works perfectly.
Gitlab Error:
> [email protected] tsc
> tsc
models/Agenda/agenda.validator.ts(127,77): error TS2694: Namespace '"*"' has no exported member 'ValidateFunction'.
models/Agenda/agenda.validator.ts
...
export type ValidateFunction<T> = ((data: unknown) => data is T) & Pick<Ajv.ValidateFunction, 'errors'>
export const isIAgenda = ajv.compile(IAgendaSchema) as ValidateFunction<IAgenda>;
export default function validate(value: unknown): IAgenda {
if (isIAgenda(value)) {
return value;
} else {
throw new Error(
ajv.errorsText(isIAgenda.errors!.filter((e: any) => e.keyword !== 'if'), {dataVar: 'IAgenda'}) +
'\n\n' +
inspect(value),
);
}
}
gitlab-ci.yml
build:
stage: build
script:
- (cd backend && npm ci --cache .npm --prefer-offline && npm run tsc)
- mkdir -p dist
- cp -r backend dist/backend
- cp web/cms.zip dist/cms.zip
artifacts:
paths:
- dist
- web/app
I have quite a few problems using the generated file:
I run npx typescript-json-validator src/CustomApp.ts ICustomApp
Which generated this file
`import {inspect} from 'util';
import Ajv = require('ajv'); // 1
import ICustomApp from './CustomApp'; // 2
export const ajv = new Ajv({"allErrors":true,"coerceTypes":false,"format":"fast","nullable":true,"unicode":true,"uniqueItems":true,"useDefaults":true}); // 1, 3
ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json'));
export {ICustomApp};
import Ajv = require('ajv')
...
export type ValidateFunction = ((data: unknown) => data is T) & Pick<Ajv.ValidateFunction, 'errors'> // 4
export const isICustomApp = ajv.compile(ICustomAppSchema) as ValidateFunction;
export default function validate(value: unknown): ICustomApp {
if (isICustomApp(value)) {
return value;
} else {
throw new Error(
ajv.errorsText(isICustomApp.errors!.filter((e: any) => e.keyword !== 'if'), {dataVar: 'ICustomApp'}) +
'\n\n' +
inspect(value),
);
}
}`
This yields those errors:
I can fix 2 with changing it to `import {ICustomApp} from './CustomApp'; and
1 with import Ajv from "ajv". But this results in the following two new errors:
Argument of type '{ allErrors: true; coerceTypes: false; format: string; nullable: boolean; unicode: true; uniqueItems: boolean; useDefaults: true; }' is not assignable to parameter of type 'Options'. Object literal may only specify known properties, and '"format"' does not exist in type 'Options'.
`
Ajv' only refers to a type, but is being used as a namespace here.ts(2702) Exported type alias 'ValidateFunction' has or is using private name 'Ajv'
3 Can be fixed with removing "format":"fast","nullable":true, "uniqueItems":true,
4 Can be fixed only when changing the import back to import Ajv = require('ajv');
which again triggers error 1.
Am I doing something wrong or is the tool generating wrong files?
Interface
interface Foo {
id: number | null;
}
fails the validation by saying Error: Foo.id should be number
Validator file
...
properties: {
id: {
type: 'number',
},
}
...
Any plans or ideas on how to get this to work with recursive types? I get an error when attempting to use it, Maximum call stack size exceeded
I guess for now the alternative is to flatten my data for validation purposes
I seems that typescript utility types are not supported.
import jwt from 'express-jwt';
import jwks from 'jwks-rsa';
export default interface ConfigOptions extends Omit<jwt.Options, 'secret'>, jwks.ClientOptions {
secret?: Pick<jwt.Options, 'secret'>,
issuer: any,
audience: any
}
Utility types
The generated schema looks like this.
export const ConfigOptionsSchema = {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"patternProperties": {
"^[0-9]+$": {
}
},
"type": "object"
};
Same result with --format full
Am I doing something wrong?
After my update of package-log.json file this compilation error is thrown.
TSError: ⨯ Unable to compile TypeScript:
src/components/campaigns/controllers/validators/validate-agents.ts:6:24 - error TS2351: This expression is not constructable.
Type 'typeof import("/Users/jurajzovinec/Documents/MY CLOUDTALK PROJECTS/campaigns/node_modules/ajv/dist/ajv")' has no construct signatures.
validator function
import { inspect } from 'util'
import Ajv = require('ajv')
import { Agents } from '../shared/types'
export const ajv = new Ajv({ // Ajv is underscored
allErrors: true,
coerceTypes: false,
format: 'fast',
nullable: true,
unicode: true,
uniqueItems: true,
useDefaults: true,
})
Ajv reference
import type { AnySchemaObject } from "./types";
import AjvCore from "./core";
declare class Ajv extends AjvCore {
_addVocabularies(): void;
_addDefaultMetaSchema(): void;
defaultMeta(): string | AnySchemaObject | undefined;
}
export default Ajv;
export { Format, FormatDefinition, AsyncFormatDefinition, KeywordDefinition, KeywordErrorDefinition, CodeKeywordDefinition, MacroKeywordDefinition, FuncKeywordDefinition, Vocabulary, Schema, SchemaObject, AnySchemaObject, AsyncSchema, AnySchema, ValidateFunction, AsyncValidateFunction, SchemaValidateFunction, ErrorObject, ErrorNoParams, } from "./types";
export { Plugin, Options, CodeOptions, InstanceOptions, Logger, ErrorsTextOptions } from "./core";
export { SchemaCxt, SchemaObjCxt } from "./compile";
export { KeywordCxt } from "./compile/validate";
export { DefinedError } from "./vocabularies/errors";
export { JSONType } from "./compile/rules";
export { JSONSchemaType } from "./types/json-schema";
export { _, str, stringify, nil, Name, Code, CodeGen, CodeGenOptions } from "./compile/codegen";
Also deprecation warning thrown at npm install may be helpful
npm WARN deprecated @types/[email protected]: This is a stub types definition for ajv (https://github.com/epoberezkin/ajv). ajv provides its own type definitions, so you don't need @types/ajv installed!
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.