@contractkit/plugin-typescript 0.28.0 → 0.28.1
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/.turbo/turbo-build$colon$ci.log +4 -4
- package/.turbo/turbo-test$colon$ci.log +19 -18
- package/CHANGELOG.md +8 -0
- package/dist/codegen-contract.d.ts.map +1 -1
- package/dist/codegen-sdk.d.ts.map +1 -1
- package/dist/index.js +234 -210
- package/dist/index.js.map +1 -1
- package/dist/path-utils.d.ts.map +1 -1
- package/dist/ts-render.d.ts +6 -0
- package/dist/ts-render.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/codegen-contract.ts +7 -4
- package/src/codegen-operation.ts +4 -4
- package/src/codegen-plain-types.ts +17 -14
- package/src/codegen-sdk.ts +5 -4
- package/src/path-utils.ts +37 -20
- package/src/ts-render.ts +21 -6
- package/tests/codegen-contract.test.ts +4 -0
- package/tests/codegen-sdk.test.ts +8 -0
- package/tests/escaping-security.test.ts +143 -0
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/clover.xml +0 -2213
- package/coverage/coverage-final.json +0 -9
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +0 -131
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -210
- package/coverage/src/codegen-contract.ts.html +0 -3661
- package/coverage/src/codegen-operation.ts.html +0 -2584
- package/coverage/src/codegen-plain-types.ts.html +0 -997
- package/coverage/src/codegen-sdk.ts.html +0 -3901
- package/coverage/src/index.html +0 -206
- package/coverage/src/index.ts.html +0 -2761
- package/coverage/src/path-utils.ts.html +0 -745
- package/coverage/src/ts-render.ts.html +0 -592
- package/coverage/tests/helpers.ts.html +0 -826
- package/coverage/tests/index.html +0 -116
package/dist/index.js
CHANGED
|
@@ -8,6 +8,160 @@ import { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync, readdirSync
|
|
|
8
8
|
// src/codegen-contract.ts
|
|
9
9
|
import { relative, dirname } from "path";
|
|
10
10
|
import { collectTypeRefs, computeModelsWithOutput as ckComputeModelsWithOutput, collectExternalOutputRefs as ckCollectExternalOutputRefs } from "@contractkit/core";
|
|
11
|
+
|
|
12
|
+
// src/ts-render.ts
|
|
13
|
+
var JSON_VALUE_TYPE_DECL = "export type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue };";
|
|
14
|
+
function quoteKey(name) {
|
|
15
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name) ? name : `'${name}'`;
|
|
16
|
+
}
|
|
17
|
+
__name(quoteKey, "quoteKey");
|
|
18
|
+
function escapeJsDocLines(text) {
|
|
19
|
+
return text.replace(/\*\//g, "*\\/").split("\n");
|
|
20
|
+
}
|
|
21
|
+
__name(escapeJsDocLines, "escapeJsDocLines");
|
|
22
|
+
function escapeSingleQuoted(s) {
|
|
23
|
+
return s.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n").replace(/\r/g, "\\r");
|
|
24
|
+
}
|
|
25
|
+
__name(escapeSingleQuoted, "escapeSingleQuoted");
|
|
26
|
+
function headerNameToProperty(name) {
|
|
27
|
+
const parts = name.split(/[-_]/).filter(Boolean);
|
|
28
|
+
return parts.map((p, i) => {
|
|
29
|
+
const lower = p.toLowerCase();
|
|
30
|
+
return i === 0 ? lower : lower.charAt(0).toUpperCase() + lower.slice(1);
|
|
31
|
+
}).join("");
|
|
32
|
+
}
|
|
33
|
+
__name(headerNameToProperty, "headerNameToProperty");
|
|
34
|
+
function renderTsType(type) {
|
|
35
|
+
switch (type.kind) {
|
|
36
|
+
case "scalar":
|
|
37
|
+
return renderTsScalar(type.name);
|
|
38
|
+
case "array": {
|
|
39
|
+
const inner = renderTsType(type.item);
|
|
40
|
+
const needsParens = type.item.kind === "union" || type.item.kind === "discriminatedUnion" || type.item.kind === "intersection" || type.item.kind === "enum";
|
|
41
|
+
return needsParens ? `(${inner})[]` : `${inner}[]`;
|
|
42
|
+
}
|
|
43
|
+
case "tuple":
|
|
44
|
+
return `[${type.items.map(renderTsType).join(", ")}]`;
|
|
45
|
+
case "record":
|
|
46
|
+
return `Record<${renderTsType(type.key)}, ${renderTsType(type.value)}>`;
|
|
47
|
+
case "enum":
|
|
48
|
+
return type.values.map((v) => `'${escapeSingleQuoted(v)}'`).join(" | ");
|
|
49
|
+
case "literal":
|
|
50
|
+
return typeof type.value === "string" ? `'${escapeSingleQuoted(type.value)}'` : String(type.value);
|
|
51
|
+
case "union":
|
|
52
|
+
return type.members.map(renderTsType).join(" | ");
|
|
53
|
+
case "discriminatedUnion":
|
|
54
|
+
return type.members.map(renderTsType).join(" | ");
|
|
55
|
+
case "intersection":
|
|
56
|
+
return type.members.map(renderTsType).join(" & ");
|
|
57
|
+
case "ref":
|
|
58
|
+
return type.name;
|
|
59
|
+
case "lazy":
|
|
60
|
+
return renderTsType(type.inner);
|
|
61
|
+
case "inlineObject":
|
|
62
|
+
return renderTsInlineObject(type.fields);
|
|
63
|
+
default:
|
|
64
|
+
return "unknown";
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
__name(renderTsType, "renderTsType");
|
|
68
|
+
function renderTsScalar(name) {
|
|
69
|
+
switch (name) {
|
|
70
|
+
case "string":
|
|
71
|
+
case "email":
|
|
72
|
+
case "url":
|
|
73
|
+
case "uuid":
|
|
74
|
+
return "string";
|
|
75
|
+
case "number":
|
|
76
|
+
case "int":
|
|
77
|
+
return "number";
|
|
78
|
+
case "bigint":
|
|
79
|
+
return "bigint";
|
|
80
|
+
case "boolean":
|
|
81
|
+
return "boolean";
|
|
82
|
+
case "date":
|
|
83
|
+
case "time":
|
|
84
|
+
case "datetime":
|
|
85
|
+
case "duration":
|
|
86
|
+
case "interval":
|
|
87
|
+
return "string";
|
|
88
|
+
case "null":
|
|
89
|
+
return "null";
|
|
90
|
+
case "unknown":
|
|
91
|
+
return "unknown";
|
|
92
|
+
case "object":
|
|
93
|
+
return "Record<string, unknown>";
|
|
94
|
+
case "binary":
|
|
95
|
+
return "Blob";
|
|
96
|
+
case "json":
|
|
97
|
+
return "JsonValue";
|
|
98
|
+
default: {
|
|
99
|
+
const _exhaustive = name;
|
|
100
|
+
throw new Error(`plugin-typescript: unmapped scalar '${String(_exhaustive)}' \u2014 add a case`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
__name(renderTsScalar, "renderTsScalar");
|
|
105
|
+
function renderTsInlineObject(fields) {
|
|
106
|
+
const entries = fields.map((f) => {
|
|
107
|
+
const opt = f.optional ? "?" : "";
|
|
108
|
+
return `${quoteKey(f.name)}${opt}: ${renderTsType(f.type)}`;
|
|
109
|
+
});
|
|
110
|
+
return `{ ${entries.join("; ")} }`;
|
|
111
|
+
}
|
|
112
|
+
__name(renderTsInlineObject, "renderTsInlineObject");
|
|
113
|
+
function renderInputTsType(type, modelsWithInput) {
|
|
114
|
+
if (!modelsWithInput || modelsWithInput.size === 0) return renderTsType(type);
|
|
115
|
+
switch (type.kind) {
|
|
116
|
+
case "ref":
|
|
117
|
+
return modelsWithInput.has(type.name) ? `${type.name}Input` : type.name;
|
|
118
|
+
case "array": {
|
|
119
|
+
const inner = renderInputTsType(type.item, modelsWithInput);
|
|
120
|
+
const needsParens = type.item.kind === "union" || type.item.kind === "discriminatedUnion" || type.item.kind === "intersection" || type.item.kind === "enum";
|
|
121
|
+
return needsParens ? `(${inner})[]` : `${inner}[]`;
|
|
122
|
+
}
|
|
123
|
+
case "intersection":
|
|
124
|
+
return type.members.map((m) => renderInputTsType(m, modelsWithInput)).join(" & ");
|
|
125
|
+
case "union":
|
|
126
|
+
return type.members.map((m) => renderInputTsType(m, modelsWithInput)).join(" | ");
|
|
127
|
+
case "discriminatedUnion":
|
|
128
|
+
return type.members.map((m) => renderInputTsType(m, modelsWithInput)).join(" | ");
|
|
129
|
+
case "inlineObject":
|
|
130
|
+
return `{ ${type.fields.map((f) => `${quoteKey(f.name)}${f.optional ? "?" : ""}: ${renderInputTsType(f.type, modelsWithInput)}`).join("; ")} }`;
|
|
131
|
+
case "lazy":
|
|
132
|
+
return renderInputTsType(type.inner, modelsWithInput);
|
|
133
|
+
default:
|
|
134
|
+
return renderTsType(type);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
__name(renderInputTsType, "renderInputTsType");
|
|
138
|
+
function renderOutputTsType(type, modelsWithOutput) {
|
|
139
|
+
if (!modelsWithOutput || modelsWithOutput.size === 0) return renderTsType(type);
|
|
140
|
+
switch (type.kind) {
|
|
141
|
+
case "ref":
|
|
142
|
+
return modelsWithOutput.has(type.name) ? `${type.name}Output` : type.name;
|
|
143
|
+
case "array": {
|
|
144
|
+
const inner = renderOutputTsType(type.item, modelsWithOutput);
|
|
145
|
+
const needsParens = type.item.kind === "union" || type.item.kind === "discriminatedUnion" || type.item.kind === "intersection" || type.item.kind === "enum";
|
|
146
|
+
return needsParens ? `(${inner})[]` : `${inner}[]`;
|
|
147
|
+
}
|
|
148
|
+
case "intersection":
|
|
149
|
+
return type.members.map((m) => renderOutputTsType(m, modelsWithOutput)).join(" & ");
|
|
150
|
+
case "union":
|
|
151
|
+
return type.members.map((m) => renderOutputTsType(m, modelsWithOutput)).join(" | ");
|
|
152
|
+
case "discriminatedUnion":
|
|
153
|
+
return type.members.map((m) => renderOutputTsType(m, modelsWithOutput)).join(" | ");
|
|
154
|
+
case "inlineObject":
|
|
155
|
+
return `{ ${type.fields.map((f) => `${quoteKey(f.name)}${f.optional ? "?" : ""}: ${renderOutputTsType(f.type, modelsWithOutput)}`).join("; ")} }`;
|
|
156
|
+
case "lazy":
|
|
157
|
+
return renderOutputTsType(type.inner, modelsWithOutput);
|
|
158
|
+
default:
|
|
159
|
+
return renderTsType(type);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
__name(renderOutputTsType, "renderOutputTsType");
|
|
163
|
+
|
|
164
|
+
// src/codegen-contract.ts
|
|
11
165
|
function modeToWrapper(mode) {
|
|
12
166
|
switch (mode) {
|
|
13
167
|
case "strict":
|
|
@@ -56,7 +210,7 @@ function generateComments(model, outPath) {
|
|
|
56
210
|
lines.push(` * @deprecated`);
|
|
57
211
|
}
|
|
58
212
|
if (model.description) {
|
|
59
|
-
lines.push(` * ${
|
|
213
|
+
for (const l of escapeJsDocLines(model.description)) lines.push(` * ${l}`);
|
|
60
214
|
}
|
|
61
215
|
const relPath = outPath ? relative(dirname(outPath), model.loc.file) : model.loc.file;
|
|
62
216
|
lines.push(` * generated from [${model.name}](file://./${relPath}#L${model.loc.line})`);
|
|
@@ -199,9 +353,9 @@ function generateSimpleModel(model, outPath) {
|
|
|
199
353
|
const outputKey = applyCase(field.name, outputCase);
|
|
200
354
|
if (field.optional) {
|
|
201
355
|
const guard = hasInputTransform ? `data.${inputKey} != null` : `data.${inputKey} !== undefined`;
|
|
202
|
-
lines.push(` ...(${guard} ? { ${
|
|
356
|
+
lines.push(` ...(${guard} ? { ${quoteKey2(outputKey)}: data.${inputKey} } : {}),`);
|
|
203
357
|
} else {
|
|
204
|
-
lines.push(` ${
|
|
358
|
+
lines.push(` ${quoteKey2(outputKey)}: data.${inputKey},`);
|
|
205
359
|
}
|
|
206
360
|
}
|
|
207
361
|
lines.push(`}));`);
|
|
@@ -298,7 +452,7 @@ function generateThreeSchemaModel(model, outPath, modelsWithInput, modelsWithWri
|
|
|
298
452
|
}
|
|
299
453
|
const omitClause = fieldsToOmit.size > 0 ? `.omit({ ${[
|
|
300
454
|
...fieldsToOmit
|
|
301
|
-
].map((f) => `${
|
|
455
|
+
].map((f) => `${quoteKey2(f)}: true`).join(", ")} })` : "";
|
|
302
456
|
if (bases.length > 0) {
|
|
303
457
|
const { head, tail } = buildExtendChain(bases, (b) => modelsWithInput?.has(b) ? `${b}Input` : b);
|
|
304
458
|
lines.push(`export const ${name}Input = ${head}${tail}${omitClause}.extend({`);
|
|
@@ -343,7 +497,7 @@ function renderFieldsAsPascalCase(fields, defaultMode) {
|
|
|
343
497
|
expr += ".nullable()";
|
|
344
498
|
}
|
|
345
499
|
if (f.description) expr += `.describe("${escapeString(f.description)}")`;
|
|
346
|
-
return `${
|
|
500
|
+
return `${quoteKey2(pascalKey)}: ${expr},`;
|
|
347
501
|
});
|
|
348
502
|
}
|
|
349
503
|
__name(renderFieldsAsPascalCase, "renderFieldsAsPascalCase");
|
|
@@ -361,7 +515,7 @@ function renderFieldsAsSnakeCase(fields, defaultMode) {
|
|
|
361
515
|
expr += ".nullable()";
|
|
362
516
|
}
|
|
363
517
|
if (f.description) expr += `.describe("${escapeString(f.description)}")`;
|
|
364
|
-
return `${
|
|
518
|
+
return `${quoteKey2(snakeKey)}: ${expr},`;
|
|
365
519
|
});
|
|
366
520
|
}
|
|
367
521
|
__name(renderFieldsAsSnakeCase, "renderFieldsAsSnakeCase");
|
|
@@ -377,7 +531,7 @@ function renderField(field, defaultMode) {
|
|
|
377
531
|
expr += ".optional()";
|
|
378
532
|
}
|
|
379
533
|
if (field.description) expr += `.describe("${escapeString(field.description)}")`;
|
|
380
|
-
lines.push(`${
|
|
534
|
+
lines.push(`${quoteKey2(field.name)}: ${expr},`);
|
|
381
535
|
return lines;
|
|
382
536
|
}
|
|
383
537
|
__name(renderField, "renderField");
|
|
@@ -502,8 +656,10 @@ function renderScalar(s) {
|
|
|
502
656
|
return "_ZodBinary";
|
|
503
657
|
case "json":
|
|
504
658
|
return "_ZodJson";
|
|
505
|
-
default:
|
|
506
|
-
|
|
659
|
+
default: {
|
|
660
|
+
const _exhaustive = s.name;
|
|
661
|
+
throw new Error(`plugin-typescript: unmapped scalar '${String(_exhaustive)}' \u2014 add a case`);
|
|
662
|
+
}
|
|
507
663
|
}
|
|
508
664
|
}
|
|
509
665
|
__name(renderScalar, "renderScalar");
|
|
@@ -523,7 +679,7 @@ function renderRecord(r) {
|
|
|
523
679
|
}
|
|
524
680
|
__name(renderRecord, "renderRecord");
|
|
525
681
|
function renderEnum(e) {
|
|
526
|
-
const vals = e.values.map((v) => `"${v}"`).join(", ");
|
|
682
|
+
const vals = e.values.map((v) => `"${escapeString(v)}"`).join(", ");
|
|
527
683
|
return `z.enum([${vals}])`;
|
|
528
684
|
}
|
|
529
685
|
__name(renderEnum, "renderEnum");
|
|
@@ -572,9 +728,9 @@ function renderInlineObject(o, parseCaseTransform, defaultMode) {
|
|
|
572
728
|
const transformEntries = o.fields.map((f) => {
|
|
573
729
|
const snakeKey = camelToSnake(f.name);
|
|
574
730
|
if (f.optional) {
|
|
575
|
-
return ` ...(data.${snakeKey} != null ? { ${
|
|
731
|
+
return ` ...(data.${snakeKey} != null ? { ${quoteKey2(f.name)}: data.${snakeKey} } : {}),`;
|
|
576
732
|
}
|
|
577
|
-
return ` ${
|
|
733
|
+
return ` ${quoteKey2(f.name)}: data.${snakeKey},`;
|
|
578
734
|
}).join("\n");
|
|
579
735
|
return `${wrapper}({
|
|
580
736
|
${joined}
|
|
@@ -588,9 +744,9 @@ ${transformEntries}
|
|
|
588
744
|
const transformEntries = o.fields.map((f) => {
|
|
589
745
|
const pascalKey = camelToPascal(f.name);
|
|
590
746
|
if (f.optional) {
|
|
591
|
-
return ` ...(data.${pascalKey} != null ? { ${
|
|
747
|
+
return ` ...(data.${pascalKey} != null ? { ${quoteKey2(f.name)}: data.${pascalKey} } : {}),`;
|
|
592
748
|
}
|
|
593
|
-
return ` ${
|
|
749
|
+
return ` ${quoteKey2(f.name)}: data.${pascalKey},`;
|
|
594
750
|
}).join("\n");
|
|
595
751
|
return `${wrapper}({
|
|
596
752
|
${joined}
|
|
@@ -676,7 +832,7 @@ function renderInputField(field, modelsWithInput, defaultMode) {
|
|
|
676
832
|
expr += ".optional()";
|
|
677
833
|
}
|
|
678
834
|
if (field.description) expr += `.describe("${escapeString(field.description)}")`;
|
|
679
|
-
lines.push(`${
|
|
835
|
+
lines.push(`${quoteKey2(field.name)}: ${expr},`);
|
|
680
836
|
return lines;
|
|
681
837
|
}
|
|
682
838
|
__name(renderInputField, "renderInputField");
|
|
@@ -736,17 +892,17 @@ function renderQueryField(field, modelsWithInput, defaultMode) {
|
|
|
736
892
|
expr += ".optional()";
|
|
737
893
|
}
|
|
738
894
|
if (field.description) expr += `.describe("${escapeString(field.description)}")`;
|
|
739
|
-
return `${
|
|
895
|
+
return `${quoteKey2(field.name)}: ${expr},`;
|
|
740
896
|
}
|
|
741
897
|
__name(renderQueryField, "renderQueryField");
|
|
742
898
|
function isValidIdentifier(name) {
|
|
743
899
|
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
744
900
|
}
|
|
745
901
|
__name(isValidIdentifier, "isValidIdentifier");
|
|
746
|
-
function
|
|
902
|
+
function quoteKey2(name) {
|
|
747
903
|
return isValidIdentifier(name) ? name : `'${name}'`;
|
|
748
904
|
}
|
|
749
|
-
__name(
|
|
905
|
+
__name(quoteKey2, "quoteKey");
|
|
750
906
|
function escapeString(s) {
|
|
751
907
|
return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r");
|
|
752
908
|
}
|
|
@@ -950,149 +1106,6 @@ __name(pascalToDotCase, "pascalToDotCase");
|
|
|
950
1106
|
|
|
951
1107
|
// src/codegen-operation.ts
|
|
952
1108
|
import { resolveModifiers, resolveSecurity, SECURITY_NONE, classifyContentType } from "@contractkit/core";
|
|
953
|
-
|
|
954
|
-
// src/ts-render.ts
|
|
955
|
-
var JSON_VALUE_TYPE_DECL = "export type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue };";
|
|
956
|
-
function quoteKey2(name) {
|
|
957
|
-
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name) ? name : `'${name}'`;
|
|
958
|
-
}
|
|
959
|
-
__name(quoteKey2, "quoteKey");
|
|
960
|
-
function headerNameToProperty(name) {
|
|
961
|
-
const parts = name.split(/[-_]/).filter(Boolean);
|
|
962
|
-
return parts.map((p, i) => {
|
|
963
|
-
const lower = p.toLowerCase();
|
|
964
|
-
return i === 0 ? lower : lower.charAt(0).toUpperCase() + lower.slice(1);
|
|
965
|
-
}).join("");
|
|
966
|
-
}
|
|
967
|
-
__name(headerNameToProperty, "headerNameToProperty");
|
|
968
|
-
function renderTsType(type) {
|
|
969
|
-
switch (type.kind) {
|
|
970
|
-
case "scalar":
|
|
971
|
-
return renderTsScalar(type.name);
|
|
972
|
-
case "array": {
|
|
973
|
-
const inner = renderTsType(type.item);
|
|
974
|
-
const needsParens = type.item.kind === "union" || type.item.kind === "discriminatedUnion" || type.item.kind === "intersection" || type.item.kind === "enum";
|
|
975
|
-
return needsParens ? `(${inner})[]` : `${inner}[]`;
|
|
976
|
-
}
|
|
977
|
-
case "tuple":
|
|
978
|
-
return `[${type.items.map(renderTsType).join(", ")}]`;
|
|
979
|
-
case "record":
|
|
980
|
-
return `Record<${renderTsType(type.key)}, ${renderTsType(type.value)}>`;
|
|
981
|
-
case "enum":
|
|
982
|
-
return type.values.map((v) => `'${v}'`).join(" | ");
|
|
983
|
-
case "literal":
|
|
984
|
-
return typeof type.value === "string" ? `'${type.value}'` : String(type.value);
|
|
985
|
-
case "union":
|
|
986
|
-
return type.members.map(renderTsType).join(" | ");
|
|
987
|
-
case "discriminatedUnion":
|
|
988
|
-
return type.members.map(renderTsType).join(" | ");
|
|
989
|
-
case "intersection":
|
|
990
|
-
return type.members.map(renderTsType).join(" & ");
|
|
991
|
-
case "ref":
|
|
992
|
-
return type.name;
|
|
993
|
-
case "lazy":
|
|
994
|
-
return renderTsType(type.inner);
|
|
995
|
-
case "inlineObject":
|
|
996
|
-
return renderTsInlineObject(type.fields);
|
|
997
|
-
default:
|
|
998
|
-
return "unknown";
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
__name(renderTsType, "renderTsType");
|
|
1002
|
-
function renderTsScalar(name) {
|
|
1003
|
-
switch (name) {
|
|
1004
|
-
case "string":
|
|
1005
|
-
case "email":
|
|
1006
|
-
case "url":
|
|
1007
|
-
case "uuid":
|
|
1008
|
-
return "string";
|
|
1009
|
-
case "number":
|
|
1010
|
-
case "int":
|
|
1011
|
-
return "number";
|
|
1012
|
-
case "bigint":
|
|
1013
|
-
return "bigint";
|
|
1014
|
-
case "boolean":
|
|
1015
|
-
return "boolean";
|
|
1016
|
-
case "date":
|
|
1017
|
-
case "datetime":
|
|
1018
|
-
case "duration":
|
|
1019
|
-
case "interval":
|
|
1020
|
-
return "string";
|
|
1021
|
-
case "null":
|
|
1022
|
-
return "null";
|
|
1023
|
-
case "unknown":
|
|
1024
|
-
return "unknown";
|
|
1025
|
-
case "object":
|
|
1026
|
-
return "Record<string, unknown>";
|
|
1027
|
-
case "binary":
|
|
1028
|
-
return "Blob";
|
|
1029
|
-
case "json":
|
|
1030
|
-
return "JsonValue";
|
|
1031
|
-
default:
|
|
1032
|
-
return "unknown";
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
__name(renderTsScalar, "renderTsScalar");
|
|
1036
|
-
function renderTsInlineObject(fields) {
|
|
1037
|
-
const entries = fields.map((f) => {
|
|
1038
|
-
const opt = f.optional ? "?" : "";
|
|
1039
|
-
return `${quoteKey2(f.name)}${opt}: ${renderTsType(f.type)}`;
|
|
1040
|
-
});
|
|
1041
|
-
return `{ ${entries.join("; ")} }`;
|
|
1042
|
-
}
|
|
1043
|
-
__name(renderTsInlineObject, "renderTsInlineObject");
|
|
1044
|
-
function renderInputTsType(type, modelsWithInput) {
|
|
1045
|
-
if (!modelsWithInput || modelsWithInput.size === 0) return renderTsType(type);
|
|
1046
|
-
switch (type.kind) {
|
|
1047
|
-
case "ref":
|
|
1048
|
-
return modelsWithInput.has(type.name) ? `${type.name}Input` : type.name;
|
|
1049
|
-
case "array": {
|
|
1050
|
-
const inner = renderInputTsType(type.item, modelsWithInput);
|
|
1051
|
-
const needsParens = type.item.kind === "union" || type.item.kind === "discriminatedUnion" || type.item.kind === "intersection" || type.item.kind === "enum";
|
|
1052
|
-
return needsParens ? `(${inner})[]` : `${inner}[]`;
|
|
1053
|
-
}
|
|
1054
|
-
case "intersection":
|
|
1055
|
-
return type.members.map((m) => renderInputTsType(m, modelsWithInput)).join(" & ");
|
|
1056
|
-
case "union":
|
|
1057
|
-
return type.members.map((m) => renderInputTsType(m, modelsWithInput)).join(" | ");
|
|
1058
|
-
case "discriminatedUnion":
|
|
1059
|
-
return type.members.map((m) => renderInputTsType(m, modelsWithInput)).join(" | ");
|
|
1060
|
-
case "inlineObject":
|
|
1061
|
-
return `{ ${type.fields.map((f) => `${quoteKey2(f.name)}${f.optional ? "?" : ""}: ${renderInputTsType(f.type, modelsWithInput)}`).join("; ")} }`;
|
|
1062
|
-
case "lazy":
|
|
1063
|
-
return renderInputTsType(type.inner, modelsWithInput);
|
|
1064
|
-
default:
|
|
1065
|
-
return renderTsType(type);
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
__name(renderInputTsType, "renderInputTsType");
|
|
1069
|
-
function renderOutputTsType(type, modelsWithOutput) {
|
|
1070
|
-
if (!modelsWithOutput || modelsWithOutput.size === 0) return renderTsType(type);
|
|
1071
|
-
switch (type.kind) {
|
|
1072
|
-
case "ref":
|
|
1073
|
-
return modelsWithOutput.has(type.name) ? `${type.name}Output` : type.name;
|
|
1074
|
-
case "array": {
|
|
1075
|
-
const inner = renderOutputTsType(type.item, modelsWithOutput);
|
|
1076
|
-
const needsParens = type.item.kind === "union" || type.item.kind === "discriminatedUnion" || type.item.kind === "intersection" || type.item.kind === "enum";
|
|
1077
|
-
return needsParens ? `(${inner})[]` : `${inner}[]`;
|
|
1078
|
-
}
|
|
1079
|
-
case "intersection":
|
|
1080
|
-
return type.members.map((m) => renderOutputTsType(m, modelsWithOutput)).join(" & ");
|
|
1081
|
-
case "union":
|
|
1082
|
-
return type.members.map((m) => renderOutputTsType(m, modelsWithOutput)).join(" | ");
|
|
1083
|
-
case "discriminatedUnion":
|
|
1084
|
-
return type.members.map((m) => renderOutputTsType(m, modelsWithOutput)).join(" | ");
|
|
1085
|
-
case "inlineObject":
|
|
1086
|
-
return `{ ${type.fields.map((f) => `${quoteKey2(f.name)}${f.optional ? "?" : ""}: ${renderOutputTsType(f.type, modelsWithOutput)}`).join("; ")} }`;
|
|
1087
|
-
case "lazy":
|
|
1088
|
-
return renderOutputTsType(type.inner, modelsWithOutput);
|
|
1089
|
-
default:
|
|
1090
|
-
return renderTsType(type);
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1093
|
-
__name(renderOutputTsType, "renderOutputTsType");
|
|
1094
|
-
|
|
1095
|
-
// src/codegen-operation.ts
|
|
1096
1109
|
import { basename, dirname as dirname2, relative as relative2 } from "path";
|
|
1097
1110
|
function bodyParserToken(contentType) {
|
|
1098
1111
|
switch (classifyContentType(contentType)) {
|
|
@@ -1244,7 +1257,7 @@ function generateHandler(route, op, root, options) {
|
|
|
1244
1257
|
lines.push("/**");
|
|
1245
1258
|
const desc = op.description ?? route.description;
|
|
1246
1259
|
if (desc) {
|
|
1247
|
-
lines.push(` * ${
|
|
1260
|
+
for (const l of escapeJsDocLines(desc)) lines.push(` * ${l}`);
|
|
1248
1261
|
}
|
|
1249
1262
|
const relFile = outPath ? relative2(dirname2(outPath), file) : file;
|
|
1250
1263
|
lines.push(` * from [${basename(file)}](file://./${relFile}#L${op.loc.line})`);
|
|
@@ -1273,7 +1286,7 @@ function generateHandler(route, op, root, options) {
|
|
|
1273
1286
|
middlewares.push(`bodyParserMiddleware([${tokensExpr}])`);
|
|
1274
1287
|
}
|
|
1275
1288
|
if (op.signature) {
|
|
1276
|
-
const sigArgs = op.signaturePolicy ? `'${op.signature}', { policy: '${op.signaturePolicy}' }` : `'${op.signature}'`;
|
|
1289
|
+
const sigArgs = op.signaturePolicy ? `'${escapeSingleQuoted(op.signature)}', { policy: '${escapeSingleQuoted(op.signaturePolicy)}' }` : `'${escapeSingleQuoted(op.signature)}'`;
|
|
1277
1290
|
middlewares.push(`requireSignature(${sigArgs})`);
|
|
1278
1291
|
}
|
|
1279
1292
|
const middlewareStr = middlewares.length > 0 ? `, ${middlewares.join(", ")},` : ",";
|
|
@@ -1312,7 +1325,7 @@ function generateHandler(route, op, root, options) {
|
|
|
1312
1325
|
const serviceParts = inferService(op, route, file);
|
|
1313
1326
|
const respHeaders = primaryResponse?.headers ?? [];
|
|
1314
1327
|
const hasRespHeaders = respHeaders.length > 0;
|
|
1315
|
-
const headersAnnotation = hasRespHeaders ? `{ ${respHeaders.map((h) => `${
|
|
1328
|
+
const headersAnnotation = hasRespHeaders ? `{ ${respHeaders.map((h) => `${quoteKey(headerNameToProperty(h.name))}${h.optional ? "?" : ""}: ${renderOutputTsType(h.type, options.modelsWithOutput)}`).join("; ")} }` : "";
|
|
1316
1329
|
if (primaryResponse?.bodyType) {
|
|
1317
1330
|
const { annotation, prelude } = formatTypeAnnotation(primaryResponse.bodyType, options.modelsWithOutput);
|
|
1318
1331
|
if (prelude) {
|
|
@@ -1953,18 +1966,19 @@ function generateMethod(route, op, file, options) {
|
|
|
1953
1966
|
const dataType = isVoid ? "void" : respCategory === "text" ? "string" : respCategory === "binary" ? "Blob" : renderOutputTsType(primaryResponse.bodyType, modelsWithOutput);
|
|
1954
1967
|
const respHeaders = primaryResponse?.headers ?? [];
|
|
1955
1968
|
const hasRespHeaders = respHeaders.length > 0;
|
|
1956
|
-
const headersShape = hasRespHeaders ? `{ ${respHeaders.map((h) => `${
|
|
1969
|
+
const headersShape = hasRespHeaders ? `{ ${respHeaders.map((h) => `${quoteKey(headerNameToProperty(h.name))}${h.optional ? "?" : ""}: ${renderOutputTsType(h.type, modelsWithOutput)}`).join("; ")} }` : "";
|
|
1957
1970
|
const returnType = hasRespHeaders ? isVoid ? `{ headers: ${headersShape} }` : `{ data: ${dataType}; headers: ${headersShape} }` : dataType;
|
|
1958
1971
|
const desc = op.description ?? route.description;
|
|
1959
1972
|
if (op.name || desc) {
|
|
1960
1973
|
const tags = [];
|
|
1961
1974
|
if (op.name) tags.push(`@name ${op.name}`);
|
|
1962
1975
|
if (desc) tags.push(`@description ${desc}`);
|
|
1963
|
-
|
|
1964
|
-
|
|
1976
|
+
const contentLines = tags.flatMap((t) => escapeJsDocLines(t));
|
|
1977
|
+
if (contentLines.length === 1) {
|
|
1978
|
+
lines.push(` /** ${contentLines[0]} */`);
|
|
1965
1979
|
} else {
|
|
1966
1980
|
lines.push(` /**`);
|
|
1967
|
-
for (const
|
|
1981
|
+
for (const l of contentLines) lines.push(` * ${l}`);
|
|
1968
1982
|
lines.push(` */`);
|
|
1969
1983
|
}
|
|
1970
1984
|
}
|
|
@@ -2040,7 +2054,7 @@ function generateMethod(route, op, file, options) {
|
|
|
2040
2054
|
}
|
|
2041
2055
|
const readBodyExpr = respCategory === "text" ? `await result.text()` : respCategory === "binary" ? `await result.blob()` : `await parseJson<${dataType}>(result)`;
|
|
2042
2056
|
if (hasRespHeaders) {
|
|
2043
|
-
const headerEntries = respHeaders.map((h) => `${
|
|
2057
|
+
const headerEntries = respHeaders.map((h) => `${quoteKey(headerNameToProperty(h.name))}: result.headers.get('${h.name}') ?? undefined`).join(", ");
|
|
2044
2058
|
if (isVoid) {
|
|
2045
2059
|
lines.push(` return { headers: { ${headerEntries} } };`);
|
|
2046
2060
|
} else {
|
|
@@ -2152,7 +2166,7 @@ function buildMethodParams(route, op, modelsWithInput) {
|
|
|
2152
2166
|
}
|
|
2153
2167
|
if (op.query) {
|
|
2154
2168
|
if (op.query.kind === "params") {
|
|
2155
|
-
const fields = op.query.nodes.map((p) => `${
|
|
2169
|
+
const fields = op.query.nodes.map((p) => `${quoteKey(p.name)}?: ${renderInputTsType(p.type, modelsWithInput)}`).join("; ");
|
|
2156
2170
|
params.push({
|
|
2157
2171
|
name: "query",
|
|
2158
2172
|
type: `{ ${fields} }`,
|
|
@@ -2175,7 +2189,7 @@ function buildMethodParams(route, op, modelsWithInput) {
|
|
|
2175
2189
|
}
|
|
2176
2190
|
if (op.headers) {
|
|
2177
2191
|
if (op.headers.kind === "params") {
|
|
2178
|
-
const fields = op.headers.nodes.map((p) => `${
|
|
2192
|
+
const fields = op.headers.nodes.map((p) => `${quoteKey(p.name)}?: ${renderInputTsType(p.type, modelsWithInput)}`).join("; ");
|
|
2179
2193
|
params.push({
|
|
2180
2194
|
name: "customHeaders",
|
|
2181
2195
|
type: `{ ${fields} }`,
|
|
@@ -2877,7 +2891,7 @@ function generateComments2(model, outPath) {
|
|
|
2877
2891
|
lines.push(` * @deprecated`);
|
|
2878
2892
|
}
|
|
2879
2893
|
if (model.description) {
|
|
2880
|
-
lines.push(` * ${
|
|
2894
|
+
for (const l of escapeJsDocLines(model.description)) lines.push(` * ${l}`);
|
|
2881
2895
|
}
|
|
2882
2896
|
const relPath = outPath ? relative4(dirname4(outPath), model.loc.file) : model.loc.file;
|
|
2883
2897
|
lines.push(` * generated from [${model.name}](file://./${relPath}#L${model.loc.line})`);
|
|
@@ -2941,34 +2955,40 @@ function generateVisibilityModel(model, outPath, modelsWithInput, modelMap) {
|
|
|
2941
2955
|
return lines;
|
|
2942
2956
|
}
|
|
2943
2957
|
__name(generateVisibilityModel, "generateVisibilityModel");
|
|
2958
|
+
function withFieldJsDoc(jsdocParts, line) {
|
|
2959
|
+
if (jsdocParts.length === 0) return line;
|
|
2960
|
+
const contentLines = escapeJsDocLines(jsdocParts.join(" "));
|
|
2961
|
+
if (contentLines.length === 1) {
|
|
2962
|
+
return `/** ${contentLines[0]} */
|
|
2963
|
+
${line}`;
|
|
2964
|
+
}
|
|
2965
|
+
const body = contentLines.map((l) => ` * ${l}`).join("\n");
|
|
2966
|
+
return `/**
|
|
2967
|
+
${body}
|
|
2968
|
+
*/
|
|
2969
|
+
${line}`;
|
|
2970
|
+
}
|
|
2971
|
+
__name(withFieldJsDoc, "withFieldJsDoc");
|
|
2944
2972
|
function renderField2(field) {
|
|
2945
2973
|
const opt = field.optional || field.default !== void 0 ? "?" : "";
|
|
2946
2974
|
let typeStr = renderTsType(field.type);
|
|
2947
2975
|
if (field.nullable) typeStr += " | null";
|
|
2948
|
-
const line = `${
|
|
2976
|
+
const line = `${quoteKey(field.name)}${opt}: ${typeStr};`;
|
|
2949
2977
|
const jsdocParts = [];
|
|
2950
2978
|
if (field.deprecated) jsdocParts.push("@deprecated");
|
|
2951
2979
|
if (field.description) jsdocParts.push(field.description);
|
|
2952
|
-
|
|
2953
|
-
return `/** ${jsdocParts.join(" ")} */
|
|
2954
|
-
${line}`;
|
|
2955
|
-
}
|
|
2956
|
-
return line;
|
|
2980
|
+
return withFieldJsDoc(jsdocParts, line);
|
|
2957
2981
|
}
|
|
2958
2982
|
__name(renderField2, "renderField");
|
|
2959
2983
|
function renderInputField2(field, modelsWithInput) {
|
|
2960
2984
|
const opt = field.optional || field.default !== void 0 ? "?" : "";
|
|
2961
2985
|
let typeStr = renderInputTsType(field.type, modelsWithInput);
|
|
2962
2986
|
if (field.nullable) typeStr += " | null";
|
|
2963
|
-
const line = `${
|
|
2987
|
+
const line = `${quoteKey(field.name)}${opt}: ${typeStr};`;
|
|
2964
2988
|
const jsdocParts = [];
|
|
2965
2989
|
if (field.deprecated) jsdocParts.push("@deprecated");
|
|
2966
2990
|
if (field.description) jsdocParts.push(field.description);
|
|
2967
|
-
|
|
2968
|
-
return `/** ${jsdocParts.join(" ")} */
|
|
2969
|
-
${line}`;
|
|
2970
|
-
}
|
|
2971
|
-
return line;
|
|
2991
|
+
return withFieldJsDoc(jsdocParts, line);
|
|
2972
2992
|
}
|
|
2973
2993
|
__name(renderInputField2, "renderInputField");
|
|
2974
2994
|
function camelToSnake2(s) {
|
|
@@ -3011,22 +3031,26 @@ function renderOutputField(field, outputCase, modelsWithOutput) {
|
|
|
3011
3031
|
const key = applyOutputCase(field.name, outputCase);
|
|
3012
3032
|
let typeStr = renderOutputTsType(field.type, modelsWithOutput);
|
|
3013
3033
|
if (field.nullable) typeStr += " | null";
|
|
3014
|
-
const line = `${
|
|
3034
|
+
const line = `${quoteKey(key)}${opt}: ${typeStr};`;
|
|
3015
3035
|
const jsdocParts = [];
|
|
3016
3036
|
if (field.deprecated) jsdocParts.push("@deprecated");
|
|
3017
3037
|
if (field.description) jsdocParts.push(field.description);
|
|
3018
|
-
|
|
3019
|
-
return `/** ${jsdocParts.join(" ")} */
|
|
3020
|
-
${line}`;
|
|
3021
|
-
}
|
|
3022
|
-
return line;
|
|
3038
|
+
return withFieldJsDoc(jsdocParts, line);
|
|
3023
3039
|
}
|
|
3024
3040
|
__name(renderOutputField, "renderOutputField");
|
|
3025
3041
|
|
|
3026
3042
|
// src/path-utils.ts
|
|
3027
|
-
import { resolve, join, relative as relative5, dirname as dirname5 } from "path";
|
|
3043
|
+
import { resolve, join, relative as relative5, dirname as dirname5, isAbsolute } from "path";
|
|
3028
3044
|
import { collectTypeRefs as collectTypeRefs2, collectPublicTypeNames } from "@contractkit/core";
|
|
3029
3045
|
var TEMPLATE_VAR_RE = /\{\w+\}/;
|
|
3046
|
+
function assertWithinBase(baseOutDir, outPath) {
|
|
3047
|
+
const rel = relative5(resolve(baseOutDir), resolve(outPath));
|
|
3048
|
+
if (rel === "" || rel.startsWith("..") || isAbsolute(rel)) {
|
|
3049
|
+
throw new Error(`Refusing to emit outside output directory: resolved path "${outPath}" escapes "${baseOutDir}" (check options { keys } values used in output path templates)`);
|
|
3050
|
+
}
|
|
3051
|
+
return outPath;
|
|
3052
|
+
}
|
|
3053
|
+
__name(assertWithinBase, "assertWithinBase");
|
|
3030
3054
|
function resolveTemplate(template, vars) {
|
|
3031
3055
|
return template.replace(/\{(\w+)\}/g, (_, key) => vars[key] ?? `{${key}}`);
|
|
3032
3056
|
}
|
|
@@ -3065,14 +3089,14 @@ function computeOpOutPath(filePath, baseDir, output, defaultSuffix, commonRoot,
|
|
|
3065
3089
|
ext: "ck",
|
|
3066
3090
|
...meta
|
|
3067
3091
|
});
|
|
3068
|
-
if (includesFilename(resolved)) return join(baseOutDir, resolved);
|
|
3069
|
-
return join(baseOutDir, resolved, defaultName);
|
|
3092
|
+
if (includesFilename(resolved)) return assertWithinBase(baseOutDir, join(baseOutDir, resolved));
|
|
3093
|
+
return assertWithinBase(baseOutDir, join(baseOutDir, resolved, defaultName));
|
|
3070
3094
|
}
|
|
3071
3095
|
if (output) {
|
|
3072
|
-
if (includesFilename(output)) return join(baseOutDir, output);
|
|
3073
|
-
return join(baseOutDir, output, relDir, defaultName);
|
|
3096
|
+
if (includesFilename(output)) return assertWithinBase(baseOutDir, join(baseOutDir, output));
|
|
3097
|
+
return assertWithinBase(baseOutDir, join(baseOutDir, output, relDir, defaultName));
|
|
3074
3098
|
}
|
|
3075
|
-
return join(baseOutDir, relDir, defaultName);
|
|
3099
|
+
return assertWithinBase(baseOutDir, join(baseOutDir, relDir, defaultName));
|
|
3076
3100
|
}
|
|
3077
3101
|
__name(computeOpOutPath, "computeOpOutPath");
|
|
3078
3102
|
function computeContractOutPath(filePath, baseDir, output, defaultSuffix, commonRoot, meta = {}) {
|
|
@@ -3093,14 +3117,14 @@ function computeSdkOutPath(filePath, rootDir, clientOutput, commonRoot, meta = {
|
|
|
3093
3117
|
ext: "ck",
|
|
3094
3118
|
...meta
|
|
3095
3119
|
});
|
|
3096
|
-
if (includesFilename(resolved)) return join(baseOutDir, resolved);
|
|
3097
|
-
return join(baseOutDir, resolved, defaultOutName);
|
|
3120
|
+
if (includesFilename(resolved)) return assertWithinBase(baseOutDir, join(baseOutDir, resolved));
|
|
3121
|
+
return assertWithinBase(baseOutDir, join(baseOutDir, resolved, defaultOutName));
|
|
3098
3122
|
}
|
|
3099
3123
|
if (clientOutput) {
|
|
3100
|
-
if (includesFilename(clientOutput)) return join(baseOutDir, clientOutput);
|
|
3101
|
-
return join(baseOutDir, clientOutput, relDir, defaultOutName);
|
|
3124
|
+
if (includesFilename(clientOutput)) return assertWithinBase(baseOutDir, join(baseOutDir, clientOutput));
|
|
3125
|
+
return assertWithinBase(baseOutDir, join(baseOutDir, clientOutput, relDir, defaultOutName));
|
|
3102
3126
|
}
|
|
3103
|
-
return join(baseOutDir, relDir, defaultOutName);
|
|
3127
|
+
return assertWithinBase(baseOutDir, join(baseOutDir, relDir, defaultOutName));
|
|
3104
3128
|
}
|
|
3105
3129
|
__name(computeSdkOutPath, "computeSdkOutPath");
|
|
3106
3130
|
function computeSdkAreaClientOutPath(area, rootDir, clientOutput) {
|
|
@@ -3121,14 +3145,14 @@ function computeSdkAreaClientOutPath(area, rootDir, clientOutput) {
|
|
|
3121
3145
|
subarea: ""
|
|
3122
3146
|
});
|
|
3123
3147
|
const cleaned = fixHiddenSegment(resolved.replace(/\/+/g, "/").replace(/^\//, ""));
|
|
3124
|
-
if (includesFilename(cleaned)) return join(baseOutDir, cleaned);
|
|
3125
|
-
return join(baseOutDir, cleaned, `${filename}.client.ts`);
|
|
3148
|
+
if (includesFilename(cleaned)) return assertWithinBase(baseOutDir, join(baseOutDir, cleaned));
|
|
3149
|
+
return assertWithinBase(baseOutDir, join(baseOutDir, cleaned, `${filename}.client.ts`));
|
|
3126
3150
|
}
|
|
3127
3151
|
if (clientOutput) {
|
|
3128
|
-
if (includesFilename(clientOutput)) return join(baseOutDir, clientOutput);
|
|
3129
|
-
return join(baseOutDir, clientOutput, `${filename}.client.ts`);
|
|
3152
|
+
if (includesFilename(clientOutput)) return assertWithinBase(baseOutDir, join(baseOutDir, clientOutput));
|
|
3153
|
+
return assertWithinBase(baseOutDir, join(baseOutDir, clientOutput, `${filename}.client.ts`));
|
|
3130
3154
|
}
|
|
3131
|
-
return join(baseOutDir, `${filename}.client.ts`);
|
|
3155
|
+
return assertWithinBase(baseOutDir, join(baseOutDir, `${filename}.client.ts`));
|
|
3132
3156
|
}
|
|
3133
3157
|
__name(computeSdkAreaClientOutPath, "computeSdkAreaClientOutPath");
|
|
3134
3158
|
function computeSdkTypeOutPath(filePath, rootDir, typeOutput, commonRoot, meta = {}) {
|
|
@@ -3145,11 +3169,11 @@ function computeSdkTypeOutPath(filePath, rootDir, typeOutput, commonRoot, meta =
|
|
|
3145
3169
|
ext: "ck",
|
|
3146
3170
|
...meta
|
|
3147
3171
|
});
|
|
3148
|
-
if (includesFilename(resolved)) return join(baseOutDir, resolved);
|
|
3149
|
-
return join(baseOutDir, resolved, defaultOutName);
|
|
3172
|
+
if (includesFilename(resolved)) return assertWithinBase(baseOutDir, join(baseOutDir, resolved));
|
|
3173
|
+
return assertWithinBase(baseOutDir, join(baseOutDir, resolved, defaultOutName));
|
|
3150
3174
|
}
|
|
3151
|
-
if (includesFilename(typeOutput)) return join(baseOutDir, typeOutput);
|
|
3152
|
-
return join(baseOutDir, typeOutput, relDir, defaultOutName);
|
|
3175
|
+
if (includesFilename(typeOutput)) return assertWithinBase(baseOutDir, join(baseOutDir, typeOutput));
|
|
3176
|
+
return assertWithinBase(baseOutDir, join(baseOutDir, typeOutput, relDir, defaultOutName));
|
|
3153
3177
|
}
|
|
3154
3178
|
__name(computeSdkTypeOutPath, "computeSdkTypeOutPath");
|
|
3155
3179
|
function generateBarrelFiles(contractPaths) {
|