@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.
Files changed (75) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/src/core/components/index.d.ts +2 -0
  3. package/dist/src/core/components/index.d.ts.map +1 -0
  4. package/dist/src/core/components/index.js +1 -0
  5. package/dist/src/core/components/output.d.ts +10 -0
  6. package/dist/src/core/components/output.d.ts.map +1 -0
  7. package/dist/src/core/components/output.js +16 -0
  8. package/dist/src/core/context/index.d.ts +1 -0
  9. package/dist/src/core/context/index.d.ts.map +1 -1
  10. package/dist/src/core/context/index.js +2 -1
  11. package/dist/src/core/context/tsp-context.d.ts +13 -0
  12. package/dist/src/core/context/tsp-context.d.ts.map +1 -0
  13. package/dist/src/core/context/tsp-context.js +13 -0
  14. package/dist/src/core/index.d.ts +1 -0
  15. package/dist/src/core/index.d.ts.map +1 -1
  16. package/dist/src/core/index.js +1 -0
  17. package/dist/src/core/write-output.d.ts +2 -1
  18. package/dist/src/core/write-output.d.ts.map +1 -1
  19. package/dist/src/core/write-output.js +5 -6
  20. package/dist/src/typescript/components/enum-declaration.d.ts.map +1 -1
  21. package/dist/src/typescript/components/enum-declaration.js +4 -1
  22. package/dist/src/typescript/components/interface-declaration.d.ts.map +1 -1
  23. package/dist/src/typescript/components/interface-declaration.js +9 -3
  24. package/dist/src/typescript/components/interface-member.d.ts.map +1 -1
  25. package/dist/src/typescript/components/interface-member.js +4 -1
  26. package/dist/src/typescript/components/type-alias-declaration.d.ts.map +1 -1
  27. package/dist/src/typescript/components/type-alias-declaration.js +4 -1
  28. package/dist/src/typescript/components/type-expression.d.ts.map +1 -1
  29. package/dist/src/typescript/components/type-expression.js +8 -5
  30. package/dist/src/typescript/components/type-transform.d.ts.map +1 -1
  31. package/dist/src/typescript/components/type-transform.js +26 -5
  32. package/dist/src/typescript/components/union-declaration.d.ts.map +1 -1
  33. package/dist/src/typescript/components/union-declaration.js +4 -1
  34. package/dist/src/typescript/components/union-expression.d.ts.map +1 -1
  35. package/dist/src/typescript/components/union-expression.js +4 -1
  36. package/dist/src/typescript/utils/operation.d.ts.map +1 -1
  37. package/dist/src/typescript/utils/operation.js +7 -1
  38. package/dist/test/typescript/components/arrow-function.test.js +11 -1
  39. package/dist/test/typescript/components/enum-declaration.test.js +47 -18
  40. package/dist/test/typescript/components/function-declaration.test.js +9 -1
  41. package/dist/test/typescript/components/function-expression.test.js +11 -1
  42. package/dist/test/typescript/components/function-type.test.js +11 -1
  43. package/dist/test/typescript/components/interface-declaration.test.js +20 -2
  44. package/dist/test/typescript/components/interface-method.test.js +26 -2
  45. package/dist/test/typescript/components/member-expression.test.js +61 -32
  46. package/dist/test/typescript/components/type-alias-declaration.test.js +9 -1
  47. package/dist/test/typescript/components/union-declaration.test.js +9 -1
  48. package/dist/test/typescript/components/value-expression.test.js +9 -7
  49. package/package.json +7 -7
  50. package/src/core/components/index.tsx +1 -0
  51. package/src/core/components/output.tsx +19 -0
  52. package/src/core/context/index.ts +1 -0
  53. package/src/core/context/tsp-context.ts +30 -0
  54. package/src/core/index.ts +1 -0
  55. package/src/core/write-output.ts +14 -7
  56. package/src/typescript/components/enum-declaration.tsx +2 -1
  57. package/src/typescript/components/interface-declaration.tsx +7 -3
  58. package/src/typescript/components/interface-member.tsx +2 -1
  59. package/src/typescript/components/type-alias-declaration.tsx +2 -1
  60. package/src/typescript/components/type-expression.tsx +7 -5
  61. package/src/typescript/components/type-transform.tsx +17 -5
  62. package/src/typescript/components/union-declaration.tsx +2 -1
  63. package/src/typescript/components/union-expression.tsx +2 -1
  64. package/src/typescript/utils/operation.ts +3 -1
  65. package/test/typescript/components/arrow-function.test.tsx +5 -4
  66. package/test/typescript/components/enum-declaration.test.tsx +29 -16
  67. package/test/typescript/components/function-declaration.test.tsx +9 -8
  68. package/test/typescript/components/function-expression.test.tsx +5 -4
  69. package/test/typescript/components/function-type.test.tsx +5 -4
  70. package/test/typescript/components/interface-declaration.test.tsx +20 -20
  71. package/test/typescript/components/interface-method.test.tsx +12 -10
  72. package/test/typescript/components/member-expression.test.tsx +25 -16
  73. package/test/typescript/components/type-alias-declaration.test.tsx +7 -6
  74. package/test/typescript/components/union-declaration.test.tsx +9 -7
  75. 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 { Output, render } from "@alloy-js/core";
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, initEmptyProgram } from "../test-host.js";
9
+ import { getProgram } from "../test-host.js";
10
+ let program;
10
11
  beforeAll(async () => {
11
- await initEmptyProgram();
12
+ program = await getProgram("");
12
13
  });
13
14
  it("renders strings", async () => {
14
- const value = $.value.createString("test");
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 = $.value.createNumeric(42);
20
+ const value = $(program).value.createNumeric(42);
20
21
  await testValueExpression(value, `42`);
21
22
  });
22
23
  it("renders decimals", async () => {
23
- const value = $.value.createNumeric(42.5);
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 = $.value.createBoolean(true);
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: [$.value.createString("foo"), $.value.createNumeric(42), $.value.createBoolean(true)]
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.6.0-dev.6",
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.0",
25
- "@typespec/http": "^1.0.0-rc.0",
26
- "@typespec/rest": "^0.68.0 || >=0.69.0-dev <0.69.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.0",
35
- "@typespec/http": "^1.0.0-rc.0",
36
- "@typespec/rest": "^0.68.0 || >=0.69.0-dev <0.69.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
+ }
@@ -1 +1,2 @@
1
1
  export * from "./name-policy-context.js";
2
+ export * from "./tsp-context.js";
@@ -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
@@ -1,3 +1,4 @@
1
+ export * from "./components/index.js";
1
2
  export * from "./context/index.js";
2
3
  export * from "./transport-name-policy.js";
3
4
  export * from "./write-output.js";
@@ -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(rootComponent: Children, emitterOutputDir: string) {
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(dir: OutputDirectory, emitterOutputDir: string) {
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($.program, {
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 { $ } from "@typespec/compiler/experimental/typekit";
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 { $ } from "@typespec/compiler/experimental/typekit";
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 { $ } from "@typespec/compiler/experimental/typekit";
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 { $ } from "@typespec/compiler/experimental/typekit";
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 { $ } from "@typespec/compiler/experimental/typekit";
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 collapsedProperty = getCollapsedProperty(props.type, props.collapse ?? false);
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(model: Type, collapse: boolean): ModelProperty | undefined {
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 { $ } from "@typespec/compiler/experimental/typekit";
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 { $ } from "@typespec/compiler/experimental/typekit";
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 { $ } from "@typespec/compiler/experimental/typekit";
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 { Output, render } from "@alloy-js/core";
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}