@typespec/compiler 0.52.0-dev.1 → 0.52.0-dev.10

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 (159) hide show
  1. package/dist/.scripts/build-init-templates.d.ts +2 -0
  2. package/dist/.scripts/build-init-templates.d.ts.map +1 -0
  3. package/dist/.scripts/build-init-templates.js +38 -0
  4. package/dist/.scripts/build-init-templates.js.map +1 -0
  5. package/dist/.scripts/helpers.d.ts +4 -0
  6. package/dist/.scripts/helpers.d.ts.map +1 -0
  7. package/dist/.scripts/helpers.js +44 -0
  8. package/dist/.scripts/helpers.js.map +1 -0
  9. package/dist/manifest.js +2 -2
  10. package/dist/src/config/config-loader.d.ts.map +1 -1
  11. package/dist/src/config/config-loader.js +1 -1
  12. package/dist/src/config/config-loader.js.map +1 -1
  13. package/dist/src/core/binder.d.ts.map +1 -1
  14. package/dist/src/core/binder.js +1 -1
  15. package/dist/src/core/binder.js.map +1 -1
  16. package/dist/src/core/checker.d.ts +4 -0
  17. package/dist/src/core/checker.d.ts.map +1 -1
  18. package/dist/src/core/checker.js +154 -64
  19. package/dist/src/core/checker.js.map +1 -1
  20. package/dist/src/core/cli/actions/format.js +1 -1
  21. package/dist/src/core/cli/actions/format.js.map +1 -1
  22. package/dist/src/core/cli/actions/init.d.ts +1 -0
  23. package/dist/src/core/cli/actions/init.d.ts.map +1 -1
  24. package/dist/src/core/cli/actions/init.js +1 -1
  25. package/dist/src/core/cli/actions/init.js.map +1 -1
  26. package/dist/src/core/cli/cli.js +6 -1
  27. package/dist/src/core/cli/cli.js.map +1 -1
  28. package/dist/src/core/cli/utils.d.ts.map +1 -1
  29. package/dist/src/core/cli/utils.js +3 -0
  30. package/dist/src/core/cli/utils.js.map +1 -1
  31. package/dist/src/core/diagnostic-creator.d.ts +11 -0
  32. package/dist/src/core/diagnostic-creator.d.ts.map +1 -0
  33. package/dist/src/core/diagnostic-creator.js +48 -0
  34. package/dist/src/core/diagnostic-creator.js.map +1 -0
  35. package/dist/src/core/diagnostics.d.ts +2 -11
  36. package/dist/src/core/diagnostics.d.ts.map +1 -1
  37. package/dist/src/core/diagnostics.js +3 -52
  38. package/dist/src/core/diagnostics.js.map +1 -1
  39. package/dist/src/core/formatter-fs.d.ts +1 -1
  40. package/dist/src/core/formatter-fs.d.ts.map +1 -1
  41. package/dist/src/core/formatter-fs.js +1 -1
  42. package/dist/src/core/formatter-fs.js.map +1 -1
  43. package/dist/src/core/helpers/location-context.js +1 -1
  44. package/dist/src/core/helpers/location-context.js.map +1 -1
  45. package/dist/src/core/index.d.ts +1 -1
  46. package/dist/src/core/index.d.ts.map +1 -1
  47. package/dist/src/core/index.js +1 -1
  48. package/dist/src/core/index.js.map +1 -1
  49. package/dist/src/core/library.d.ts +4 -3
  50. package/dist/src/core/library.d.ts.map +1 -1
  51. package/dist/src/core/library.js +14 -15
  52. package/dist/src/core/library.js.map +1 -1
  53. package/dist/src/core/linter.d.ts.map +1 -1
  54. package/dist/src/core/linter.js +12 -6
  55. package/dist/src/core/linter.js.map +1 -1
  56. package/dist/src/core/logger/logger.d.ts +1 -1
  57. package/dist/src/core/logger/logger.d.ts.map +1 -1
  58. package/dist/src/core/messages.d.ts +41 -8
  59. package/dist/src/core/messages.d.ts.map +1 -1
  60. package/dist/src/core/messages.js +12 -3
  61. package/dist/src/core/messages.js.map +1 -1
  62. package/dist/src/core/node-host.d.ts.map +1 -1
  63. package/dist/src/core/node-host.js +4 -3
  64. package/dist/src/core/node-host.js.map +1 -1
  65. package/dist/src/core/param-message.d.ts +3 -0
  66. package/dist/src/core/param-message.d.ts.map +1 -0
  67. package/dist/src/core/param-message.js +16 -0
  68. package/dist/src/core/param-message.js.map +1 -0
  69. package/dist/src/core/parser.d.ts +5 -1
  70. package/dist/src/core/parser.d.ts.map +1 -1
  71. package/dist/src/core/parser.js +56 -2
  72. package/dist/src/core/parser.js.map +1 -1
  73. package/dist/src/core/program.js +8 -5
  74. package/dist/src/core/program.js.map +1 -1
  75. package/dist/src/core/types.d.ts +31 -15
  76. package/dist/src/core/types.d.ts.map +1 -1
  77. package/dist/src/core/types.js +7 -5
  78. package/dist/src/core/types.js.map +1 -1
  79. package/dist/src/core/util.d.ts +1 -2
  80. package/dist/src/core/util.d.ts.map +1 -1
  81. package/dist/src/core/util.js +2 -3
  82. package/dist/src/core/util.js.map +1 -1
  83. package/dist/src/emitter-framework/reference-cycle.d.ts +1 -1
  84. package/dist/src/emitter-framework/reference-cycle.d.ts.map +1 -1
  85. package/dist/src/emitter-framework/reference-cycle.js +1 -1
  86. package/dist/src/emitter-framework/reference-cycle.js.map +1 -1
  87. package/dist/src/formatter/print/printer.d.ts +2 -1
  88. package/dist/src/formatter/print/printer.d.ts.map +1 -1
  89. package/dist/src/formatter/print/printer.js +12 -0
  90. package/dist/src/formatter/print/printer.js.map +1 -1
  91. package/dist/src/init/core-templates.d.ts +6 -0
  92. package/dist/src/init/core-templates.d.ts.map +1 -0
  93. package/dist/src/init/core-templates.js +11 -0
  94. package/dist/src/init/core-templates.js.map +1 -0
  95. package/dist/src/init/file-templating.d.ts +25 -0
  96. package/dist/src/init/file-templating.d.ts.map +1 -0
  97. package/dist/src/init/file-templating.js +39 -0
  98. package/dist/src/init/file-templating.js.map +1 -0
  99. package/dist/src/init/init-template.d.ts +3 -3
  100. package/dist/src/init/init-template.d.ts.map +1 -1
  101. package/dist/src/init/init-template.js +4 -3
  102. package/dist/src/init/init-template.js.map +1 -1
  103. package/dist/src/init/init.d.ts +11 -47
  104. package/dist/src/init/init.d.ts.map +1 -1
  105. package/dist/src/init/init.js +32 -190
  106. package/dist/src/init/init.js.map +1 -1
  107. package/dist/src/init/scaffold.d.ts +39 -0
  108. package/dist/src/init/scaffold.d.ts.map +1 -0
  109. package/dist/src/init/scaffold.js +132 -0
  110. package/dist/src/init/scaffold.js.map +1 -0
  111. package/dist/src/manifest.d.ts.map +1 -1
  112. package/dist/src/manifest.js +10 -3
  113. package/dist/src/manifest.js.map +1 -1
  114. package/dist/src/server/completion.js +3 -3
  115. package/dist/src/server/completion.js.map +1 -1
  116. package/dist/src/server/serverlib.d.ts.map +1 -1
  117. package/dist/src/server/serverlib.js +4 -0
  118. package/dist/src/server/serverlib.js.map +1 -1
  119. package/dist/src/server/tmlanguage.js +1 -1
  120. package/dist/src/server/tmlanguage.js.map +1 -1
  121. package/dist/src/testing/test-host.js +2 -2
  122. package/dist/src/testing/test-host.js.map +1 -1
  123. package/dist/src/testing/test-utils.d.ts +2 -0
  124. package/dist/src/testing/test-utils.d.ts.map +1 -1
  125. package/dist/src/testing/test-utils.js +8 -3
  126. package/dist/src/testing/test-utils.js.map +1 -1
  127. package/dist/typespec.tmLanguage +8 -0
  128. package/dist/vitest.config.d.ts +3 -0
  129. package/dist/vitest.config.d.ts.map +1 -0
  130. package/dist/vitest.config.e2e.d.ts +3 -0
  131. package/dist/vitest.config.e2e.d.ts.map +1 -0
  132. package/dist/vitest.config.e2e.js +16 -0
  133. package/dist/vitest.config.e2e.js.map +1 -0
  134. package/dist/vitest.config.js +15 -0
  135. package/dist/vitest.config.js.map +1 -0
  136. package/lib/decorators.tsp +3 -3
  137. package/lib/lib.tsp +30 -25
  138. package/package.json +12 -9
  139. package/templates/__snapshots__/emitter-ts/.eslintrc.yml +14 -0
  140. package/templates/__snapshots__/emitter-ts/package.json +37 -0
  141. package/templates/__snapshots__/emitter-ts/prettierrc.yaml +8 -0
  142. package/templates/__snapshots__/emitter-ts/src/emitter.ts +10 -0
  143. package/templates/__snapshots__/emitter-ts/src/index.ts +2 -0
  144. package/templates/__snapshots__/emitter-ts/src/lib.ts +8 -0
  145. package/templates/__snapshots__/emitter-ts/src/testing/index.ts +10 -0
  146. package/templates/__snapshots__/emitter-ts/test/hello.test.ts +10 -0
  147. package/templates/__snapshots__/emitter-ts/test/test-host.ts +47 -0
  148. package/templates/__snapshots__/emitter-ts/tsconfig.json +17 -0
  149. package/templates/emitter-ts/.eslintrc.yml +14 -0
  150. package/templates/emitter-ts/package.json +37 -0
  151. package/templates/emitter-ts/prettierrc.yaml +8 -0
  152. package/templates/emitter-ts/src/emitter.ts +10 -0
  153. package/templates/emitter-ts/src/index.ts +2 -0
  154. package/templates/emitter-ts/src/lib.ts +8 -0
  155. package/templates/emitter-ts/src/testing/index.ts +10 -0
  156. package/templates/emitter-ts/test/hello.test.ts +10 -0
  157. package/templates/emitter-ts/test/test-host.ts.mu +47 -0
  158. package/templates/emitter-ts/tsconfig.json +17 -0
  159. package/templates/scaffolding.json +79 -0
