typespec-typescript-emitter 1.1.1 → 1.1.2

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 (48) hide show
  1. package/.husky/pre-commit +1 -0
  2. package/CHANGELOG.md +4 -9
  3. package/dist/src/emit_types_resolve.d.ts +2 -0
  4. package/dist/src/emit_types_resolve.js +49 -5
  5. package/dist/src/emit_types_resolve.js.map +1 -1
  6. package/dist/src/index.d.ts +1 -1
  7. package/dist/src/index.js.map +1 -1
  8. package/eslint.config.js +2 -0
  9. package/package.json +8 -4
  10. package/src/emit_types_resolve.ts +58 -5
  11. package/src/index.ts +1 -1
  12. package/test/main.test.ts +83 -0
  13. package/test/out/.gitkeep +0 -0
  14. package/test/runner.ts +5 -0
  15. package/test/targets/enum.routed-types.ts +59 -0
  16. package/test/targets/enum.routes.ts +29 -0
  17. package/test/targets/enum.target.ts +39 -0
  18. package/test/targets/enum.tsp +36 -0
  19. package/test/targets/pr8.routed-types.ts +131 -0
  20. package/test/targets/pr8.routes.ts +30 -0
  21. package/test/targets/pr8.target.ts +97 -0
  22. package/test/targets/pr8.tsp +62 -0
  23. package/test/targets/simple-routes.routed-types.ts +64 -0
  24. package/test/targets/simple-routes.routes.ts +29 -0
  25. package/test/targets/simple-routes.target.ts +21 -0
  26. package/test/targets/simple-routes.tsp +23 -0
  27. package/test/targets/union.routed-types.ts +59 -0
  28. package/test/targets/union.routes.ts +23 -0
  29. package/test/targets/union.target.ts +59 -0
  30. package/test/targets/union.tsp +38 -0
  31. package/test/targets/visibility.routed-types.ts +81 -0
  32. package/test/targets/visibility.routes.ts +38 -0
  33. package/test/targets/visibility.target.ts +36 -0
  34. package/test/targets/visibility.tsp +49 -0
  35. package/tsconfig.json +1 -1
  36. package/vitest.config.ts +10 -0
  37. package/dist/src/testing/index.d.ts +0 -2
  38. package/dist/src/testing/index.js +0 -8
  39. package/dist/src/testing/index.js.map +0 -1
  40. package/dist/test/hello.test.d.ts +0 -1
  41. package/dist/test/hello.test.js +0 -10
  42. package/dist/test/hello.test.js.map +0 -1
  43. package/dist/test/test-host.d.ts +0 -5
  44. package/dist/test/test-host.js +0 -36
  45. package/dist/test/test-host.js.map +0 -1
  46. package/src/testing/index.ts +0 -12
  47. package/test/hello.test.ts +0 -10
  48. package/test/test-host.ts +0 -49
package/.husky/pre-commit CHANGED
@@ -1,3 +1,4 @@
1
+ npm run test
1
2
  npm run lint
2
3
  npm run format
3
4
  npm run build
