@typespec/http-server-js 0.58.0-alpha.12-dev.0 → 0.58.0-alpha.12-dev.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/dist/generated-defs/helpers/datetime.d.ts +4 -0
- package/dist/generated-defs/helpers/datetime.d.ts.map +1 -0
- package/dist/generated-defs/helpers/datetime.js +256 -0
- package/dist/generated-defs/helpers/datetime.js.map +1 -0
- package/dist/generated-defs/helpers/index.d.ts.map +1 -1
- package/dist/generated-defs/helpers/index.js +1 -0
- package/dist/generated-defs/helpers/index.js.map +1 -1
- package/dist/src/common/declaration.js +1 -1
- package/dist/src/common/declaration.js.map +1 -1
- package/dist/src/common/reference.js +1 -1
- package/dist/src/common/reference.js.map +1 -1
- package/dist/src/common/scalar.d.ts +175 -22
- package/dist/src/common/scalar.d.ts.map +1 -1
- package/dist/src/common/scalar.js +420 -93
- package/dist/src/common/scalar.js.map +1 -1
- package/dist/src/common/serialization/index.d.ts +2 -2
- package/dist/src/common/serialization/index.d.ts.map +1 -1
- package/dist/src/common/serialization/index.js +9 -3
- package/dist/src/common/serialization/index.js.map +1 -1
- package/dist/src/common/serialization/json.d.ts +2 -2
- package/dist/src/common/serialization/json.d.ts.map +1 -1
- package/dist/src/common/serialization/json.js +144 -42
- package/dist/src/common/serialization/json.js.map +1 -1
- package/dist/src/helpers/datetime.d.ts +92 -0
- package/dist/src/helpers/datetime.d.ts.map +1 -0
- package/dist/src/helpers/datetime.js +151 -0
- package/dist/src/helpers/datetime.js.map +1 -0
- package/dist/src/http/server/index.d.ts.map +1 -1
- package/dist/src/http/server/index.js +17 -12
- package/dist/src/http/server/index.js.map +1 -1
- package/dist/src/http/server/multipart.js +1 -1
- package/dist/src/http/server/multipart.js.map +1 -1
- package/dist/src/lib.d.ts +10 -1
- package/dist/src/lib.d.ts.map +1 -1
- package/dist/src/lib.js +6 -0
- package/dist/src/lib.js.map +1 -1
- package/dist/src/util/case.d.ts +9 -0
- package/dist/src/util/case.d.ts.map +1 -1
- package/dist/src/util/case.js +18 -0
- package/dist/src/util/case.js.map +1 -1
- package/dist/src/util/differentiate.d.ts +4 -4
- package/dist/src/util/differentiate.d.ts.map +1 -1
- package/dist/src/util/differentiate.js +10 -10
- package/dist/src/util/differentiate.js.map +1 -1
- package/generated-defs/helpers/datetime.ts +263 -0
- package/generated-defs/helpers/index.ts +1 -0
- package/package.json +7 -7
- package/src/common/declaration.ts +1 -1
- package/src/common/reference.ts +1 -1
- package/src/common/scalar.ts +709 -103
- package/src/common/serialization/index.ts +11 -4
- package/src/common/serialization/json.ts +174 -52
- package/src/helpers/datetime.ts +235 -0
- package/src/http/server/index.ts +29 -15
- package/src/http/server/multipart.ts +1 -1
- package/src/lib.ts +6 -0
- package/src/util/case.ts +19 -0
- package/src/util/differentiate.ts +15 -8
- package/temp/tsconfig.tsbuildinfo +1 -1
- package/test/datetime.test.ts +226 -0
- package/test/scalar.test.ts +345 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { deepStrictEqual, strictEqual, throws } from "assert";
|
|
2
|
+
import { describe, it } from "vitest";
|
|
3
|
+
import { Duration } from "../src/helpers/datetime.js";
|
|
4
|
+
|
|
5
|
+
describe("datetime", () => {
|
|
6
|
+
describe("duration", () => {
|
|
7
|
+
it("parses an ISO8601 duration string", () => {
|
|
8
|
+
deepStrictEqual(Duration.parseISO8601("P1Y2M3D"), {
|
|
9
|
+
sign: "+",
|
|
10
|
+
years: 1,
|
|
11
|
+
months: 2,
|
|
12
|
+
weeks: 0,
|
|
13
|
+
days: 3,
|
|
14
|
+
hours: 0,
|
|
15
|
+
minutes: 0,
|
|
16
|
+
seconds: 0,
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("parses a negative ISO8601 duration string", () => {
|
|
21
|
+
deepStrictEqual(Duration.parseISO8601("-P1Y2M3D"), {
|
|
22
|
+
sign: "-",
|
|
23
|
+
years: 1,
|
|
24
|
+
months: 2,
|
|
25
|
+
weeks: 0,
|
|
26
|
+
days: 3,
|
|
27
|
+
hours: 0,
|
|
28
|
+
minutes: 0,
|
|
29
|
+
seconds: 0,
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("parses a duration string with hours and minutes", () => {
|
|
34
|
+
deepStrictEqual(Duration.parseISO8601("PT1H2M"), {
|
|
35
|
+
sign: "+",
|
|
36
|
+
years: 0,
|
|
37
|
+
months: 0,
|
|
38
|
+
weeks: 0,
|
|
39
|
+
days: 0,
|
|
40
|
+
hours: 1,
|
|
41
|
+
minutes: 2,
|
|
42
|
+
seconds: 0,
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("parses a duration string with fractional years", () => {
|
|
47
|
+
deepStrictEqual(Duration.parseISO8601("P1.5Y"), {
|
|
48
|
+
sign: "+",
|
|
49
|
+
years: 1.5,
|
|
50
|
+
months: 0,
|
|
51
|
+
weeks: 0,
|
|
52
|
+
days: 0,
|
|
53
|
+
hours: 0,
|
|
54
|
+
minutes: 0,
|
|
55
|
+
seconds: 0,
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("does not parse an invalid duration string", () => {
|
|
60
|
+
throws(() => Duration.parseISO8601("1Y2M3D4H"), {
|
|
61
|
+
message: "Invalid ISO8601 duration: 1Y2M3D4H",
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("does not parse a duration string with too many digits in a component", () => {
|
|
66
|
+
throws(
|
|
67
|
+
() =>
|
|
68
|
+
Duration.parseISO8601(
|
|
69
|
+
"P123429384502934875023948572039485720394857230948572309485723094857203948572309456789.19821374652345232304958273049582730495827340958720349857452345234529223450928347592834387456928374659238476Y",
|
|
70
|
+
),
|
|
71
|
+
{
|
|
72
|
+
message:
|
|
73
|
+
"ISO8601 duration string is too long: P123429384502934875023948572039485720394857230948572309485723094857203948572309456789.19821374652345232304958273049582730495827340958720349857452345234529223450928347592834387456928374659238476Y",
|
|
74
|
+
},
|
|
75
|
+
);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("does not parse a duration string with an invalid group", () => {
|
|
79
|
+
throws(() => Duration.parseISO8601("P1Y2M3D4H5X"), {
|
|
80
|
+
message: "Invalid ISO8601 duration: P1Y2M3D4H5X",
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("does not parse a duration string with missing group", () => {
|
|
85
|
+
throws(() => Duration.parseISO8601("P1Y2M3D4H5.5"), {
|
|
86
|
+
message: "Invalid ISO8601 duration: P1Y2M3D4H5.5",
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("does not parse a duration string with multiple points", () => {
|
|
91
|
+
throws(() => Duration.parseISO8601("P1.2.3Y"), {
|
|
92
|
+
message: "Invalid ISO8601 duration: P1.2.3Y",
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("allows comma as decimal separator", () => {
|
|
97
|
+
deepStrictEqual(Duration.parseISO8601("P1,5Y4.2DT1,005S"), {
|
|
98
|
+
sign: "+",
|
|
99
|
+
years: 1.5,
|
|
100
|
+
months: 0,
|
|
101
|
+
weeks: 0,
|
|
102
|
+
days: 4.2,
|
|
103
|
+
hours: 0,
|
|
104
|
+
minutes: 0,
|
|
105
|
+
seconds: 1.005,
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("writes an ISO8601 duration string", () => {
|
|
110
|
+
const duration: Duration = {
|
|
111
|
+
sign: "+",
|
|
112
|
+
years: 1,
|
|
113
|
+
months: 2,
|
|
114
|
+
weeks: 3,
|
|
115
|
+
days: 4,
|
|
116
|
+
hours: 5,
|
|
117
|
+
minutes: 6,
|
|
118
|
+
seconds: 7,
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
strictEqual(Duration.toISO8601(duration), "P1Y2M3W4DT5H6M7S");
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("writes a negative ISO8601 duration string", () => {
|
|
125
|
+
const duration: Duration = {
|
|
126
|
+
sign: "-",
|
|
127
|
+
years: 1,
|
|
128
|
+
months: 2,
|
|
129
|
+
weeks: 3,
|
|
130
|
+
days: 4,
|
|
131
|
+
hours: 5,
|
|
132
|
+
minutes: 6,
|
|
133
|
+
seconds: 7,
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
strictEqual(Duration.toISO8601(duration), "-P1Y2M3W4DT5H6M7S");
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("writes a duration string with only years", () => {
|
|
140
|
+
const duration: Duration = {
|
|
141
|
+
sign: "+",
|
|
142
|
+
years: 1,
|
|
143
|
+
months: 0,
|
|
144
|
+
weeks: 0,
|
|
145
|
+
days: 0,
|
|
146
|
+
hours: 0,
|
|
147
|
+
minutes: 0,
|
|
148
|
+
seconds: 0,
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
strictEqual(Duration.toISO8601(duration), "P1Y");
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("writes a duration string with only hours", () => {
|
|
155
|
+
const duration: Duration = {
|
|
156
|
+
sign: "+",
|
|
157
|
+
years: 0,
|
|
158
|
+
months: 0,
|
|
159
|
+
weeks: 0,
|
|
160
|
+
days: 0,
|
|
161
|
+
hours: 36,
|
|
162
|
+
minutes: 0,
|
|
163
|
+
seconds: 0,
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
strictEqual(Duration.toISO8601(duration), "PT36H");
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it("writes a duration string with fractional amounts", () => {
|
|
170
|
+
const duration: Duration = {
|
|
171
|
+
sign: "+",
|
|
172
|
+
years: 1.5,
|
|
173
|
+
months: 0,
|
|
174
|
+
weeks: 0,
|
|
175
|
+
days: 0,
|
|
176
|
+
hours: 0,
|
|
177
|
+
minutes: 0,
|
|
178
|
+
seconds: 1.005,
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
strictEqual(Duration.toISO8601(duration), "P1.5YT1.005S");
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it("computes total seconds in durations", () => {
|
|
185
|
+
const duration = Duration.parseISO8601("PT22H96M60S");
|
|
186
|
+
|
|
187
|
+
strictEqual(Duration.totalSeconds(duration), 22 * 60 * 60 + 96 * 60 + 60);
|
|
188
|
+
strictEqual(Duration.totalSecondsBigInt(duration), 22n * 60n * 60n + 96n * 60n + 60n);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it("computes total seconds in durations with fractional amounts", () => {
|
|
192
|
+
const duration = Duration.parseISO8601("PT1.5H22.005S");
|
|
193
|
+
|
|
194
|
+
strictEqual(Duration.totalSeconds(duration), 1.5 * 60 * 60 + 22 + 0.005);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("does not allow total seconds for durations with years, months, weeks, or days", () => {
|
|
198
|
+
const durations = ["P1Y", "P1M", "P1W", "P1D"].map((iso) => Duration.parseISO8601(iso));
|
|
199
|
+
|
|
200
|
+
for (const duration of durations) {
|
|
201
|
+
throws(() => Duration.totalSeconds(duration), {
|
|
202
|
+
message:
|
|
203
|
+
"Cannot calculate total seconds for a duration with years, months, weeks, or days.",
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
throws(() => Duration.totalSecondsBigInt(duration), {
|
|
207
|
+
message:
|
|
208
|
+
"Cannot calculate total seconds for a duration with years, months, weeks, or days.",
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it("does not allow total seconds as bigint for durations with fractional amounts", () => {
|
|
214
|
+
const durations = ["PT1.5H", "PT1.5M", "PT1.5S", "PT1H1.5M", "PT1H1.5S", "PT1M1.5S"].map(
|
|
215
|
+
(iso) => Duration.parseISO8601(iso),
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
for (const duration of durations) {
|
|
219
|
+
throws(() => Duration.totalSecondsBigInt(duration), {
|
|
220
|
+
message:
|
|
221
|
+
"Cannot calculate total seconds as a BigInt for a duration with non-integer components.",
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
});
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { ModelProperty, NoTarget, Scalar } from "@typespec/compiler";
|
|
2
|
+
import { BasicTestRunner, createTestRunner } from "@typespec/compiler/testing";
|
|
3
|
+
import { deepStrictEqual, strictEqual } from "assert";
|
|
4
|
+
import { beforeEach, describe, it } from "vitest";
|
|
5
|
+
import { getJsScalar } from "../src/common/scalar.js";
|
|
6
|
+
import { createPathCursor, JsContext, Module } from "../src/ctx.js";
|
|
7
|
+
|
|
8
|
+
import { module as dateTimeModule } from "../generated-defs/helpers/datetime.js";
|
|
9
|
+
|
|
10
|
+
describe("scalar", () => {
|
|
11
|
+
let runner: BasicTestRunner;
|
|
12
|
+
|
|
13
|
+
beforeEach(async () => {
|
|
14
|
+
runner = await createTestRunner();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
function createFakeModule(): [JsContext, Module] {
|
|
18
|
+
const module: Module = {
|
|
19
|
+
name: "example",
|
|
20
|
+
cursor: createPathCursor(),
|
|
21
|
+
|
|
22
|
+
imports: [],
|
|
23
|
+
declarations: [],
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// Min context
|
|
27
|
+
const ctx: JsContext = {
|
|
28
|
+
program: runner.program,
|
|
29
|
+
rootModule: module,
|
|
30
|
+
} as JsContext;
|
|
31
|
+
|
|
32
|
+
return [ctx, module];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function getScalar(...names: string[]): Promise<Scalar[]> {
|
|
36
|
+
const { test } = (await runner.compile(`
|
|
37
|
+
model Example {
|
|
38
|
+
@test test: [${names.join(", ")}];
|
|
39
|
+
}
|
|
40
|
+
`)) as { test: ModelProperty };
|
|
41
|
+
|
|
42
|
+
if (test.type.kind !== "Tuple") {
|
|
43
|
+
throw new Error("Expected tuple type");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!test.type.values.every((t) => t.kind === "Scalar")) {
|
|
47
|
+
throw new Error("Expected scalar types only");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return test.type.values as Scalar[];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
it("has no-op encoding for string", async () => {
|
|
54
|
+
const [string] = await getScalar("TypeSpec.string");
|
|
55
|
+
|
|
56
|
+
const [ctx, mod] = createFakeModule();
|
|
57
|
+
|
|
58
|
+
const jsScalar = getJsScalar(ctx, mod, string, NoTarget);
|
|
59
|
+
|
|
60
|
+
strictEqual(jsScalar.type, "string");
|
|
61
|
+
strictEqual(jsScalar.getEncoding("default", string)?.encode("asdf"), "(asdf)");
|
|
62
|
+
strictEqual(mod.imports.length, 0);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("correctly encodes and decodes all numbers using default string encoding", async () => {
|
|
66
|
+
const [string, ...numbers] = await getScalar(
|
|
67
|
+
"string",
|
|
68
|
+
"float32",
|
|
69
|
+
"float64",
|
|
70
|
+
"int8",
|
|
71
|
+
"int16",
|
|
72
|
+
"int32",
|
|
73
|
+
"uint8",
|
|
74
|
+
"uint16",
|
|
75
|
+
"uint32",
|
|
76
|
+
"safeint",
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const [ctx, mod] = createFakeModule();
|
|
80
|
+
|
|
81
|
+
for (const number of numbers) {
|
|
82
|
+
const jsScalar = getJsScalar(ctx, mod, number, NoTarget);
|
|
83
|
+
|
|
84
|
+
strictEqual(jsScalar.type, "number");
|
|
85
|
+
|
|
86
|
+
const encoding = jsScalar.getEncoding("default", string);
|
|
87
|
+
|
|
88
|
+
if (!encoding) {
|
|
89
|
+
throw new Error("Expected default encoding");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const encoded = encoding.encode("asdf");
|
|
93
|
+
|
|
94
|
+
strictEqual(encoded, "globalThis.String((asdf))");
|
|
95
|
+
|
|
96
|
+
const decoded = encoding.decode("asdf");
|
|
97
|
+
|
|
98
|
+
strictEqual(decoded, "globalThis.Number((asdf))");
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("encodes and decodes types that coerce to bigint using default string encoding", async () => {
|
|
103
|
+
const [string, ...bigints] = await getScalar("string", "uint64", "int64", "integer");
|
|
104
|
+
|
|
105
|
+
const [ctx, mod] = createFakeModule();
|
|
106
|
+
|
|
107
|
+
for (const bigint of bigints) {
|
|
108
|
+
const jsScalar = getJsScalar(ctx, mod, bigint, NoTarget);
|
|
109
|
+
|
|
110
|
+
strictEqual(jsScalar.type, "bigint");
|
|
111
|
+
|
|
112
|
+
const encoding = jsScalar.getEncoding("default", string);
|
|
113
|
+
|
|
114
|
+
if (!encoding) {
|
|
115
|
+
throw new Error("Expected default encoding");
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const encoded = encoding.encode("asdf");
|
|
119
|
+
|
|
120
|
+
strictEqual(encoded, "globalThis.String((asdf))");
|
|
121
|
+
|
|
122
|
+
const decoded = encoding.decode("asdf");
|
|
123
|
+
|
|
124
|
+
strictEqual(decoded, "globalThis.BigInt((asdf))");
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("bytes base64 encoding", async () => {
|
|
129
|
+
const [string, bytes] = await getScalar("TypeSpec.string", "TypeSpec.bytes");
|
|
130
|
+
|
|
131
|
+
const [ctx, mod] = createFakeModule();
|
|
132
|
+
|
|
133
|
+
const jsScalar = getJsScalar(ctx, mod, bytes, NoTarget);
|
|
134
|
+
|
|
135
|
+
strictEqual(jsScalar.type, "Uint8Array");
|
|
136
|
+
|
|
137
|
+
const encoding = jsScalar.getEncoding("base64", string);
|
|
138
|
+
|
|
139
|
+
if (!encoding) {
|
|
140
|
+
throw new Error("Expected base64 encoding");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const encoded = encoding.encode("asdf");
|
|
144
|
+
|
|
145
|
+
strictEqual(
|
|
146
|
+
encoded,
|
|
147
|
+
"((asdf) instanceof globalThis.Buffer ? (asdf) : globalThis.Buffer.from((asdf))).toString('base64')",
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
const decoded = encoding.decode("asdf");
|
|
151
|
+
|
|
152
|
+
strictEqual(decoded, "globalThis.Buffer.from((asdf), 'base64')");
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it("bytes base64url encoding", async () => {
|
|
156
|
+
const [string, bytes] = await getScalar("TypeSpec.string", "TypeSpec.bytes");
|
|
157
|
+
|
|
158
|
+
const [ctx, mod] = createFakeModule();
|
|
159
|
+
|
|
160
|
+
const jsScalar = getJsScalar(ctx, mod, bytes, NoTarget);
|
|
161
|
+
|
|
162
|
+
strictEqual(jsScalar.type, "Uint8Array");
|
|
163
|
+
|
|
164
|
+
const encoding = jsScalar.getEncoding("base64url", string);
|
|
165
|
+
|
|
166
|
+
if (!encoding) {
|
|
167
|
+
throw new Error("Expected base64url encoding");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const encoded = encoding.encode("asdf");
|
|
171
|
+
|
|
172
|
+
strictEqual(
|
|
173
|
+
encoded,
|
|
174
|
+
"globalThis.encodeURIComponent((((asdf)) instanceof globalThis.Buffer ? ((asdf)) : globalThis.Buffer.from(((asdf)))).toString('base64'))",
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
const decoded = encoding.decode("asdf");
|
|
178
|
+
|
|
179
|
+
strictEqual(
|
|
180
|
+
decoded,
|
|
181
|
+
"globalThis.Buffer.from((globalThis.decodeURIComponent((asdf))), 'base64')",
|
|
182
|
+
);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
describe("duration", () => {
|
|
186
|
+
it("produces correct parse template for ISO8601 duration", async () => {
|
|
187
|
+
const [Duration, string] = await getScalar("TypeSpec.duration", "TypeSpec.string");
|
|
188
|
+
|
|
189
|
+
const [ctx, mod] = createFakeModule();
|
|
190
|
+
|
|
191
|
+
const jsScalar = getJsScalar(ctx, mod, Duration, NoTarget);
|
|
192
|
+
|
|
193
|
+
strictEqual(jsScalar.type, "Duration");
|
|
194
|
+
strictEqual(
|
|
195
|
+
jsScalar.getEncoding("ISO8601", string)?.decode("asdf"),
|
|
196
|
+
"Duration.parseISO8601((asdf))",
|
|
197
|
+
);
|
|
198
|
+
strictEqual(mod.imports[0].from, dateTimeModule);
|
|
199
|
+
deepStrictEqual(mod.imports[0].binder, ["Duration"]);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it("produces correct write template for ISO8601 duration", async () => {
|
|
203
|
+
const [Duration, string] = await getScalar("TypeSpec.duration", "TypeSpec.string");
|
|
204
|
+
|
|
205
|
+
const [ctx, mod] = createFakeModule();
|
|
206
|
+
|
|
207
|
+
const jsScalar = getJsScalar(ctx, mod, Duration, NoTarget);
|
|
208
|
+
|
|
209
|
+
strictEqual(jsScalar.type, "Duration");
|
|
210
|
+
strictEqual(
|
|
211
|
+
jsScalar.getEncoding("ISO8601", string)?.encode("asdf"),
|
|
212
|
+
"Duration.toISO8601((asdf))",
|
|
213
|
+
);
|
|
214
|
+
strictEqual(mod.imports[0].from, dateTimeModule);
|
|
215
|
+
deepStrictEqual(mod.imports[0].binder, ["Duration"]);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it("can parse and write ISO8601 duration", async () => {
|
|
219
|
+
const [Duration, string] = await getScalar("TypeSpec.duration", "TypeSpec.string");
|
|
220
|
+
|
|
221
|
+
const [ctx, mod] = createFakeModule();
|
|
222
|
+
|
|
223
|
+
const jsScalar = getJsScalar(ctx, mod, Duration, NoTarget);
|
|
224
|
+
|
|
225
|
+
strictEqual(jsScalar.type, "Duration");
|
|
226
|
+
|
|
227
|
+
const encoding = jsScalar.getEncoding("ISO8601", string);
|
|
228
|
+
|
|
229
|
+
if (!encoding) {
|
|
230
|
+
throw new Error("Expected ISO8601 encoding");
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const encoded = encoding.encode("duration");
|
|
234
|
+
|
|
235
|
+
strictEqual(encoded, "Duration.toISO8601((duration))");
|
|
236
|
+
|
|
237
|
+
const decoded = encoding.decode('"P1Y2M3DT4H5M6S"');
|
|
238
|
+
|
|
239
|
+
strictEqual(decoded, 'Duration.parseISO8601(("P1Y2M3DT4H5M6S"))');
|
|
240
|
+
|
|
241
|
+
strictEqual(mod.imports[0].from, dateTimeModule);
|
|
242
|
+
deepStrictEqual(mod.imports[0].binder, ["Duration"]);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it("allows default string encoding through via", async () => {
|
|
246
|
+
const [Duration, string] = await getScalar("duration", "string");
|
|
247
|
+
|
|
248
|
+
const [ctx, mod] = createFakeModule();
|
|
249
|
+
|
|
250
|
+
const jsScalar = getJsScalar(ctx, mod, Duration, NoTarget);
|
|
251
|
+
|
|
252
|
+
strictEqual(jsScalar.type, "Duration");
|
|
253
|
+
|
|
254
|
+
const encoding = jsScalar.getEncoding("default", string);
|
|
255
|
+
|
|
256
|
+
if (!encoding) {
|
|
257
|
+
throw new Error("Expected default encoding");
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const encoded = encoding.encode("duration");
|
|
261
|
+
|
|
262
|
+
strictEqual(encoded, "Duration.toISO8601(((duration)))");
|
|
263
|
+
|
|
264
|
+
const decoded = encoding.decode("duration");
|
|
265
|
+
|
|
266
|
+
strictEqual(decoded, "Duration.parseISO8601(((duration)))");
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it("allows encoding seconds to number types", async () => {
|
|
270
|
+
const [Duration, int32, uint32] = await getScalar("duration", "int32", "uint32");
|
|
271
|
+
|
|
272
|
+
const [ctx, mod] = createFakeModule();
|
|
273
|
+
|
|
274
|
+
const jsScalar = getJsScalar(ctx, mod, Duration, NoTarget);
|
|
275
|
+
|
|
276
|
+
strictEqual(jsScalar.type, "Duration");
|
|
277
|
+
|
|
278
|
+
const encodingInt32 = jsScalar.getEncoding("seconds", int32);
|
|
279
|
+
|
|
280
|
+
if (!encodingInt32) {
|
|
281
|
+
throw new Error("Expected seconds encoding int32");
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const encodedInt32 = encodingInt32.encode("duration");
|
|
285
|
+
|
|
286
|
+
strictEqual(encodedInt32, "Duration.totalSeconds((duration))");
|
|
287
|
+
|
|
288
|
+
const decodedInt32 = encodingInt32.decode("duration");
|
|
289
|
+
|
|
290
|
+
strictEqual(decodedInt32, "Duration.fromSeconds((duration))");
|
|
291
|
+
|
|
292
|
+
const encodingUint32 = jsScalar.getEncoding("seconds", uint32);
|
|
293
|
+
|
|
294
|
+
if (!encodingUint32) {
|
|
295
|
+
throw new Error("Expected seconds encoding uint32");
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const encodedUint32 = encodingUint32.encode("duration");
|
|
299
|
+
|
|
300
|
+
strictEqual(encodedUint32, "Duration.totalSeconds((duration))");
|
|
301
|
+
|
|
302
|
+
const decodedUint32 = encodingUint32.decode("duration");
|
|
303
|
+
|
|
304
|
+
strictEqual(decodedUint32, "Duration.fromSeconds((duration))");
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it("allows encoding seconds to bigint types", async () => {
|
|
308
|
+
const [Duration, int64, uint64] = await getScalar("duration", "int64", "uint64");
|
|
309
|
+
|
|
310
|
+
const [ctx, mod] = createFakeModule();
|
|
311
|
+
|
|
312
|
+
const jsScalar = getJsScalar(ctx, mod, Duration, NoTarget);
|
|
313
|
+
|
|
314
|
+
strictEqual(jsScalar.type, "Duration");
|
|
315
|
+
|
|
316
|
+
const encodingInt64 = jsScalar.getEncoding("seconds", int64);
|
|
317
|
+
|
|
318
|
+
if (!encodingInt64) {
|
|
319
|
+
throw new Error("Expected seconds encoding int64");
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const encodedInt64 = encodingInt64.encode("duration");
|
|
323
|
+
|
|
324
|
+
strictEqual(encodedInt64, "Duration.totalSecondsBigInt((duration))");
|
|
325
|
+
|
|
326
|
+
const decodedInt64 = encodingInt64.decode("duration");
|
|
327
|
+
|
|
328
|
+
strictEqual(decodedInt64, "Duration.fromSeconds(globalThis.Number((duration)))");
|
|
329
|
+
|
|
330
|
+
const encodingUint64 = jsScalar.getEncoding("seconds", uint64);
|
|
331
|
+
|
|
332
|
+
if (!encodingUint64) {
|
|
333
|
+
throw new Error("Expected seconds encoding uint64");
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const encodedUint64 = encodingUint64.encode("duration");
|
|
337
|
+
|
|
338
|
+
strictEqual(encodedUint64, "Duration.totalSecondsBigInt((duration))");
|
|
339
|
+
|
|
340
|
+
const decodedUint64 = encodingUint64.decode("duration");
|
|
341
|
+
|
|
342
|
+
strictEqual(decodedUint64, "Duration.fromSeconds(globalThis.Number((duration)))");
|
|
343
|
+
});
|
|
344
|
+
});
|
|
345
|
+
});
|