-
Notifications
You must be signed in to change notification settings - Fork 237
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a new init template to setup a library (#2766)
Add a new library template with: - `@alernateName` decorator with some custom diagnostics and tests for it. - a linter rule and 2 rulesets(`recommended` and `all`)
- Loading branch information
1 parent
53aa383
commit 55e232d
Showing
45 changed files
with
702 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
common/changes/@typespec/compiler/library-init-template_2023-12-20-21-48.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"changes": [ | ||
{ | ||
"packageName": "@typespec/compiler", | ||
"comment": "Add a new `tsp init` template for setting up a library", | ||
"type": "none" | ||
} | ||
], | ||
"packageName": "@typespec/compiler" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 5 additions & 7 deletions
12
packages/compiler/templates/__snapshots__/emitter-ts/src/testing/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,8 @@ | ||
import { | ||
createTestLibrary, | ||
findTestPackageRoot, | ||
TypeSpecTestLibrary, | ||
} from "@typespec/compiler/testing"; | ||
import { resolvePath } from "@typespec/compiler"; | ||
import { createTestLibrary, TypeSpecTestLibrary } from "@typespec/compiler/testing"; | ||
import { fileURLToPath } from "url"; | ||
|
||
export const TestLibrary: TypeSpecTestLibrary = createTestLibrary({ | ||
export const EmitterTsTestLibrary: TypeSpecTestLibrary = createTestLibrary({ | ||
name: "emitter-ts", | ||
packageRoot: await findTestPackageRoot(import.meta.url), | ||
packageRoot: resolvePath(fileURLToPath(import.meta.url), "../../../../"), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
packages/compiler/templates/__snapshots__/library-ts/.eslintrc.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
root: true | ||
env: | ||
es2021: true | ||
node: true | ||
extends: | ||
- eslint:recommended | ||
- plugin:@typescript-eslint/recommended | ||
parser: "@typescript-eslint/parser" | ||
parserOptions: | ||
ecmaVersion: latest | ||
sourceType: module | ||
plugins: | ||
- "@typescript-eslint" | ||
rules: {} |
12 changes: 12 additions & 0 deletions
12
packages/compiler/templates/__snapshots__/library-ts/lib/decorators.tsp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import "../dist/src/decorators.js"; | ||
|
||
using TypeSpec.Reflection; | ||
|
||
namespace LibraryTs; | ||
|
||
/** | ||
* __Example Decorator__ | ||
* Provide an alternate name for an operation. | ||
* @param name The alternate name. | ||
*/ | ||
extern dec alternateName(target: Operation, name: valueof string); |
1 change: 1 addition & 0 deletions
1
packages/compiler/templates/__snapshots__/library-ts/lib/main.tsp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
import "./decorators.tsp"; |
40 changes: 40 additions & 0 deletions
40
packages/compiler/templates/__snapshots__/library-ts/package.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
{ | ||
"name": "library-ts", | ||
"version": "0.1.0", | ||
"type": "module", | ||
"main": "dist/src/index.js", | ||
"tspMain": "lib/main.tsp", | ||
"exports": { | ||
".": { | ||
"types": "./dist/src/index.d.ts", | ||
"default": "./dist/src/index.js" | ||
}, | ||
"./testing": { | ||
"types": "./dist/src/testing/index.d.ts", | ||
"default": "./dist/src/testing/index.js" | ||
} | ||
}, | ||
"dependencies": { | ||
"@typespec/compiler": "latest" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "latest", | ||
"@typescript-eslint/eslint-plugin": "^6.0.0", | ||
"@typescript-eslint/parser": "^6.0.0", | ||
"@typespec/library-linter": "latest", | ||
"eslint": "^8.45.0", | ||
"prettier": "^3.0.3", | ||
"typescript": "^5.3.3" | ||
}, | ||
"scripts": { | ||
"build": "tsc && npm run build:tsp", | ||
"watch": "tsc --watch", | ||
"build:tsp": "tsp compile . --warn-as-error --import @typespec/library-linter --no-emit", | ||
"test": "node --test ./dist/test/", | ||
"lint": "eslint src/ test/ --report-unused-disable-directives --max-warnings=0", | ||
"lint:fix": "eslint . --report-unused-disable-directives --fix", | ||
"format": "prettier . --write", | ||
"format:check": "prettier --check ." | ||
}, | ||
"private": true | ||
} |
8 changes: 8 additions & 0 deletions
8
packages/compiler/templates/__snapshots__/library-ts/prettierrc.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
trailingComma: "all" | ||
printWidth: 120 | ||
quoteProps: "consistent" | ||
endOfLine: lf | ||
arrowParens: always | ||
plugins: | ||
- "./node_modules/@typespec/prettier-plugin-typespec/dist/index.js" | ||
overrides: [{ "files": "*.tsp", "options": { "parser": "typespec" } }] |
33 changes: 33 additions & 0 deletions
33
packages/compiler/templates/__snapshots__/library-ts/src/decorators.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { DecoratorContext, Operation, Program } from "@typespec/compiler"; | ||
import { StateKeys, reportDiagnostic } from "./lib.js"; | ||
|
||
export const namespace = "LibraryTs"; | ||
|
||
/** | ||
* __Example implementation of the `@alternateName` decorator.__ | ||
* | ||
* @param context Decorator context. | ||
* @param target Decorator target. Must be an operation. | ||
* @param name Alternate name. | ||
*/ | ||
export function $alternateName(context: DecoratorContext, target: Operation, name: string) { | ||
if (name === "banned") { | ||
reportDiagnostic(context.program, { | ||
code: "banned-alternate-name", | ||
target: context.getArgumentTarget(0)!, | ||
format: { name }, | ||
}); | ||
} | ||
context.program.stateMap(StateKeys.alternateName).set(target, name); | ||
} | ||
|
||
/** | ||
* __Example accessor for the `@alternateName` decorator.__ | ||
* | ||
* @param program TypeSpec program. | ||
* @param target Decorator target. Must be an operation. | ||
* @returns Altenate name if provided on the given operation or undefined | ||
*/ | ||
export function getAlternateName(program: Program, target: Operation): string | undefined { | ||
return program.stateMap(StateKeys.alternateName).get(target); | ||
} |
2 changes: 2 additions & 0 deletions
2
packages/compiler/templates/__snapshots__/library-ts/src/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { getAlternateName } from "./decorators.js"; | ||
export { $lib } from "./lib.js"; |
20 changes: 20 additions & 0 deletions
20
packages/compiler/templates/__snapshots__/library-ts/src/lib.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { createTypeSpecLibrary, paramMessage } from "@typespec/compiler"; | ||
|
||
export const $lib = createTypeSpecLibrary({ | ||
name: "library-ts", | ||
// Define diagnostics for the library. This will provide a typed API to report diagnostic as well as a auto doc generation. | ||
diagnostics: { | ||
"banned-alternate-name": { | ||
severity: "error", | ||
messages: { | ||
default: paramMessage`Banned alternate name "${"name"}".`, | ||
}, | ||
}, | ||
}, | ||
// Defined state keys for storing metadata in decorator. | ||
state: { | ||
alternateName: { description: "alternateName" }, | ||
}, | ||
}); | ||
|
||
export const { reportDiagnostic, createDiagnostic, stateKeys: StateKeys } = $lib; |
14 changes: 14 additions & 0 deletions
14
packages/compiler/templates/__snapshots__/library-ts/src/linter.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { defineLinter } from "@typespec/compiler"; | ||
import { noInterfaceRule } from "./rules/no-interfaces.rule.js"; | ||
|
||
export const $linter = defineLinter({ | ||
rules: [noInterfaceRule], | ||
ruleSets: { | ||
recommended: { | ||
enable: { [`library-ts/${noInterfaceRule.name}`]: true }, | ||
}, | ||
all: { | ||
enable: { [`library-ts/${noInterfaceRule.name}`]: true }, | ||
}, | ||
}, | ||
}); |
19 changes: 19 additions & 0 deletions
19
packages/compiler/templates/__snapshots__/library-ts/src/rules/no-interfaces.rule.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { createRule } from "@typespec/compiler"; | ||
|
||
export const noInterfaceRule = createRule({ | ||
name: "no-interface", | ||
severity: "warning", | ||
description: "Make sure interface are not used.", | ||
messages: { | ||
default: "Interface shouldn't be used with this library. Keep operations at the root.", | ||
}, | ||
create: (context) => { | ||
return { | ||
interface: (iface) => { | ||
context.reportDiagnostic({ | ||
target: iface, | ||
}); | ||
}, | ||
}; | ||
}, | ||
}); |
8 changes: 8 additions & 0 deletions
8
packages/compiler/templates/__snapshots__/library-ts/src/testing/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { resolvePath } from "@typespec/compiler"; | ||
import { createTestLibrary, TypeSpecTestLibrary } from "@typespec/compiler/testing"; | ||
import { fileURLToPath } from "url"; | ||
|
||
export const LibraryTsTestLibrary: TypeSpecTestLibrary = createTestLibrary({ | ||
name: "library-ts", | ||
packageRoot: resolvePath(fileURLToPath(import.meta.url), "../../../../"), | ||
}); |
48 changes: 48 additions & 0 deletions
48
packages/compiler/templates/__snapshots__/library-ts/test/decorators.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { strictEqual } from "node:assert"; | ||
import { describe, it, beforeEach } from "node:test"; | ||
import { Operation } from "@typespec/compiler"; | ||
import { BasicTestRunner, expectDiagnostics, extractCursor } from "@typespec/compiler/testing"; | ||
import { getAlternateName } from "../src/decorators.js"; | ||
import { createLibraryTsTestRunner } from "./test-host.js"; | ||
|
||
describe("decorators", () => { | ||
let runner: BasicTestRunner; | ||
|
||
beforeEach(async () => { | ||
runner = await createLibraryTsTestRunner(); | ||
}) | ||
|
||
describe("@alternateName", () => { | ||
it("set alternate name on operation", async () => { | ||
const { test } = (await runner.compile( | ||
`@alternateName("bar") @test op test(): void;` | ||
)) as { test: Operation }; | ||
strictEqual(getAlternateName(runner.program, test), "bar"); | ||
}); | ||
|
||
it("emit diagnostic if not used on an operation", async () => { | ||
const diagnostics = await runner.diagnose( | ||
`@alternateName("bar") model Test {}` | ||
); | ||
expectDiagnostics(diagnostics, { | ||
severity: "error", | ||
code: "decorator-wrong-target", | ||
message: "Cannot apply @alternateName decorator to Test since it is not assignable to Operation" | ||
}) | ||
}); | ||
|
||
|
||
it("emit diagnostic if using banned name", async () => { | ||
const {pos, source} = extractCursor(`@alternateName(┆"banned") op test(): void;`) | ||
const diagnostics = await runner.diagnose( | ||
source | ||
); | ||
expectDiagnostics(diagnostics, { | ||
severity: "error", | ||
code: "library-ts/banned-alternate-name", | ||
message: `Banned alternate name "banned".`, | ||
pos: pos + runner.autoCodeOffset | ||
}) | ||
}); | ||
}); | ||
}); |
29 changes: 29 additions & 0 deletions
29
packages/compiler/templates/__snapshots__/library-ts/test/rules/no-interfaces.rule.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { | ||
LinterRuleTester, | ||
createLinterRuleTester, | ||
createTestRunner, | ||
} from "@typespec/compiler/testing"; | ||
import { beforeEach, describe, it } from "node:test"; | ||
import { noInterfaceRule } from "../../src/rules/no-interfaces.rule.js"; | ||
|
||
describe("noInterfaceRule", () => { | ||
let ruleTester: LinterRuleTester; | ||
|
||
beforeEach(async () => { | ||
const runner = await createTestRunner(); | ||
ruleTester = createLinterRuleTester(runner, noInterfaceRule, "library-ts"); | ||
}); | ||
|
||
describe("models", () => { | ||
it("emit diagnostics if using interfaces", async () => { | ||
await ruleTester.expect(`interface Test {}`).toEmitDiagnostics({ | ||
code: "library-ts/no-interface", | ||
message: "Interface shouldn't be used with this library. Keep operations at the root.", | ||
}); | ||
}); | ||
|
||
it("should be valid if operation is at the root", async () => { | ||
await ruleTester.expect(`op test(): void;`).toBeValid(); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.