@typespec/spec-coverage-sdk 0.1.0-alpha.9 → 0.1.0-dev.0
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/CHANGELOG.md +61 -0
- package/dist/client.d.ts +4 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +70 -9
- package/dist/client.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +10 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +9 -8
- package/src/client.ts +77 -9
- package/src/constants.ts +0 -1
- package/src/index.ts +0 -1
- package/src/types.ts +10 -1
- package/temp/.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,66 @@
|
|
|
1
1
|
# Change Log - @typespec/spec-coverage-sdk
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.16
|
|
4
|
+
|
|
5
|
+
### Bump dependencies
|
|
6
|
+
|
|
7
|
+
- [#9838](https://github.com/microsoft/typespec/pull/9838) Upgrade dependencies
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
- [#9752](https://github.com/microsoft/typespec/pull/9752) Update to how coverage manifest are managed. The manifest upload each individual one as a single file
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## 0.1.0-alpha.15
|
|
15
|
+
|
|
16
|
+
### Bump dependencies
|
|
17
|
+
|
|
18
|
+
- [#9446](https://github.com/microsoft/typespec/pull/9446) Upgrade dependencies
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## 0.1.0-alpha.14
|
|
22
|
+
|
|
23
|
+
### Bump dependencies
|
|
24
|
+
|
|
25
|
+
- [#9223](https://github.com/microsoft/typespec/pull/9223) Upgrade dependencies
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## 0.1.0-alpha.13
|
|
29
|
+
|
|
30
|
+
### Bump dependencies
|
|
31
|
+
|
|
32
|
+
- [#9046](https://github.com/microsoft/typespec/pull/9046) Upgrade dependencies
|
|
33
|
+
|
|
34
|
+
### Bug Fixes
|
|
35
|
+
|
|
36
|
+
- [#8985](https://github.com/microsoft/typespec/pull/8985) Add new `sourceUrl` handling for the go to source navigation
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
## 0.1.0-alpha.12
|
|
40
|
+
|
|
41
|
+
### Features
|
|
42
|
+
|
|
43
|
+
- [#8938](https://github.com/microsoft/typespec/pull/8938) Resolve packageName and spec display name from spec set package.json
|
|
44
|
+
|
|
45
|
+
### Bump dependencies
|
|
46
|
+
|
|
47
|
+
- [#8823](https://github.com/microsoft/typespec/pull/8823) Upgrade dependencies
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
## 0.1.0-alpha.11
|
|
51
|
+
|
|
52
|
+
### Bump dependencies
|
|
53
|
+
|
|
54
|
+
- [#8437](https://github.com/microsoft/typespec/pull/8437) Upgrade dependencies
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
## 0.1.0-alpha.10
|
|
58
|
+
|
|
59
|
+
### Bump dependencies
|
|
60
|
+
|
|
61
|
+
- [#8317](https://github.com/microsoft/typespec/pull/8317) Upgrade dependencies
|
|
62
|
+
|
|
63
|
+
|
|
3
64
|
## 0.1.0-alpha.9
|
|
4
65
|
|
|
5
66
|
### Bump dependencies
|
package/dist/client.d.ts
CHANGED
|
@@ -14,8 +14,10 @@ export declare class SpecCoverageClient {
|
|
|
14
14
|
export declare class SpecManifestOperations {
|
|
15
15
|
#private;
|
|
16
16
|
constructor(container: ContainerClient);
|
|
17
|
-
upload(
|
|
18
|
-
|
|
17
|
+
upload(name: string, manifest: ScenarioManifest): Promise<void>;
|
|
18
|
+
uploadIfVersionNew(name: string, manifest: ScenarioManifest): Promise<"uploaded" | "skipped">;
|
|
19
|
+
get(name: string, version?: string): Promise<ScenarioManifest>;
|
|
20
|
+
tryGet(name: string, version?: string): Promise<ScenarioManifest | undefined>;
|
|
19
21
|
}
|
|
20
22
|
export declare class SpecCoverageOperations {
|
|
21
23
|
#private;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EACL,mBAAmB,EAGnB,eAAe,EACf,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EACL,mBAAmB,EAGnB,eAAe,EACf,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,qBAAa,kBAAkB;;IAE7B,QAAQ,EAAE,sBAAsB,CAAC;IACjC,QAAQ,EAAE,sBAAsB,CAAC;gBAG/B,kBAAkB,EAAE,MAAM,EAC1B,OAAO,CAAC,EAAE;QACR,UAAU,CAAC,EAAE,0BAA0B,GAAG,mBAAmB,GAAG,eAAe,CAAC;QAChF,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB;IAWU,iBAAiB;CAK/B;AAED,qBAAa,sBAAsB;;gBAGrB,SAAS,EAAE,eAAe;IAIzB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAe/D,kBAAkB,CAC7B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAcrB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAK9D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;CAe3F;AAoBD,qBAAa,sBAAsB;;gBAGrB,SAAS,EAAE,eAAe;IAIzB,MAAM,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBnF,oBAAoB,CAC/B,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC;YA4ChC,WAAW;CAY1B"}
|
package/dist/client.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BlobServiceClient, } from "@azure/storage-blob";
|
|
2
|
+
import { eq as semverEq, gt as semverGt, valid as semverValid } from "semver";
|
|
2
3
|
export class SpecCoverageClient {
|
|
3
4
|
#container;
|
|
4
5
|
manifest;
|
|
@@ -15,23 +16,70 @@ export class SpecCoverageClient {
|
|
|
15
16
|
}
|
|
16
17
|
}
|
|
17
18
|
export class SpecManifestOperations {
|
|
18
|
-
#blob;
|
|
19
19
|
#container;
|
|
20
20
|
constructor(container) {
|
|
21
21
|
this.#container = container;
|
|
22
|
-
this.#blob = this.#container.getBlockBlobClient("manifest.json");
|
|
23
22
|
}
|
|
24
|
-
async upload(manifest) {
|
|
23
|
+
async upload(name, manifest) {
|
|
24
|
+
await this.#upload(name, "latest", manifest);
|
|
25
|
+
await this.#upload(name, manifest.version, manifest);
|
|
26
|
+
}
|
|
27
|
+
async #upload(name, version, manifest) {
|
|
28
|
+
const blob = this.#container.getBlockBlobClient(this.#blobName(name, version));
|
|
25
29
|
const content = JSON.stringify(manifest, null, 2);
|
|
26
|
-
await
|
|
30
|
+
await blob.upload(content, content.length, {
|
|
27
31
|
blobHTTPHeaders: {
|
|
28
32
|
blobContentType: "application/json; charset=utf-8",
|
|
29
33
|
},
|
|
30
34
|
});
|
|
31
35
|
}
|
|
32
|
-
async
|
|
33
|
-
|
|
36
|
+
async uploadIfVersionNew(name, manifest) {
|
|
37
|
+
const existingVersion = await this.tryGet(name, manifest.version);
|
|
38
|
+
if (existingVersion) {
|
|
39
|
+
return "skipped";
|
|
40
|
+
}
|
|
41
|
+
const existingLatest = await this.tryGet(name);
|
|
42
|
+
if (existingLatest && !isVersionNewer(manifest.version, existingLatest.version)) {
|
|
43
|
+
return "skipped";
|
|
44
|
+
}
|
|
45
|
+
await this.upload(name, manifest);
|
|
46
|
+
return "uploaded";
|
|
47
|
+
}
|
|
48
|
+
async get(name, version) {
|
|
49
|
+
const blob = this.#container.getBlockBlobClient(this.#blobName(name, version));
|
|
50
|
+
return readJsonBlob(blob);
|
|
51
|
+
}
|
|
52
|
+
async tryGet(name, version) {
|
|
53
|
+
const blob = this.#container.getBlockBlobClient(this.#blobName(name, version));
|
|
54
|
+
try {
|
|
55
|
+
return await readJsonBlob(blob);
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
if ("code" in e && e.code === "BlobNotFound") {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
throw e;
|
|
62
|
+
}
|
|
34
63
|
}
|
|
64
|
+
#blobName(name, version) {
|
|
65
|
+
return `manifests/${name}/${version ?? "latest"}.json`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function areVersionsEquivalent(left, right) {
|
|
69
|
+
const leftValid = semverValid(left);
|
|
70
|
+
const rightValid = semverValid(right);
|
|
71
|
+
if (leftValid && rightValid) {
|
|
72
|
+
return semverEq(leftValid, rightValid);
|
|
73
|
+
}
|
|
74
|
+
return left === right;
|
|
75
|
+
}
|
|
76
|
+
function isVersionNewer(candidate, existing) {
|
|
77
|
+
const candidateValid = semverValid(candidate);
|
|
78
|
+
const existingValid = semverValid(existing);
|
|
79
|
+
if (candidateValid && existingValid) {
|
|
80
|
+
return semverGt(candidateValid, existingValid);
|
|
81
|
+
}
|
|
82
|
+
return !areVersionsEquivalent(candidate, existing);
|
|
35
83
|
}
|
|
36
84
|
export class SpecCoverageOperations {
|
|
37
85
|
#container;
|
|
@@ -113,8 +161,21 @@ function getCoverageContainer(storageAccountName, credential, containerName) {
|
|
|
113
161
|
}
|
|
114
162
|
async function readJsonBlob(blobClient) {
|
|
115
163
|
const blob = await blobClient.download();
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
164
|
+
if (blob.blobBody) {
|
|
165
|
+
const body = await blob.blobBody;
|
|
166
|
+
const content = await body.text();
|
|
167
|
+
return JSON.parse(content);
|
|
168
|
+
}
|
|
169
|
+
else if (blob.readableStreamBody) {
|
|
170
|
+
const stream = blob.readableStreamBody;
|
|
171
|
+
let content = "";
|
|
172
|
+
for await (const chunk of stream) {
|
|
173
|
+
content += chunk;
|
|
174
|
+
}
|
|
175
|
+
return JSON.parse(content);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
throw new Error("Blob has no body");
|
|
179
|
+
}
|
|
119
180
|
}
|
|
120
181
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,iBAAiB,GAIlB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export {};
|
|
2
2
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":""}
|
package/dist/constants.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export {};
|
|
2
2
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export { SpecCoverageClient, SpecCoverageOperations, SpecManifestOperations } from "./client.js";
|
|
2
|
-
export { GeneratorMode } from "./constants.js";
|
|
3
2
|
export { CoverageReport, GeneratorMetadata, LineAndCharacter, ResolvedCoverageReport, ScenarioData, ScenarioLocation, ScenarioManifest, ScenarioStatus, ScenariosMetadata, } from "./types.js";
|
|
4
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACjG,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACjG,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
export type ScenarioManifest = {
|
|
2
|
+
packageName?: string;
|
|
3
|
+
displayName?: string;
|
|
4
|
+
/** Repository where scenarios live */
|
|
5
|
+
repo?: string;
|
|
6
|
+
/**
|
|
7
|
+
* Template of where the source file lives
|
|
8
|
+
* Interpolate {scenarioPath} with the scenario file path
|
|
9
|
+
* @example "https://github.com/microsoft/typespec/tree/main/packages/http-specs/specs/{scenarioPath}"
|
|
10
|
+
*/
|
|
11
|
+
sourceUrl?: string;
|
|
2
12
|
commit: string;
|
|
3
13
|
version: string;
|
|
4
14
|
scenarios: ScenarioData[];
|
|
5
|
-
setName: string;
|
|
6
15
|
};
|
|
7
16
|
export type ScenarioData = {
|
|
8
17
|
name: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,YAAY,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,gBAAgB,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,gBAAgB,CAAC;IACxB,GAAG,EAAE,gBAAgB,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,cAAc,GAEtB,MAAM,GAEN,MAAM,GAEN,iBAAiB,GAEjB,eAAe,GAEf,gBAAgB,CAAC;AAErB,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,iBAAiB,EAAE,iBAAiB,CAAC;IAErC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAExC;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAuB,SAAQ,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC;IAC5E,iBAAiB,EAAE,iBAAiB,CAAC;CACtC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typespec/spec-coverage-sdk",
|
|
3
|
-
"version": "0.1.0-
|
|
3
|
+
"version": "0.1.0-dev.0",
|
|
4
4
|
"description": "Spec utility to manage the reported coverage",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -18,18 +18,19 @@
|
|
|
18
18
|
},
|
|
19
19
|
"homepage": "https://github.com/microsoft/typespec#readme",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@azure/identity": "~4.
|
|
22
|
-
"@azure/storage-blob": "~12.
|
|
23
|
-
"@types/node": "~
|
|
21
|
+
"@azure/identity": "~4.13.0",
|
|
22
|
+
"@azure/storage-blob": "~12.31.0",
|
|
23
|
+
"@types/node": "~25.3.0",
|
|
24
|
+
"@types/semver": "^7.5.8",
|
|
25
|
+
"semver": "^7.7.1"
|
|
24
26
|
},
|
|
25
27
|
"devDependencies": {
|
|
26
|
-
"rimraf": "~6.
|
|
27
|
-
"typescript": "~5.
|
|
28
|
+
"rimraf": "~6.1.3",
|
|
29
|
+
"typescript": "~5.9.3"
|
|
28
30
|
},
|
|
29
31
|
"scripts": {
|
|
30
32
|
"watch": "tsc -p ./tsconfig.build.json --watch",
|
|
31
33
|
"build": "tsc -p ./tsconfig.build.json",
|
|
32
|
-
"clean": "rimraf dist/ temp/"
|
|
33
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
34
|
+
"clean": "rimraf dist/ temp/"
|
|
34
35
|
}
|
|
35
36
|
}
|
package/src/client.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
ContainerClient,
|
|
7
7
|
StorageSharedKeyCredential,
|
|
8
8
|
} from "@azure/storage-blob";
|
|
9
|
+
import { eq as semverEq, gt as semverGt, valid as semverValid } from "semver";
|
|
9
10
|
import {
|
|
10
11
|
CoverageReport,
|
|
11
12
|
GeneratorMetadata,
|
|
@@ -42,26 +43,82 @@ export class SpecCoverageClient {
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
export class SpecManifestOperations {
|
|
45
|
-
#blob: BlockBlobClient;
|
|
46
46
|
#container: ContainerClient;
|
|
47
47
|
|
|
48
48
|
constructor(container: ContainerClient) {
|
|
49
49
|
this.#container = container;
|
|
50
|
-
this.#blob = this.#container.getBlockBlobClient("manifest.json");
|
|
51
50
|
}
|
|
52
51
|
|
|
53
|
-
public async upload(
|
|
52
|
+
public async upload(name: string, manifest: ScenarioManifest): Promise<void> {
|
|
53
|
+
await this.#upload(name, "latest", manifest);
|
|
54
|
+
await this.#upload(name, manifest.version, manifest);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async #upload(name: string, version: string, manifest: ScenarioManifest): Promise<void> {
|
|
58
|
+
const blob = this.#container.getBlockBlobClient(this.#blobName(name, version));
|
|
54
59
|
const content = JSON.stringify(manifest, null, 2);
|
|
55
|
-
await
|
|
60
|
+
await blob.upload(content, content.length, {
|
|
56
61
|
blobHTTPHeaders: {
|
|
57
62
|
blobContentType: "application/json; charset=utf-8",
|
|
58
63
|
},
|
|
59
64
|
});
|
|
60
65
|
}
|
|
61
66
|
|
|
62
|
-
public async
|
|
63
|
-
|
|
67
|
+
public async uploadIfVersionNew(
|
|
68
|
+
name: string,
|
|
69
|
+
manifest: ScenarioManifest,
|
|
70
|
+
): Promise<"uploaded" | "skipped"> {
|
|
71
|
+
const existingVersion = await this.tryGet(name, manifest.version);
|
|
72
|
+
if (existingVersion) {
|
|
73
|
+
return "skipped";
|
|
74
|
+
}
|
|
75
|
+
const existingLatest = await this.tryGet(name);
|
|
76
|
+
if (existingLatest && !isVersionNewer(manifest.version, existingLatest.version)) {
|
|
77
|
+
return "skipped";
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
await this.upload(name, manifest);
|
|
81
|
+
return "uploaded";
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public async get(name: string, version?: string): Promise<ScenarioManifest> {
|
|
85
|
+
const blob = this.#container.getBlockBlobClient(this.#blobName(name, version));
|
|
86
|
+
return readJsonBlob<ScenarioManifest>(blob);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public async tryGet(name: string, version?: string): Promise<ScenarioManifest | undefined> {
|
|
90
|
+
const blob = this.#container.getBlockBlobClient(this.#blobName(name, version));
|
|
91
|
+
try {
|
|
92
|
+
return await readJsonBlob<ScenarioManifest>(blob);
|
|
93
|
+
} catch (e: any) {
|
|
94
|
+
if ("code" in e && e.code === "BlobNotFound") {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
throw e;
|
|
98
|
+
}
|
|
64
99
|
}
|
|
100
|
+
|
|
101
|
+
#blobName(name: string, version?: string) {
|
|
102
|
+
return `manifests/${name}/${version ?? "latest"}.json`;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function areVersionsEquivalent(left: string, right: string): boolean {
|
|
107
|
+
const leftValid = semverValid(left);
|
|
108
|
+
const rightValid = semverValid(right);
|
|
109
|
+
if (leftValid && rightValid) {
|
|
110
|
+
return semverEq(leftValid, rightValid);
|
|
111
|
+
}
|
|
112
|
+
return left === right;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function isVersionNewer(candidate: string, existing: string): boolean {
|
|
116
|
+
const candidateValid = semverValid(candidate);
|
|
117
|
+
const existingValid = semverValid(existing);
|
|
118
|
+
if (candidateValid && existingValid) {
|
|
119
|
+
return semverGt(candidateValid, existingValid);
|
|
120
|
+
}
|
|
121
|
+
return !areVersionsEquivalent(candidate, existing);
|
|
65
122
|
}
|
|
66
123
|
|
|
67
124
|
export class SpecCoverageOperations {
|
|
@@ -168,7 +225,18 @@ function getCoverageContainer(
|
|
|
168
225
|
|
|
169
226
|
async function readJsonBlob<T>(blobClient: BlockBlobClient): Promise<T> {
|
|
170
227
|
const blob = await blobClient.download();
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
228
|
+
if (blob.blobBody) {
|
|
229
|
+
const body = await blob.blobBody;
|
|
230
|
+
const content = await body!.text();
|
|
231
|
+
return JSON.parse(content);
|
|
232
|
+
} else if (blob.readableStreamBody) {
|
|
233
|
+
const stream = blob.readableStreamBody;
|
|
234
|
+
let content = "";
|
|
235
|
+
for await (const chunk of stream) {
|
|
236
|
+
content += chunk;
|
|
237
|
+
}
|
|
238
|
+
return JSON.parse(content);
|
|
239
|
+
} else {
|
|
240
|
+
throw new Error("Blob has no body");
|
|
241
|
+
}
|
|
174
242
|
}
|
package/src/constants.ts
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const GeneratorMode: string[] = ["azure", "standard"];
|
package/src/index.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
export type ScenarioManifest = {
|
|
2
|
+
packageName?: string;
|
|
3
|
+
displayName?: string;
|
|
4
|
+
/** Repository where scenarios live */
|
|
5
|
+
repo?: string;
|
|
6
|
+
/**
|
|
7
|
+
* Template of where the source file lives
|
|
8
|
+
* Interpolate {scenarioPath} with the scenario file path
|
|
9
|
+
* @example "https://github.com/microsoft/typespec/tree/main/packages/http-specs/specs/{scenarioPath}"
|
|
10
|
+
*/
|
|
11
|
+
sourceUrl?: string;
|
|
2
12
|
commit: string;
|
|
3
13
|
version: string;
|
|
4
14
|
scenarios: ScenarioData[];
|
|
5
|
-
setName: string;
|
|
6
15
|
};
|
|
7
16
|
|
|
8
17
|
export type ScenarioData = {
|