package/lib/lib.tsp CHANGED
@@ -138,18 +138,18 @@ scalar unixTimestamp32 extends utcDateTime;
138
138
  model object {}
139
139
 
140
140
  /**
141
- * @dev Array model type, equivalent to `T[]`
142
- * @template T The type of the array elements
141
+ * @dev Array model type, equivalent to `Element[]`
142
+ * @template Element The type of the array elements
143
143
  */
144
- @indexer(integer, T)
145
- model Array<T> {}
144
+ @indexer(integer, Element)
145
+ model Array<Element> {}
146
146
 
147
147
  /**
148
- * @dev Model with string properties where all the properties have type `T`
149
- * @template T The type of the properties
148
+ * @dev Model with string properties where all the properties have type `Property`
149
+ * @template Element The type of the properties
150
150
  */
151
- @indexer(string, T)
152
- model Record<T> {}
151
+ @indexer(string, Element)
152
+ model Record<Element> {}
153
153
 
154
154
  /**
155
155
  * Represent a URL string as described by https://url.spec.whatwg.org/
@@ -158,51 +158,56 @@ scalar url extends string;
158
158
 
159
159
  /**
160
160
  * Represents a collection of optional properties.
161
- * @template T An object whose spread properties are all optional.
161
+ *
162
+ * @template Source An object whose spread properties are all optional.
162
163
  */
