Configure eslint for all packages with shared config pkg (#188)

This commit is contained in:
Timothee Guerin 2022-02-22 13:58:17 -08:00 коммит произвёл GitHub
Родитель cf029ac3ad
Коммит 1ef6878f01
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
54 изменённых файлов: 863 добавлений и 273 удалений

3
.vscode/extensions.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,3 @@
{
"recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"]
}

Просмотреть файл

@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@cadl-lang/compiler",
"comment": "",
"type": "none"
}
],
"packageName": "@cadl-lang/compiler"
}

Просмотреть файл

@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@cadl-lang/eslint-config-cadl",
"comment": "",
"type": "none"
}
],
"packageName": "@cadl-lang/eslint-config-cadl"
}

Просмотреть файл

@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@cadl-lang/openapi",
"comment": "",
"type": "none"
}
],
"packageName": "@cadl-lang/openapi"
}

Просмотреть файл

@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@cadl-lang/openapi3",
"comment": "",
"type": "none"
}
],
"packageName": "@cadl-lang/openapi3"
}

Просмотреть файл

@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@cadl-lang/rest",
"comment": "",
"type": "none"
}
],
"packageName": "@cadl-lang/rest"
}

Просмотреть файл

@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@cadl-lang/versioning",
"comment": "",
"type": "none"
}
],
"packageName": "@cadl-lang/versioning"
}

Просмотреть файл

@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "cadl-vscode",
"comment": "",
"type": "none"
}
],
"packageName": "cadl-vscode"
}

Просмотреть файл

@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "tmlanguage-generator",
"comment": "",
"type": "none"
}
],
"packageName": "tmlanguage-generator"
}

Просмотреть файл

