@typespec/emitter-framework 0.6.0-dev.2 → 0.6.0-dev.4

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 (67) hide show
  1. package/dist/src/typescript/components/arrow-function.d.ts +17 -0
  2. package/dist/src/typescript/components/arrow-function.d.ts.map +1 -0
  3. package/dist/src/typescript/components/arrow-function.js +31 -0
  4. package/dist/src/typescript/components/arrow-function.js.map +1 -0
  5. package/dist/src/typescript/components/function-declaration.d.ts +5 -0
  6. package/dist/src/typescript/components/function-declaration.d.ts.map +1 -1
  7. package/dist/src/typescript/components/function-declaration.js +5 -1
  8. package/dist/src/typescript/components/function-declaration.js.map +1 -1
  9. package/dist/src/typescript/components/function-expression.d.ts +17 -0
  10. package/dist/src/typescript/components/function-expression.d.ts.map +1 -0
  11. package/dist/src/typescript/components/function-expression.js +31 -0
  12. package/dist/src/typescript/components/function-expression.js.map +1 -0
  13. package/dist/src/typescript/components/function-type.d.ts +17 -0
  14. package/dist/src/typescript/components/function-type.d.ts.map +1 -0
  15. package/dist/src/typescript/components/function-type.js +31 -0
  16. package/dist/src/typescript/components/function-type.js.map +1 -0
  17. package/dist/src/typescript/components/index.d.ts +6 -0
  18. package/dist/src/typescript/components/index.d.ts.map +1 -1
  19. package/dist/src/typescript/components/index.js +6 -0
  20. package/dist/src/typescript/components/index.js.map +1 -1
  21. package/dist/src/typescript/components/interface-member.d.ts +1 -2
  22. package/dist/src/typescript/components/interface-member.d.ts.map +1 -1
  23. package/dist/src/typescript/components/interface-member.js +3 -19
  24. package/dist/src/typescript/components/interface-member.js.map +1 -1
  25. package/dist/src/typescript/components/interface-method.d.ts +15 -0
  26. package/dist/src/typescript/components/interface-method.d.ts.map +1 -0
  27. package/dist/src/typescript/components/interface-method.js +34 -0
  28. package/dist/src/typescript/components/interface-method.js.map +1 -0
  29. package/dist/src/typescript/components/type-alias-declaration.d.ts +6 -2
  30. package/dist/src/typescript/components/type-alias-declaration.d.ts.map +1 -1
  31. package/dist/src/typescript/components/type-alias-declaration.js +7 -2
  32. package/dist/src/typescript/components/type-alias-declaration.js.map +1 -1
  33. package/dist/src/typescript/components/type-declaration.d.ts.map +1 -1
  34. package/dist/src/typescript/components/type-declaration.js +4 -0
  35. package/dist/src/typescript/components/type-declaration.js.map +1 -1
  36. package/dist/src/typescript/components/type-expression.d.ts +6 -0
  37. package/dist/src/typescript/components/type-expression.d.ts.map +1 -1
  38. package/dist/src/typescript/components/type-expression.js +6 -1
  39. package/dist/src/typescript/components/type-expression.js.map +1 -1
  40. package/dist/test/typescript/components/arrow-function.test.d.ts +2 -0
  41. package/dist/test/typescript/components/arrow-function.test.d.ts.map +1 -0
  42. package/dist/test/typescript/components/function-expression.test.d.ts +2 -0
  43. package/dist/test/typescript/components/function-expression.test.d.ts.map +1 -0
  44. package/dist/test/typescript/components/function-type.test.d.ts +2 -0
  45. package/dist/test/typescript/components/function-type.test.d.ts.map +1 -0
  46. package/dist/test/typescript/components/interface-method.test.d.ts +2 -0
  47. package/dist/test/typescript/components/interface-method.test.d.ts.map +1 -0
  48. package/dist/test/utils.d.ts +3 -2
  49. package/dist/test/utils.d.ts.map +1 -1
  50. package/package.json +5 -5
  51. package/src/typescript/components/arrow-function.tsx +39 -0
  52. package/src/typescript/components/function-declaration.tsx +5 -2
  53. package/src/typescript/components/function-expression.tsx +41 -0
  54. package/src/typescript/components/function-type.tsx +38 -0
  55. package/src/typescript/components/index.ts +6 -0
  56. package/src/typescript/components/interface-member.tsx +2 -19
  57. package/src/typescript/components/interface-method.tsx +50 -0
  58. package/src/typescript/components/type-alias-declaration.tsx +10 -4
  59. package/src/typescript/components/type-declaration.tsx +2 -0
  60. package/src/typescript/components/type-expression.tsx +11 -2
  61. package/test/typescript/components/arrow-function.test.tsx +85 -0
  62. package/test/typescript/components/function-expression.test.tsx +85 -0
  63. package/test/typescript/components/function-type.test.tsx +80 -0
  64. package/test/typescript/components/interface-declaration.test.tsx +6 -6
  65. package/test/typescript/components/interface-method.test.tsx +69 -0
  66. package/test/typescript/components/type-alias-declaration.test.tsx +20 -2
  67. package/test/utils.ts +8 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function-expression.test.d.ts","sourceRoot":"","sources":["../../../../test/typescript/components/function-expression.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=function-type.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function-type.test.d.ts","sourceRoot":"","sources":["../../../../test/typescript/components/function-type.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=interface-method.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface-method.test.d.ts","sourceRoot":"","sources":["../../../../test/typescript/components/interface-method.test.tsx"],"names":[],"mappings":""}
