@typespec/http-server-js 0.58.0-alpha.14-dev.5 → 0.58.0-alpha.14
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.
- package/CHANGELOG.md +8 -0
- package/dist/src/scripts/scaffold/bin.d.mts +5 -1
- package/dist/src/scripts/scaffold/bin.d.mts.map +1 -1
- package/dist/src/scripts/scaffold/bin.mjs +62 -45
- package/dist/src/scripts/scaffold/bin.mjs.map +1 -1
- package/package.json +12 -12
- package/src/scripts/scaffold/bin.mts +97 -51
- package/temp/tsconfig.tsbuildinfo +1 -1
|
@@ -5,9 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
import { hsjsDependencies } from "../../../generated-defs/package.json.js";
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
import {
|
|
9
|
+
compile,
|
|
10
|
+
formatDiagnostic,
|
|
11
|
+
NodeHost,
|
|
12
|
+
OperationContainer,
|
|
13
|
+
resolveCompilerOptions,
|
|
14
|
+
ResolveCompilerOptionsOptions,
|
|
15
|
+
} from "@typespec/compiler";
|
|
11
16
|
|
|
12
17
|
import { getHttpService, HttpOperation, HttpService } from "@typespec/http";
|
|
13
18
|
import { spawn as _spawn, SpawnOptions } from "node:child_process";
|
|
@@ -23,6 +28,7 @@ import { module as httpHelperModule } from "../../../generated-defs/helpers/http
|
|
|
23
28
|
import { module as routerModule } from "../../../generated-defs/helpers/router.js";
|
|
24
29
|
import { emitOptionsType } from "../../common/interface.js";
|
|
25
30
|
import { emitTypeReference, isValueLiteralType } from "../../common/reference.js";
|
|
31
|
+
import { JsEmitterOptions } from "../../lib.js";
|
|
26
32
|
import { getAllProperties } from "../../util/extends.js";
|
|
27
33
|
import { bifilter, indent } from "../../util/iter.js";
|
|
28
34
|
import { createOnceQueue } from "../../util/once-queue.js";
|
|
@@ -50,7 +56,7 @@ const COMMON_PATHS = {
|
|
|
50
56
|
vsCodeTasksJson: "./.vscode/tasks.json",
|
|
51
57
|
} as const;
|
|
52
58
|
|
|
53
|
-
function getDefaultTsConfig(standalone: boolean) {
|
|
59
|
+
function getDefaultTsConfig(standalone: boolean, outputSlice: string[]) {
|
|
54
60
|
return {
|
|
55
61
|
compilerOptions: {
|
|
56
62
|
target: "es2020",
|
|
@@ -65,9 +71,7 @@ function getDefaultTsConfig(standalone: boolean) {
|
|
|
65
71
|
declaration: true,
|
|
66
72
|
sourceMap: true,
|
|
67
73
|
},
|
|
68
|
-
include: standalone
|
|
69
|
-
? ["src/**/*.ts"]
|
|
70
|
-
: ["src/**/*.ts", "tsp-output/@typespec/http-server-js/**/*.ts"],
|
|
74
|
+
include: standalone ? ["src/**/*.ts"] : ["src/**/*.ts", `${outputSlice.join("/")}/**/*.ts`],
|
|
71
75
|
} as const;
|
|
72
76
|
}
|
|
73
77
|
|
|
@@ -109,11 +113,16 @@ interface ScaffoldingOptions {
|
|
|
109
113
|
* If true, writes will be forced even if the file or setting already exists. Use with caution.
|
|
110
114
|
*/
|
|
111
115
|
force: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* If true, stop and print a help message.
|
|
118
|
+
*/
|
|
119
|
+
help: boolean;
|
|
112
120
|
}
|
|
113
121
|
|
|
114
122
|
const DEFAULT_SCAFFOLDING_OPTIONS: ScaffoldingOptions = {
|
|
115
123
|
"no-standalone": false,
|
|
116
124
|
force: false,
|
|
125
|
+
help: false,
|
|
117
126
|
};
|
|
118
127
|
|
|
119
128
|
function parseScaffoldArguments(args: string[]): ScaffoldingOptions {
|
|
@@ -127,6 +136,9 @@ function parseScaffoldArguments(args: string[]): ScaffoldingOptions {
|
|
|
127
136
|
options["no-standalone"] = true;
|
|
128
137
|
} else if (arg === "--force") {
|
|
129
138
|
options.force = true;
|
|
139
|
+
} else if (arg === "--help") {
|
|
140
|
+
printHelp();
|
|
141
|
+
process.exit(0);
|
|
130
142
|
} else {
|
|
131
143
|
console.error(`[hsjs] Unrecognized scaffolding argument: '${arg}'`);
|
|
132
144
|
process.exit(1);
|
|
@@ -138,6 +150,17 @@ function parseScaffoldArguments(args: string[]): ScaffoldingOptions {
|
|
|
138
150
|
return { ...DEFAULT_SCAFFOLDING_OPTIONS, ...options };
|
|
139
151
|
}
|
|
140
152
|
|
|
153
|
+
function printHelp() {
|
|
154
|
+
console.info("[hsjs] Project scaffolding for @typespec/http-server-js.");
|
|
155
|
+
console.info("[hsjs] This command generates a TypeScript project for your generated server.");
|
|
156
|
+
console.info("[hsjs] Scaffolding options:");
|
|
157
|
+
console.info(" --force: Force overwrite existing files and settings.");
|
|
158
|
+
console.info(" --help: Show this help message.");
|
|
159
|
+
console.info(
|
|
160
|
+
" --no-standalone: Generate project in current directory (WARNING: highly experimental and likely to fail).",
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
141
164
|
async function confirmYesNo(message: string): Promise<void> {
|
|
142
165
|
const rl = readline.createInterface({
|
|
143
166
|
input: process.stdin,
|
|
@@ -156,8 +179,8 @@ async function confirmYesNo(message: string): Promise<void> {
|
|
|
156
179
|
}
|
|
157
180
|
}
|
|
158
181
|
|
|
159
|
-
export async function scaffold(
|
|
160
|
-
if (
|
|
182
|
+
export async function scaffold(scaffoldingOptions: ScaffoldingOptions) {
|
|
183
|
+
if (scaffoldingOptions.force) {
|
|
161
184
|
await confirmYesNo(
|
|
162
185
|
"[hsjs] The `--force` flag is set and will overwrite existing files and settings that may have been modified. Continue?",
|
|
163
186
|
);
|
|
@@ -173,35 +196,47 @@ export async function scaffold(options: ScaffoldingOptions) {
|
|
|
173
196
|
`[hsjs] Using project file '${path.relative(cwd, projectYamlPath)}' and main file '${path.relative(cwd, mainTspPath)}'`,
|
|
174
197
|
);
|
|
175
198
|
|
|
176
|
-
|
|
199
|
+
const overrides: Partial<ResolveCompilerOptionsOptions["overrides"]> = {
|
|
200
|
+
emit: [],
|
|
201
|
+
};
|
|
177
202
|
|
|
178
|
-
|
|
179
|
-
|
|
203
|
+
const [compilerOptions, diagnostics] = await resolveCompilerOptions(NodeHost, {
|
|
204
|
+
cwd: process.cwd(),
|
|
205
|
+
entrypoint: mainTspPath,
|
|
206
|
+
overrides,
|
|
207
|
+
});
|
|
180
208
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
209
|
+
let hadError = false;
|
|
210
|
+
|
|
211
|
+
for (const diagnostic of diagnostics) {
|
|
212
|
+
hadError ||= diagnostic.severity === "error";
|
|
213
|
+
|
|
214
|
+
console.error(formatDiagnostic(diagnostic, { pathRelativeTo: cwd, pretty: true }));
|
|
187
215
|
}
|
|
188
216
|
|
|
189
|
-
|
|
190
|
-
|
|
217
|
+
if (hadError) {
|
|
218
|
+
console.error("[hsjs] Failed to resolve TypeSpec compiler options. Exiting.");
|
|
219
|
+
process.exit(1);
|
|
220
|
+
}
|
|
191
221
|
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
222
|
+
const emitterOptions = (compilerOptions.options?.["@typespec/http-server-js"] ?? {}) as Partial<
|
|
223
|
+
JsEmitterOptions & { "emitter-output-dir": string }
|
|
224
|
+
>;
|
|
195
225
|
|
|
196
226
|
const emitterOutputDir =
|
|
197
|
-
|
|
198
|
-
path.join(
|
|
227
|
+
emitterOptions["emitter-output-dir"] ??
|
|
228
|
+
path.join(compilerOptions.outputDir ?? "tsp-output", "@typespec", "http-server-js");
|
|
229
|
+
|
|
230
|
+
const baseOutputDir = scaffoldingOptions["no-standalone"] ? cwd : emitterOutputDir;
|
|
199
231
|
|
|
200
|
-
const
|
|
201
|
-
|
|
232
|
+
const outputSlice = path
|
|
233
|
+
.resolve(cwd, emitterOutputDir)
|
|
234
|
+
.replace(cwd, "")
|
|
235
|
+
.split(/[\\/]/)
|
|
236
|
+
.filter((segment) => !!segment);
|
|
202
237
|
|
|
203
238
|
const expressOptions: PackageJsonExpressOptions = {
|
|
204
|
-
isExpress:
|
|
239
|
+
isExpress: emitterOptions.express ?? false,
|
|
205
240
|
openApi3: undefined,
|
|
206
241
|
};
|
|
207
242
|
|
|
@@ -209,7 +244,7 @@ export async function scaffold(options: ScaffoldingOptions) {
|
|
|
209
244
|
`[hsjs] Emitter options have 'express: ${expressOptions.isExpress}'. Generating server model: '${expressOptions.isExpress ? "Express" : "Node"}'.`,
|
|
210
245
|
);
|
|
211
246
|
|
|
212
|
-
if (
|
|
247
|
+
if (scaffoldingOptions["no-standalone"]) {
|
|
213
248
|
console.info("[hsjs] Standalone mode disabled, generating project in current directory.");
|
|
214
249
|
} else {
|
|
215
250
|
console.info("[hsjs] Generating standalone project in output directory.");
|
|
@@ -217,11 +252,7 @@ export async function scaffold(options: ScaffoldingOptions) {
|
|
|
217
252
|
|
|
218
253
|
console.info("[hsjs] Compiling TypeSpec project...");
|
|
219
254
|
|
|
220
|
-
const program = await compile(NodeHost, mainTspPath,
|
|
221
|
-
noEmit: true,
|
|
222
|
-
config: projectYamlPath,
|
|
223
|
-
emit: [],
|
|
224
|
-
});
|
|
255
|
+
const program = await compile(NodeHost, mainTspPath, compilerOptions);
|
|
225
256
|
|
|
226
257
|
const jsCtx = await createInitialContext(program, {
|
|
227
258
|
express: expressOptions.isExpress,
|
|
@@ -238,7 +269,7 @@ export async function scaffold(options: ScaffoldingOptions) {
|
|
|
238
269
|
|
|
239
270
|
const [httpService, httpDiagnostics] = getHttpService(program, jsCtx.service.type);
|
|
240
271
|
|
|
241
|
-
|
|
272
|
+
hadError = false;
|
|
242
273
|
|
|
243
274
|
for (const diagnostic of [...program.diagnostics, ...httpDiagnostics]) {
|
|
244
275
|
hadError = hadError || diagnostic.severity === "error";
|
|
@@ -269,8 +300,8 @@ export async function scaffold(options: ScaffoldingOptions) {
|
|
|
269
300
|
|
|
270
301
|
indexModule.imports.push({
|
|
271
302
|
binder: ["create" + routerName],
|
|
272
|
-
from:
|
|
273
|
-
? "
|
|
303
|
+
from: scaffoldingOptions["no-standalone"]
|
|
304
|
+
? `../${outputSlice.join("/")}/src/generated/http/router.js`
|
|
274
305
|
: "./generated/http/router.js",
|
|
275
306
|
});
|
|
276
307
|
|
|
@@ -309,7 +340,9 @@ export async function scaffold(options: ScaffoldingOptions) {
|
|
|
309
340
|
},
|
|
310
341
|
{
|
|
311
342
|
binder: ["openApiDocument"],
|
|
312
|
-
from: "
|
|
343
|
+
from: scaffoldingOptions["no-standalone"]
|
|
344
|
+
? `../${outputSlice.join("/")}/src/generated/http/openapi3.js`
|
|
345
|
+
: "./generated/http/openapi3.js",
|
|
313
346
|
},
|
|
314
347
|
{
|
|
315
348
|
binder: "type express",
|
|
@@ -381,7 +414,7 @@ export async function scaffold(options: ScaffoldingOptions) {
|
|
|
381
414
|
for (const module of controllerModules) {
|
|
382
415
|
module.imports = module.imports.map((_import) => {
|
|
383
416
|
if (
|
|
384
|
-
|
|
417
|
+
scaffoldingOptions["no-standalone"] &&
|
|
385
418
|
typeof _import.from !== "string" &&
|
|
386
419
|
!controllerModules.has(_import.from)
|
|
387
420
|
) {
|
|
@@ -395,9 +428,7 @@ export async function scaffold(options: ScaffoldingOptions) {
|
|
|
395
428
|
|
|
396
429
|
const targetPath = [
|
|
397
430
|
...backout.slice(1),
|
|
398
|
-
|
|
399
|
-
"@typespec",
|
|
400
|
-
"http-server-js",
|
|
431
|
+
...outputSlice,
|
|
401
432
|
..._import.from.cursor.path.slice(0, -1),
|
|
402
433
|
...(targetIsIndex ? [modulePrincipalName, "index.js"] : [`${modulePrincipalName}.js`]),
|
|
403
434
|
].join("/");
|
|
@@ -412,11 +443,19 @@ export async function scaffold(options: ScaffoldingOptions) {
|
|
|
412
443
|
}
|
|
413
444
|
|
|
414
445
|
// Force writing of http helper module
|
|
415
|
-
await writeModuleFile(
|
|
446
|
+
await writeModuleFile(
|
|
447
|
+
jsCtx,
|
|
448
|
+
scaffoldingOptions["no-standalone"] ? emitterOutputDir : baseOutputDir,
|
|
449
|
+
httpHelperModule,
|
|
450
|
+
queue,
|
|
451
|
+
/* format */ true,
|
|
452
|
+
tryWrite,
|
|
453
|
+
);
|
|
416
454
|
|
|
417
455
|
await tryWrite(
|
|
418
|
-
|
|
419
|
-
JSON.stringify(getDefaultTsConfig(!
|
|
456
|
+
path.resolve(baseOutputDir, COMMON_PATHS.tsConfigJson),
|
|
457
|
+
JSON.stringify(getDefaultTsConfig(!scaffoldingOptions["no-standalone"], outputSlice), null, 2) +
|
|
458
|
+
"\n",
|
|
420
459
|
);
|
|
421
460
|
|
|
422
461
|
const vsCodeLaunchJsonPath = path.resolve(baseOutputDir, COMMON_PATHS.vsCodeLaunchJson);
|
|
@@ -441,10 +480,14 @@ export async function scaffold(options: ScaffoldingOptions) {
|
|
|
441
480
|
|
|
442
481
|
let packageJsonChanged = true;
|
|
443
482
|
|
|
444
|
-
if (
|
|
483
|
+
if (scaffoldingOptions["no-standalone"]) {
|
|
445
484
|
console.info("[hsjs] Checking package.json for changes...");
|
|
446
485
|
|
|
447
|
-
packageJsonChanged = updatePackageJson(
|
|
486
|
+
packageJsonChanged = updatePackageJson(
|
|
487
|
+
ownPackageJson,
|
|
488
|
+
scaffoldingOptions.force,
|
|
489
|
+
externalDependencies,
|
|
490
|
+
);
|
|
448
491
|
|
|
449
492
|
if (packageJsonChanged) {
|
|
450
493
|
console.info("[hsjs] Writing updated package.json...");
|
|
@@ -479,7 +522,7 @@ export async function scaffold(options: ScaffoldingOptions) {
|
|
|
479
522
|
try {
|
|
480
523
|
await spawn("npm", ["install"], {
|
|
481
524
|
stdio: "inherit",
|
|
482
|
-
cwd:
|
|
525
|
+
cwd: scaffoldingOptions["no-standalone"] ? cwd : baseOutputDir,
|
|
483
526
|
shell: process.platform === "win32",
|
|
484
527
|
});
|
|
485
528
|
} catch {
|
|
@@ -494,7 +537,7 @@ export async function scaffold(options: ScaffoldingOptions) {
|
|
|
494
537
|
try {
|
|
495
538
|
await spawn("npm", ["run", "build"], {
|
|
496
539
|
stdio: "inherit",
|
|
497
|
-
cwd:
|
|
540
|
+
cwd: scaffoldingOptions["no-standalone"] ? cwd : baseOutputDir,
|
|
498
541
|
shell: process.platform === "win32",
|
|
499
542
|
});
|
|
500
543
|
} catch {
|
|
@@ -502,7 +545,10 @@ export async function scaffold(options: ScaffoldingOptions) {
|
|
|
502
545
|
process.exit(1);
|
|
503
546
|
}
|
|
504
547
|
|
|
505
|
-
const codeDirectory = path.relative(
|
|
548
|
+
const codeDirectory = path.relative(
|
|
549
|
+
cwd,
|
|
550
|
+
scaffoldingOptions["no-standalone"] ? cwd : baseOutputDir,
|
|
551
|
+
);
|
|
506
552
|
|
|
507
553
|
console.info("[hsjs] Project is ready to run. Use `npm start` to launch the server.");
|
|
508
554
|
console.info("[hsjs] A debug configuration has been created for Visual Studio Code.");
|
|
@@ -523,7 +569,7 @@ export async function scaffold(options: ScaffoldingOptions) {
|
|
|
523
569
|
.then(() => true)
|
|
524
570
|
.catch(() => false);
|
|
525
571
|
|
|
526
|
-
if (exists && !
|
|
572
|
+
if (exists && !scaffoldingOptions.force) {
|
|
527
573
|
console.warn(`[hsjs] File '${relative}' already exists and will not be overwritten.`);
|
|
528
574
|
console.warn(`[hsjs] Manually update the file or delete it and run scaffolding again.`);
|
|
529
575
|
|