Skip to content

Commit dee0040

Browse files
authored
Add LegacyOperations interface and linting rules (#2675)
1 parent b1a79f9 commit dee0040

File tree

11 files changed

+848
-0
lines changed

11 files changed

+848
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
3+
changeKind: fix
4+
packages:
5+
- "@azure-tools/typespec-azure-rulesets"
6+
---
7+
8+
Discourage use of legacy types outside brownfield conversions
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
changeKind: feature
3+
packages:
4+
- "@azure-tools/typespec-azure-resource-manager"
5+
---
6+
7+
Add support for resources with multiple operation paths

packages/typespec-autorest/test/arm/resources.test.ts

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,3 +375,168 @@ it("excludes properties marked @invisible from the resource payload", async () =
375375
required: ["size"],
376376
});
377377
});
378+
379+
it("allows resources with multiple endpoint using LegacyOperations", async () => {
380+
const openApi = await openApiFor(`
381+
@armProviderNamespace
382+
@useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1)
383+
namespace Microsoft.ContosoProviderhub;
384+
385+
using Azure.ResourceManager.Legacy;
386+
387+
/** A ContosoProviderHub resource */
388+
model Employee is TrackedResource<EmployeeProperties> {
389+
...ResourceNameParameter<Employee>;
390+
}
391+
392+
/** Employee properties */
393+
model EmployeeProperties {
394+
/** Age of employee */
395+
age?: int32;
396+
397+
/** City of employee */
398+
city?: string;
399+
400+
/** Profile of employee */
401+
@encode("base64url")
402+
profile?: bytes;
403+
404+
/** The status of the last operation. */
405+
@visibility(Lifecycle.Read)
406+
provisioningState?: ProvisioningState;
407+
}
408+
409+
/** The provisioning state of a resource. */
410+
@lroStatus
411+
union ProvisioningState {
412+
string,
413+
414+
/** The resource create request has been accepted */
415+
Accepted: "Accepted",
416+
417+
/** The resource is being provisioned */
418+
Provisioning: "Provisioning",
419+
420+
/** The resource is updating */
421+
Updating: "Updating",
422+
423+
/** Resource has been created. */
424+
Succeeded: "Succeeded",
425+
426+
/** Resource creation failed. */
427+
Failed: "Failed",
428+
429+
/** Resource creation was canceled. */
430+
Canceled: "Canceled",
431+
432+
/** The resource is being deleted */
433+
Deleting: "Deleting",
434+
}
435+
436+
/** Employee move request */
437+
model MoveRequest {
438+
/** The moving from location */
439+
from: string;
440+
441+
/** The moving to location */
442+
to: string;
443+
}
444+
445+
/** Employee move response */
446+
model MoveResponse {
447+
/** The status of the move */
448+
movingStatus: string;
449+
}
450+
451+
interface Operations extends Azure.ResourceManager.Operations {}
452+
453+
/** A custom error type */
454+
@error
455+
model MyErrorType {
456+
/** error code */
457+
code: string;
458+
459+
/** error message */
460+
message: string;
461+
}
462+
463+
@armResourceOperations
464+
interface OtherOps
465+
extends Azure.ResourceManager.Legacy.LegacyOperations<
466+
ParentParameters = ParentScope,
467+
ResourceTypeParameter = InstanceScope,
468+
ErrorType = MyErrorType
469+
> {}
470+
471+
alias BaseScope = {
472+
...ApiVersionParameter;
473+
...SubscriptionIdParameter;
474+
...Azure.ResourceManager.Legacy.Provider;
475+
...LocationParameter;
476+
};
477+
478+
/** Experiments with scope */
479+
alias InstanceScope = {
480+
@doc("The employee name")
481+
@path
482+
@segment("employees")
483+
employeeName: string;
484+
};
485+
486+
/** The parent scope */
487+
alias ParentScope = {
488+
...BaseScope;
489+
...ParentKeysOf<{
490+
@doc("The employee name")
491+
@path
492+
@segment("employees")
493+
@key
494+
employeeName: string;
495+
}>;
496+
};
497+
498+
@armResourceOperations
499+
interface Employees {
500+
get is OtherOps.Read<Employee>;
501+
otherCreateOrUpdate is ArmResourceCreateOrReplaceAsync<Employee>;
502+
createOrUpdate is OtherOps.CreateOrUpdateAsync<Employee>;
503+
update is OtherOps.CustomPatchAsync<Employee, Employee>;
504+
delete is OtherOps.DeleteAsync<Employee>;
505+
list is OtherOps.List<Employee>;
506+
listBySubscription is ArmListBySubscription<Employee>;
507+
508+
/** A sample resource action that move employee to different location */
509+
move is OtherOps.ActionAsync<Employee, MoveRequest, MoveResponse>;
510+
511+
/** A sample HEAD operation to check resource existence */
512+
checkExistence is ArmResourceCheckExistence<Employee>;
513+
}
514+
`);
515+
ok(
516+
openApi.paths[
517+
"/subscriptions/{subscriptionId}/providers/Microsoft.ContosoProviderhub/employees"
518+
].get,
519+
);
520+
ok(
521+
openApi.paths[
522+
"/subscriptions/{subscriptionId}/providers/Microsoft.ContosoProviderhub/locations/{location}/employees"
523+
].get,
524+
);
525+
const resourceGroupOperations =
526+
openApi.paths[
527+
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContosoProviderhub/employees/{employeeName}"
528+
];
529+
const locationPath =
530+
"/subscriptions/{subscriptionId}/providers/Microsoft.ContosoProviderhub/locations/{location}/employees/{employeeName}";
531+
532+
const locationOperations = openApi.paths[locationPath];
533+
ok(resourceGroupOperations);
534+
ok(locationOperations);
535+
ok(locationOperations.get);
536+
ok(locationOperations.put);
537+
ok(locationOperations.patch);
538+
ok(locationOperations.delete);
539+
ok(openApi.paths[`${locationPath}/move`].post);
540+
ok(resourceGroupOperations.put);
541+
ok(resourceGroupOperations.head);
542+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
import "./managed-identity.tsp";
22
import "./decorator.tsp";
3+
import "./operations.tsp";

0 commit comments

Comments
 (0)