-
Notifications
You must be signed in to change notification settings - Fork 358
feat: enable C# emitter in playground with backend server #10346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
4301e90
437b2ca
da56524
b07b370
a6006ff
f03059f
ef6e306
f03f775
a7c273b
01c4644
99e0ee5
fadf720
664aff5
5780707
ed629d0
b4d53db
700d1b1
5cb4659
bd34a3c
cf88a0a
2d85b12
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| node_modules/ | ||
|
JoshLove-msft marked this conversation as resolved.
|
||
| dist/ | ||
| emitter/ | ||
| .tspd/ | ||
| **/artifacts/ | ||
| *.md | ||
| *.tsp | ||
| package-lock.json | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
|
||
| // Browser implementation: sends code model to a playground server for generation. | ||
|
|
||
| import { resolvePath } from "@typespec/compiler"; | ||
| import type { GenerateOptions } from "./emit-generate.js"; | ||
| import { CSharpEmitterContext } from "./sdk-context.js"; | ||
|
|
||
| const SERVER_URL = "https://csharp-playground-server.azurewebsites.net"; | ||
| const MAX_RESPONSE_SIZE = 10 * 1024 * 1024; // 10 MB | ||
|
|
||
| export async function generate( | ||
| sdkContext: CSharpEmitterContext, | ||
| codeModelJson: string, | ||
| configJson: string, | ||
| options: GenerateOptions, | ||
| ): Promise<void> { | ||
| const response = await fetch(`${SERVER_URL}/generate`, { | ||
| method: "POST", | ||
| headers: { "Content-Type": "application/json" }, | ||
| body: JSON.stringify({ | ||
| codeModel: codeModelJson, | ||
| configuration: configJson, | ||
| generatorName: options.generatorName, | ||
| }), | ||
| }); | ||
|
|
||
| if (!response.ok) { | ||
| const errorText = await response.text(); | ||
| throw new Error(`Playground server error (${response.status}): ${errorText}`); | ||
| } | ||
|
|
||
| const contentType = response.headers.get("content-type"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering about a limit on response size? content-length is not a great way to police this, but not sure what size quotas are available to use
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added a Content-Length check against a 10 MB limit before parsing the response JSON. As you noted, Content-Length isn't always reliable, but it provides a reasonable guard against obviously oversized responses without buffering the entire body. -- Generated by Copilot |
||
| if (!contentType?.includes("application/json")) { | ||
| throw new Error(`Unexpected response content-type: ${contentType}`); | ||
| } | ||
|
|
||
| const contentLength = response.headers.get("content-length"); | ||
| if (contentLength && parseInt(contentLength, 10) > MAX_RESPONSE_SIZE) { | ||
| throw new Error( | ||
| `Response too large: ${contentLength} bytes exceeds ${MAX_RESPONSE_SIZE} byte limit`, | ||
| ); | ||
| } | ||
|
|
||
| const result = await response.json(); | ||
|
|
||
| if (!result || !Array.isArray(result.files)) { | ||
| throw new Error("Invalid response: expected { files: [...] }"); | ||
| } | ||
|
|
||
| for (const file of result.files) { | ||
| if (typeof file.path !== "string" || typeof file.content !== "string") { | ||
| throw new Error(`Invalid file entry: expected { path: string, content: string }`); | ||
| } | ||
| await sdkContext.program.host.writeFile( | ||
| resolvePath(options.outputFolder, file.path), | ||
| file.content, | ||
| ); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there any emitter option that allow users to run a post emitting script that would allow a playground user to basically run code on the server?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the closest thing is there an option to configure a plugin but the plugin would need to exist on the server.