Skip to content

Commit b52d650

Browse files
Init template can define a project kind which decide if dependencies are added to peer or regular dependencies (#6923)
fix [#6602](#6602)
1 parent 44187f8 commit b52d650

File tree

7 files changed

+77
-23
lines changed

7 files changed

+77
-23
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
3+
changeKind: feature
4+
packages:
5+
- "@typespec/compiler"
6+
---
7+
8+
Init templates can define a project kind which decide if dependencies are added to peer or regular dependencies

packages/compiler/.scripts/build-init-templates.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ const builtInTemplates: Record<string, InitTemplate> = {
8383
files: [...(await localDir("rest"))],
8484
},
8585
"library-ts": {
86+
target: "library",
8687
title: "TypeSpec library",
8788
description: "Build your own TypeSpec library with custom types, decorators or linters.",
8889
compilerVersion: minCompilerVersion,
@@ -94,6 +95,7 @@ const builtInTemplates: Record<string, InitTemplate> = {
9495
],
9596
},
9697
"emitter-ts": {
98+
target: "library",
9799
title: "TypeSpec emitter",
98100
description: "Create a new package that emits artifacts from TypeSpec.",
99101
compilerVersion: minCompilerVersion,

packages/compiler/src/init/init-template.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ export interface InitTemplateInput {
1515
}
1616

1717
export interface InitTemplate {
18+
/**
19+
* The kind of project this tempolate initialize. This will change things like where dependencies are added.
20+
* For example, a library will add dependencies to `peer` and `dev` dependencies, while a project will add them to `dependencies`.
21+
* @default "project"
22+
*/
23+
target?: "library" | "project";
24+
1825
/**
1926
* Name of the template
2027
*/
@@ -114,6 +121,7 @@ export const InitTemplateSchema: JSONSchemaType<InitTemplate> = {
114121
properties: {
115122
title: { type: "string" },
116123
description: { type: "string" },
124+
target: { type: "string", enum: ["library", "project"], default: "project", nullable: true },
117125
compilerVersion: { type: "string", nullable: true },
118126
libraries: {
119127
type: "array",

packages/compiler/src/init/scaffold.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,33 +109,35 @@ async function writePackageJson(host: SystemHost, config: ScaffoldingConfig) {
109109
if (isFileSkipGeneration("package.json", config.template.files ?? [])) {
110110
return;
111111
}
112-
const peerDependencies: Record<string, string> = {};
113-
const devDependencies: Record<string, string> = {};
112+
113+
const dependencies: Record<string, string> = {};
114114

115115
if (!config.template.skipCompilerPackage) {
116-
peerDependencies["@typespec/compiler"] = "latest";
117-
devDependencies["@typespec/compiler"] = "latest";
116+
dependencies["@typespec/compiler"] = "latest";
118117
}
119118

120119
for (const library of config.libraries) {
121-
peerDependencies[library.name] = await getPackageVersion(library);
122-
devDependencies[library.name] = await getPackageVersion(library);
120+
dependencies[library.name] = await getPackageVersion(library);
123121
}
124122

125123
for (const key of Object.keys(config.emitters)) {
126-
peerDependencies[key] = await getPackageVersion(config.emitters[key]);
127-
devDependencies[key] = await getPackageVersion(config.emitters[key]);
124+
dependencies[key] = await getPackageVersion(config.emitters[key]);
128125
}
129126

130127
const packageJson: PackageJson = {
131128
name: config.name,
132129
version: "0.1.0",
133130
type: "module",
134-
peerDependencies,
135-
devDependencies,
136131
private: true,
137132
};
138133

134+
if (config.template.target === "library") {
135+
packageJson.peerDependencies = dependencies;
136+
packageJson.devDependencies = dependencies;
137+
} else {
138+
packageJson.dependencies = dependencies;
139+
}
140+
139141
return host.writeFile(
140142
joinPaths(config.directory, "package.json"),
141143
JSON.stringify(packageJson, null, 2),

packages/compiler/templates/__snapshots__/rest/package.json

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,12 @@
22
"name": "rest",
33
"version": "0.1.0",
44
"type": "module",
5-
"peerDependencies": {
5+
"private": true,
6+
"dependencies": {
67
"@typespec/compiler": "latest",
78
"@typespec/http": "latest",
89
"@typespec/rest": "latest",
910
"@typespec/openapi": "latest",
1011
"@typespec/openapi3": "latest"
11-
},
12-
"devDependencies": {
13-
"@typespec/compiler": "latest",
14-
"@typespec/http": "latest",
15-
"@typespec/rest": "latest",
16-
"@typespec/openapi": "latest",
17-
"@typespec/openapi3": "latest"
18-
},
19-
"private": true
12+
}
2013
}

packages/compiler/templates/scaffolding.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
]
6868
},
6969
"library-ts": {
70+
"target": "library",
7071
"title": "TypeSpec library",
7172
"description": "Build your own TypeSpec library with custom types, decorators or linters.",
7273
"compilerVersion": "1.0.0",
@@ -143,6 +144,7 @@
143144
]
144145
},
145146
"emitter-ts": {
147+
"target": "library",
146148
"title": "TypeSpec emitter",
147149
"description": "Create a new package that emits artifacts from TypeSpec.",
148150
"compilerVersion": "1.0.0",

packages/compiler/test/init/init-template.test.ts

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { deepStrictEqual, ok, strictEqual } from "assert";
1+
import { ok, strictEqual } from "assert";
22
import { beforeEach, describe, expect, it } from "vitest";
33
import { parse } from "yaml";
44
import { InitTemplate } from "../../src/init/init-template.js";
@@ -38,18 +38,40 @@ async function runTemplate(
3838
}
3939

4040
describe("libraries", () => {
41+
it("adds libraries to peer and dev dependencies fields", async () => {
42+
await runTemplate({
43+
target: "library",
44+
libraries: [{ name: "bar" }],
45+
});
46+
47+
const pkgJson = JSON.parse(getOutputFile("package.json")!);
48+
49+
expect(pkgJson.peerDependencies).toEqual({
50+
"@typespec/compiler": "latest",
51+
bar: "latest",
52+
});
53+
expect(pkgJson.devDependencies).toEqual({
54+
"@typespec/compiler": "latest",
55+
bar: "latest",
56+
});
57+
expect(pkgJson.dependencies).toBeUndefined();
58+
});
59+
4160
it("templates can contain specific library versions to use", async () => {
4261
await runTemplate({
62+
target: "library",
4363
libraries: [{ name: "foo", version: "~1.2.3" }, { name: "bar" }],
4464
});
4565

46-
deepStrictEqual(JSON.parse(getOutputFile("package.json")!).peerDependencies, {
66+
const pkgJson = JSON.parse(getOutputFile("package.json")!);
67+
68+
expect(pkgJson.peerDependencies).toEqual({
4769
"@typespec/compiler": "latest",
4870
foo: "~1.2.3",
4971
bar: "latest",
5072
});
5173

52-
deepStrictEqual(JSON.parse(getOutputFile("package.json")!).devDependencies, {
74+
expect(pkgJson.devDependencies).toEqual({
5375
"@typespec/compiler": "latest",
5476
foo: "~1.2.3",
5577
bar: "latest",
@@ -59,6 +81,23 @@ describe("libraries", () => {
5981
});
6082
});
6183

84+
describe("project", () => {
85+
it("adds libraries to dependencies field", async () => {
86+
await runTemplate({
87+
libraries: [{ name: "bar" }],
88+
});
89+
90+
const pkgJson = JSON.parse(getOutputFile("package.json")!);
91+
92+
expect(pkgJson.dependencies).toEqual({
93+
"@typespec/compiler": "latest",
94+
bar: "latest",
95+
});
96+
expect(pkgJson.peerDependencies).toBeUndefined();
97+
expect(pkgJson.devDependencies).toBeUndefined();
98+
});
99+
});
100+
62101
it("can generate .gitignore file by default", async () => {
63102
await runTemplate({});
64103
strictEqual(typeof getOutputFile(".gitignore"), "string");

0 commit comments

Comments
 (0)