@@ -1,4 +1,5 @@
1
- import { Children } from "@alloy-js/core";
1
+ import { Children, OutputDirectory } from "@alloy-js/core";
2
2
  import { Program } from "@typespec/compiler";
3
- export declare function getEmitOutput(tspCode: string, cb: (program: Program) => Children): Promise<string | (import("@alloy-js/core").OutputDirectory | import("@alloy-js/core").OutputFile)[]>;
3
+ export declare function getEmitOutput(tspCode: string, cb: (program: Program) => Children): Promise<string | (OutputDirectory | import("@alloy-js/core").OutputFile)[]>;
4
+ export declare function assertFileContents(res: OutputDirectory, contents: string): void;
4
5
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../test/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAU,MAAM,gBAAgB,CAAC;AAGlD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,QAAQ,wGAOtF"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../test/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAU,MAAM,gBAAgB,CAAC;AAGnE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAI7C,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,QAAQ,+EAOtF;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,QAIxE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typespec/emitter-framework",
3
- "version": "0.6.0-dev.2",
3
+ "version": "0.6.0-dev.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
@@ -19,16 +19,16 @@
19
19
  "license": "MIT",
20
20
  "description": "",
21
21
  "peerDependencies": {
22
- "@alloy-js/core": "^0.10.0",
23
- "@alloy-js/typescript": "^0.10.0",
22
+ "@alloy-js/core": "^0.11.0",
23
+ "@alloy-js/typescript": "^0.11.0",
24
24
  "@typespec/compiler": "^1.0.0-rc.0",
25
25
  "@typespec/http": "^1.0.0-rc.0",
26
26
  "@typespec/rest": "^0.68.0 || >=0.69.0-dev <0.69.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@alloy-js/babel-preset": "^0.2.0",
30
- "@alloy-js/core": "^0.10.0",
31
- "@alloy-js/typescript": "^0.10.0",
30
+ "@alloy-js/core": "^0.11.0",
31
+ "@alloy-js/typescript": "^0.11.0",
32
32
  "@babel/cli": "^7.24.8",
33
33
  "@babel/core": "^7.26.10",
34
34
  "@rollup/plugin-babel": "^6.0.4",
@@ -0,0 +1,39 @@
1
+ import { splitProps } from "@alloy-js/core/jsx-runtime";
2
+ import * as ts from "@alloy-js/typescript";
3
+ import { Operation } from "@typespec/compiler";
4
+ import { buildParameterDescriptors, getReturnType } from "../utils/operation.js";
5
+ import { TypeExpression } from "./type-expression.jsx";
6
+
7
+ export interface ArrowFunctionProps extends ts.ArrowFunctionProps {
8
+ type?: Operation;
9
+ /**
10
+ * Where the parameters from passed to the `parameters` prop should be placed
11
+ * relative the ones created from the T`ypeSpec operation.
12
+ */
13
+ parametersMode?: "prepend" | "append" | "replace";
14
+ }
15
+
16
+ /**
17
+ * A TypeScript arrow function. Pass the `type` prop to create the arrow
18
+ * function by converting from a TypeSpec Operation. Any other props provided
19
+ * will take precedence.
20
+ */
21
+ export function ArrowFunction(props: Readonly<ArrowFunctionProps>) {
22
+ const [efProps, updateProps, forwardProps] = splitProps(
23
+ props,
24
+ ["type"],
25
+ ["returnType", "parameters"],
26
+ );
27
+
28
+ if (!efProps.type) {
29
+ return <ts.ArrowFunction {...forwardProps} {...updateProps} />;
30
+ }
31
+
32
+ const returnType = props.returnType ?? <TypeExpression type={getReturnType(efProps.type)} />;
33
+ const allParameters = buildParameterDescriptors(efProps.type.parameters, {
34
+ params: props.parameters,
35
+ mode: props.parametersMode,
36
+ });
37
+
38
+ return <ts.ArrowFunction {...forwardProps} returnType={returnType} parameters={allParameters} />;
39
+ }
@@ -15,10 +15,13 @@ export type FunctionDeclarationProps =
15
15
  | FunctionDeclarationPropsWithType
16
16
  | ts.FunctionDeclarationProps;
17
17
 
18
+ /**
19
+ * A TypeScript function declaration. Pass the `type` prop to create the
20
+ * function declaration by converting from a TypeSpec Operation. Any other props
21
+ * provided will take precedence.
22
+ */
18
23
  export function FunctionDeclaration(props: FunctionDeclarationProps) {
19
24
  if (!isTypedFunctionDeclarationProps(props)) {
20
- if (!props.name) {
21
- }
22
25
  return <ts.FunctionDeclaration {...props} />;
23
26
  }
24
27
 
@@ -0,0 +1,41 @@
1
+ import { splitProps } from "@alloy-js/core/jsx-runtime";
2
+ import * as ts from "@alloy-js/typescript";
3
+ import { Operation } from "@typespec/compiler";
4
+ import { buildParameterDescriptors, getReturnType } from "../utils/operation.js";
5
+ import { TypeExpression } from "./type-expression.jsx";
6
+
7
+ export interface FunctionExpressionProps extends ts.FunctionExpressionProps {
8
+ type?: Operation;
9
+ /**
10
+ * Where the parameters from passed to the `parameters` prop should be placed
11
+ * relative the ones created from the TypeSpec operation.
12
+ */
13
+ parametersMode?: "prepend" | "append" | "replace";
14
+ }
15
+
16
+ /**
17
+ * A TypeScript function expression. Pass the `type` prop to create the
18
+ * function expression by converting from a TypeSpec Operation. Any other props
19
+ * provided will take precedence.
20
+ */
21
+ export function FunctionExpression(props: Readonly<FunctionExpressionProps>) {
22
+ const [efProps, updateProps, forwardProps] = splitProps(
23
+ props,
24
+ ["type"],
25
+ ["returnType", "parameters"],
26
+ );
27
+
28
+ if (!efProps.type) {
29
+ return <ts.FunctionExpression {...forwardProps} {...updateProps} />;
30
+ }
31
+
32
+ const returnType = props.returnType ?? <TypeExpression type={getReturnType(efProps.type)} />;
33
+ const allParameters = buildParameterDescriptors(efProps.type.parameters, {
34
+ params: props.parameters,
35
+ mode: props.parametersMode,
36
+ });
37
+
38
+ return (
39
+ <ts.FunctionExpression {...forwardProps} returnType={returnType} parameters={allParameters} />
40
+ );
41
+ }
@@ -0,0 +1,38 @@
1
+ import { splitProps } from "@alloy-js/core/jsx-runtime";
2
+ import * as ts from "@alloy-js/typescript";
3
+ import { Operation } from "@typespec/compiler";
4
+ import { buildParameterDescriptors, getReturnType } from "../utils/operation.js";
5
+ import { TypeExpression } from "./type-expression.jsx";
6
+
7
+ export interface FunctionTypeProps extends ts.FunctionTypeProps {
8
+ type?: Operation;
9
+ /**
10
+ * Where the parameters from passed to the `parameters` prop should be placed
11
+ * relative the ones created from the TypeSpec operation.
12
+ */
13
+ parametersMode?: "prepend" | "append" | "replace";
14
+ }
15
+ /**
16
+ * A TypeScript function type. Pass the `type` prop to create the function type
17
+ * by converting from a TypeSpec Operation. Any other props provided will take
18
+ * precedence.
19
+ */
20
+ export function FunctionType(props: Readonly<FunctionTypeProps>) {
21
+ const [efProps, updateProps, forwardProps] = splitProps(
22
+ props,
23
+ ["type"],
24
+ ["returnType", "parameters"],
25
+ );
26
+
27
+ if (!efProps.type) {
28
+ return <ts.FunctionType {...forwardProps} {...updateProps} />;
29
+ }
30
+
31
+ const returnType = props.returnType ?? <TypeExpression type={getReturnType(efProps.type)} />;
32
+ const allParameters = buildParameterDescriptors(efProps.type.parameters, {
33
+ params: props.parameters,
34
+ mode: props.parametersMode,
35
+ });
36
+
37
+ return <ts.FunctionType {...forwardProps} returnType={returnType} parameters={allParameters} />;
38
+ }
@@ -1,10 +1,16 @@
1
+ export * from "./array-expression.jsx";
2
+ export * from "./arrow-function.jsx";
1
3
  export * from "./class-method.js";
2
4
  export * from "./function-declaration.js";
5
+ export * from "./function-expression.js";
6
+ export * from "./function-type.js";
3
7
  export * from "./interface-declaration.js";
4
8
  export * from "./interface-member.js";
9
+ export * from "./interface-method.js";
5
10
  export * from "./static-serializers.js";
6
11
  export * from "./type-declaration.js";
7
12
  export * from "./type-expression.js";
8
13
  export * from "./type-transform.js";
9
14
  export * from "./union-declaration.js";
10
15
  export * from "./union-expression.js";
16
+ export * from "./value-expression.js";
@@ -1,9 +1,8 @@
1
- import * as ay from "@alloy-js/core";
2
1
  import * as ts from "@alloy-js/typescript";
3
2
  import { isNeverType, ModelProperty, Operation } from "@typespec/compiler";
4
3
  import { $ } from "@typespec/compiler/experimental/typekit";
5
4
  import { getHttpPart } from "@typespec/http";
6
- import { FunctionDeclaration } from "./function-declaration.js";
5
+ import { InterfaceMethod } from "./interface-method.jsx";
7
6
  import { TypeExpression } from "./type-expression.js";
8
7
 
9
8
  export interface InterfaceMemberProps {
@@ -36,22 +35,6 @@ export function InterfaceMember(props: InterfaceMemberProps) {
36
35
  }
37
36
 
38
37
  if ($.operation.is(props.type)) {
39
- const returnType = <TypeExpression type={props.type.returnType} />;
40
- const params = (
41
- <ay.Scope>
42
- <FunctionDeclaration.Parameters type={props.type.parameters} />
43
- </ay.Scope>
44
- );
45
-
46
- return (
47
- <ts.InterfaceMember
48
- name={name}
49
- type={
50
- <>
51
- ({params}) =&gt {returnType}
52
- </>
53
- }
54
- />
55
- );
38
+ return <InterfaceMethod type={props.type} />;
56
39
  }
57
40
  }
@@ -0,0 +1,50 @@
1
+ import { splitProps } from "@alloy-js/core/jsx-runtime";
2
+ import * as ts from "@alloy-js/typescript";
3
+ import { Operation } from "@typespec/compiler";
4
+ import { buildParameterDescriptors, getReturnType } from "../utils/operation.js";
5
+ import { TypeExpression } from "./type-expression.jsx";
6
+
7
+ export interface InterfaceMethodPropsWithType extends Omit<ts.InterfaceMethodProps, "name"> {
8
+ type: Operation;
9
+ name?: string;
10
+ parametersMode?: "prepend" | "append" | "replace";
11
+ }
12
+
13
+ export type InterfaceMethodProps = InterfaceMethodPropsWithType | ts.InterfaceMethodProps;
14
+
15
+ /**
16
+ * A TypeScript interface method. Pass the `type` prop to create the
17
+ * method by converting from a TypeSpec Operation. Any other props
18
+ * provided will take precedence.
19
+ */
20
+ export function InterfaceMethod(props: Readonly<InterfaceMethodProps>) {
21
+ const isTypeSpecTyped = "type" in props;
22
+ if (!isTypeSpecTyped) {
23
+ return <ts.InterfaceMethod {...props} />;
24
+ }
25
+
26
+ const [efProps, updateProps, forwardProps] = splitProps(
27
+ props,
28
+ ["type"],
29
+ ["returnType", "parameters"],
30
+ );
31
+
32
+ const name = props.name
33
+ ? props.name
34
+ : ts.useTSNamePolicy().getName(efProps.type.name, "function");
35
+ const returnType = props.returnType ?? <TypeExpression type={getReturnType(efProps.type)} />;
36
+ const allParameters = buildParameterDescriptors(efProps.type.parameters, {
37
+ params: props.parameters,
38
+ mode: props.parametersMode,
39
+ });
40
+
41
+ return (
42
+ <ts.InterfaceMethod
43
+ {...forwardProps}
44
+ name={name}
45
+ returnType={returnType}
46
+ parameters={allParameters}
47
+ {...updateProps}
48
+ />
49
+ );
50
+ }
@@ -1,23 +1,29 @@
1
1
  import { refkey as getRefkey } from "@alloy-js/core";
2
2
  import * as ts from "@alloy-js/typescript";
3
- import { Scalar } from "@typespec/compiler";
3
+ import { Type } from "@typespec/compiler";
4
4
  import { $ } from "@typespec/compiler/experimental/typekit";
5
5
  import { reportDiagnostic } from "../../lib.js";
6
6
  import { TypeExpression } from "./type-expression.jsx";
7
7
 
8
8
  export interface TypedAliasDeclarationProps extends Omit<ts.TypeDeclarationProps, "name"> {
9
- type: Scalar;
9
+ type: Type;
10
10
  name?: string;
11
11
  }
12
12
 
13
13
  export type TypeAliasDeclarationProps = TypedAliasDeclarationProps | ts.TypeDeclarationProps;
14
14
 
15
+ /**
16
+ * Create a TypeScript type alias declaration. Pass the `type` prop to emit the
17
+ * type alias as the provided TypeSpec type.
18
+ */
15
19
  export function TypeAliasDeclaration(props: TypeAliasDeclarationProps) {
16
20
  if (!isTypedAliasDeclarationProps(props)) {
17
21
  return <ts.TypeDeclaration {...props}>{props.children}</ts.TypeDeclaration>;
18
22
  }
19
23
 
20
- const originalName = props.name ?? props.type.name;
24
+ const originalName =
25
+ props.name ??
26
+ ("name" in props.type && typeof props.type.name === "string" ? props.type.name : "");
21
27
 
22
28
  if (!originalName || originalName === "") {
23
29
  reportDiagnostic($.program, { code: "type-declaration-missing-name", target: props.type });
@@ -26,7 +32,7 @@ export function TypeAliasDeclaration(props: TypeAliasDeclarationProps) {
26
32
  const name = ts.useTSNamePolicy().getName(originalName, "type");
27
33
  return (
28
34
  <ts.TypeDeclaration {...props} name={name} refkey={props.refkey ?? getRefkey(props.type)}>
29
- <TypeExpression type={props.type} />
35
+ <TypeExpression type={props.type} noReference />
30
36
  {props.children}
31
37
  </ts.TypeDeclaration>
32
38
  );
@@ -27,5 +27,7 @@ export function TypeDeclaration(props: TypeDeclarationProps) {
27
27
  return <EnumDeclaration type={type} {...restProps} />;
28
28
  case "Scalar":
29
29
  return <TypeAliasDeclaration type={type} {...restProps} />;
30
+ case "Operation":
31
+ return <TypeAliasDeclaration type={type} {...restProps} />;
30
32
  }
31
33
  }
@@ -5,17 +5,25 @@ import { $ } from "@typespec/compiler/experimental/typekit";
5
5
  import "@typespec/http/experimental/typekit";
6
6
  import { reportTypescriptDiagnostic } from "../../typescript/lib.js";
7
7
  import { ArrayExpression } from "./array-expression.js";
8
+ import { FunctionType } from "./function-type.js";
8
9
  import { InterfaceExpression } from "./interface-declaration.js";
9
10
  import { RecordExpression } from "./record-expression.js";
10
11
  import { UnionExpression } from "./union-expression.js";
11
12
 
12
13
  export interface TypeExpressionProps {
13
14
  type: Type;
15
+
16
+ /**
17
+ * Whether to disallow references. Setting this will force the type to be
18
+ * emitted inline, even if it is a declaration that would otherwise be
19
+ * referenced.
20
+ */
21
+ noReference?: boolean;
14
22
  }
15
23
 
16
24
  export function TypeExpression(props: TypeExpressionProps) {
17
25
  const type = $.httpPart.unpack(props.type);
18
- if (isDeclaration(type)) {
26
+ if (!props.noReference && isDeclaration(type)) {
19
27
  // todo: probably need abstraction around deciding what's a declaration in the output
20
28
  // (it may not correspond to things which are declarations in TypeSpec?)
21
29
  return <Reference refkey={refkey(type)} />;
@@ -64,7 +72,8 @@ export function TypeExpression(props: TypeExpressionProps) {
64
72
  }
65
73
 
66
74
  return <InterfaceExpression type={type} />;
67
-
75
+ case "Operation":
76
+ return <FunctionType type={type} />;
68
77
  default:
69
78
  reportTypescriptDiagnostic($.program, { code: "typescript-unsupported-type", target: type });
70
79
  return "any";
@@ -0,0 +1,85 @@
1
+ import { Output, render } from "@alloy-js/core";
2
+ import { d } from "@alloy-js/core/testing";
3
+ import { SourceFile } from "@alloy-js/typescript";
4
+ import { Operation } from "@typespec/compiler";
5
+ import { BasicTestRunner } from "@typespec/compiler/testing";
6
+ import { beforeEach, describe, it } from "vitest";
7
+ import { ArrowFunction } from "../../../src/typescript/components/arrow-function.jsx";
8
+ import { assertFileContents } from "../../utils.js";
9
+ import { createEmitterFrameworkTestRunner } from "../test-host.js";
10
+
11
+ describe("arrow functions with a `type` prop", () => {
12
+ let runner: BasicTestRunner;
13
+
14
+ beforeEach(async () => {
15
+ runner = await createEmitterFrameworkTestRunner();
16
+ });
17
+
18
+ it("creates a function", async () => {
19
+ const { getName } = (await runner.compile(`
20
+ @test op getName(id: string): string;
21
+ `)) as { getName: Operation };
22
+
23
+ const res = render(
24
+ <Output>
25
+ <SourceFile path="test.ts">
26
+ <ArrowFunction type={getName}>console.log("Hello!");</ArrowFunction>
27
+ </SourceFile>
28
+ </Output>,
29
+ );
30
+
31
+ assertFileContents(
32
+ res,
33
+ d`
34
+ (id: string): string => {
35
+ console.log("Hello!");
36
+ }
37
+ `,
38
+ );
39
+ });
40
+
41
+ it("creates an async function", async () => {
42
+ const { getName } = (await runner.compile(`
43
+ @test op getName(id: string): string;
44
+ `)) as { getName: Operation };
45
+
46
+ const res = render(
47
+ <Output>
48
+ <SourceFile path="test.ts">
49
+ <ArrowFunction async type={getName} />
50
+ </SourceFile>
51
+ </Output>,
52
+ );
53
+
54
+ assertFileContents(
55
+ res,
56
+ d`
57
+ async (id: string): Promise<string> => {}
58
+ `,
59
+ );
60
+ });
61
+
62
+ it("can append extra parameters with raw params provided", async () => {
63
+ const { getName } = (await runner.compile(`
64
+ @test op getName(id: string): string;
65
+ `)) as { getName: Operation };
66
+
67
+ const res = render(
68
+ <Output>
69
+ <SourceFile path="test.ts">
70
+ <ArrowFunction
71
+ type={getName}
72
+ parameters={[{ name: "additionalParam", type: "number" }]}
73
+ />
74
+ </SourceFile>
75
+ </Output>,
76
+ );
77
+
78
+ assertFileContents(
79
+ res,
80
+ d`
81
+ (additionalParam: number, id: string): string => {}
82
+ `,
83
+ );
84
+ });
85
+ });
@@ -0,0 +1,85 @@
1
+ import { Output, render } from "@alloy-js/core";
2
+ import { d } from "@alloy-js/core/testing";
3
+ import { SourceFile } from "@alloy-js/typescript";
4
+ import { Operation } from "@typespec/compiler";
5
+ import { BasicTestRunner } from "@typespec/compiler/testing";
6
+ import { beforeEach, describe, it } from "vitest";
7
+ import { FunctionExpression } from "../../../src/typescript/components/function-expression.jsx";
8
+ import { assertFileContents } from "../../utils.js";
9
+ import { createEmitterFrameworkTestRunner } from "../test-host.js";
10
+
11
+ describe("function expressions with a `type` prop", () => {
12
+ let runner: BasicTestRunner;
13
+
14
+ beforeEach(async () => {
15
+ runner = await createEmitterFrameworkTestRunner();
16
+ });
17
+
18
+ it("creates a function", async () => {
19
+ const { getName } = (await runner.compile(`
20
+ @test op getName(id: string): string;
21
+ `)) as { getName: Operation };
22
+
23
+ const res = render(
24
+ <Output>
25
+ <SourceFile path="test.ts">
26
+ <FunctionExpression type={getName}>console.log("Hello!");</FunctionExpression>
27
+ </SourceFile>
28
+ </Output>,
29
+ );
30
+
31
+ assertFileContents(
32
+ res,
33
+ d`
34
+ function (id: string): string {
35
+ console.log("Hello!");
36
+ }
37
+ `,
38
+ );
39
+ });
40
+
41
+ it("creates an async function", async () => {
42
+ const { getName } = (await runner.compile(`
43
+ @test op getName(id: string): string;
44
+ `)) as { getName: Operation };
45
+
46
+ const res = render(
47
+ <Output>
48
+ <SourceFile path="test.ts">
49
+ <FunctionExpression async type={getName} />
50
+ </SourceFile>
51
+ </Output>,
52
+ );
53
+
54
+ assertFileContents(
55
+ res,
56
+ d`
57
+ async function (id: string): Promise<string> {}
58
+ `,
59
+ );
60
+ });
61
+
62
+ it("can append extra parameters with raw params provided", async () => {
63
+ const { getName } = (await runner.compile(`
64
+ @test op getName(id: string): string;
65
+ `)) as { getName: Operation };
66
+
67
+ const res = render(
68
+ <Output>
69
+ <SourceFile path="test.ts">
70
+ <FunctionExpression
71
+ type={getName}
72
+ parameters={[{ name: "additionalParam", type: "number" }]}
73
+ />
74
+ </SourceFile>
75
+ </Output>,
76
+ );
77
+
78
+ assertFileContents(
79
+ res,
80
+ d`
81
+ function (additionalParam: number, id: string): string {}
82
+ `,
83
+ );
84
+ });
85
+ });
@@ -0,0 +1,80 @@
1
+ import { Output, render } from "@alloy-js/core";
2
+ import { d } from "@alloy-js/core/testing";
3
+ import { SourceFile } from "@alloy-js/typescript";
4
+ import { Operation } from "@typespec/compiler";
5
+ import { BasicTestRunner } from "@typespec/compiler/testing";
6
+ import { beforeEach, describe, it } from "vitest";
7
+ import { FunctionType } from "../../../src/typescript/index.js";
8
+ import { assertFileContents } from "../../utils.js";
9
+ import { createEmitterFrameworkTestRunner } from "../test-host.js";
10
+
11
+ describe("function types with a `type` prop", () => {
12
+ let runner: BasicTestRunner;
13
+
14
+ beforeEach(async () => {
15
+ runner = await createEmitterFrameworkTestRunner();
16
+ });
17
+
18
+ it("creates a function type", async () => {
19
+ const { getName } = (await runner.compile(`
20
+ @test op getName(id: string): string;
21
+ `)) as { getName: Operation };
22
+
23
+ const res = render(
24
+ <Output>
25
+ <SourceFile path="test.ts">
26
+ <FunctionType type={getName} />
27
+ </SourceFile>
28
+ </Output>,
29
+ );
30
+
31
+ assertFileContents(
32
+ res,
33
+ d`
34
+ (id: string) => string
35
+ `,
36
+ );
37
+ });
38
+
39
+ it("creates an async function type", async () => {
40
+ const { getName } = (await runner.compile(`
41
+ @test op getName(id: string): string;
42
+ `)) as { getName: Operation };
43
+
44
+ const res = render(
45
+ <Output>
46
+ <SourceFile path="test.ts">
47
+ <FunctionType async type={getName} />
48
+ </SourceFile>
49
+ </Output>,
50
+ );
51
+
52
+ assertFileContents(
53
+ res,
54
+ d`
55
+ (id: string) => Promise<string>
56
+ `,
57
+ );
58
+ });
59
+
60
+ it("can append extra parameters with raw params provided", async () => {
61
+ const { getName } = (await runner.compile(`
62
+ @test op getName(id: string): string;
63
+ `)) as { getName: Operation };
64
+
65
+ const res = render(
66
+ <Output>
67
+ <SourceFile path="test.ts">
68
+ <FunctionType type={getName} parameters={[{ name: "additionalParam", type: "number" }]} />
69
+ </SourceFile>
70
+ </Output>,
71
+ );
72
+
73
+ assertFileContents(
74
+ res,
75
+ d`
76
+ (additionalParam: number, id: string) => string
77
+ `,
78
+ );
79
+ });
80
+ });