@ -61,6 +61,20 @@
"summary": "(CUSTOM) Globally installs local builds of @cadl-lang/compiler and cadl-vscode.",
"shellCommand": "node eng/scripts/dogfood.js"
},
{
"commandKind": "bulk",
"name": "lint",
"summary": "Lint projects. Runs `npm run lint` on all projects.",
"enableParallelism": true,
"ignoreMissingScript": true
},
{
"commandKind": "bulk",
"name": "lint:fix",
"summary": "Fix lint issues in projects. Runs `npm run lint:fix` on all projects.",
"enableParallelism": true,
"ignoreMissingScript": true
},
{
"commandKind": "global",
"safeForSimultaneousRushProcesses": true,

650
common/config/rush/pnpm-lock.yaml сгенерированный

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -25,6 +25,9 @@ steps:
- script: node common/scripts/install-run-rush.js check-format
displayName: Check Formatting
- script: node common/scripts/install-run-rush.js lint
displayName: Lint
- script: cd packages/samples && npm run regen-samples
displayName: Regenerate Samples

Просмотреть файл

@ -12,7 +12,7 @@ granted herein, whether by implication, estoppel or otherwise.
2. brace-expansion version 1.1.11 (https://github.com/juliangruber/brace-expansion)
3. concat-map version 0.0.1 (https://github.com/substack/node-concat-map)
4. lru-cache version 6.0.0 (https://github.com/isaacs/node-lru-cache)
5. minimatch version 3.0.5 (https://github.com/isaacs/minimatch)
5. minimatch version 3.0.4 (https://github.com/isaacs/minimatch)
6. semver version 7.3.5 (https://github.com/npm/node-semver)
7. yallist version 4.0.0 (https://github.com/isaacs/yallist)

Просмотреть файл

@ -104,6 +104,8 @@
"@types/mocha": "~9.1.0",
"@types/node": "~14.0.27",
"@types/vscode": "~1.53.0",
"@cadl-lang/eslint-config-cadl": "~0.1.0",
"eslint": "^8.7.0",
"c8": "~7.11.0",
"mkdirp": "~1.0.4",
"mocha": "~9.2.0",

Просмотреть файл

@ -0,0 +1,5 @@
require("@cadl-lang/eslint-config-cadl/patch/modern-module-resolution");
module.exports = {
extends: "@cadl-lang/eslint-config-cadl",
};

Просмотреть файл

@ -22,7 +22,7 @@ export interface CadlConfig {
emitters: Record<string, boolean>;
}
export type RuleValue = "on" | "off" | {};
export type RuleValue = "on" | "off" | Record<string, unknown>;
/**
* Represent the configuration that can be provided in a config file.

Просмотреть файл

@ -455,7 +455,7 @@ export function createChecker(program: Program): Checker {
function getNodeSymId(
node: ModelStatementNode | AliasStatementNode | InterfaceStatementNode | UnionStatementNode
): number {
return node.symbol?.id!;
return node.symbol!.id!;
}
function getModelName(model: ModelType) {
@ -679,7 +679,7 @@ export function createChecker(program: Program): Checker {
}
function checkUnionExpression(node: UnionExpressionNode): UnionType {
const variants: [string | Symbol, UnionTypeVariant][] = node.options.flatMap((o) => {
const variants: [string | symbol, UnionTypeVariant][] = node.options.flatMap((o) => {
const type = getTypeForNode(o);
// The type `A | never` is just `A`
@ -1509,7 +1509,7 @@ export function createChecker(program: Program): Checker {
const defaultValue = prop.default && checkDefault(getTypeForNode(prop.default), valueType);
const name = prop.id.kind === SyntaxKind.Identifier ? prop.id.sv : prop.id.value;
let type: ModelTypeProperty = createType({
const type: ModelTypeProperty = createType({
kind: "ModelProperty",
name,
node: prop,
@ -1561,7 +1561,6 @@ export function createChecker(program: Program): Checker {
return checkDefaultTypeIsBoolean(defaultType);
case "int32":
case "int64":
case "int32":
case "int16":
case "int8":
case "uint64":
@ -1609,10 +1608,12 @@ export function createChecker(program: Program): Checker {
if (defaultType.value === (option as StringLiteralType).value) {
return defaultType;
}
break;
case "Number":
if (defaultType.value === (option as NumericLiteralType).value) {
return defaultType;
}
break;
}
}
}
@ -2135,7 +2136,7 @@ export function createChecker(program: Program): Checker {
case "Model":
clone = finishType({
...type,
properties: additionalProps.hasOwnProperty("properties")
properties: Object.prototype.hasOwnProperty.call(additionalProps, "properties")
? undefined
: new Map(
Array.from(type.properties.entries()).map(([key, prop]) => [key, cloneType(prop)])
@ -2146,7 +2147,7 @@ export function createChecker(program: Program): Checker {
case "Union":
clone = finishType({
...type,
variants: new Map<string | Symbol, UnionTypeVariant>(
variants: new Map<string | symbol, UnionTypeVariant>(
Array.from(type.variants.entries()).map(([key, prop]) => [
key,
prop.kind === "UnionVariant" ? cloneType(prop) : prop,
@ -2506,7 +2507,7 @@ export function createChecker(program: Program): Checker {
function evalProjectionBlockExpression(node: ProjectionBlockExpressionNode): TypeOrReturnRecord {
let lastVal: Type = voidType;
for (const stmt of node.statements) {
let stmtValue = evalProjectionNode(stmt);
const stmtValue = evalProjectionNode(stmt);
if (stmtValue.kind === "Return") {
return stmtValue;
}
@ -2566,7 +2567,7 @@ export function createChecker(program: Program): Checker {
throw new ProjectionError("need argument for parameter " + node.parameters[i]);
}
let argVal = args[i];
const argVal = args[i];
let typeVal;
if (typeof argVal === "number" || typeof argVal === "string" || typeof argVal === "boolean") {
@ -2695,18 +2696,6 @@ export function createChecker(program: Program): Checker {
} as const);
}
function isLiteralType(
type: Type
): type is StringLiteralType | NumericLiteralType | BooleanLiteralType {
switch (type.kind) {
case "String":
case "Number":
case "Boolean":
return true;
default:
return false;
}
}
function literalTypeToValue(type: StringLiteralType): string;
function literalTypeToValue(type: NumericLiteralType): number;
function literalTypeToValue(type: BooleanLiteralType): boolean;
@ -2753,7 +2742,7 @@ export function createChecker(program: Program): Checker {
return createType({
kind: "Function",
call(...args: Type[]): Type {
let retval = ref.value!({ program }, ...marshalProjectionArguments(args));
ref.value!({ program }, ...marshalProjectionArguments(args));
return voidType;
},
} as const);
@ -2783,7 +2772,7 @@ export function createChecker(program: Program): Checker {
const t: FunctionType = createType({
kind: "Function",
call(...args: Type[]): Type {
let retval = ref.value!(program, ...marshalProjectionArguments(args));
const retval = ref.value!(program, ...marshalProjectionArguments(args));
return marshalProjectionReturn(retval);
},
} as const);

Просмотреть файл

@ -201,12 +201,12 @@ function compileInput(
let compileRequested: boolean = false;
let currentCompilePromise: Promise<Program> | undefined = undefined;
let log = (message?: any, ...optionalParams: any[]) => {
let prefix = compilerOptions.watchForChanges ? `[${new Date().toLocaleTimeString()}] ` : "";
const log = (message?: any, ...optionalParams: any[]) => {
const prefix = compilerOptions.watchForChanges ? `[${new Date().toLocaleTimeString()}] ` : "";
console.log(`${prefix}${message}`, ...optionalParams);
};
let runCompile = () => {
const runCompile = () => {
// Don't run the compiler if it's already running
if (!currentCompilePromise) {
// Clear the console before compiling in watch mode
@ -224,7 +224,7 @@ function compileInput(
return currentCompilePromise;
};
let onCompileFinished = (program: Program) => {
const onCompileFinished = (program: Program) => {
if (program.diagnostics.length > 0) {
log("Diagnostics were reported during compilation:\n");
logDiagnostics(program.diagnostics, NodeHost.logSink);
@ -358,7 +358,7 @@ async function installVsix(pkg: string, install: (vsixPaths: string[]) => void,
// locate .vsix
const dir = joinPaths(temp, "node_modules", pkg);
const files = await readdir(dir);
let vsixPaths: string[] = [];
const vsixPaths: string[] = [];
for (const file of files) {
if (file.endsWith(".vsix")) {
vsixPaths.push(joinPaths(dir, file));

Просмотреть файл

@ -261,8 +261,6 @@ export function compilerAssert(
message: string,
target?: DiagnosticTarget
): asserts condition {
let locationError: Error | undefined;
if (condition) {
return;
}
@ -271,9 +269,7 @@ export function compilerAssert(
let location: SourceLocation | undefined;
try {
location = getSourceLocation(target);
} catch (err: any) {
locationError = err;
}
} catch (err: any) {}
if (location) {
const pos = location.file.getLineAndCharacterOfPosition(location.pos);

Просмотреть файл

@ -1,5 +1,11 @@
import { createDiagnosticCreator } from "./diagnostics.js";
import { CadlLibrary, CadlLibraryDef, CallableMessage, DiagnosticMessages } from "./types.js";
import {
CadlLibrary,
CadlLibraryDef,
CallableMessage,
DecoratorFunction,
DiagnosticMessages,
} from "./types.js";
/**
* Create a new Cadl library definition.
@ -46,6 +52,6 @@ export function paramMessage<T extends string[]>(
return template;
}
export function setDecoratorNamespace(namespace: string, ...decorators: Function[]): void {
export function setDecoratorNamespace(namespace: string, ...decorators: DecoratorFunction[]): void {
decorators.forEach((c: any) => (c.namespace = namespace));
}

Просмотреть файл

@ -51,7 +51,7 @@ export async function resolveModule(
// Check if the module name is referencing a path(./foo, /foo, file:/foo)
if (/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/.test(name)) {
const res = resolvePath(absoluteStart, name);
var m = (await loadAsFile(res)) || (await loadAsDirectory(res));
const m = (await loadAsFile(res)) || (await loadAsDirectory(res));
if (m) return host.realpath(m);
}
@ -86,7 +86,7 @@ export async function resolveModule(
const dirs = getPackageCandidates(name, baseDir);
for (const dir of dirs) {
if (await isDirectory(host, dir)) {
var n = loadAsDirectory(dir);
const n = loadAsDirectory(dir);
if (n) return n;
}
}

Просмотреть файл

@ -122,6 +122,7 @@ interface UndecoratedListKind extends ListKind {
/**
* The fixed set of options for each of the kinds of delimited lists in Cadl.
*/
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace ListKind {
const PropertiesBase = {
allowEmpty: true,
@ -823,7 +824,7 @@ export function parse(code: string | SourceFile, options: ParseOptions = {}): Ca
function parseUnionExpressionOrHigher(): Expression {
const pos = tokenPos();
parseOptional(Token.Bar);
let node: Expression = parseIntersectionExpressionOrHigher();
const node: Expression = parseIntersectionExpressionOrHigher();
if (token() !== Token.Bar) {
return node;
@ -845,7 +846,7 @@ export function parse(code: string | SourceFile, options: ParseOptions = {}): Ca
function parseIntersectionExpressionOrHigher(): Expression {
const pos = tokenPos();
parseOptional(Token.Ampersand);
let node: Expression = parseArrayExpressionOrHigher();
const node: Expression = parseArrayExpressionOrHigher();
if (token() !== Token.Ampersand) {
return node;
@ -2024,7 +2025,7 @@ export function parse(code: string | SourceFile, options: ParseOptions = {}): Ca
// position. The code path taken by error recovery after logging an error
// can otherwise produce redundant and less decipherable errors, which this
// suppresses.
let realPos = report.target?.realPos ?? location.pos;
const realPos = report.target?.realPos ?? location.pos;
if (realPositionOfLastError === realPos) {
return;
}
@ -2298,7 +2299,7 @@ export function visitChildren<T>(node: Node, cb: NodeCb<T>): T | undefined {
// Dummy const to ensure we handle all node types.
// If you get an error here, add a case for the new node type
// you added..
const assertNever: never = node;
const _assertNever: never = node;
return;
}
}

Просмотреть файл

@ -57,10 +57,10 @@ export interface Program {
evalCadlScript(cadlScript: string): void;
onValidate(cb: (program: Program) => void): Promise<void> | void;
getOption(key: string): string | undefined;
stateSet(key: Symbol): Set<Type>;
stateSets: Map<Symbol, Set<Type>>;
stateMap(key: Symbol): Map<Type, any>;
stateMaps: Map<Symbol, Map<Type, any>>;
stateSet(key: symbol): Set<Type>;
stateSets: Map<symbol, Set<Type>>;
stateMap(key: symbol): Map<Type, any>;
stateMaps: Map<symbol, Map<Type, any>>;
hasError(): boolean;
reportDiagnostic(diagnostic: Diagnostic): void;
reportDiagnostics(diagnostics: readonly Diagnostic[]): void;
@ -77,7 +77,7 @@ interface EmitterRef {
class StateMap<V> implements Map<Type, V> {
private internalState = new Map<undefined | Projector, Map<Type, V>>();
constructor(public program: Program, public key: Symbol) {}
constructor(public program: Program, public key: symbol) {}
has(t: Type) {
return this.dispatch(t)?.has(t) ?? false;
@ -138,7 +138,7 @@ class StateMap<V> implements Map<Type, V> {
}
class StateSet implements Set<Type> {
private internalState = new Map<undefined | Projector, Set<Type>>();
constructor(public program: Program, public key: Symbol) {}
constructor(public program: Program, public key: symbol) {}
has(t: Type) {
return this.dispatch(t)?.has(t) ?? false;
@ -200,8 +200,8 @@ export async function createProgram(
options: CompilerOptions = {}
): Promise<Program> {
const validateCbs: any = [];
const stateMaps = new Map<Symbol, StateMap<any>>();
const stateSets = new Map<Symbol, StateSet>();
const stateMaps = new Map<symbol, StateMap<any>>();
const stateSets = new Map<symbol, StateSet>();
const diagnostics: Diagnostic[] = [];
const seenSourceFiles = new Set<string>();
const duplicateSymbols = new Set<Sym>();
@ -307,7 +307,7 @@ export async function createProgram(
diagnosticTarget: DiagnosticTarget | typeof NoTarget
): Promise<string> {
const pkgJsonPath = resolvePath(dir, "package.json");
let [pkg] = await loadFile(host, pkgJsonPath, JSON.parse, program.reportDiagnostic, {
const [pkg] = await loadFile(host, pkgJsonPath, JSON.parse, program.reportDiagnostic, {
allowFileNotFound: true,
diagnosticTarget,
});
@ -338,7 +338,7 @@ export async function createProgram(
path: string,
diagnosticTarget: DiagnosticTarget | typeof NoTarget
): Promise<JsSourceFileNode | undefined> {
let sourceFile = program.jsSourceFiles.get(path);
const sourceFile = program.jsSourceFiles.get(path);
if (sourceFile !== undefined) {
return sourceFile;
}
@ -644,7 +644,7 @@ export async function createProgram(
return (options.miscOptions || {})[key];
}
function stateMap(key: Symbol): StateMap<any> {
function stateMap(key: symbol): StateMap<any> {
let m = stateMaps.get(key);
if (!m) {
@ -655,7 +655,7 @@ export async function createProgram(
return m;
}
function stateSet(key: Symbol): StateSet {
function stateSet(key: symbol): StateSet {
let s = stateSets.get(key);
if (!s) {

Просмотреть файл

@ -6,15 +6,8 @@ import { ObjectType, Type, UnionTypeVariant } from "./types.js";
export function createProjectionMembers(checker: Checker): {
[TKind in Type["kind"]]?: Record<string, (base: Type & { kind: TKind }) => Type>;
} {
const {
voidType,
neverType,
errorType,
createType,
createFunctionType,
createLiteralType,
cloneType,
} = checker;
const { voidType, neverType, createType, createFunctionType, createLiteralType, cloneType } =
checker;
return {
Array: {

Просмотреть файл

@ -21,7 +21,6 @@ import {
function foo() {}
foo();
type DeclScope = NamespaceType | ModelType | InterfaceType | UnionType | EnumType | OperationType;
/**
* Creates a projector which returns a projected view of either the global namespace or the
@ -53,13 +52,13 @@ export function createProjector(
const projectedTypes = new Map<Type, Type>();
const checker = program.checker!;
const neverType = checker.neverType;
let scope: Type[] = [];
const scope: Type[] = [];
const projector: Projector = {
projectedTypes,
projections,
projectType,
};
let projectedNamespaces: NamespaceType[] = [];
const projectedNamespaces: NamespaceType[] = [];
program.currentProjector = projector;
@ -94,6 +93,7 @@ export function createProjector(
switch (type.kind) {
case "Namespace":
compilerAssert(false, "Namespace should have already been projected.");
break;
case "Model":
projected = projectModel(type);
break;
@ -140,7 +140,7 @@ export function createProjector(
const childInterfaces = new Map<string, InterfaceType>();
const childUnions = new Map<string, UnionType>();
const childEnums = new Map<string, EnumType>();
let projectedNs = shallowClone(ns, {
const projectedNs = shallowClone(ns, {
namespaces: childNamespaces,
models: childModels,
operations: childOperations,
@ -218,7 +218,7 @@ export function createProjector(
const properties = new Map<string, ModelTypeProperty>();
let templateArguments: Type[] | undefined;
let projectedModel = shallowClone(model, {
const projectedModel = shallowClone(model, {
properties,
});
@ -294,7 +294,7 @@ export function createProjector(
const returnType = projectType(op.returnType);
const decorators = projectDecorators(op.decorators);
let projectedOp = shallowClone(op, {
const projectedOp = shallowClone(op, {
decorators,
parameters,
returnType,
@ -313,7 +313,7 @@ export function createProjector(
function projectInterface(iface: InterfaceType): Type {
const operations = new Map<string, OperationType>();
const decorators = projectDecorators(iface.decorators);
let projectedIface = shallowClone(iface, {
const projectedIface = shallowClone(iface, {
decorators,
operations,
});
@ -333,10 +333,10 @@ export function createProjector(
}
function projectUnion(union: UnionType) {
const variants = new Map<string | Symbol, UnionTypeVariant>();
const variants = new Map<string | symbol, UnionTypeVariant>();
const decorators = projectDecorators(union.decorators);
let projectedUnion = shallowClone(union, {
const projectedUnion = shallowClone(union, {
decorators,
variants,
});
@ -505,7 +505,7 @@ export function createProjector(
for (const projectionApplication of inScopeProjections) {
const projectionsByName = baseType.projectionsByName(projectionApplication.projectionName);
if (projectionsByName.length === 0) continue;
let targetNode =
const targetNode =
projectionApplication.direction === "from"
? projectionsByName[0].from!
: projectionsByName[0].to!;

Просмотреть файл

@ -545,7 +545,7 @@ export function createScanner(
return scanWhitespace();
}
let cp = input.codePointAt(position)!;
const cp = input.codePointAt(position)!;
if (isNonAsciiIdentifierCharacter(cp)) {
return scanNonAsciiIdentifier(cp);
}
@ -854,7 +854,7 @@ export function createScanner(
let pos = start;
while (pos < end) {
let ch = input.charCodeAt(pos);
const ch = input.charCodeAt(pos);
if (ch !== CharCode.Backslash) {
pos++;
continue;
@ -948,7 +948,7 @@ export function createScanner(
} while (isAsciiIdentifierContinue((ch = input.charCodeAt(position))));
if (ch > CharCode.MaxAscii) {
let cp = input.codePointAt(position)!;
const cp = input.codePointAt(position)!;
if (isNonAsciiIdentifierCharacter(cp)) {
return scanNonAsciiIdentifier(cp);
}
@ -970,7 +970,7 @@ export function createScanner(
export function skipTrivia(input: string, position: number): number {
while (position < input.length) {
let ch = input.charCodeAt(position);
const ch = input.charCodeAt(position);
if (isWhiteSpace(ch)) {
position++;

Просмотреть файл

@ -247,7 +247,7 @@ function navigateType(
default:
// Dummy const to ensure we handle all types.
// If you get an error here, add a case for the new type you added
const assertNever: never = type;
const _assertNever: never = type;
return;
}
}

Просмотреть файл

@ -241,14 +241,14 @@ export interface UnionType extends BaseType, DecoratedType, TemplatedType {
name?: string;
node: UnionExpressionNode | UnionStatementNode;
namespace?: NamespaceType;
variants: Map<string | Symbol, UnionTypeVariant>;
variants: Map<string | symbol, UnionTypeVariant>;
expression: boolean;
readonly options: Type[];
}
export interface UnionTypeVariant extends BaseType, DecoratedType {
kind: "UnionVariant";
name: string | Symbol;
name: string | symbol;
node: UnionVariantNode | undefined;
type: Type;
}
@ -1156,7 +1156,9 @@ export type DiagnosticFormat<
T extends { [code: string]: DiagnosticMessages },
C extends keyof T,
M extends keyof T[C] = "default"
> = T[C][M] extends CallableMessage<infer A> ? { format: Record<A[number], string> } : {};
> = T[C][M] extends CallableMessage<infer A>
? { format: Record<A[number], string> }
: Record<string, unknown>;
export interface DiagnosticDefinition<M extends DiagnosticMessages> {
readonly severity: "warning" | "error";
@ -1236,7 +1238,7 @@ export interface CadlLibrary<
/**
* Get the options for the onEmit of this library.
*/
export type EmitOptionsFor<C> = C extends CadlLibrary<infer T, infer E> ? EmitOptions<E> : never;
export type EmitOptionsFor<C> = C extends CadlLibrary<infer _T, infer E> ? EmitOptions<E> : never;
export interface EmitOptions<E extends string> {
name?: E;

Просмотреть файл

@ -176,6 +176,7 @@ export function resolveRelativeUrlOrPath(base: string, relativeOrAbsolute: strin
* A specially typed version of `Array.isArray` to work around [this issue](https://github.com/microsoft/TypeScript/issues/17002).
*/
export function isArray<T>(
// eslint-disable-next-line @typescript-eslint/ban-types
arg: T | {}
): arg is T extends readonly any[] ? (unknown extends T ? never : readonly any[]) : any[] {
return Array.isArray(arg);

Просмотреть файл

@ -33,7 +33,7 @@ import { isArray } from "../../core/util.js";
import { commentHandler } from "./comment-handler.js";
import { CadlPrettierOptions, DecorableNode, PrettierChildPrint } from "./types.js";
const { align, breakParent, concat, group, hardline, ifBreak, indent, join, line, softline } =
const { align, breakParent, group, hardline, ifBreak, indent, join, line, softline } =
prettier.doc.builders;
const { isNextLineEmpty } = prettier.util;

Просмотреть файл

@ -45,7 +45,9 @@
"test": "mocha",
"test-official": "c8 mocha --forbid-only",
"regen-nonascii": "node scripts/regen-nonascii.js",
"fuzz": "node dist/test/manual/fuzz.js run"
"fuzz": "node dist/test/manual/fuzz.js run",
"lint": "eslint . --ext .ts --max-warnings=0",
"lint:fix": "eslint . --fix --ext .ts"
},
"dependencies": {
"ajv": "~8.9.0",
@ -72,6 +74,8 @@
"@types/prettier": "^2.0.2",
"@types/prompts": "~2.0.14",
"@types/yargs": "~17.0.2",
"@cadl-lang/eslint-config-cadl": "~0.1.0",
"eslint": "^8.7.0",
"grammarkdown": "~3.1.2",
"mocha": "~9.2.0",
"c8": "~7.11.0",

Просмотреть файл

@ -232,7 +232,7 @@ describe("compiler: interfaces", () => {
});
it("doesn't invoke decorators on uninstantiated templates", async () => {
let blues = new WeakSet();
const blues = new WeakSet();
let calls = 0;
testHost.addJsFile("dec.js", {
$blue(p: any, t: Type) {

Просмотреть файл

@ -54,7 +54,7 @@ describe("compiler: models", () => {
});
it("doesn't invoke decorators on uninstantiated templates", async () => {
let blues = new WeakSet();
const blues = new WeakSet();
let calls = 0;
testHost.addJsFile("dec.js", {
$blue(p: any, t: Type) {
@ -159,8 +159,8 @@ describe("compiler: models", () => {
describe("with is", () => {
let testHost: TestHost;
let blues = new WeakSet();
let reds = new WeakSet();
const blues = new WeakSet();
const reds = new WeakSet();
beforeEach(async () => {
testHost = await createTestHost();
testHost.addJsFile("dec.js", {

Просмотреть файл

@ -45,10 +45,10 @@ describe("cadl: projections", () => {
}
`;
let result = (await testProjection(code, [projection("v", 1)])) as ModelType;
const result = (await testProjection(code, [projection("v", 1)])) as ModelType;
strictEqual(result.properties.size, 1);
let result2 = (await testProjection(code, [projection("v", 2)])) as ModelType;
const result2 = (await testProjection(code, [projection("v", 2)])) as ModelType;
strictEqual(result2.properties.size, 2);
});
@ -195,14 +195,14 @@ describe("cadl: projections", () => {
}
`;
let result = (await testProjection(code, [projection("v", 1)])) as ModelType;
const result = (await testProjection(code, [projection("v", 1)])) as ModelType;
strictEqual(result.properties.size, 4);
let resultNested = result.properties.get("e")!.type as ModelType;
const resultNested = result.properties.get("e")!.type as ModelType;
strictEqual(resultNested.properties.size, 1);
let result2 = (await testProjection(code, [projection("v", 2)])) as ModelType;
const result2 = (await testProjection(code, [projection("v", 2)])) as ModelType;
strictEqual(result2.properties.size, 4);
let resultNested2 = result2.properties.get("e")!.type as ModelType;
const resultNested2 = result2.properties.get("e")!.type as ModelType;
strictEqual(resultNested2.properties.size, 2);
});

Просмотреть файл

@ -10,7 +10,7 @@ describe("compiler: union declarations", () => {
});
it("can be declared and decorated", async () => {
let blues = new WeakSet();
const blues = new WeakSet();
testHost.addJsFile("test.js", {
$blue(p: any, t: UnionType | UnionTypeVariant) {
blues.add(t);

Просмотреть файл

@ -186,7 +186,7 @@ function fuzzTest(iterations: number) {
return contents;
}
function repeatBinomial(fn: Function, p: number, opts: { atLeastOnce?: boolean } = {}) {
function repeatBinomial(fn: () => any, p: number, opts: { atLeastOnce?: boolean } = {}) {
if (opts.atLeastOnce) {
fn();
}
@ -196,7 +196,7 @@ function fuzzTest(iterations: number) {
}
}
function roll<T>(opts: Record<keyof T, Function>, weights: Record<keyof T, number>): void {
function roll<T>(opts: Record<keyof T, () => any>, weights: Record<keyof T, number>): void {
let sum = 0;
for (const w of Object.values<number>(weights)) {
sum += w;
@ -217,7 +217,7 @@ function fuzzTest(iterations: number) {
return arr[index];
}
function maybe(fn: Function, p: number) {
function maybe(fn: () => any, p: number) {
if (Math.random() < p) {
fn();
}

Просмотреть файл

@ -117,7 +117,7 @@ describe("compiler: syntax", () => {
]);
parseErrorEach([
["model foo extends { }", [/Identifier expected/]],
["model foo extends bar, baz { }", [/\'{' expected/]],
["model foo extends bar, baz { }", [/'{' expected/]],
["model foo extends = { }", [/Identifier expected/]],
["model foo extends bar = { }", [/'{' expected/]],
]);

Просмотреть файл

@ -0,0 +1,47 @@
module.exports = {
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint/eslint-plugin", "prettier"],
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
env: {
node: true,
es2021: true,
},
rules: {
/**
* Typescript plugin overrides
*/
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-unused-vars": [
"warn",
{ varsIgnorePattern: "^_", argsIgnorePattern: ".*", ignoreRestSiblings: true },
],
/**
* Core
*/
"no-inner-declarations": "off",
"no-empty": "off",
"no-constant-condition": "off",
"no-case-declarations": "off",
"no-ex-assign": "off",
"prefer-const": [
"warn",
{
destructuring: "all",
},
],
},
ignorePatterns: ["dist/**/*", "dist-dev/**/*"],
overrides: [
{
files: ["test/**/*"],
rules: {
"@typescript-eslint/no-non-null-asserted-optional-chain": "off",
},
},
],
};

Просмотреть файл

@ -0,0 +1,27 @@
{
"name": "@cadl-lang/eslint-config-cadl",
"version": "0.1.0",
"description": "ESLint config for cadl packages",
"main": "index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/Microsoft/cadl.git"
},
"bugs": {
"url": "https://github.com/Microsoft/cadl/issues"
},
"scripts": {
"build": "echo 'No build.'"
},
"dependencies": {
"@typescript-eslint/eslint-plugin": "^5.10.0",
"@typescript-eslint/parser": "^5.10.0",
"@rushstack/eslint-patch": "1.1.0 ",
"eslint": "^8.7.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"typescript": "~4.5.5"
},
"author": "",
"license": "ISC"
}

Просмотреть файл

@ -0,0 +1 @@
require("@rushstack/eslint-patch/modern-module-resolution");

Просмотреть файл

@ -0,0 +1,5 @@
require("@cadl-lang/eslint-config-cadl/patch/modern-module-resolution");
module.exports = {
extends: "@cadl-lang/eslint-config-cadl",
};

Просмотреть файл

@ -41,7 +41,9 @@
"build": "tsc -p .",
"watch": "tsc -p . --watch",
"test": "mocha",
"test-official": "c8 mocha --forbid-only"
"test-official": "c8 mocha --forbid-only",
"lint": "eslint . --ext .ts --max-warnings=0",
"lint:fix": "eslint . --fix --ext .ts"
},
"files": [
"lib/*.cadl",
@ -57,6 +59,8 @@
"@types/node": "~14.0.27",
"@cadl-lang/compiler": "~0.28.0",
"@cadl-lang/rest": "~0.11.0",
"@cadl-lang/eslint-config-cadl": "~0.1.0",
"eslint": "^8.7.0",
"mocha": "~9.2.0",
"c8": "~7.11.0",
"rimraf": "~3.0.2",

Просмотреть файл

@ -0,0 +1,5 @@
require("@cadl-lang/eslint-config-cadl/patch/modern-module-resolution");
module.exports = {
extends: "@cadl-lang/eslint-config-cadl",
};

Просмотреть файл

@ -27,7 +27,9 @@
"build": "tsc -p .",
"watch": "tsc -p . --watch",
"test": "mocha",
"test-official": "c8 mocha --forbid-only"
"test-official": "c8 mocha --forbid-only",
"lint": "eslint . --ext .ts --max-warnings=0",
"lint:fix": "eslint . --fix --ext .ts"
},
"files": [
"lib/*.cadl",
@ -47,6 +49,8 @@
"@cadl-lang/rest": "~0.11.0",
"@cadl-lang/openapi": "~0.6.1",
"@cadl-lang/versioning": "~0.3.1",
"@cadl-lang/eslint-config-cadl": "~0.1.0",
"eslint": "^8.7.0",
"mocha": "~9.2.0",
"c8": "~7.11.0",
"rimraf": "~3.0.2",

Просмотреть файл

@ -175,7 +175,6 @@ function createOAPIEmitter(program: Program, options: OpenAPIEmitterOptions) {
// Get the service namespace string for use in name shortening
let serviceNamespace: string | undefined;
let currentBasePath: string | undefined;
let currentPath: any;
let currentEndpoint: any;
@ -220,7 +219,6 @@ function createOAPIEmitter(program: Program, options: OpenAPIEmitterOptions) {
}
serviceNamespace = getServiceNamespaceString(program);
currentBasePath = "";
currentPath = root.paths;
currentEndpoint = undefined;
schemas = new Set();
@ -261,7 +259,7 @@ function createOAPIEmitter(program: Program, options: OpenAPIEmitterOptions) {
emitTags();
// Clean up empty entries
for (let elem of Object.keys(root.components)) {
for (const elem of Object.keys(root.components)) {
if (Object.keys(root.components[elem]).length === 0) {
delete root.components[elem];
}
@ -355,7 +353,7 @@ function createOAPIEmitter(program: Program, options: OpenAPIEmitterOptions) {
function emitResponseObject(responseModel: Type) {
// Get explicity defined status codes
let statusCodes = getResponseStatusCodes(responseModel);
const statusCodes = getResponseStatusCodes(responseModel);
// Get explicitly defined content types
const contentTypes = getResponseContentTypes(responseModel);
@ -684,7 +682,7 @@ function createOAPIEmitter(program: Program, options: OpenAPIEmitterOptions) {
const contentTypes = contentTypeParam
? getContentTypes(contentTypeParam.param)
: ["application/json"];
for (let contentType of contentTypes) {
for (const contentType of contentTypes) {
const isBinary = isBinaryPayload(bodyType, contentType);
const bodySchema = isBinary ? { type: "string", format: "binary" } : getSchemaOrRef(bodyType);
const contentEntry: any = {
@ -721,20 +719,6 @@ function createOAPIEmitter(program: Program, options: OpenAPIEmitterOptions) {
return [];
}
function getModelTypeIfNullable(type: Type): ModelType | undefined {
if (type.kind === "Model") {
return type;
} else if (type.kind === "Union") {
// Remove all `null` types and make sure there's a single model type
const nonNulls = type.options.filter((o) => !isNullType(o));
if (nonNulls.every((t) => t.kind === "Model")) {
return nonNulls.length === 1 ? (nonNulls[0] as ModelType) : undefined;
}
}
return undefined;
}
function emitParameter(parent: ModelType | undefined, param: ModelTypeProperty, kind: string) {
const ph = getParamPlaceholder(parent, param);
currentEndpoint.parameters.push(ph);
@ -752,7 +736,7 @@ function createOAPIEmitter(program: Program, options: OpenAPIEmitterOptions) {
ph.description = getDoc(program, param);
// Apply decorators to the schema for the parameter.
let schema = applyIntrinsicDecorators(param, getSchemaForType(param.type));
const schema = applyIntrinsicDecorators(param, getSchemaForType(param.type));
if (param.type.kind === "Array") {
schema.items = getSchemaForType(param.type.elementType);
}
@ -915,7 +899,6 @@ function createOAPIEmitter(program: Program, options: OpenAPIEmitterOptions) {
return schema;
} else {
const variants = nonNullOptions.map((s) => getSchemaOrRef(s));
const ofType = getOneOf(program, union) ? "oneOf" : "anyOf";
const schema: any = { [ofType]: nonNullOptions.map((s) => getSchemaOrRef(s)) };
return schema;
@ -1010,7 +993,7 @@ function createOAPIEmitter(program: Program, options: OpenAPIEmitterOptions) {
}
// getSchemaOrRef on all children to push them into components.schemas
for (let child of childModels) {
for (const child of childModels) {
getSchemaOrRef(child);
}
@ -1094,13 +1077,13 @@ function createOAPIEmitter(program: Program, options: OpenAPIEmitterOptions) {
function validateDiscriminator(discriminator: any, childModels: ModelType[]): boolean {
const { propertyName } = discriminator;
var retVals = childModels.map((t) => {
const retVals = childModels.map((t) => {
const prop = getProperty(t, propertyName);
if (!prop) {
reportDiagnostic(program, { code: "discriminator", messageId: "missing", target: t });
return false;
}
var retval = true;
let retval = true;
if (!isOasString(prop.type)) {
reportDiagnostic(program, { code: "discriminator", messageId: "type", target: prop });
retval = false;
@ -1113,7 +1096,7 @@ function createOAPIEmitter(program: Program, options: OpenAPIEmitterOptions) {
});
// Map of discriminator value to the model in which it is declared
const discriminatorValues = new Map<string, string>();
for (let t of childModels) {
for (const t of childModels) {
// Get the discriminator property directly in the child model
const prop = t.properties?.get(propertyName);
// Issue warning diagnostic if discriminator property missing or is not a string literal
@ -1153,7 +1136,7 @@ function createOAPIEmitter(program: Program, options: OpenAPIEmitterOptions) {
}
return undefined;
};
var mappings = childModels.flatMap(getMapping).filter((v) => v); // only defined values
const mappings = childModels.flatMap(getMapping).filter((v) => v); // only defined values
return mappings.length > 0 ? mappings.reduce((a, s) => ({ ...a, ...s }), {}) : undefined;
}
@ -1211,7 +1194,7 @@ function createOAPIEmitter(program: Program, options: OpenAPIEmitterOptions) {
}
// Try to shorten the type name to exclude the top-level service namespace
typeName = program!.checker!.getTypeName(type).replace(/<([\w\.]+)>/, "_$1");
typeName = program!.checker!.getTypeName(type).replace(/<([\w.]+)>/, "_$1");
if (isRefSafeName(typeName)) {
if (serviceNamespace) {
@ -1224,15 +1207,6 @@ function createOAPIEmitter(program: Program, options: OpenAPIEmitterOptions) {
return typeName;
}
function hasSchemaProperties(properties: Map<string, ModelTypeProperty>) {
for (const property of properties.values()) {
if (isSchemaProperty(property)) {
return true;
}
}
return false;
}
function applyIntrinsicDecorators(cadlType: Type, target: any): any {
const newTarget = { ...target };
const docStr = getDoc(program, cadlType);

Просмотреть файл

@ -0,0 +1,5 @@
require("@cadl-lang/eslint-config-cadl/patch/modern-module-resolution");
module.exports = {
extends: "@cadl-lang/eslint-config-cadl",
};

Просмотреть файл

@ -41,7 +41,9 @@
"build": "tsc -p .",
"watch": "tsc -p . --watch",
"test": "mocha",
"test-official": "c8 mocha --forbid-only"
"test-official": "c8 mocha --forbid-only",
"lint": "eslint . --ext .ts --max-warnings=0",
"lint:fix": "eslint . --fix --ext .ts"
},
"files": [
"lib/*.cadl",
@ -55,6 +57,8 @@
"@types/mocha": "~9.1.0",
"@types/node": "~14.0.27",
"@cadl-lang/compiler": "~0.28.0",
"@cadl-lang/eslint-config-cadl": "~0.1.0",
"eslint": "^8.7.0",
"mocha": "~9.2.0",
"c8": "~7.11.0",
"rimraf": "~3.0.2",

Просмотреть файл

@ -65,7 +65,7 @@ export function $routeReset({ program }: DecoratorContext, entity: Type, path: s
const routeContainerKey = Symbol();
function addRouteContainer(program: Program, entity: Type): void {
let container = entity.kind === "Operation" ? entity.interface || entity.namespace : entity;
const container = entity.kind === "Operation" ? entity.interface || entity.namespace : entity;
if (!container) {
// Somehow the entity doesn't have a container. This should only happen
// when a type was created manually and not by the checker.
@ -358,7 +358,7 @@ function buildRoutes(
// Build all child routes and append them to the list, but don't recurse in
// the global scope because that could pull in unwanted operations
if (container.kind === "Namespace" && container.name !== "") {
let children: OperationContainer[] = [
const children: OperationContainer[] = [
...container.namespaces.values(),
...container.interfaces.values(),
];
@ -366,7 +366,7 @@ function buildRoutes(
const childRoutes = children.flatMap((child) =>
buildRoutes(program, child, parentFragments, visitedOperations)
);
operations.push.apply(operations, childRoutes);
for (const child of childRoutes) [operations.push(child)];
}
return operations;

Просмотреть файл

@ -0,0 +1,5 @@
require("@cadl-lang/eslint-config-cadl/patch/modern-module-resolution");
module.exports = {
extends: "@cadl-lang/eslint-config-cadl",
};

Просмотреть файл

@ -23,7 +23,9 @@
},
"scripts": {
"build": "tsc -p .",
"watch": "tsc -p . --watch"
"watch": "tsc -p . --watch",
"lint": "eslint . --ext .ts --max-warnings=0",
"lint:fix": "eslint . --fix --ext .ts"
},
"files": [
"dist/**",
@ -36,6 +38,8 @@
"devDependencies": {
"@types/node": "~14.0.27",
"@types/plist": "~3.0.2",
"@cadl-lang/eslint-config-cadl": "~0.1.0",
"eslint": "^8.7.0",
"typescript": "~4.5.5"
}
}

Просмотреть файл

@ -0,0 +1,5 @@
require("@cadl-lang/eslint-config-cadl/patch/modern-module-resolution");
module.exports = {
extends: "@cadl-lang/eslint-config-cadl",
};

Просмотреть файл

@ -41,7 +41,9 @@
"build": "tsc -p .",
"watch": "tsc -p . --watch",
"test": "mocha",
"test-official": "c8 mocha --forbid-only"
"test-official": "c8 mocha --forbid-only",
"lint": "eslint . --ext .ts --max-warnings=0",
"lint:fix": "eslint . --fix --ext .ts"
},
"files": [
"lib/*.cadl",
@ -54,6 +56,8 @@
"devDependencies": {
"@types/mocha": "~9.1.0",
"@types/node": "~14.0.27",
"@cadl-lang/eslint-config-cadl": "~0.1.0",
"eslint": "^8.7.0",
"mocha": "~9.2.0",
"c8": "~7.11.0",
"rimraf": "~3.0.2",

Просмотреть файл

@ -165,7 +165,6 @@ describe("cadl: versioning", () => {
it("can make properties optional", async () => {
const {
source,
projections: [v1, v2],
} = await versionedModel(
["1", "2"],

Просмотреть файл

@ -90,6 +90,12 @@
"reviewCategory": "production",
"shouldPublish": true
},
{
"packageName": "@cadl-lang/eslint-config-cadl",
"projectFolder": "packages/eslint-config-cadl",
"reviewCategory": "production",
"shouldPublish": true
},
{
"packageName": "@cadl-lang/spec",
"projectFolder": "packages/spec",