@typespec/emitter-framework 0.6.0-dev.6 → 0.7.0-dev.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/CHANGELOG.md +17 -0
- package/dist/src/core/components/index.d.ts +2 -0
- package/dist/src/core/components/index.d.ts.map +1 -0
- package/dist/src/core/components/index.js +1 -0
- package/dist/src/core/components/output.d.ts +10 -0
- package/dist/src/core/components/output.d.ts.map +1 -0
- package/dist/src/core/components/output.js +16 -0
- package/dist/src/core/context/index.d.ts +1 -0
- package/dist/src/core/context/index.d.ts.map +1 -1
- package/dist/src/core/context/index.js +2 -1
- package/dist/src/core/context/tsp-context.d.ts +13 -0
- package/dist/src/core/context/tsp-context.d.ts.map +1 -0
- package/dist/src/core/context/tsp-context.js +13 -0
- package/dist/src/core/index.d.ts +1 -0
- package/dist/src/core/index.d.ts.map +1 -1
- package/dist/src/core/index.js +1 -0
- package/dist/src/core/write-output.d.ts +2 -1
- package/dist/src/core/write-output.d.ts.map +1 -1
- package/dist/src/core/write-output.js +5 -6
- package/dist/src/typescript/components/enum-declaration.d.ts.map +1 -1
- package/dist/src/typescript/components/enum-declaration.js +4 -1
- package/dist/src/typescript/components/interface-declaration.d.ts.map +1 -1
- package/dist/src/typescript/components/interface-declaration.js +9 -3
- package/dist/src/typescript/components/interface-member.d.ts.map +1 -1
- package/dist/src/typescript/components/interface-member.js +4 -1
- package/dist/src/typescript/components/type-alias-declaration.d.ts.map +1 -1
- package/dist/src/typescript/components/type-alias-declaration.js +4 -1
- package/dist/src/typescript/components/type-expression.d.ts.map +1 -1
- package/dist/src/typescript/components/type-expression.js +8 -5
- package/dist/src/typescript/components/type-transform.d.ts.map +1 -1
- package/dist/src/typescript/components/type-transform.js +26 -5
- package/dist/src/typescript/components/union-declaration.d.ts.map +1 -1
- package/dist/src/typescript/components/union-declaration.js +4 -1
- package/dist/src/typescript/components/union-expression.d.ts.map +1 -1
- package/dist/src/typescript/components/union-expression.js +4 -1
- package/dist/src/typescript/utils/operation.d.ts.map +1 -1
- package/dist/src/typescript/utils/operation.js +7 -1
- package/dist/test/typescript/components/arrow-function.test.js +11 -1
- package/dist/test/typescript/components/enum-declaration.test.js +47 -18
- package/dist/test/typescript/components/function-declaration.test.js +9 -1
- package/dist/test/typescript/components/function-expression.test.js +11 -1
- package/dist/test/typescript/components/function-type.test.js +11 -1
- package/dist/test/typescript/components/interface-declaration.test.js +20 -2
- package/dist/test/typescript/components/interface-method.test.js +26 -2
- package/dist/test/typescript/components/member-expression.test.js +61 -32
- package/dist/test/typescript/components/type-alias-declaration.test.js +9 -1
- package/dist/test/typescript/components/union-declaration.test.js +9 -1
- package/dist/test/typescript/components/value-expression.test.js +9 -7
- package/package.json +7 -7
- package/src/core/components/index.tsx +1 -0
- package/src/core/components/output.tsx +19 -0
- package/src/core/context/index.ts +1 -0
- package/src/core/context/tsp-context.ts +30 -0
- package/src/core/index.ts +1 -0
- package/src/core/write-output.ts +14 -7
- package/src/typescript/components/enum-declaration.tsx +2 -1
- package/src/typescript/components/interface-declaration.tsx +7 -3
- package/src/typescript/components/interface-member.tsx +2 -1
- package/src/typescript/components/type-alias-declaration.tsx +2 -1
- package/src/typescript/components/type-expression.tsx +7 -5
- package/src/typescript/components/type-transform.tsx +17 -5
- package/src/typescript/components/union-declaration.tsx +2 -1
- package/src/typescript/components/union-expression.tsx +2 -1
- package/src/typescript/utils/operation.ts +3 -1
- package/test/typescript/components/arrow-function.test.tsx +5 -4
- package/test/typescript/components/enum-declaration.test.tsx +29 -16
- package/test/typescript/components/function-declaration.test.tsx +9 -8
- package/test/typescript/components/function-expression.test.tsx +5 -4
- package/test/typescript/components/function-type.test.tsx +5 -4
- package/test/typescript/components/interface-declaration.test.tsx +20 -20
- package/test/typescript/components/interface-method.test.tsx +12 -10
- package/test/typescript/components/member-expression.test.tsx +25 -16
- package/test/typescript/components/type-alias-declaration.test.tsx +7 -6
- package/test/typescript/components/union-declaration.test.tsx +9 -7
- package/test/typescript/components/value-expression.test.tsx +22 -8
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { render } from "@alloy-js/core";
|
|
3
3
|
import { SourceFile } from "@alloy-js/typescript";
|
|
4
4
|
import { format } from "prettier";
|
|
5
5
|
import { assert, describe, expect, it } from "vitest";
|
|
6
|
+
import { Output } from "../../../src/core/components/output.js";
|
|
6
7
|
import { UnionDeclaration } from "../../../src/typescript/components/union-declaration.js";
|
|
7
8
|
import { UnionExpression } from "../../../src/typescript/components/union-expression.js";
|
|
8
9
|
import { getProgram } from "../test-host.js";
|
|
9
10
|
describe("Typescript Union Declaration", () => {
|
|
10
11
|
describe("Union not bound to Typespec Types", () => {
|
|
11
12
|
it("creates a union declaration", async () => {
|
|
13
|
+
const program = await getProgram("");
|
|
12
14
|
const res = render(_$createComponent(Output, {
|
|
15
|
+
program: program,
|
|
13
16
|
get children() {
|
|
14
17
|
return _$createComponent(SourceFile, {
|
|
15
18
|
path: "test.ts",
|
|
@@ -46,6 +49,7 @@ describe("Typescript Union Declaration", () => {
|
|
|
46
49
|
const [namespace] = program.resolveTypeReference("DemoService");
|
|
47
50
|
const union = Array.from(namespace.unions.values())[0];
|
|
48
51
|
const res = render(_$createComponent(Output, {
|
|
52
|
+
program: program,
|
|
49
53
|
get children() {
|
|
50
54
|
return _$createComponent(SourceFile, {
|
|
51
55
|
path: "test.ts",
|
|
@@ -78,6 +82,7 @@ describe("Typescript Union Declaration", () => {
|
|
|
78
82
|
const [namespace] = program.resolveTypeReference("DemoService");
|
|
79
83
|
const union = Array.from(namespace.unions.values())[0];
|
|
80
84
|
const res = render(_$createComponent(Output, {
|
|
85
|
+
program: program,
|
|
81
86
|
get children() {
|
|
82
87
|
return _$createComponent(SourceFile, {
|
|
83
88
|
path: "test.ts",
|
|
@@ -112,6 +117,7 @@ describe("Typescript Union Declaration", () => {
|
|
|
112
117
|
const [namespace] = program.resolveTypeReference("DemoService");
|
|
113
118
|
const union = Array.from(namespace.unions.values())[0];
|
|
114
119
|
const res = render(_$createComponent(Output, {
|
|
120
|
+
program: program,
|
|
115
121
|
get children() {
|
|
116
122
|
return _$createComponent(SourceFile, {
|
|
117
123
|
path: "test.ts",
|
|
@@ -145,6 +151,7 @@ describe("Typescript Union Declaration", () => {
|
|
|
145
151
|
const [namespace] = program.resolveTypeReference("DemoService");
|
|
146
152
|
const union = Array.from(namespace.unions.values())[0];
|
|
147
153
|
const res = render(_$createComponent(Output, {
|
|
154
|
+
program: program,
|
|
148
155
|
get children() {
|
|
149
156
|
return _$createComponent(SourceFile, {
|
|
150
157
|
path: "test.ts",
|
|
@@ -179,6 +186,7 @@ describe("Typescript Union Declaration", () => {
|
|
|
179
186
|
const [namespace] = program.resolveTypeReference("DemoService");
|
|
180
187
|
const union = Array.from(namespace.enums.values())[0];
|
|
181
188
|
const res = render(_$createComponent(Output, {
|
|
189
|
+
program: program,
|
|
182
190
|
get children() {
|
|
183
191
|
return _$createComponent(SourceFile, {
|
|
184
192
|
path: "test.ts",
|
|
@@ -6,21 +6,22 @@ import { Numeric } from "@typespec/compiler";
|
|
|
6
6
|
import { $ } from "@typespec/compiler/experimental/typekit";
|
|
7
7
|
import { assert, beforeAll, describe, expect, it } from "vitest";
|
|
8
8
|
import { ValueExpression } from "../../../src/typescript/components/value-expression.js";
|
|
9
|
-
import { getProgram
|
|
9
|
+
import { getProgram } from "../test-host.js";
|
|
10
|
+
let program;
|
|
10
11
|
beforeAll(async () => {
|
|
11
|
-
await
|
|
12
|
+
program = await getProgram("");
|
|
12
13
|
});
|
|
13
14
|
it("renders strings", async () => {
|
|
14
|
-
const value =
|
|
15
|
+
const value = $(program).value.createString("test");
|
|
15
16
|
await testValueExpression(value, `"test"`);
|
|
16
17
|
});
|
|
17
18
|
describe("numeric values", () => {
|
|
18
19
|
it("renders integers", async () => {
|
|
19
|
-
const value =
|
|
20
|
+
const value = $(program).value.createNumeric(42);
|
|
20
21
|
await testValueExpression(value, `42`);
|
|
21
22
|
});
|
|
22
23
|
it("renders decimals", async () => {
|
|
23
|
-
const value =
|
|
24
|
+
const value = $(program).value.createNumeric(42.5);
|
|
24
25
|
await testValueExpression(value, `42.5`);
|
|
25
26
|
});
|
|
26
27
|
it("renders bigints", async () => {
|
|
@@ -43,7 +44,7 @@ describe("numeric values", () => {
|
|
|
43
44
|
});
|
|
44
45
|
});
|
|
45
46
|
it("renders booleans", async () => {
|
|
46
|
-
const value =
|
|
47
|
+
const value = $(program).value.createBoolean(true);
|
|
47
48
|
await testValueExpression(value, `true`);
|
|
48
49
|
});
|
|
49
50
|
it("renders nulls", async () => {
|
|
@@ -64,11 +65,12 @@ it("renders empty arrays", async () => {
|
|
|
64
65
|
await testValueExpression(value, `[]`);
|
|
65
66
|
});
|
|
66
67
|
it("renders arrays with mixed values", async () => {
|
|
68
|
+
const tk = $(program);
|
|
67
69
|
// Can be replaced with with TypeKit once #6976 is implemented
|
|
68
70
|
const value = {
|
|
69
71
|
entityKind: "Value",
|
|
70
72
|
valueKind: "ArrayValue",
|
|
71
|
-
values: [
|
|
73
|
+
values: [tk.value.createString("foo"), tk.value.createNumeric(42), tk.value.createBoolean(true)]
|
|
72
74
|
};
|
|
73
75
|
await testValueExpression(value, `["foo", 42, true]`);
|
|
74
76
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typespec/emitter-framework",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0-dev.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"@alloy-js/core": "^0.11.0",
|
|
23
23
|
"@alloy-js/typescript": "^0.11.0",
|
|
24
|
-
"@typespec/compiler": "^1.0.0-rc.
|
|
25
|
-
"@typespec/http": "^1.0.0-rc.
|
|
26
|
-
"@typespec/rest": "^0.
|
|
24
|
+
"@typespec/compiler": "^1.0.0-rc.1",
|
|
25
|
+
"@typespec/http": "^1.0.0-rc.1",
|
|
26
|
+
"@typespec/rest": "^0.69.0 || >=0.70.0-dev <0.70.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@alloy-js/cli": "^0.11.0",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"@alloy-js/core": "^0.11.0",
|
|
32
32
|
"@alloy-js/typescript": "^0.11.0",
|
|
33
33
|
"@types/minimist": "^1.2.5",
|
|
34
|
-
"@typespec/compiler": "^1.0.0-rc.
|
|
35
|
-
"@typespec/http": "^1.0.0-rc.
|
|
36
|
-
"@typespec/rest": "^0.
|
|
34
|
+
"@typespec/compiler": "^1.0.0-rc.1",
|
|
35
|
+
"@typespec/http": "^1.0.0-rc.1",
|
|
36
|
+
"@typespec/rest": "^0.69.0 || >=0.70.0-dev <0.70.0",
|
|
37
37
|
"concurrently": "^9.1.2",
|
|
38
38
|
"minimist": "^1.2.8",
|
|
39
39
|
"prettier": "~3.5.3",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./output.jsx";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as ay from "@alloy-js/core";
|
|
2
|
+
import { Program } from "@typespec/compiler";
|
|
3
|
+
import { TspContext } from "../context/tsp-context.js";
|
|
4
|
+
|
|
5
|
+
export interface OutputProps extends ay.OutputProps {
|
|
6
|
+
/**
|
|
7
|
+
* TypeSpec program.
|
|
8
|
+
*/
|
|
9
|
+
program: Program;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function Output(props: OutputProps) {
|
|
13
|
+
const [{ program }, rest] = ay.splitProps(props, ["program"]);
|
|
14
|
+
return (
|
|
15
|
+
<TspContext.Provider value={{ program }}>
|
|
16
|
+
<ay.Output {...rest} />
|
|
17
|
+
</TspContext.Provider>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ComponentContext, createNamedContext, useContext } from "@alloy-js/core";
|
|
2
|
+
import { Program } from "@typespec/compiler";
|
|
3
|
+
import { unsafe_$ } from "@typespec/compiler/experimental";
|
|
4
|
+
import { Typekit } from "@typespec/compiler/experimental/typekit";
|
|
5
|
+
|
|
6
|
+
export type TspContext = {
|
|
7
|
+
program: Program;
|
|
8
|
+
$: Typekit;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const TspContext: ComponentContext<{ program: Program; $?: Typekit }> = createNamedContext<{
|
|
12
|
+
program: Program;
|
|
13
|
+
$?: Typekit;
|
|
14
|
+
}>("TspContext");
|
|
15
|
+
|
|
16
|
+
export function useTsp() {
|
|
17
|
+
const context = useContext(TspContext)!;
|
|
18
|
+
|
|
19
|
+
if (!context) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
"TspContext is not set. Make sure the component is wrapped in TspContext.Provider or the emitter framework Output component.",
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!context.$) {
|
|
26
|
+
context.$ = unsafe_$(context.program);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return context as TspContext;
|
|
30
|
+
}
|
package/src/core/index.ts
CHANGED
package/src/core/write-output.ts
CHANGED
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
import { Children, OutputDirectory, render } from "@alloy-js/core";
|
|
2
|
-
import { emitFile, joinPaths } from "@typespec/compiler";
|
|
3
|
-
import { unsafe_$ as $ } from "@typespec/compiler/experimental";
|
|
2
|
+
import { emitFile, joinPaths, Program } from "@typespec/compiler";
|
|
4
3
|
|
|
5
|
-
export async function writeOutput(
|
|
4
|
+
export async function writeOutput(
|
|
5
|
+
program: Program,
|
|
6
|
+
rootComponent: Children,
|
|
7
|
+
emitterOutputDir: string,
|
|
8
|
+
) {
|
|
6
9
|
const tree = render(rootComponent);
|
|
7
|
-
await writeOutputDirectory(tree, emitterOutputDir);
|
|
10
|
+
await writeOutputDirectory(program, tree, emitterOutputDir);
|
|
8
11
|
}
|
|
9
12
|
|
|
10
|
-
async function writeOutputDirectory(
|
|
13
|
+
async function writeOutputDirectory(
|
|
14
|
+
program: Program,
|
|
15
|
+
dir: OutputDirectory,
|
|
16
|
+
emitterOutputDir: string,
|
|
17
|
+
) {
|
|
11
18
|
for (const sub of dir.contents) {
|
|
12
19
|
if (Array.isArray(sub.contents)) {
|
|
13
|
-
await writeOutputDirectory(sub as OutputDirectory, emitterOutputDir);
|
|
20
|
+
await writeOutputDirectory(program, sub as OutputDirectory, emitterOutputDir);
|
|
14
21
|
} else {
|
|
15
|
-
await emitFile(
|
|
22
|
+
await emitFile(program, {
|
|
16
23
|
content: sub.contents as string,
|
|
17
24
|
path: joinPaths(emitterOutputDir, sub.path),
|
|
18
25
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as ay from "@alloy-js/core";
|
|
2
2
|
import * as ts from "@alloy-js/typescript";
|
|
3
3
|
import { Enum, EnumMember as TspEnumMember, Union } from "@typespec/compiler";
|
|
4
|
-
import {
|
|
4
|
+
import { useTsp } from "../../core/context/tsp-context.js";
|
|
5
5
|
import { reportDiagnostic } from "../../lib.js";
|
|
6
6
|
|
|
7
7
|
export interface EnumDeclarationProps extends Omit<ts.TypeDeclarationProps, "name"> {
|
|
@@ -10,6 +10,7 @@ export interface EnumDeclarationProps extends Omit<ts.TypeDeclarationProps, "nam
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export function EnumDeclaration(props: EnumDeclarationProps) {
|
|
13
|
+
const { $ } = useTsp();
|
|
13
14
|
let type: Enum;
|
|
14
15
|
if ($.union.is(props.type)) {
|
|
15
16
|
if (!$.union.isValidEnum(props.type)) {
|
|
@@ -9,8 +9,9 @@ import {
|
|
|
9
9
|
Operation,
|
|
10
10
|
RekeyableMap,
|
|
11
11
|
} from "@typespec/compiler";
|
|
12
|
-
import {
|
|
12
|
+
import { Typekit } from "@typespec/compiler/experimental/typekit";
|
|
13
13
|
import { createRekeyableMap } from "@typespec/compiler/utils";
|
|
14
|
+
import { useTsp } from "../../core/context/tsp-context.js";
|
|
14
15
|
import { reportDiagnostic } from "../../lib.js";
|
|
15
16
|
import { InterfaceMember } from "./interface-member.js";
|
|
16
17
|
import { TypeExpression } from "./type-expression.jsx";
|
|
@@ -24,6 +25,8 @@ export type InterfaceDeclarationProps =
|
|
|
24
25
|
| ts.InterfaceDeclarationProps;
|
|
25
26
|
|
|
26
27
|
export function InterfaceDeclaration(props: InterfaceDeclarationProps) {
|
|
28
|
+
const { $ } = useTsp();
|
|
29
|
+
|
|
27
30
|
if (!isTypedInterfaceDeclarationProps(props)) {
|
|
28
31
|
return <ts.InterfaceDeclaration {...props} />;
|
|
29
32
|
}
|
|
@@ -40,7 +43,7 @@ export function InterfaceDeclaration(props: InterfaceDeclarationProps) {
|
|
|
40
43
|
|
|
41
44
|
const refkey = props.refkey ?? getRefkey(props.type);
|
|
42
45
|
|
|
43
|
-
const extendsType = props.extends ?? getExtendsType(props.type);
|
|
46
|
+
const extendsType = props.extends ?? getExtendsType($, props.type);
|
|
44
47
|
|
|
45
48
|
return (
|
|
46
49
|
<ts.InterfaceDeclaration
|
|
@@ -74,7 +77,7 @@ export function InterfaceExpression(props: InterfaceExpressionProps) {
|
|
|
74
77
|
);
|
|
75
78
|
}
|
|
76
79
|
|
|
77
|
-
function getExtendsType(type: Model | Interface): Children | undefined {
|
|
80
|
+
function getExtendsType($: Typekit, type: Model | Interface): Children | undefined {
|
|
78
81
|
if (!$.model.is(type)) {
|
|
79
82
|
return undefined;
|
|
80
83
|
}
|
|
@@ -120,6 +123,7 @@ function getExtendsType(type: Model | Interface): Children | undefined {
|
|
|
120
123
|
* Renders the members of an interface from its properties, including any additional children.
|
|
121
124
|
*/
|
|
122
125
|
function InterfaceBody(props: TypedInterfaceDeclarationProps): Children {
|
|
126
|
+
const { $ } = useTsp();
|
|
123
127
|
let typeMembers: RekeyableMap<string, ModelProperty | Operation> | undefined;
|
|
124
128
|
if ($.model.is(props.type)) {
|
|
125
129
|
typeMembers = $.model.getProperties(props.type);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as ts from "@alloy-js/typescript";
|
|
2
2
|
import { isNeverType, ModelProperty, Operation } from "@typespec/compiler";
|
|
3
|
-
import { $ } from "@typespec/compiler/experimental/typekit";
|
|
4
3
|
import { getHttpPart } from "@typespec/http";
|
|
4
|
+
import { useTsp } from "../../core/context/tsp-context.js";
|
|
5
5
|
import { InterfaceMethod } from "./interface-method.jsx";
|
|
6
6
|
import { TypeExpression } from "./type-expression.js";
|
|
7
7
|
|
|
@@ -11,6 +11,7 @@ export interface InterfaceMemberProps {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export function InterfaceMember(props: InterfaceMemberProps) {
|
|
14
|
+
const { $ } = useTsp();
|
|
14
15
|
const namer = ts.useTSNamePolicy();
|
|
15
16
|
const name = namer.getName(props.type.name, "object-member-getter");
|
|
16
17
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { refkey as getRefkey } from "@alloy-js/core";
|
|
2
2
|
import * as ts from "@alloy-js/typescript";
|
|
3
3
|
import { Type } from "@typespec/compiler";
|
|
4
|
-
import {
|
|
4
|
+
import { useTsp } from "../../core/context/tsp-context.js";
|
|
5
5
|
import { reportDiagnostic } from "../../lib.js";
|
|
6
6
|
import { TypeExpression } from "./type-expression.jsx";
|
|
7
7
|
|
|
@@ -17,6 +17,7 @@ export type TypeAliasDeclarationProps = TypedAliasDeclarationProps | ts.TypeDecl
|
|
|
17
17
|
* type alias as the provided TypeSpec type.
|
|
18
18
|
*/
|
|
19
19
|
export function TypeAliasDeclaration(props: TypeAliasDeclarationProps) {
|
|
20
|
+
const { $ } = useTsp();
|
|
20
21
|
if (!isTypedAliasDeclarationProps(props)) {
|
|
21
22
|
return <ts.TypeDeclaration {...props}>{props.children}</ts.TypeDeclaration>;
|
|
22
23
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { For, refkey } from "@alloy-js/core";
|
|
2
2
|
import { Reference, ValueExpression } from "@alloy-js/typescript";
|
|
3
3
|
import { IntrinsicType, Model, Scalar, Type } from "@typespec/compiler";
|
|
4
|
-
import {
|
|
4
|
+
import { Typekit } from "@typespec/compiler/experimental/typekit";
|
|
5
5
|
import "@typespec/http/experimental/typekit";
|
|
6
|
+
import { useTsp } from "../../core/context/tsp-context.js";
|
|
6
7
|
import { reportTypescriptDiagnostic } from "../../typescript/lib.js";
|
|
7
8
|
import { ArrayExpression } from "./array-expression.js";
|
|
8
9
|
import { FunctionType } from "./function-type.js";
|
|
@@ -22,8 +23,9 @@ export interface TypeExpressionProps {
|
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
export function TypeExpression(props: TypeExpressionProps) {
|
|
26
|
+
const { $ } = useTsp();
|
|
25
27
|
const type = $.httpPart.unpack(props.type);
|
|
26
|
-
if (!props.noReference && isDeclaration(type)) {
|
|
28
|
+
if (!props.noReference && isDeclaration($, type)) {
|
|
27
29
|
// todo: probably need abstraction around deciding what's a declaration in the output
|
|
28
30
|
// (it may not correspond to things which are declarations in TypeSpec?)
|
|
29
31
|
return <Reference refkey={refkey(type)} />;
|
|
@@ -34,7 +36,7 @@ export function TypeExpression(props: TypeExpressionProps) {
|
|
|
34
36
|
switch (type.kind) {
|
|
35
37
|
case "Scalar":
|
|
36
38
|
case "Intrinsic":
|
|
37
|
-
return <>{getScalarIntrinsicExpression(type)}</>;
|
|
39
|
+
return <>{getScalarIntrinsicExpression($, type)}</>;
|
|
38
40
|
case "Boolean":
|
|
39
41
|
case "Number":
|
|
40
42
|
case "String":
|
|
@@ -119,7 +121,7 @@ const intrinsicNameToTSType = new Map<string, string | null>([
|
|
|
119
121
|
["url", "string"], // Matches TypeScript's `string`
|
|
120
122
|
]);
|
|
121
123
|
|
|
122
|
-
function getScalarIntrinsicExpression(type: Scalar | IntrinsicType): string | null {
|
|
124
|
+
function getScalarIntrinsicExpression($: Typekit, type: Scalar | IntrinsicType): string | null {
|
|
123
125
|
let intrinsicName: string;
|
|
124
126
|
if ($.scalar.is(type)) {
|
|
125
127
|
if ($.scalar.isUtcDateTime(type) || $.scalar.extendsUtcDateTime(type)) {
|
|
@@ -152,7 +154,7 @@ function getScalarIntrinsicExpression(type: Scalar | IntrinsicType): string | nu
|
|
|
152
154
|
return tsType;
|
|
153
155
|
}
|
|
154
156
|
|
|
155
|
-
function isDeclaration(type: Type): boolean {
|
|
157
|
+
function isDeclaration($: Typekit, type: Type): boolean {
|
|
156
158
|
switch (type.kind) {
|
|
157
159
|
case "Namespace":
|
|
158
160
|
case "Interface":
|
|
@@ -9,8 +9,9 @@ import {
|
|
|
9
9
|
Type,
|
|
10
10
|
Union,
|
|
11
11
|
} from "@typespec/compiler";
|
|
12
|
-
import {
|
|
12
|
+
import { Typekit } from "@typespec/compiler/experimental/typekit";
|
|
13
13
|
import { createRekeyableMap } from "@typespec/compiler/utils";
|
|
14
|
+
import { useTsp } from "../../core/context/tsp-context.js";
|
|
14
15
|
import { reportDiagnostic } from "../../lib.js";
|
|
15
16
|
import { reportTypescriptDiagnostic } from "../../typescript/lib.js";
|
|
16
17
|
import {
|
|
@@ -33,6 +34,7 @@ export interface UnionTransformProps {
|
|
|
33
34
|
target: "application" | "transport";
|
|
34
35
|
}
|
|
35
36
|
function UnionTransformExpression(props: UnionTransformProps) {
|
|
37
|
+
const { $ } = useTsp();
|
|
36
38
|
const discriminator = $.type.getDiscriminator(props.type);
|
|
37
39
|
|
|
38
40
|
if (!discriminator) {
|
|
@@ -56,6 +58,7 @@ interface DiscriminateExpressionProps {
|
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
function DiscriminateExpression(props: DiscriminateExpressionProps) {
|
|
61
|
+
const { $ } = useTsp();
|
|
59
62
|
const discriminatedUnion = $.model.is(props.type)
|
|
60
63
|
? $.model.getDiscriminatedUnion(props.type)
|
|
61
64
|
: $.union.getDiscriminatedUnion(props.type);
|
|
@@ -89,6 +92,7 @@ function DiscriminateExpression(props: DiscriminateExpressionProps) {
|
|
|
89
92
|
* Component that represents a function declaration that transforms a model to a transport or application model.
|
|
90
93
|
*/
|
|
91
94
|
export function TypeTransformDeclaration(props: TypeTransformProps) {
|
|
95
|
+
const { $ } = useTsp();
|
|
92
96
|
const namePolicy = ts.useTSNamePolicy();
|
|
93
97
|
|
|
94
98
|
// Record and array have their general serializers
|
|
@@ -179,6 +183,7 @@ export interface ModelTransformExpressionProps {
|
|
|
179
183
|
* Component that represents an object expression that transforms a model to a transport or application model.
|
|
180
184
|
*/
|
|
181
185
|
export function ModelTransformExpression(props: ModelTransformExpressionProps) {
|
|
186
|
+
const { $ } = useTsp();
|
|
182
187
|
if (props.type.baseModel) {
|
|
183
188
|
reportTypescriptDiagnostic($.program, {
|
|
184
189
|
code: "typescript-extended-model-transform-nyi",
|
|
@@ -233,7 +238,7 @@ export function ModelTransformExpression(props: ModelTransformExpressionProps) {
|
|
|
233
238
|
<TypeTransformCall target={props.target} type={unpackedType} itemPath={itemPath} />
|
|
234
239
|
);
|
|
235
240
|
|
|
236
|
-
if (property.optional && needsTransform(unpackedType)) {
|
|
241
|
+
if (property.optional && needsTransform($, unpackedType)) {
|
|
237
242
|
value = (
|
|
238
243
|
<>
|
|
239
244
|
{itemPath.join(".")} ?{" "}
|
|
@@ -260,6 +265,7 @@ interface TransformReferenceProps {
|
|
|
260
265
|
* Given a type and target, gets the reference to the transform function
|
|
261
266
|
*/
|
|
262
267
|
function TransformReference(props: TransformReferenceProps) {
|
|
268
|
+
const { $ } = useTsp();
|
|
263
269
|
if ($.scalar.is(props.type)) {
|
|
264
270
|
return <TransformScalarReference type={props.type} target={props.target} />;
|
|
265
271
|
}
|
|
@@ -290,6 +296,7 @@ interface TransformScalarReferenceProps {
|
|
|
290
296
|
* Handles scalar transformations
|
|
291
297
|
*/
|
|
292
298
|
function TransformScalarReference(props: TransformScalarReferenceProps) {
|
|
299
|
+
const { $ } = useTsp();
|
|
293
300
|
let reference: Refkey | undefined;
|
|
294
301
|
if ($.scalar.isUtcDateTime(props.type)) {
|
|
295
302
|
// TODO: Handle encoding, likely to need access to parents to avoid passing the modelProperty
|
|
@@ -331,7 +338,7 @@ export interface TypeTransformCallProps {
|
|
|
331
338
|
optionsBagName?: string;
|
|
332
339
|
}
|
|
333
340
|
|
|
334
|
-
function needsTransform(type: Type): boolean {
|
|
341
|
+
function needsTransform($: Typekit, type: Type): boolean {
|
|
335
342
|
return $.model.is(type) || $.scalar.isUtcDateTime(type);
|
|
336
343
|
}
|
|
337
344
|
|
|
@@ -339,7 +346,8 @@ function needsTransform(type: Type): boolean {
|
|
|
339
346
|
* This component represents a function call to transform a type
|
|
340
347
|
*/
|
|
341
348
|
export function TypeTransformCall(props: TypeTransformCallProps): Children {
|
|
342
|
-
const
|
|
349
|
+
const { $ } = useTsp();
|
|
350
|
+
const collapsedProperty = getCollapsedProperty($, props.type, props.collapse ?? false);
|
|
343
351
|
const itemPath = collapsedProperty
|
|
344
352
|
? [...(props.itemPath ?? []), collapsedProperty.name]
|
|
345
353
|
: (props.itemPath ?? []);
|
|
@@ -410,7 +418,11 @@ export function TypeTransformCall(props: TypeTransformCallProps): Children {
|
|
|
410
418
|
return itemName;
|
|
411
419
|
}
|
|
412
420
|
|
|
413
|
-
function getCollapsedProperty(
|
|
421
|
+
function getCollapsedProperty(
|
|
422
|
+
$: Typekit,
|
|
423
|
+
model: Type,
|
|
424
|
+
collapse: boolean,
|
|
425
|
+
): ModelProperty | undefined {
|
|
414
426
|
if (!$.model.is(model)) {
|
|
415
427
|
return undefined;
|
|
416
428
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { refkey as getRefkey } from "@alloy-js/core";
|
|
2
2
|
import * as ts from "@alloy-js/typescript";
|
|
3
3
|
import { Enum, Union } from "@typespec/compiler";
|
|
4
|
-
import {
|
|
4
|
+
import { useTsp } from "../../core/context/tsp-context.js";
|
|
5
5
|
import { reportDiagnostic } from "../../lib.js";
|
|
6
6
|
import { UnionExpression } from "./union-expression.js";
|
|
7
7
|
|
|
@@ -13,6 +13,7 @@ export interface TypedUnionDeclarationProps extends Omit<ts.TypeDeclarationProps
|
|
|
13
13
|
export type UnionDeclarationProps = TypedUnionDeclarationProps | ts.TypeDeclarationProps;
|
|
14
14
|
|
|
15
15
|
export function UnionDeclaration(props: UnionDeclarationProps) {
|
|
16
|
+
const { $ } = useTsp();
|
|
16
17
|
if (!isTypedUnionDeclarationProps(props)) {
|
|
17
18
|
return <ts.TypeDeclaration {...props}>{props.children}</ts.TypeDeclaration>;
|
|
18
19
|
}
|
|
@@ -2,7 +2,7 @@ import * as ay from "@alloy-js/core";
|
|
|
2
2
|
import { Children } from "@alloy-js/core";
|
|
3
3
|
import * as ts from "@alloy-js/typescript";
|
|
4
4
|
import { Enum, EnumMember, Union, UnionVariant } from "@typespec/compiler";
|
|
5
|
-
import {
|
|
5
|
+
import { useTsp } from "../../core/context/tsp-context.js";
|
|
6
6
|
import { TypeExpression } from "./type-expression.jsx";
|
|
7
7
|
|
|
8
8
|
export interface UnionExpressionProps {
|
|
@@ -11,6 +11,7 @@ export interface UnionExpressionProps {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export function UnionExpression({ type, children }: UnionExpressionProps) {
|
|
14
|
+
const { $ } = useTsp();
|
|
14
15
|
const items = ($.union.is(type) ? type.variants : type.members) as Map<
|
|
15
16
|
string,
|
|
16
17
|
UnionVariant | EnumMember
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { refkey as getRefkey } from "@alloy-js/core";
|
|
2
2
|
import * as ts from "@alloy-js/typescript";
|
|
3
3
|
import { Model, ModelProperty, Operation, Type } from "@typespec/compiler";
|
|
4
|
-
import {
|
|
4
|
+
import { useTsp } from "../../core/index.js";
|
|
5
5
|
import { TypeExpression } from "../components/type-expression.jsx";
|
|
6
6
|
|
|
7
7
|
export function getReturnType(
|
|
8
8
|
type: Operation,
|
|
9
9
|
options: { skipErrorFiltering: boolean } = { skipErrorFiltering: false },
|
|
10
10
|
): Type {
|
|
11
|
+
const { $ } = useTsp();
|
|
11
12
|
let returnType = type.returnType;
|
|
12
13
|
|
|
13
14
|
if (!options.skipErrorFiltering && type.returnType.kind === "Union") {
|
|
@@ -26,6 +27,7 @@ export function buildParameterDescriptors(
|
|
|
26
27
|
type: Model,
|
|
27
28
|
options: BuildParameterDescriptorsOptions = {},
|
|
28
29
|
): ts.ParameterDescriptor[] | undefined {
|
|
30
|
+
const { $ } = useTsp();
|
|
29
31
|
const optionsParams = normalizeParameters(options.params);
|
|
30
32
|
|
|
31
33
|
if (options.mode === "replace") {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { render } from "@alloy-js/core";
|
|
2
2
|
import { d } from "@alloy-js/core/testing";
|
|
3
3
|
import { SourceFile } from "@alloy-js/typescript";
|
|
4
4
|
import { Operation } from "@typespec/compiler";
|
|
5
5
|
import { BasicTestRunner } from "@typespec/compiler/testing";
|
|
6
6
|
import { beforeEach, describe, it } from "vitest";
|
|
7
|
+
import { Output } from "../../../src/core/components/output.jsx";
|
|
7
8
|
import { ArrowFunction } from "../../../src/typescript/components/arrow-function.jsx";
|
|
8
9
|
import { assertFileContents } from "../../utils.js";
|
|
9
10
|
import { createEmitterFrameworkTestRunner } from "../test-host.js";
|
|
@@ -21,7 +22,7 @@ describe("arrow functions with a `type` prop", () => {
|
|
|
21
22
|
`)) as { getName: Operation };
|
|
22
23
|
|
|
23
24
|
const res = render(
|
|
24
|
-
<Output>
|
|
25
|
+
<Output program={runner.program}>
|
|
25
26
|
<SourceFile path="test.ts">
|
|
26
27
|
<ArrowFunction type={getName}>console.log("Hello!");</ArrowFunction>
|
|
27
28
|
</SourceFile>
|
|
@@ -44,7 +45,7 @@ describe("arrow functions with a `type` prop", () => {
|
|
|
44
45
|
`)) as { getName: Operation };
|
|
45
46
|
|
|
46
47
|
const res = render(
|
|
47
|
-
<Output>
|
|
48
|
+
<Output program={runner.program}>
|
|
48
49
|
<SourceFile path="test.ts">
|
|
49
50
|
<ArrowFunction async type={getName} />
|
|
50
51
|
</SourceFile>
|
|
@@ -65,7 +66,7 @@ describe("arrow functions with a `type` prop", () => {
|
|
|
65
66
|
`)) as { getName: Operation };
|
|
66
67
|
|
|
67
68
|
const res = render(
|
|
68
|
-
<Output>
|
|
69
|
+
<Output program={runner.program}>
|
|
69
70
|
<SourceFile path="test.ts">
|
|
70
71
|
<ArrowFunction
|
|
71
72
|
type={getName}
|