@azure-tools/typespec-azure-core 0.71.0-dev.2 → 0.71.0-dev.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,7 +49,7 @@ Available ruleSets:
49
49
  | [`@azure-tools/typespec-azure-core/no-response-body`](https://azure.github.io/typespec-azure/docs/libraries/azure-core/rules/no-response-body) | Ensure that the body is set correctly for the response type. |
50
50
  | [`@azure-tools/typespec-azure-core/no-rpc-path-params`](https://azure.github.io/typespec-azure/docs/libraries/azure-core/rules/no-rpc-path-params) | Operations defined using RpcOperation should not have path parameters. |
51
51
  | [`@azure-tools/typespec-azure-core/no-openapi`](https://azure.github.io/typespec-azure/docs/libraries/azure-core/rules/no-openapi) | Azure specs should not be using decorators from @typespec/openapi or @azure-tools/typespec-autorest |
52
- | [`@azure-tools/typespec-azure-core/no-unnamed-union`](https://azure.github.io/typespec-azure/docs/libraries/azure-core/rules/no-unnamed-union) | Azure services should not define a union expression but create a declaration. |
52
+ | [`@azure-tools/typespec-azure-core/no-unnamed-types`](https://azure.github.io/typespec-azure/docs/libraries/azure-core/rules/no-unnamed-types) | Azure services should not have anonymous models, union expressions, enum expressions, or scalar expressions. Define them as named declarations. |
53
53
  | [`@azure-tools/typespec-azure-core/no-header-explode`](https://azure.github.io/typespec-azure/docs/libraries/azure-core/rules/no-header-explode) | It is recommended to serialize header parameter without explode: true |
54
54
  | [`@azure-tools/typespec-azure-core/no-format`](https://azure.github.io/typespec-azure/docs/libraries/azure-core/rules/no-format) | Azure services should not use the `@format` decorator. |
55
55
  | [`@azure-tools/typespec-azure-core/no-multiple-discriminator`](https://azure.github.io/typespec-azure/docs/libraries/azure-core/rules/no-multiple-discriminator) | Classes should have at most one discriminator. |
@@ -25,7 +25,7 @@ import { noResponseBodyRule } from "./rules/no-response-body.js";
25
25
  import { noRouteParameterNameMismatchRule } from "./rules/no-route-parameter-name-mismatch.js";
26
26
  import { noRpcPathParamsRule } from "./rules/no-rpc-path-params.js";
27
27
  import { noStringDiscriminatorRule } from "./rules/no-string-discriminator.js";
28
- import { noUnnamedUnionRule } from "./rules/no-unnamed-union.js";
28
+ import { noUnnamedTypesRule } from "./rules/no-unnamed-types.js";
29
29
  import { nonBreakingVersioningRule } from "./rules/non-breaking-versioning.js";
30
30
  import { apiVersionRule } from "./rules/operation-missing-api-version.js";
31
31
  import { preventFormatRule } from "./rules/prevent-format.js";
@@ -61,7 +61,7 @@ const rules = [
61
61
  noResponseBodyRule,
62
62
  noRpcPathParamsRule,
63
63
  noOpenAPIRule,
64
- noUnnamedUnionRule,
64
+ noUnnamedTypesRule,
65
65
  noHeaderExplodeRule,
66
66
  preventFormatRule,
67
67
  noMultipleDiscriminatorRule,
@@ -0,0 +1,4 @@
1
+ export declare const noUnnamedTypesRule: import("@typespec/compiler").LinterRuleDefinition<"no-unnamed-types", {
2
+ readonly default: import("@typespec/compiler").CallableMessage<["type", "type"]>;
3
+ }, Record<string, never>>;
4
+ //# sourceMappingURL=no-unnamed-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-unnamed-types.d.ts","sourceRoot":"","sources":["../../../src/rules/no-unnamed-types.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,kBAAkB;;yBAkF7B,CAAC"}
@@ -0,0 +1,103 @@
1
+ import { createRule, isNullType, paramMessage, } from "@typespec/compiler";
2
+ import { SyntaxKind } from "@typespec/compiler/ast";
3
+ import { getHeaderFieldName, isBody, isBodyRoot, isHeader, isMetadata, isMultipartBodyProperty, isStatusCode, } from "@typespec/http";
4
+ export const noUnnamedTypesRule = createRule({
5
+ name: "no-unnamed-types",
6
+ description: "Azure services should not have anonymous models, union expressions, enum expressions, or scalar expressions. Define them as named declarations.",
7
+ severity: "warning",
8
+ url: "https://azure.github.io/typespec-azure/docs/libraries/azure-core/rules/no-unnamed-types",
9
+ messages: {
10
+ default: paramMessage `Anonymous ${"type"} should be defined as a named ${"type"} declaration.`,
11
+ },
12
+ create(context) {
13
+ const program = context.program;
14
+ // Unions: collect all unnamed unions, then exclude specific patterns.
15
+ const excludedUnions = new Set();
16
+ const invalidUnions = new Set();
17
+ // Models: only flag anonymous models used as property types (inline in model properties).
18
+ const invalidModels = new Set();
19
+ const excludedModels = new Set();
20
+ return {
21
+ modelProperty: (prop) => {
22
+ const type = prop.type;
23
+ // Exclude unions used in status code or content-type header positions.
24
+ if (type.kind === "Union" && !type.name) {
25
+ if (isStatusCode(program, prop) ||
26
+ (isHeader(program, prop) &&
27
+ getHeaderFieldName(program, prop).toLowerCase() === "content-type")) {
28
+ excludedUnions.add(type);
29
+ }
30
+ }
31
+ // Flag anonymous models used as property types.
32
+ if (type.kind === "Model" &&
33
+ type.name === "" &&
34
+ type.properties.size > 0 &&
35
+ !isHttpEnvelope(program, type) &&
36
+ !isInsideTemplateArgument(type) &&
37
+ !isMultipartBodyProperty(program, prop)) {
38
+ invalidModels.add(type);
39
+ }
40
+ // Flag anonymous enums used as property types.
41
+ if (type.kind === "Enum" && !type.name && !isInsideTemplateArgument(type)) {
42
+ context.reportDiagnostic({ target: type, format: { type: "enum" } });
43
+ }
44
+ // Flag anonymous scalars used as property types.
45
+ if (type.kind === "Scalar" && !type.name && !isInsideTemplateArgument(type)) {
46
+ context.reportDiagnostic({ target: type, format: { type: "scalar" } });
47
+ }
48
+ },
49
+ operation: (operation) => {
50
+ // Exclude the top-level return type union (response envelope).
51
+ if (operation.returnType.kind === "Union") {
52
+ excludedUnions.add(operation.returnType);
53
+ }
54
+ },
55
+ union: (union) => {
56
+ if (!union.name && !isOnlyNullableUnion(union)) {
57
+ invalidUnions.add(union);
58
+ }
59
+ },
60
+ exit: () => {
61
+ for (const union of invalidUnions) {
62
+ if (!excludedUnions.has(union)) {
63
+ context.reportDiagnostic({ target: union, format: { type: "union" } });
64
+ }
65
+ }
66
+ for (const model of invalidModels) {
67
+ if (!excludedModels.has(model)) {
68
+ context.reportDiagnostic({ target: model, format: { type: "model" } });
69
+ }
70
+ }
71
+ },
72
+ };
73
+ },
74
+ });
75
+ /** Check if the type's source node is inside a template argument position */
76
+ function isInsideTemplateArgument(type) {
77
+ let node = type.node;
78
+ while (node) {
79
+ if (node.kind === SyntaxKind.TemplateArgument) {
80
+ return true;
81
+ }
82
+ node = node.parent;
83
+ }
84
+ return false;
85
+ }
86
+ function isHttpEnvelope(program, model) {
87
+ for (const property of model.properties.values()) {
88
+ if (isMetadata(program, property) ||
89
+ isStatusCode(program, property) ||
90
+ isBody(program, property) ||
91
+ isBodyRoot(program, property) ||
92
+ isMultipartBodyProperty(program, property)) {
93
+ return true;
94
+ }
95
+ }
96
+ return false;
97
+ }
98
+ /** Check if the union is only there to make the type nullable */
99
+ function isOnlyNullableUnion(union) {
100
+ const nonNullVariants = [...union.variants.values()].filter((v) => !isNullType(v.type));
101
+ return nonNullVariants.length <= 1;
102
+ }
103
+ //# sourceMappingURL=no-unnamed-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-unnamed-types.js","sourceRoot":"","sources":["../../../src/rules/no-unnamed-types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azure-tools/typespec-azure-core",
3
- "version": "0.71.0-dev.2",
3
+ "version": "0.71.0-dev.3",
4
4
  "author": "Microsoft Corporation",
5
5
  "description": "TypeSpec Azure Core library",
6
6
  "homepage": "https://azure.github.io/typespec-azure",
@@ -1,4 +0,0 @@
1
- export declare const noUnnamedUnionRule: import("@typespec/compiler").LinterRuleDefinition<"no-unnamed-union", {
2
- readonly default: import("@typespec/compiler").CallableMessage<[]>;
3
- }, Record<string, never>>;
4
- //# sourceMappingURL=no-unnamed-union.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"no-unnamed-union.d.ts","sourceRoot":"","sources":["../../../src/rules/no-unnamed-union.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,kBAAkB;;yBAoD7B,CAAC"}
@@ -1,57 +0,0 @@
1
- import { createRule, fileRef, paramMessage } from "@typespec/compiler";
2
- import { $ } from "@typespec/compiler/typekit";
3
- import { getHeaderFieldName, isHeader, isStatusCode } from "@typespec/http";
4
- export const noUnnamedUnionRule = createRule({
5
- name: "no-unnamed-union",
6
- docs: fileRef.fromPackageRoot("src/rules/no-unnamed-union.md"),
7
- description: "Azure services should not define a union expression but create a declaration.",
8
- severity: "warning",
9
- url: "https://azure.github.io/typespec-azure/docs/libraries/azure-core/rules/no-unnamed-union",
10
- messages: {
11
- default: paramMessage `Union expression should be defined as a named union declaration.`,
12
- },
13
- create(context) {
14
- const program = context.program;
15
- const excludedUnions = new Set();
16
- const invalidUnions = new Set();
17
- return {
18
- modelProperty: (prop) => {
19
- const type = prop.type;
20
- if (type.kind !== "Union" || type.name) {
21
- return;
22
- }
23
- if (isStatusCode(program, prop) ||
24
- (isHeader(program, prop) &&
25
- getHeaderFieldName(program, prop).toLowerCase() === "content-type")) {
26
- excludedUnions.add(type);
27
- }
28
- },
29
- operation: (operation) => {
30
- if (operation.returnType.kind === "Union") {
31
- excludedUnions.add(operation.returnType);
32
- }
33
- },
34
- union: (union) => {
35
- if (union.kind === "Union" && !union.name && !isOnlyNullableUnion(program, union)) {
36
- invalidUnions.add(union);
37
- }
38
- },
39
- exit: () => {
40
- for (const union of invalidUnions) {
41
- if (!excludedUnions.has(union)) {
42
- context.reportDiagnostic({
43
- format: { enumName: union.name },
44
- target: union,
45
- codefixes: [],
46
- });
47
- }
48
- }
49
- },
50
- };
51
- },
52
- });
53
- /** Check if the union is only there to make the type nullable */
54
- function isOnlyNullableUnion(program, union) {
55
- return ([...union.variants.values()].filter((v) => v.type !== $(program).intrinsic.null).length === 1);
56
- }
57
- //# sourceMappingURL=no-unnamed-union.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"no-unnamed-union.js","sourceRoot":"","sources":["../../../src/rules/no-unnamed-union.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAkB,MAAM,oBAAoB,CAAC;AACvF,OAAO,EAAE,CAAC,EAAE,MAAM,4BAA4B,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE5E,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC;IAC3C,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE,OAAO,CAAC,eAAe,CAAC,+BAA+B,CAAC;IAC9D,WAAW,EAAE,+EAA+E;IAC5F,QAAQ,EAAE,SAAS;IACnB,GAAG,EAAE,yFAAyF;IAC9F,QAAQ,EAAE;QACR,OAAO,EAAE,YAAY,CAAA,kEAAkE;KACxF;IACD,MAAM,CAAC,OAAO;QACZ,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAChC,MAAM,cAAc,GAAG,IAAI,GAAG,EAAS,CAAC;QACxC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAS,CAAC;QAEvC,OAAO;YACL,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE;gBACtB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;gBACvB,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;oBACvC,OAAO;gBACT,CAAC;gBAED,IACE,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC;oBAC3B,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;wBACtB,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,cAAc,CAAC,EACrE,CAAC;oBACD,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC3B,CAAC;YACH,CAAC;YACD,SAAS,EAAE,CAAC,SAAS,EAAE,EAAE;gBACvB,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC1C,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;YACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;gBACf,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;oBAClF,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAC3B,CAAC;YACH,CAAC;YACD,IAAI,EAAE,GAAG,EAAE;gBACT,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;oBAClC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;wBAC/B,OAAO,CAAC,gBAAgB,CAAC;4BACvB,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE;4BAChC,MAAM,EAAE,KAAK;4BACb,SAAS,EAAE,EAAE;yBACd,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC;AAEH,iEAAiE;AACjE,SAAS,mBAAmB,CAAC,OAAgB,EAAE,KAAY;IACzD,OAAO,CACL,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAC9F,CAAC;AACJ,CAAC"}