163
164
  @doc("The template for adding optional properties.")
164
165
  @withOptionalProperties
165
- model OptionalProperties<T> {
166
- ...T;
166
+ model OptionalProperties<Source> {
167
+ ...Source;
167
168
  }
168
169
 
169
170
  /**
170
171
  * Represents a collection of updateable properties.
171
- * @template T An object whose spread properties are all updateable.
172
+ *
173
+ * @template Source An object whose spread properties are all updateable.
172
174
  */
173
175
  @doc("The template for adding updateable properties.")
174
176
  @withUpdateableProperties
175
- model UpdateableProperties<T> {
176
- ...T;
177
+ model UpdateableProperties<Source> {
178
+ ...Source;
177
179
  }
178
180
 
179
181
  /**
180
182
  * Represents a collection of omitted properties.
181
- * @template T An object whose properties are spread.
182
- * @template TKeys The property keys to omit.
183
+ *
184
+ * @template Source An object whose properties are spread.
185
+ * @template Keys The property keys to omit.
183
186
  */
184
187
  @doc("The template for omitting properties.")
185
- @withoutOmittedProperties(TKeys)
186
- model OmitProperties<T, TKeys extends string> {
187
- ...T;
188
+ @withoutOmittedProperties(Keys)
189
+ model OmitProperties<Source, Keys extends string> {
190
+ ...Source;
188
191
  }
189
192
 
190
193
  /**
191
194
  * Represents a collection of properties with default values omitted.
192
- * @template T An object whose spread property defaults are all omitted.
195
+ *
196
+ * @template Source An object whose spread property defaults are all omitted.
193
197
  */
194
198
  @withoutDefaultValues
195
- model OmitDefaults<T> {
196
- ...T;
199
+ model OmitDefaults<Source> {
200
+ ...Source;
197
201
  }
198
202
 
199
203
  /**
200
204
  * Applies a visibility setting to a collection of properties.
201
- * @template T An object whose properties are spread.
205
+ *
206
+ * @template Source An object whose properties are spread.
202
207
  * @template Visibility The visibility to apply to all properties.
203
208
  */
204
209
  @doc("The template for setting the default visibility of key properties.")
205
210
  @withDefaultKeyVisibility(Visibility)
206
- model DefaultKeyVisibility<T, Visibility extends valueof string> {
207
- ...T;
211
+ model DefaultKeyVisibility<Source, Visibility extends valueof string> {
212
+ ...Source;
208
213
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typespec/compiler",
3
- "version": "0.52.0-dev.1",
3
+ "version": "0.52.0-dev.10",
4
4
  "description": "TypeSpec Compiler Preview",
5
5
  "author": "Microsoft Corporation",
6
6
  "license": "MIT",
@@ -52,6 +52,7 @@
52
52
  "files": [
53
53
  "lib/*.tsp",
54
54
  "dist/**",
55
+ "templates/**",
55
56
  "entrypoints",
56
57
  "!dist/test/**"
57
58
  ],
@@ -72,7 +73,6 @@
72
73
  },
73
74
  "devDependencies": {
74
75
  "@types/babel__code-frame": "~7.0.6",
75
- "@types/mocha": "~10.0.6",
76
76
  "@types/mustache": "~4.2.5",
77
77
  "@types/node": "~18.11.9",
78
78
  "@types/prompts": "~2.4.9",
@@ -82,9 +82,8 @@
82
82
  "@typespec/internal-build-utils": "~0.51.0 || >=0.52.0-dev <0.52.0",
83
83
  "eslint": "^8.55.0",
84
84
  "grammarkdown": "~3.3.2",
85
- "mocha": "~10.2.0",
86
- "mocha-junit-reporter": "~2.2.1",
87
- "mocha-multi-reporters": "~1.5.1",
85
+ "vitest": "^1.1.0",
86
+ "@vitest/coverage-v8": "^1.1.0",
88
87
  "c8": "~8.0.1",
89
88
  "prettier-plugin-organize-imports": "~3.2.4",
90
89
  "source-map-support": "~0.5.21",
@@ -94,19 +93,23 @@
94
93
  "vscode-oniguruma": "~2.0.1",
95
94
  "vscode-textmate": "~9.0.0",
96
95
  "sinon": "~17.0.1",
97
- "@types/sinon": "~10.0.20"
96
+ "@types/sinon": "~10.0.20",
97
+ "ts-node": "~10.9.1"
98
98
  },
99
99
  "peerDependencies": {},
100
100
  "scripts": {
101
101
  "clean": "rimraf ./dist ./temp",
102
- "build": "npm run gen-manifest && npm run compile && npm run generate-tmlanguage",
102
+ "build:init-templates-index": "node --no-warnings --experimental-specifier-resolution=node --loader ts-node/esm ./.scripts/build-init-templates.ts",
103
+ "build": "npm run gen-manifest && npm run build:init-templates-index && npm run compile && npm run generate-tmlanguage",
103
104
  "compile": "tsc -p .",
104
105
  "watch": "tsc -p . --watch",
105
106
  "watch-tmlanguage": "node scripts/watch-tmlanguage.js",
106
107
  "generate-tmlanguage": "node scripts/generate-tmlanguage.js",
107
108
  "dogfood": "node scripts/dogfood.js",
108
- "test": "mocha",
109
- "test-official": "c8 mocha --forbid-only --reporter mocha-multi-reporters",
109
+ "test": "vitest run",
110
+ "test:watch": "vitest -w",
111
+ "test-official": "vitest run --coverage --reporter=junit --reporter=default --no-file-parallelism",
112
+ "e2e": "vitest run --config ./vitest.config.e2e.ts",
110
113
  "gen-manifest": "node scripts/generate-manifest.js",
111
114
  "regen-nonascii": "node scripts/regen-nonascii.js",
112
115
  "fuzz": "node dist/test/manual/fuzz.js run",
@@ -0,0 +1,14 @@
1
+ root: true
2
+ env:
3
+ es2021: true
4
+ node: true
5
+ extends:
6
+ - eslint:recommended
7
+ - plugin:@typescript-eslint/recommended
8
+ parser: "@typescript-eslint/parser"
9
+ parserOptions:
10
+ ecmaVersion: latest
11
+ sourceType: module
12
+ plugins:
13
+ - "@typescript-eslint"
14
+ rules: {}
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "emitter-ts",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "dist/src/index.js",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/src/index.d.ts",
9
+ "default": "./dist/src/index.js"
10
+ },
11
+ "./testing": {
12
+ "types": "./dist/src/testing/index.d.ts",
13
+ "default": "./dist/src/testing/index.js"
14
+ }
15
+ },
16
+ "dependencies": {
17
+ "@typespec/compiler": "latest"
18
+ },
19
+ "devDependencies": {
20
+ "@types/node": "latest",
21
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
22
+ "@typescript-eslint/parser": "^6.0.0",
23
+ "eslint": "^8.45.0",
24
+ "typescript": "^5.3.3",
25
+ "prettier": "^3.0.3"
26
+ },
27
+ "scripts": {
28
+ "build": "tsc",
29
+ "watch": "tsc --watch",
30
+ "test": "node --test ./dist/test/",
31
+ "lint": "eslint src/ test/ --report-unused-disable-directives --max-warnings=0",
32
+ "lint:fix": "eslint . --report-unused-disable-directives --fix",
33
+ "format": "prettier . --write",
34
+ "format:check": "prettier --check ."
35
+ },
36
+ "private": true
37
+ }
@@ -0,0 +1,8 @@
1
+ trailingComma: "all"
2
+ printWidth: 120
3
+ quoteProps: "consistent"
4
+ endOfLine: lf
5
+ arrowParens: always
6
+ plugins:
7
+ - "./node_modules/@typespec/prettier-plugin-typespec/dist/index.js"
8
+ overrides: [{ "files": "*.tsp", "options": { "parser": "typespec" } }]
@@ -0,0 +1,10 @@
1
+ import { EmitContext, emitFile, resolvePath } from "@typespec/compiler";
2
+
3
+ export async function $onEmit(context: EmitContext) {
4
+ if (!context.program.compilerOptions.noEmit) {
5
+ await emitFile(context.program, {
6
+ path: resolvePath(context.emitterOutputDir, "output.txt"),
7
+ content: "Hello world\n",
8
+ });
9
+ }
10
+ }
@@ -0,0 +1,2 @@
1
+ export { $onEmit } from "./emitter.js";
2
+ export { $lib } from "./lib.js";
@@ -0,0 +1,8 @@
1
+ import { createTypeSpecLibrary } from "@typespec/compiler";
2
+
3
+ export const $lib = createTypeSpecLibrary({
4
+ name: "emitter-ts",
5
+ diagnostics: {},
6
+ });
7
+
8
+ export const { reportDiagnostic, createDiagnostic } = $lib;
@@ -0,0 +1,10 @@
1
+ import {
2
+ createTestLibrary,
3
+ findTestPackageRoot,
4
+ TypeSpecTestLibrary,
5
+ } from "@typespec/compiler/testing";
6
+
7
+ export const TestLibrary: TypeSpecTestLibrary = createTestLibrary({
8
+ name: "emitter-ts",
9
+ packageRoot: await findTestPackageRoot(import.meta.url),
10
+ });
@@ -0,0 +1,10 @@
1
+ import { strictEqual } from "node:assert";
2
+ import { describe, it } from "vitest";
3
+ import { emit } from "./test-host.js";
4
+
5
+ describe("hello", () => {
6
+ it("emit output.txt with content hello world", async () => {
7
+ const results = await emit(`op test(): void;`);
8
+ strictEqual(results["output.txt"], "Hello world\n");
9
+ });
10
+ });
@@ -0,0 +1,47 @@
1
+ import { Diagnostic, resolvePath } from "@typespec/compiler";
2
+ import {
3
+ createTestHost,
4
+ createTestWrapper,
5
+ expectDiagnosticEmpty,
6
+ } from "@typespec/compiler/testing";
7
+ import { TestLibrary } from "../src/testing/index.js";
8
+
9
+ export async function createEmitterTsTestHost() {
10
+ return createTestHost({
11
+ libraries: [TestLibrary],
12
+ });
13
+ }
14
+
15
+ export async function createEmitterTsTestRunner() {
16
+ const host = await createEmitterTsTestHost();
17
+
18
+ return createTestWrapper(host, {
19
+ compilerOptions: {
20
+ noEmit: false,
21
+ emit: ["emitter-ts"],
22
+ },
23
+ });
24
+ }
25
+
26
+ export async function emitWithDiagnostics(
27
+ code: string
28
+ ): Promise<[Record<string, string>, readonly Diagnostic[]]> {
29
+ const runner = await createEmitterTsTestRunner();
30
+ await runner.compileAndDiagnose(code, {
31
+ outputDir: "tsp-output",
32
+ });
33
+ const emitterOutputDir = "./tsp-output/emitter-ts";
34
+ const files = await runner.program.host.readDir(emitterOutputDir);
35
+
36
+ const result: Record<string, string> = {};
37
+ for (const file of files) {
38
+ result[file] = (await runner.program.host.readFile(resolvePath(emitterOutputDir, file))).text;
39
+ }
40
+ return [result, runner.program.diagnostics];
41
+ }
42
+
43
+ export async function emit(code: string): Promise<Record<string, string>> {
44
+ const [result, diagnostics] = await emitWithDiagnostics(code);
45
+ expectDiagnosticEmpty(diagnostics);
46
+ return result;
47
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "useDefineForClassFields": true,
5
+ "module": "NodeNext",
6
+ "moduleResolution": "NodeNext",
7
+ "lib": ["ES2022"],
8
+ "rootDir": ".",
9
+ "outDir": "dist",
10
+ "sourceMap": true,
11
+ "declaration": true,
12
+
13
+ /* Linting */
14
+ "strict": true
15
+ },
16
+ "include": ["src", "test"]
17
+ }
@@ -0,0 +1,14 @@
1
+ root: true
2
+ env:
3
+ es2021: true
4
+ node: true
5
+ extends:
6
+ - eslint:recommended
7
+ - plugin:@typescript-eslint/recommended
8
+ parser: "@typescript-eslint/parser"
9
+ parserOptions:
10
+ ecmaVersion: latest
11
+ sourceType: module
12
+ plugins:
13
+ - "@typescript-eslint"
14
+ rules: {}
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "{{name}}",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "dist/src/index.js",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/src/index.d.ts",
9
+ "default": "./dist/src/index.js"
10
+ },
11
+ "./testing": {
12
+ "types": "./dist/src/testing/index.d.ts",
13
+ "default": "./dist/src/testing/index.js"
14
+ }
15
+ },
16
+ "dependencies": {
17
+ "@typespec/compiler": "latest"
18
+ },
19
+ "devDependencies": {
20
+ "@types/node": "latest",
21
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
22
+ "@typescript-eslint/parser": "^6.0.0",
23
+ "eslint": "^8.45.0",
24
+ "typescript": "^5.3.3",
25
+ "prettier": "^3.0.3"
26
+ },
27
+ "scripts": {
28
+ "build": "tsc",
29
+ "watch": "tsc --watch",
30
+ "test": "node --test ./dist/test/",
31
+ "lint": "eslint src/ test/ --report-unused-disable-directives --max-warnings=0",
32
+ "lint:fix": "eslint . --report-unused-disable-directives --fix",
33
+ "format": "prettier . --write",
34
+ "format:check": "prettier --check ."
35
+ },
36
+ "private": true
37
+ }
@@ -0,0 +1,8 @@
1
+ trailingComma: "all"
2
+ printWidth: 120
3
+ quoteProps: "consistent"
4
+ endOfLine: lf
5
+ arrowParens: always
6
+ plugins:
7
+ - "./node_modules/@typespec/prettier-plugin-typespec/dist/index.js"
8
+ overrides: [{ "files": "*.tsp", "options": { "parser": "typespec" } }]
@@ -0,0 +1,10 @@
1
+ import { EmitContext, emitFile, resolvePath } from "@typespec/compiler";
2
+
3
+ export async function $onEmit(context: EmitContext) {
4
+ if (!context.program.compilerOptions.noEmit) {
5
+ await emitFile(context.program, {
6
+ path: resolvePath(context.emitterOutputDir, "output.txt"),
7
+ content: "Hello world\n",
8
+ });
9
+ }
10
+ }
@@ -0,0 +1,2 @@
1
+ export { $onEmit } from "./emitter.js";
2
+ export { $lib } from "./lib.js";
@@ -0,0 +1,8 @@
1
+ import { createTypeSpecLibrary } from "@typespec/compiler";
2
+
3
+ export const $lib = createTypeSpecLibrary({
4
+ name: "{{name}}",
5
+ diagnostics: {},
6
+ });
7
+
8
+ export const { reportDiagnostic, createDiagnostic } = $lib;
@@ -0,0 +1,10 @@
1
+ import {
2
+ createTestLibrary,
3
+ findTestPackageRoot,
4
+ TypeSpecTestLibrary,
5
+ } from "@typespec/compiler/testing";
6
+
7
+ export const TestLibrary: TypeSpecTestLibrary = createTestLibrary({
8
+ name: "{{name}}",
9
+ packageRoot: await findTestPackageRoot(import.meta.url),
10
+ });
@@ -0,0 +1,10 @@
1
+ import { strictEqual } from "node:assert";
2
+ import { describe, it } from "vitest";
3
+ import { emit } from "./test-host.js";
4
+
5
+ describe("hello", () => {
6
+ it("emit output.txt with content hello world", async () => {
7
+ const results = await emit(`op test(): void;`);
8
+ strictEqual(results["output.txt"], "Hello world\n");
9
+ });
10
+ });
@@ -0,0 +1,47 @@
1
+ import { Diagnostic, resolvePath } from "@typespec/compiler";
2
+ import {
3
+ createTestHost,
4
+ createTestWrapper,
5
+ expectDiagnosticEmpty,
6
+ } from "@typespec/compiler/testing";
7
+ import { TestLibrary } from "../src/testing/index.js";
8
+
9
+ export async function create{{#casing.pascalCase}}{{name}}{{/casing.pascalCase}}TestHost() {
10
+ return createTestHost({
11
+ libraries: [TestLibrary],
12
+ });
13
+ }
14
+
15
+ export async function create{{#casing.pascalCase}}{{name}}{{/casing.pascalCase}}TestRunner() {
16
+ const host = await create{{#casing.pascalCase}}{{name}}{{/casing.pascalCase}}TestHost();
17
+
18
+ return createTestWrapper(host, {
19
+ compilerOptions: {
20
+ noEmit: false,
21
+ emit: ["{{name}}"],
22
+ },
23
+ });
24
+ }
25
+
26
+ export async function emitWithDiagnostics(
27
+ code: string
28
+ ): Promise<[Record<string, string>, readonly Diagnostic[]]> {
29
+ const runner = await create{{#casing.pascalCase}}{{name}}{{/casing.pascalCase}}TestRunner();
30
+ await runner.compileAndDiagnose(code, {
31
+ outputDir: "tsp-output",
32
+ });
33
+ const emitterOutputDir = "./tsp-output/{{name}}";
34
+ const files = await runner.program.host.readDir(emitterOutputDir);
35
+
36
+ const result: Record<string, string> = {};
37
+ for (const file of files) {
38
+ result[file] = (await runner.program.host.readFile(resolvePath(emitterOutputDir, file))).text;
39
+ }
40
+ return [result, runner.program.diagnostics];
41
+ }
42
+
43
+ export async function emit(code: string): Promise<Record<string, string>> {
44
+ const [result, diagnostics] = await emitWithDiagnostics(code);
45
+ expectDiagnosticEmpty(diagnostics);
46
+ return result;
47
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "useDefineForClassFields": true,
5
+ "module": "NodeNext",
6
+ "moduleResolution": "NodeNext",
7
+ "lib": ["ES2022"],
8
+ "rootDir": ".",
9
+ "outDir": "dist",
10
+ "sourceMap": true,
11
+ "declaration": true,
12
+
13
+ /* Linting */
14
+ "strict": true
15
+ },
16
+ "include": ["src", "test"]
17
+ }
@@ -0,0 +1,79 @@
1
+ {
2
+ "empty": {
3
+ "title": "Empty project",
4
+ "description": "Create an empty project.",
5
+ "libraries": [],
6
+ "compilerVersion": "0.51.0"
7
+ },
8
+ "rest": {
9
+ "title": "Generic Rest API",
10
+ "description": "Create a project representing a generic Rest API",
11
+ "compilerVersion": "0.51.0",
12
+ "libraries": [
13
+ "@typespec/http",
14
+ "@typespec/rest",
15
+ "@typespec/openapi3"
16
+ ],
17
+ "config": {
18
+ "emit": [
19
+ "@typespec/openapi3"
20
+ ]
21
+ }
22
+ },
23
+ "emitter-ts": {
24
+ "title": "TypeSpec Emitter (With TypeScript)",
25
+ "description": "Create a new package that will be emitting typespec",
26
+ "compilerVersion": "0.51.0",
27
+ "libraries": [],
28
+ "files": [
29
+ {
30
+ "destination": "main.tsp",
31
+ "skipGeneration": true
32
+ },
33
+ {
34
+ "destination": "tspconfig.yaml",
35
+ "skipGeneration": true
36
+ },
37
+ {
38
+ "path": "emitter-ts/.eslintrc.yml",
39
+ "destination": ".eslintrc.yml"
40
+ },
41
+ {
42
+ "path": "emitter-ts/package.json",
43
+ "destination": "package.json"
44
+ },
45
+ {
46
+ "path": "emitter-ts/prettierrc.yaml",
47
+ "destination": "prettierrc.yaml"
48
+ },
49
+ {
50
+ "path": "emitter-ts/src/emitter.ts",
51
+ "destination": "src/emitter.ts"
52
+ },
53
+ {
54
+ "path": "emitter-ts/src/index.ts",
55
+ "destination": "src/index.ts"
56
+ },
57
+ {
58
+ "path": "emitter-ts/src/lib.ts",
59
+ "destination": "src/lib.ts"
60
+ },
61
+ {
62
+ "path": "emitter-ts/src/testing/index.ts",
63
+ "destination": "src/testing/index.ts"
64
+ },
65
+ {
66
+ "path": "emitter-ts/test/hello.test.ts",
67
+ "destination": "test/hello.test.ts"
68
+ },
69
+ {
70
+ "path": "emitter-ts/test/test-host.ts.mu",
71
+ "destination": "test/test-host.ts"
72
+ },
73
+ {
74
+ "path": "emitter-ts/tsconfig.json",
75
+ "destination": "tsconfig.json"
76
+ }
77
+ ]
78
+ }
79
+ }