Configure eslint for all packages with shared config pkg (#188)
This commit is contained in:
Родитель
cf029ac3ad
Коммит
1ef6878f01
|
@ -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,
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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",
|
||||
|
|
Загрузка…
Ссылка в новой задаче