package/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [1.1.2](https://github.com/crowbait/typespec-typescript-emitter/compare/v1.1.1...v1.1.2) (2025-11-17)
2
+
3
+
4
+
1
5
  ## [1.1.1](https://github.com/crowbait/typespec-typescript-emitter/compare/v1.1.0...v1.1.1) (2025-09-26)
2
6
 
3
7
 
@@ -40,12 +44,3 @@
40
44
 
41
45
 
42
46
 
43
- # [0.4.0](https://github.com/crowbait/typespec-typescript-emitter/compare/v0.3.5...v0.4.0) (2025-02-25)
44
-
45
-
46
- ### Features
47
-
48
- * option to emit relative URLs in routes object ([be50613](https://github.com/crowbait/typespec-typescript-emitter/commit/be50613ac94550899805faf2555b3f407d88be33))
49
-
50
-
51
-
@@ -16,4 +16,6 @@ export declare const resolveTuple: (t: Tuple, opts: CommonOptions) => string;
16
16
  export declare const resolveUnion: (u: Union, opts: CommonOptions) => string;
17
17
  export declare const resolveScalar: (s: Scalar) => string;
18
18
  export declare const resolveModel: (m: Model, opts: CommonOptions) => string;
19
+ export declare const resolveEnumMemberValue: (e: Enum, name: string) => string | number | undefined;
20
+ export declare const resolveEnumAsUnion: (e: Enum) => string;
19
21
  export {};
@@ -37,6 +37,17 @@ export const resolveType = (t, opts) => {
37
37
  case "Union":
38
38
  typeStr = resolveUnion(t, opts);
39
39
  break;
40
+ case "EnumMember":
41
+ if (opts.resolveEvenWithName) {
42
+ // If we're at routed typemap we will just emit enum value
43
+ const value = resolveEnumMemberValue(t.enum, t.name);
44
+ if (value) {
45
+ typeStr = typeof value === "string" ? `'${value}'` : value.toString();
46
+ }
47
+ break;
48
+ }
49
+ typeStr = `${t.enum.name}.${t.name}`;
50
+ break;
40
51
  default:
41
52
  console.warn("Could not resolve type:", t.kind);
42
53
  }
@@ -45,7 +56,7 @@ export const resolveType = (t, opts) => {
45
56
  export const resolveArray = (a, opts) => {
46
57
  if (a.name !== "Array")
47
58
  throw new Error(`Trying to parse model ${a.name} as Array`);
48
- return `(${resolveType(a.indexer.value, opts)})[]`;
59
+ return `(${resolveType(a.indexer.value, { ...opts, isNamespaceRoot: false })})[]`;
49
60
  };
50
61
  export const resolveRecord = (a, opts) => {
51
62
  if (a.name !== "Record")
@@ -55,9 +66,13 @@ export const resolveRecord = (a, opts) => {
55
66
  export const resolveEnum = (e, opts) => {
56
67
  if (e.name &&
57
68
  !opts.isNamespaceRoot &&
58
- e.namespace?.enums.has(e.name) &&
59
- !opts.resolveEvenWithName)
69
+ opts.currentNamespace.enums.has(e.name) &&
70
+ !opts.resolveEvenWithName) {
60
71
  return e.name;
72
+ }
73
+ if (opts.resolveEvenWithName) {
74
+ return resolveEnumAsUnion(e);
75
+ }
61
76
  let ret = "{\n";
62
77
  let i = 1;
63
78
  e.members.forEach((p) => {
@@ -81,7 +96,19 @@ export const resolveUnion = (u, opts) => {
81
96
  !opts.resolveEvenWithName)
82
97
  return u.name;
83
98
  return Array.from(u.variants)
84
- .map((v) => resolveType(v[1].type, opts))
99
+ .map((v) => {
100
+ const variantType = v[1].type;
101
+ // If variant is a named model in the current namespace
102
+ // and it's not in routed typemap, reference it by name:
103
+ if (!opts.resolveEvenWithName &&
104
+ variantType.kind === "Model" &&
105
+ variantType.name &&
106
+ opts.currentNamespace.models.has(variantType.name)) {
107
+ return variantType.name;
108
+ }
109
+ // Otherwise resolve type inline
110
+ return resolveType(variantType, { ...opts, isNamespaceRoot: false });
111
+ })
85
112
  .join(" | ");
86
113
  };
87
114
  export const resolveScalar = (s) => {
@@ -118,7 +145,7 @@ export const resolveScalar = (s) => {
118
145
  export const resolveModel = (m, opts) => {
119
146
  if (m.name &&
120
147
  !opts.isNamespaceRoot &&
121
- opts.currentNamespace.namespace === m.namespace &&
148
+ opts.currentNamespace.models.has(m.name) &&
122
149
  !opts.resolveEvenWithName)
123
150
  return m.name;
124
151
  let ret = "{\n";
@@ -134,6 +161,7 @@ export const resolveModel = (m, opts) => {
134
161
  const typeStr = resolveType(p.type, {
135
162
  ...opts,
136
163
  nestlevel: opts.nestlevel + 1,
164
+ isNamespaceRoot: false,
137
165
  });
138
166
  if (typeStr.includes("unknown"))
139
167
  console.warn(`Could not resolve property ${p.name} on ${m.name}`);
@@ -144,4 +172,20 @@ export const resolveModel = (m, opts) => {
144
172
  ret = ret.addLine("}", opts.nestlevel, true);
145
173
  return ret;
146
174
  };
175
+ export const resolveEnumMemberValue = (e, name) => {
176
+ const member = e.members.get(name);
177
+ if (!member) {
178
+ console.warn("Missing enum member under name:", name);
179
+ return;
180
+ }
181
+ return member?.value;
182
+ };
183
+ export const resolveEnumAsUnion = (e) => {
184
+ return Array.from(e.members.values())
185
+ .map((member, index) => {
186
+ const value = resolveEnumMemberValue(e, member.name) ?? index;
187
+ return typeof value === "string" ? `'${value}'` : value.toString();
188
+ })
189
+ .join(" | ");
190
+ };
147
191
  //# sourceMappingURL=emit_types_resolve.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"emit_types_resolve.js","sourceRoot":"","sources":["../../src/emit_types_resolve.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"emit_types_resolve.js","sourceRoot":"","sources":["../../src/emit_types_resolve.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
1
  export { $onEmit } from "./emitter.js";
2
- export { $lib } from "./lib.js";
2
+ export { $lib, EmitterOptions } from "./lib.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,IAAI,EAAkB,MAAM,UAAU,CAAC"}
package/eslint.config.js CHANGED
@@ -9,6 +9,8 @@ export default tsEslint.config(
9
9
  "**/.temp/**/*",
10
10
  "**/*.md",
11
11
  "**/node_modules/**/*",
12
+ "**/test/out/**/*",
13
+ "**/test/targets/**/*",
12
14
  ],
13
15
  },
14
16
  eslint.configs.recommended,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typespec-typescript-emitter",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "A TypeSpec library providing an emitter that generates TypeScript types and a structured routes object for robust importing",
5
5
  "homepage": "https://github.com/crowbait/typespec-typescript-emitter#readme",
6
6
  "bugs": "https://github.com/crowbait/typespec-typescript-emitter/issues",
@@ -23,12 +23,16 @@
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/node": "latest",
26
+ "@typespec/compiler": "^1.6.0",
27
+ "@typespec/http": "^1.6.0",
28
+ "@typespec/openapi3": "^1.6.0",
26
29
  "eslint": "^9.15.0",
27
30
  "husky": "^9.1.6",
28
31
  "prettier": "^3.0.3",
29
32
  "rimraf": "^6.0.1",
30
33
  "typescript": "^5.3.3",
31
- "typescript-eslint": "^8.15.0"
34
+ "typescript-eslint": "^8.15.0",
35
+ "vitest": "^4.0.10"
32
36
  },
33
37
  "peerDependencies": {
34
38
  "@typespec/compiler": "^1.0.0",
@@ -37,12 +41,12 @@
37
41
  "scripts": {
38
42
  "build": "rimraf dist && tsc",
39
43
  "watch": "tsc --watch",
40
- "test": "npm run build && node --test",
41
44
  "lint": "eslint src/ test/ --report-unused-disable-directives --max-warnings=0",
42
45
  "lint:fix": "eslint . --report-unused-disable-directives --fix",
43
46
  "format": "prettier . --write",
44
47
  "format:check": "prettier --check .",
45
48
  "prepare": "husky",
46
- "prepublishOnly": "npm run build"
49
+ "prepublishOnly": "npm run build",
50
+ "test": "vitest run"
47
51
  }
48
52
  }
@@ -56,6 +56,17 @@ export const resolveType = (t: Type, opts: CommonOptions): string => {
56
56
  case "Union":
57
57
  typeStr = resolveUnion(t, opts);
58
58
  break;
59
+ case "EnumMember":
60
+ if (opts.resolveEvenWithName) {
61
+ // If we're at routed typemap we will just emit enum value
62
+ const value = resolveEnumMemberValue(t.enum, t.name);
63
+ if (value) {
64
+ typeStr = typeof value === "string" ? `'${value}'` : value.toString();
65
+ }
66
+ break;
67
+ }
68
+ typeStr = `${t.enum.name}.${t.name}`;
69
+ break;
59
70
  default:
60
71
  console.warn("Could not resolve type:", t.kind);
61
72
  }
@@ -68,7 +79,7 @@ export const resolveArray = (
68
79
  ): string => {
69
80
  if (a.name !== "Array")
70
81
  throw new Error(`Trying to parse model ${a.name} as Array`);
71
- return `(${resolveType(a.indexer.value, opts)})[]`;
82
+ return `(${resolveType(a.indexer.value, { ...opts, isNamespaceRoot: false })})[]`;
72
83
  };
73
84
 
74
85
  export const resolveRecord = (
@@ -84,10 +95,16 @@ export const resolveEnum = (e: Enum, opts: CommonOptions): string => {
84
95
  if (
85
96
  e.name &&
86
97
  !opts.isNamespaceRoot &&
87
- e.namespace?.enums.has(e.name) &&
98
+ opts.currentNamespace.enums.has(e.name) &&
88
99
  !opts.resolveEvenWithName
89
- )
100
+ ) {
90
101
  return e.name;
102
+ }
103
+
104
+ if (opts.resolveEvenWithName) {
105
+ return resolveEnumAsUnion(e);
106
+ }
107
+
91
108
  let ret = "{\n";
92
109
  let i = 1;
93
110
  e.members.forEach((p) => {
@@ -119,7 +136,21 @@ export const resolveUnion = (u: Union, opts: CommonOptions): string => {
119
136
  )
120
137
  return u.name;
121
138
  return Array.from(u.variants)
122
- .map((v) => resolveType(v[1].type, opts))
139
+ .map((v) => {
140
+ const variantType = v[1].type;
141
+ // If variant is a named model in the current namespace
142
+ // and it's not in routed typemap, reference it by name:
143
+ if (
144
+ !opts.resolveEvenWithName &&
145
+ variantType.kind === "Model" &&
146
+ variantType.name &&
147
+ opts.currentNamespace.models.has(variantType.name)
148
+ ) {
149
+ return variantType.name;
150
+ }
151
+ // Otherwise resolve type inline
152
+ return resolveType(variantType, { ...opts, isNamespaceRoot: false });
153
+ })
123
154
  .join(" | ");
124
155
  };
125
156
  export const resolveScalar = (s: Scalar): string => {
@@ -158,7 +189,7 @@ export const resolveModel = (m: Model, opts: CommonOptions): string => {
158
189
  if (
159
190
  m.name &&
160
191
  !opts.isNamespaceRoot &&
161
- opts.currentNamespace.namespace === m.namespace &&
192
+ opts.currentNamespace.models.has(m.name) &&
162
193
  !opts.resolveEvenWithName
163
194
  )
164
195
  return m.name;
@@ -176,6 +207,7 @@ export const resolveModel = (m: Model, opts: CommonOptions): string => {
176
207
  const typeStr = resolveType(p.type, {
177
208
  ...opts,
178
209
  nestlevel: opts.nestlevel + 1,
210
+ isNamespaceRoot: false,
179
211
  });
180
212
  if (typeStr.includes("unknown"))
181
213
  console.warn(`Could not resolve property ${p.name} on ${m.name}`);
@@ -189,3 +221,24 @@ export const resolveModel = (m: Model, opts: CommonOptions): string => {
189
221
  ret = ret.addLine("}", opts.nestlevel, true);
190
222
  return ret;
191
223
  };
224
+
225
+ export const resolveEnumMemberValue = (
226
+ e: Enum,
227
+ name: string,
228
+ ): string | number | undefined => {
229
+ const member = e.members.get(name);
230
+ if (!member) {
231
+ console.warn("Missing enum member under name:", name);
232
+ return;
233
+ }
234
+ return member?.value;
235
+ };
236
+
237
+ export const resolveEnumAsUnion = (e: Enum): string => {
238
+ return Array.from(e.members.values())
239
+ .map((member, index) => {
240
+ const value = resolveEnumMemberValue(e, member.name) ?? index;
241
+ return typeof value === "string" ? `'${value}'` : value.toString();
242
+ })
243
+ .join(" | ");
244
+ };
package/src/index.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export { $onEmit } from "./emitter.js";
2
- export { $lib } from "./lib.js";
2
+ export { $lib, EmitterOptions } from "./lib.js";
@@ -0,0 +1,83 @@
1
+ import { readFileSync, writeFileSync } from "fs";
2
+ import { join } from "path";
3
+ import { expect, it } from "vitest";
4
+ import { runner } from "./runner.js";
5
+
6
+ const tests = ["simple-routes", "enum", "pr8", "union", "visibility"];
7
+
8
+ const getTestData = (
9
+ testName: (typeof tests)[number],
10
+ ): {
11
+ input: string;
12
+ output: {
13
+ ts: string;
14
+ routes: string;
15
+ routedTypes: string;
16
+ };
17
+ } => {
18
+ const targetsFolder = "targets";
19
+ return {
20
+ input: readFileSync(join(__dirname, `${targetsFolder}/${testName}.tsp`), {
21
+ encoding: "utf8",
22
+ }),
23
+ output: {
24
+ ts: readFileSync(
25
+ join(__dirname, `${targetsFolder}/${testName}.target.ts`),
26
+ { encoding: "utf8" },
27
+ )
28
+ .trim()
29
+ .replaceAll("\r\n", "\n"),
30
+ routes: readFileSync(
31
+ join(__dirname, `${targetsFolder}/${testName}.routes.ts`),
32
+ { encoding: "utf8" },
33
+ )
34
+ .trim()
35
+ .replaceAll("\r\n", "\n"),
36
+ routedTypes: readFileSync(
37
+ join(__dirname, `${targetsFolder}/${testName}.routed-types.ts`),
38
+ { encoding: "utf8" },
39
+ )
40
+ .trim()
41
+ .replaceAll("\r\n", "\n"),
42
+ },
43
+ };
44
+ };
45
+
46
+ const emitterOptions = {
47
+ "root-namespace": "test",
48
+ "enable-routes": true,
49
+ "enable-types": true,
50
+ "enable-typeguards": true,
51
+ "enable-routed-typemap": true,
52
+ };
53
+
54
+ tests.forEach((test) => {
55
+ it(`works for ${test}`, async () => {
56
+ const data = getTestData(test);
57
+ const emitter = await runner.emit(
58
+ "typespec-typescript-emitter",
59
+ emitterOptions,
60
+ );
61
+ const result = await emitter.compileAndDiagnose(data.input);
62
+
63
+ writeFileSync(
64
+ join(__dirname, `out/${test}.target.ts`),
65
+ result[0].outputs["Test.ts"],
66
+ );
67
+ writeFileSync(
68
+ join(__dirname, `out/${test}.routes.ts`),
69
+ result[0].outputs["routes_test.ts"],
70
+ );
71
+ writeFileSync(
72
+ join(__dirname, `out/${test}.routed-types.ts`),
73
+ result[0].outputs["routedTypemap_test.ts"],
74
+ );
75
+
76
+ expect(result[1].length).toBe(0);
77
+ expect(result[0].outputs["Test.ts"].trim()).toBe(data.output.ts);
78
+ expect(result[0].outputs["routes_test.ts"].trim()).toBe(data.output.routes);
79
+ expect(result[0].outputs["routedTypemap_test.ts"].trim()).toBe(
80
+ data.output.routedTypes,
81
+ );
82
+ });
83
+ });
File without changes
package/test/runner.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { createTester } from "@typespec/compiler/testing";
2
+
3
+ export const runner = createTester(".", {
4
+ libraries: ["@typespec/http", "typespec-typescript-emitter"], // Add other libraries you depend on in your tests
5
+ });
@@ -0,0 +1,59 @@
1
+ /* eslint-disable */
2
+
3
+ /*
4
+ * This file is automatically generated by typespec-typescript-emitter.
5
+ *
6
+ * You should not change or manipulate this file, as it will be overwritten.
7
+ * Instead, change the underlying spec.
8
+ */
9
+
10
+ export type types_test = {
11
+ ["/test-simple"]: {
12
+ ["GET"]: {
13
+ request: null;
14
+ response: {
15
+ status: 200;
16
+ body: {
17
+ status: 0 | 1;
18
+ status_shifted: 1 | 2;
19
+ status_text: "Status 1" | "Status 2";
20
+ }[];
21
+ };
22
+ };
23
+ ["POST"]: {
24
+ request: {
25
+ status: 0 | 1;
26
+ status_shifted: 1 | 2;
27
+ status_text: "Status 1" | "Status 2";
28
+ };
29
+ response: {
30
+ status: 200;
31
+ body: {
32
+ /** The status code. */
33
+ statusCode: 200;
34
+ };
35
+ };
36
+ };
37
+ };
38
+ ["/test-simple/{id}"]: {
39
+ ["GET"]: {
40
+ request: null;
41
+ response:
42
+ | {
43
+ status: 200;
44
+ body: {
45
+ status: 0 | 1;
46
+ status_shifted: 1 | 2;
47
+ status_text: "Status 1" | "Status 2";
48
+ };
49
+ }
50
+ | {
51
+ status: 404;
52
+ body: {
53
+ /** The status code. */
54
+ statusCode: 404;
55
+ };
56
+ };
57
+ };
58
+ };
59
+ };
@@ -0,0 +1,29 @@
1
+ /* eslint-disable */
2
+
3
+ /*
4
+ * This file is automatically generated by typespec-typescript-emitter.
5
+ *
6
+ * You should not change or manipulate this file, as it will be overwritten.
7
+ * Instead, change the underlying spec.
8
+ */
9
+
10
+ export const routes_test = {
11
+ getAll: {
12
+ method: "GET",
13
+ path: "/test-simple",
14
+ getUrl: (): string => `/test-simple`,
15
+ auth: [null],
16
+ },
17
+ add: {
18
+ method: "POST",
19
+ path: "/test-simple",
20
+ getUrl: (): string => `/test-simple`,
21
+ auth: [null],
22
+ },
23
+ getOne: {
24
+ method: "GET",
25
+ path: "/test-simple/{id}",
26
+ getUrl: (params: { id: string }): string => `/test-simple/${params.id}`,
27
+ auth: [null],
28
+ },
29
+ } as const;
@@ -0,0 +1,39 @@
1
+ /* eslint-disable */
2
+
3
+ /*
4
+ * This file is automatically generated by typespec-typescript-emitter.
5
+ *
6
+ * You should not change or manipulate this file, as it will be overwritten.
7
+ * Instead, change the underlying spec.
8
+ */
9
+
10
+ export enum Status {
11
+ STATUS_1,
12
+ STATUS_2,
13
+ }
14
+
15
+ export enum StatusShifted {
16
+ STATUS_1 = 1,
17
+ STATUS_2 = 2,
18
+ }
19
+
20
+ export enum StatusText {
21
+ STATUS_1 = "Status 1",
22
+ STATUS_2 = "Status 2",
23
+ }
24
+
25
+ export interface TestEnumModel {
26
+ status: Status;
27
+ status_shifted: StatusShifted;
28
+ status_text: StatusText;
29
+ }
30
+ export function isTestEnumModel(arg: any): arg is TestEnumModel {
31
+ return (
32
+ arg["status"] !== undefined &&
33
+ true &&
34
+ arg["status_shifted"] !== undefined &&
35
+ true &&
36
+ arg["status_text"] !== undefined &&
37
+ true
38
+ );
39
+ }
@@ -0,0 +1,36 @@
1
+ import "@typespec/http";
2
+ using TypeSpec.Http;
3
+
4
+ @route("/test-simple")
5
+ namespace test {
6
+ enum Status {
7
+ STATUS_1,
8
+ STATUS_2
9
+ }
10
+ enum StatusShifted {
11
+ STATUS_1: 1,
12
+ STATUS_2: 2
13
+ }
14
+ enum StatusText {
15
+ STATUS_1: "Status 1",
16
+ STATUS_2: "Status 2"
17
+ }
18
+
19
+ model TestEnumModel {
20
+ status: Status,
21
+ status_shifted: StatusShifted,
22
+ status_text: StatusText
23
+ }
24
+
25
+ @get
26
+ op getAll(): {@body body: TestEnumModel[]};
27
+
28
+ @post
29
+ op add(@body body: TestEnumModel): OkResponse;
30
+
31
+ @get
32
+ @route("{id}")
33
+ op getOne(
34
+ @path id: int32
35
+ ): {@body body: TestEnumModel} | NotFoundResponse;
36
+ }