@typespec/spec-coverage-sdk 0.1.0-alpha.9 → 0.1.0-dev.1

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 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(manifest: ScenarioManifest | ScenarioManifest[]): Promise<void>;
18
- get(): Promise<ScenarioManifest[]>;
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;
@@ -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;AAC7B,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;;gBAIrB,SAAS,EAAE,eAAe;IAKzB,MAAM,CAAC,QAAQ,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAStE,GAAG,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAGhD;AAED,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"}
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 this.#blob.upload(content, content.length, {
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 get() {
33
- return readJsonBlob(this.#blob);
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
- const body = await blob.blobBody;
117
- const content = await body.text();
118
- return JSON.parse(content);
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
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare const GeneratorMode: string[];
1
+ export {};
2
2
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,EAAE,MAAM,EAA0B,CAAC"}
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 const GeneratorMode = ["azure", "standard"];
1
+ export {};
2
2
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC"}
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
@@ -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,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
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
@@ -1,3 +1,2 @@
1
1
  export { SpecCoverageClient, SpecCoverageOperations, SpecManifestOperations } from "./client.js";
2
- export { GeneratorMode } from "./constants.js";
3
2
  //# sourceMappingURL=index.js.map
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;AACjG,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,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;
@@ -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;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB,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"}
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-alpha.9",
3
+ "version": "0.1.0-dev.1",
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.10.1",
22
- "@azure/storage-blob": "~12.27.0",
23
- "@types/node": "~24.1.0"
21
+ "@azure/identity": "~4.13.0",
22
+ "@azure/storage-blob": "~12.31.0",
23
+ "@types/node": "~25.5.0",
24
+ "@types/semver": "^7.7.1",
25
+ "semver": "^7.7.4"
24
26
  },
25
27
  "devDependencies": {
26
- "rimraf": "~6.0.1",
27
- "typescript": "~5.8.2"
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(manifest: ScenarioManifest | ScenarioManifest[]): Promise<void> {
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 this.#blob.upload(content, content.length, {
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 get(): Promise<ScenarioManifest[]> {
63
- return readJsonBlob<ScenarioManifest[]>(this.#blob);
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
- const body = await blob.blobBody;
172
- const content = await body!.text();
173
- return JSON.parse(content);
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
@@ -1,5 +1,4 @@
1
1
  export { SpecCoverageClient, SpecCoverageOperations, SpecManifestOperations } from "./client.js";
2
- export { GeneratorMode } from "./constants.js";
3
2
  export {
4
3
  CoverageReport,
5
4
  GeneratorMetadata,
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 = {