quicktype-core 23.2.6 → 23.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ConvenienceRenderer.d.ts +3 -0
- package/dist/ConvenienceRenderer.js +71 -4
- package/dist/language/CJSON/CJSONRenderer.d.ts +1 -0
- package/dist/language/CJSON/CJSONRenderer.js +3 -0
- package/dist/language/CPlusPlus/CPlusPlusRenderer.d.ts +1 -0
- package/dist/language/CPlusPlus/CPlusPlusRenderer.js +3 -0
- package/dist/language/CSharp/CSharpRenderer.js +8 -2
- package/dist/language/Objective-C/ObjectiveCRenderer.d.ts +1 -0
- package/dist/language/Objective-C/ObjectiveCRenderer.js +3 -0
- package/dist/language/Php/PhpRenderer.d.ts +1 -0
- package/dist/language/Php/PhpRenderer.js +17 -30
- package/dist/language/Python/PythonRenderer.d.ts +1 -1
- package/dist/language/Python/PythonRenderer.js +1 -8
- package/package.json +2 -2
|
@@ -132,6 +132,9 @@ export declare abstract class ConvenienceRenderer extends Renderer {
|
|
|
132
132
|
protected emitComments(comments: Comment[]): void;
|
|
133
133
|
protected emitCommentLines(lines: Sourcelike[], { lineStart, firstLineStart, lineEnd, beforeComment, afterComment, }?: CommentOptions): void;
|
|
134
134
|
protected emitDescription(description: Sourcelike[] | undefined): void;
|
|
135
|
+
private commentLineEscapes;
|
|
136
|
+
protected get commentLinesSpliceOnBackslash(): boolean;
|
|
137
|
+
private escapeCommentLine;
|
|
135
138
|
protected emitDescriptionBlock(lines: Sourcelike[]): void;
|
|
136
139
|
protected emitPropertyTable(c: ClassType, makePropertyRow: (name: Name, jsonName: string, p: ClassProperty) => Sourcelike[]): void;
|
|
137
140
|
private processGraph;
|
|
@@ -32,7 +32,13 @@ const unionMemberNameOrder = 40;
|
|
|
32
32
|
function splitDescription(descriptions) {
|
|
33
33
|
if (descriptions === undefined)
|
|
34
34
|
return undefined;
|
|
35
|
-
|
|
35
|
+
// U+0085, U+2028 and U+2029 count as line terminators in some
|
|
36
|
+
// target languages (JavaScript, C#), so they must not survive
|
|
37
|
+
// into single-line comments.
|
|
38
|
+
const description = Array.from(descriptions)
|
|
39
|
+
.join("\n\n")
|
|
40
|
+
.replace(/\r\n?|[\u0085\u2028\u2029]/g, "\n")
|
|
41
|
+
.trim();
|
|
36
42
|
if (description === "")
|
|
37
43
|
return undefined;
|
|
38
44
|
return wordWrap(description)
|
|
@@ -577,6 +583,13 @@ class ConvenienceRenderer extends Renderer_1.Renderer {
|
|
|
577
583
|
});
|
|
578
584
|
}
|
|
579
585
|
emitCommentLines(lines, { lineStart = this.commentLineStart, firstLineStart = lineStart, lineEnd, beforeComment, afterComment, } = {}) {
|
|
586
|
+
const replacements = this.commentLineEscapes({
|
|
587
|
+
lineStart,
|
|
588
|
+
firstLineStart,
|
|
589
|
+
lineEnd,
|
|
590
|
+
beforeComment,
|
|
591
|
+
afterComment,
|
|
592
|
+
});
|
|
580
593
|
if (beforeComment !== undefined) {
|
|
581
594
|
this.emitLine(beforeComment);
|
|
582
595
|
}
|
|
@@ -584,14 +597,15 @@ class ConvenienceRenderer extends Renderer_1.Renderer {
|
|
|
584
597
|
for (const line of lines) {
|
|
585
598
|
let start = first ? firstLineStart : lineStart;
|
|
586
599
|
first = false;
|
|
587
|
-
|
|
600
|
+
const escapedLine = this.escapeCommentLine(line, replacements, lineEnd);
|
|
601
|
+
if (this.sourcelikeToString(escapedLine) === "") {
|
|
588
602
|
start = (0, Strings_1.trimEnd)(start);
|
|
589
603
|
}
|
|
590
604
|
if (lineEnd) {
|
|
591
|
-
this.emitLine(start,
|
|
605
|
+
this.emitLine(start, escapedLine, lineEnd);
|
|
592
606
|
}
|
|
593
607
|
else {
|
|
594
|
-
this.emitLine(start,
|
|
608
|
+
this.emitLine(start, escapedLine);
|
|
595
609
|
}
|
|
596
610
|
}
|
|
597
611
|
if (afterComment !== undefined) {
|
|
@@ -604,6 +618,59 @@ class ConvenienceRenderer extends Renderer_1.Renderer {
|
|
|
604
618
|
// FIXME: word-wrap
|
|
605
619
|
this.emitDescriptionBlock(description);
|
|
606
620
|
}
|
|
621
|
+
commentLineEscapes(options) {
|
|
622
|
+
const delimiters = [
|
|
623
|
+
options.lineStart,
|
|
624
|
+
options.firstLineStart,
|
|
625
|
+
options.lineEnd,
|
|
626
|
+
options.beforeComment,
|
|
627
|
+
options.afterComment,
|
|
628
|
+
];
|
|
629
|
+
const containsDelimiter = (delimiter) => delimiters.some((part) => { var _a; return (_a = part === null || part === void 0 ? void 0 : part.includes(delimiter)) !== null && _a !== void 0 ? _a : false; });
|
|
630
|
+
const replacements = [];
|
|
631
|
+
if (containsDelimiter("/*") || containsDelimiter("*/")) {
|
|
632
|
+
// The opener must be escaped, too: some languages (Kotlin,
|
|
633
|
+
// Scala) nest block comments, so a lone `/*` would reopen a
|
|
634
|
+
// comment that the closing delimiter can't terminate.
|
|
635
|
+
replacements.push(["/*", "/ *"], ["*/", "* /"]);
|
|
636
|
+
}
|
|
637
|
+
if (containsDelimiter("{-") || containsDelimiter("-}")) {
|
|
638
|
+
replacements.push(["{-", "{ -"], ["-}", "- }"]);
|
|
639
|
+
}
|
|
640
|
+
if (containsDelimiter('"""')) {
|
|
641
|
+
// Triple-quoted comments (Python docstrings, Elixir
|
|
642
|
+
// moduledocs) are string literals, so backslashes are escape
|
|
643
|
+
// characters — in particular a trailing backslash would
|
|
644
|
+
// swallow the first quote of the closing delimiter.
|
|
645
|
+
replacements.push(["\\", "\\\\"], ['"""', '\\"\\"\\"']);
|
|
646
|
+
}
|
|
647
|
+
return replacements;
|
|
648
|
+
}
|
|
649
|
+
// C-family lexers splice a backslash-newline into one line even
|
|
650
|
+
// inside comments, which would pull the following line of
|
|
651
|
+
// generated code into an attacker-controlled comment.
|
|
652
|
+
get commentLinesSpliceOnBackslash() {
|
|
653
|
+
return false;
|
|
654
|
+
}
|
|
655
|
+
escapeCommentLine(line, replacements, lineEnd) {
|
|
656
|
+
if (replacements.length === 0 && !this.commentLinesSpliceOnBackslash) {
|
|
657
|
+
return line;
|
|
658
|
+
}
|
|
659
|
+
let escaped = replacements.reduce((result, [unsafe, safe]) => result.split(unsafe).join(safe), this.sourcelikeToString(line));
|
|
660
|
+
// A quote at the end of the line would merge with a closing
|
|
661
|
+
// `"""` emitted right after it. The quote needs escaping iff
|
|
662
|
+
// it's preceded by an even number of backslashes.
|
|
663
|
+
if (lineEnd !== undefined && lineEnd.startsWith('"')) {
|
|
664
|
+
const trailing = /(\\*)"$/.exec(escaped);
|
|
665
|
+
if (trailing !== null && trailing[1].length % 2 === 0) {
|
|
666
|
+
escaped = `${escaped.slice(0, -1)}\\"`;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
if (this.commentLinesSpliceOnBackslash && escaped.endsWith("\\")) {
|
|
670
|
+
escaped = `${escaped}.`;
|
|
671
|
+
}
|
|
672
|
+
return escaped;
|
|
673
|
+
}
|
|
607
674
|
emitDescriptionBlock(lines) {
|
|
608
675
|
this.emitCommentLines(lines);
|
|
609
676
|
}
|
|
@@ -219,6 +219,7 @@ export declare class CJSONRenderer extends ConvenienceRenderer {
|
|
|
219
219
|
* @pram global: true if global include, false otherwise (default)
|
|
220
220
|
*/
|
|
221
221
|
protected emitIncludeLine(name: Sourcelike, global?: boolean): void;
|
|
222
|
+
protected get commentLinesSpliceOnBackslash(): boolean;
|
|
222
223
|
/**
|
|
223
224
|
* Emit description block
|
|
224
225
|
* @param lines: description block lines
|
|
@@ -3067,6 +3067,9 @@ class CJSONRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
3067
3067
|
emitIncludeLine(name, global = false) {
|
|
3068
3068
|
this.emitLine("#include ", global ? "<" : '"', name, global ? ">" : '"');
|
|
3069
3069
|
}
|
|
3070
|
+
get commentLinesSpliceOnBackslash() {
|
|
3071
|
+
return true;
|
|
3072
|
+
}
|
|
3070
3073
|
/**
|
|
3071
3074
|
* Emit description block
|
|
3072
3075
|
* @param lines: description block lines
|
|
@@ -65,6 +65,7 @@ export declare class CPlusPlusRenderer extends ConvenienceRenderer {
|
|
|
65
65
|
protected finishFile(): void;
|
|
66
66
|
protected get needsTypeDeclarationBeforeUse(): boolean;
|
|
67
67
|
protected canBeForwardDeclared(t: Type): boolean;
|
|
68
|
+
protected get commentLinesSpliceOnBackslash(): boolean;
|
|
68
69
|
protected emitDescriptionBlock(lines: Sourcelike[]): void;
|
|
69
70
|
protected emitBlock(line: Sourcelike, withSemicolon: boolean, f: () => void, withIndent?: boolean): void;
|
|
70
71
|
protected emitNamespaces(namespaceNames: Iterable<string>, f: () => void): void;
|
|
@@ -458,6 +458,9 @@ class CPlusPlusRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
458
458
|
const kind = t.kind;
|
|
459
459
|
return kind === "class";
|
|
460
460
|
}
|
|
461
|
+
get commentLinesSpliceOnBackslash() {
|
|
462
|
+
return true;
|
|
463
|
+
}
|
|
461
464
|
emitDescriptionBlock(lines) {
|
|
462
465
|
this.emitCommentLines(lines, {
|
|
463
466
|
lineStart: " * ",
|
|
@@ -143,12 +143,18 @@ class CSharpRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
143
143
|
return [...propertyArray, csType, " ", name, " { get; set; }"];
|
|
144
144
|
}
|
|
145
145
|
emitDescriptionBlock(lines) {
|
|
146
|
+
// Doc comments are XML, so anything that could be mistaken
|
|
147
|
+
// for markup must be escaped.
|
|
148
|
+
const escapedLines = lines.map((line) => this.sourcelikeToString(line)
|
|
149
|
+
.replace(/&/g, "&")
|
|
150
|
+
.replace(/</g, "<")
|
|
151
|
+
.replace(/>/g, ">"));
|
|
146
152
|
const start = "/// <summary>";
|
|
147
153
|
if (this._csOptions.dense) {
|
|
148
|
-
this.emitLine(start,
|
|
154
|
+
this.emitLine(start, escapedLines.join("; "), "</summary>");
|
|
149
155
|
}
|
|
150
156
|
else {
|
|
151
|
-
this.emitCommentLines(
|
|
157
|
+
this.emitCommentLines(escapedLines, {
|
|
152
158
|
lineStart: "/// ",
|
|
153
159
|
beforeComment: start,
|
|
154
160
|
afterComment: "/// </summary>",
|
|
@@ -21,6 +21,7 @@ export declare class ObjectiveCRenderer extends ConvenienceRenderer {
|
|
|
21
21
|
protected makeUnionMemberNamer(): null;
|
|
22
22
|
protected makeEnumCaseNamer(): Namer;
|
|
23
23
|
protected namedTypeToNameForTopLevel(type: Type): Type | undefined;
|
|
24
|
+
protected get commentLinesSpliceOnBackslash(): boolean;
|
|
24
25
|
protected emitDescriptionBlock(lines: Sourcelike[]): void;
|
|
25
26
|
protected emitBlock(line: Sourcelike, f: () => void): void;
|
|
26
27
|
protected emitMethod(declaration: Sourcelike, f: () => void): void;
|
|
@@ -64,6 +64,9 @@ class ObjectiveCRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
64
64
|
namedTypeToNameForTopLevel(type) {
|
|
65
65
|
return type;
|
|
66
66
|
}
|
|
67
|
+
get commentLinesSpliceOnBackslash() {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
67
70
|
emitDescriptionBlock(lines) {
|
|
68
71
|
this.emitCommentLines(lines, { lineStart: "/// " });
|
|
69
72
|
}
|
|
@@ -35,6 +35,7 @@ export declare class PhpRenderer extends ConvenienceRenderer {
|
|
|
35
35
|
protected finishFile(): void;
|
|
36
36
|
protected emitFileHeader(fileName: Sourcelike, _imports: string[]): void;
|
|
37
37
|
emitDescriptionBlock(lines: Sourcelike[]): void;
|
|
38
|
+
private emitDocBlockDescription;
|
|
38
39
|
emitBlock(line: Sourcelike, f: () => void): void;
|
|
39
40
|
protected phpType(_reference: boolean, t: Type, isOptional?: boolean, prefix?: string, suffix?: string): Sourcelike;
|
|
40
41
|
protected phpDocConvertType(className: Name, t: Type): Sourcelike;
|
|
@@ -133,6 +133,17 @@ class PhpRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
133
133
|
afterComment: " */",
|
|
134
134
|
});
|
|
135
135
|
}
|
|
136
|
+
emitDocBlockDescription(desc) {
|
|
137
|
+
if (desc === undefined) {
|
|
138
|
+
this.emitLine("/**");
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
this.emitCommentLines(desc, {
|
|
142
|
+
lineStart: " * ",
|
|
143
|
+
beforeComment: "/**",
|
|
144
|
+
});
|
|
145
|
+
this.emitLine(" *");
|
|
146
|
+
}
|
|
136
147
|
emitBlock(line, f) {
|
|
137
148
|
this.emitLine(line, " {");
|
|
138
149
|
this.indent(f);
|
|
@@ -350,11 +361,7 @@ class PhpRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
350
361
|
});
|
|
351
362
|
}
|
|
352
363
|
emitFromMethod(names, p, className, _name, desc) {
|
|
353
|
-
this.
|
|
354
|
-
if (desc !== undefined) {
|
|
355
|
-
this.emitLine(" * ", desc);
|
|
356
|
-
this.emitLine(" *");
|
|
357
|
-
}
|
|
364
|
+
this.emitDocBlockDescription(desc);
|
|
358
365
|
// this.emitLine(" * @param ", this.phpType(false, p.type, false, "", "|null"));
|
|
359
366
|
this.emitLine(" * @param ", this.phpConvertType(className, p.type), " $value");
|
|
360
367
|
this.emitLine(" * @throws Exception");
|
|
@@ -373,11 +380,7 @@ class PhpRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
373
380
|
});
|
|
374
381
|
}
|
|
375
382
|
emitToMethod(names, p, className, name, desc) {
|
|
376
|
-
this.
|
|
377
|
-
if (desc !== undefined) {
|
|
378
|
-
this.emitLine(" * ", desc);
|
|
379
|
-
this.emitLine(" *");
|
|
380
|
-
}
|
|
383
|
+
this.emitDocBlockDescription(desc);
|
|
381
384
|
this.emitLine(" * @throws Exception");
|
|
382
385
|
this.emitLine(" * @return ", this.phpConvertType(className, p.type));
|
|
383
386
|
this.emitLine(" */");
|
|
@@ -402,11 +405,7 @@ class PhpRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
402
405
|
});
|
|
403
406
|
}
|
|
404
407
|
emitValidateMethod(names, p, className, name, desc) {
|
|
405
|
-
this.
|
|
406
|
-
if (desc !== undefined) {
|
|
407
|
-
this.emitLine(" * ", desc);
|
|
408
|
-
this.emitLine(" *");
|
|
409
|
-
}
|
|
408
|
+
this.emitDocBlockDescription(desc);
|
|
410
409
|
this.emitLine(" * @param ", this.phpType(false, p.type, false, "", "|null"));
|
|
411
410
|
this.emitLine(" * @return bool");
|
|
412
411
|
this.emitLine(" * @throws Exception");
|
|
@@ -424,11 +423,7 @@ class PhpRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
424
423
|
}
|
|
425
424
|
emitGetMethod(names, p, className, name, desc) {
|
|
426
425
|
if (this._options.withGet) {
|
|
427
|
-
this.
|
|
428
|
-
if (desc !== undefined) {
|
|
429
|
-
this.emitLine(" * ", desc);
|
|
430
|
-
this.emitLine(" *");
|
|
431
|
-
}
|
|
426
|
+
this.emitDocBlockDescription(desc);
|
|
432
427
|
if (!this._options.fastGet) {
|
|
433
428
|
this.emitLine(" * @throws Exception");
|
|
434
429
|
}
|
|
@@ -458,11 +453,7 @@ class PhpRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
458
453
|
}
|
|
459
454
|
emitSetMethod(names, p, className, name, desc) {
|
|
460
455
|
if (this._options.withSet) {
|
|
461
|
-
this.
|
|
462
|
-
if (desc !== undefined) {
|
|
463
|
-
this.emitLine(" * ", desc);
|
|
464
|
-
this.emitLine(" *");
|
|
465
|
-
}
|
|
456
|
+
this.emitDocBlockDescription(desc);
|
|
466
457
|
this.emitLine(" * @param ", this.phpType(false, p.type, false, "", "|null"));
|
|
467
458
|
this.emitLine(" * @throws Exception");
|
|
468
459
|
this.emitLine(" */");
|
|
@@ -481,11 +472,7 @@ class PhpRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
481
472
|
}
|
|
482
473
|
emitSampleMethod(names, p, className, name, desc, idx) {
|
|
483
474
|
if (this._options.withGet) {
|
|
484
|
-
this.
|
|
485
|
-
if (desc !== undefined) {
|
|
486
|
-
this.emitLine(" * ", desc);
|
|
487
|
-
this.emitLine(" *");
|
|
488
|
-
}
|
|
475
|
+
this.emitDocBlockDescription(desc);
|
|
489
476
|
const rendered = this.phpType(false, p.type);
|
|
490
477
|
this.emitLine(" * @return ", rendered);
|
|
491
478
|
this.emitLine(" */");
|
|
@@ -2,7 +2,7 @@ import { ConvenienceRenderer, type ForbiddenWordsInfo } from "../../ConvenienceR
|
|
|
2
2
|
import { type Name, type Namer } from "../../Naming";
|
|
3
3
|
import type { RenderContext } from "../../Renderer";
|
|
4
4
|
import type { OptionValues } from "../../RendererOptions";
|
|
5
|
-
import {
|
|
5
|
+
import type { Sourcelike } from "../../Source";
|
|
6
6
|
import type { TargetLanguage } from "../../TargetLanguage";
|
|
7
7
|
import { type ClassProperty, ClassType, EnumType, type Type } from "../../Type";
|
|
8
8
|
import type { pythonOptions } from "./language";
|
|
@@ -4,7 +4,6 @@ exports.PythonRenderer = void 0;
|
|
|
4
4
|
const collection_utils_1 = require("collection-utils");
|
|
5
5
|
const ConvenienceRenderer_1 = require("../../ConvenienceRenderer");
|
|
6
6
|
const Naming_1 = require("../../Naming");
|
|
7
|
-
const Source_1 = require("../../Source");
|
|
8
7
|
const Strings_1 = require("../../support/Strings");
|
|
9
8
|
const Support_1 = require("../../support/Support");
|
|
10
9
|
const Transformers_1 = require("../../Transformers");
|
|
@@ -45,14 +44,8 @@ class PythonRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
45
44
|
}
|
|
46
45
|
emitDescriptionBlock(lines) {
|
|
47
46
|
if (lines.length === 1) {
|
|
48
|
-
const docstring = (0, Source_1.modifySource)((content) => {
|
|
49
|
-
if (content.endsWith('"')) {
|
|
50
|
-
return content.slice(0, -1) + '\\"';
|
|
51
|
-
}
|
|
52
|
-
return content;
|
|
53
|
-
}, lines[0]);
|
|
54
47
|
this.emitComments([
|
|
55
|
-
{ customLines:
|
|
48
|
+
{ customLines: lines, lineStart: '"""', lineEnd: '"""' },
|
|
56
49
|
]);
|
|
57
50
|
}
|
|
58
51
|
else {
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quicktype-core",
|
|
3
|
-
"version": "23.
|
|
3
|
+
"version": "23.3.0",
|
|
4
4
|
"description": "The quicktype engine as a library",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
-
"repository": "https://github.com/
|
|
8
|
+
"repository": "https://github.com/glideapps/quicktype",
|
|
9
9
|
"scripts": {
|
|
10
10
|
"clean": "rm -rf dist node_modules *~",
|
|
11
11
|
"build": "./env.sh && tsc"
|