@allurereport/service 3.0.0-beta.27 → 3.0.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/dist/history.d.ts CHANGED
@@ -1,9 +1,16 @@
1
1
  import type { AllureHistory } from "@allurereport/core-api";
2
2
  import type { AllureServiceClient } from "./service.js";
3
3
  export declare class AllureRemoteHistory implements AllureHistory {
4
- readonly allureServiceClient: AllureServiceClient;
5
- readonly branch?: string | undefined;
6
- constructor(allureServiceClient: AllureServiceClient, branch?: string | undefined);
4
+ readonly params: {
5
+ allureServiceClient: AllureServiceClient;
6
+ branch?: string;
7
+ limit?: number;
8
+ };
9
+ constructor(params: {
10
+ allureServiceClient: AllureServiceClient;
11
+ branch?: string;
12
+ limit?: number;
13
+ });
7
14
  readHistory(): Promise<import("@allurereport/core-api").HistoryDataPoint[]>;
8
15
  appendHistory(): Promise<void>;
9
16
  }
package/dist/history.js CHANGED
@@ -1,15 +1,18 @@
1
1
  import { KnownError } from "./utils/http.js";
2
2
  export class AllureRemoteHistory {
3
- constructor(allureServiceClient, branch) {
4
- this.allureServiceClient = allureServiceClient;
5
- this.branch = branch;
3
+ constructor(params) {
4
+ this.params = params;
6
5
  }
7
6
  async readHistory() {
8
- if (!this.branch) {
7
+ const { allureServiceClient, branch, limit } = this.params;
8
+ if (!branch) {
9
9
  return [];
10
10
  }
11
11
  try {
12
- const res = await this.allureServiceClient.downloadHistory(this.branch);
12
+ const res = await allureServiceClient.downloadHistory({
13
+ branch,
14
+ limit,
15
+ });
13
16
  return res;
14
17
  }
15
18
  catch (err) {
package/dist/service.d.ts CHANGED
@@ -2,19 +2,16 @@ import { type HistoryDataPoint } from "@allurereport/core-api";
2
2
  import { type Config } from "@allurereport/plugin-api";
3
3
  export declare class AllureServiceClient {
4
4
  #private;
5
- readonly config: Config["allureService"] & {
6
- pollingDelay?: number;
7
- };
8
- currentProjectUuid: string | undefined;
9
- constructor(config: Config["allureService"] & {
10
- pollingDelay?: number;
11
- });
12
- setProject(project: string): void;
13
- login(): Promise<any>;
14
- logout(): Promise<void>;
5
+ readonly config: Config["allureService"];
6
+ constructor(config: Config["allureService"]);
7
+ decodeToken(token: string): any;
15
8
  profile(): Promise<{
16
- email: string;
9
+ user: {
10
+ email: string;
11
+ };
12
+ project: any;
17
13
  }>;
14
+ generateNewAccessToken(projectUuid: string): Promise<string>;
18
15
  projects(): Promise<{
19
16
  projects: {
20
17
  id: string;
@@ -27,16 +24,10 @@ export declare class AllureServiceClient {
27
24
  name: string;
28
25
  };
29
26
  }>;
30
- createProject(payload: {
31
- name: string;
32
- }): Promise<{
33
- id: string;
34
- name: string;
35
- }>;
36
- deleteProject(payload: {
37
- id: string;
38
- }): Promise<unknown>;
39
- downloadHistory(branch: string): Promise<HistoryDataPoint[]>;
27
+ downloadHistory(payload: {
28
+ branch: string;
29
+ limit?: number;
30
+ }): Promise<HistoryDataPoint[]>;
40
31
  createReport(payload: {
41
32
  reportName: string;
42
33
  reportUuid?: string;
package/dist/service.js CHANGED
@@ -9,68 +9,50 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _AllureServiceClient_instances, _AllureServiceClient_client, _AllureServiceClient_url, _AllureServiceClient_pollingDelay, _AllureServiceClient_getClientUrl;
12
+ var _AllureServiceClient_client, _AllureServiceClient_url;
13
13
  import { readFile } from "node:fs/promises";
14
14
  import { join as joinPosix } from "node:path/posix";
15
- import open from "open";
16
15
  import { createServiceHttpClient } from "./utils/http.js";
17
- import { decryptExchangeToken, deleteAccessToken, writeAccessToken, writeExchangeToken } from "./utils/token.js";
18
16
  const ASSET_MAX_FILE_SIZE = 200 * 1024 * 1024;
19
17
  export class AllureServiceClient {
20
18
  constructor(config) {
21
- _AllureServiceClient_instances.add(this);
22
19
  this.config = config;
23
20
  _AllureServiceClient_client.set(this, void 0);
24
21
  _AllureServiceClient_url.set(this, void 0);
25
- _AllureServiceClient_pollingDelay.set(this, void 0);
26
- if (!config.url) {
27
- throw new Error("Allure service URL is required!");
22
+ if (!config?.accessToken) {
23
+ throw new Error("Allure service access token is required");
28
24
  }
29
- __classPrivateFieldSet(this, _AllureServiceClient_url, config.url, "f");
30
- __classPrivateFieldSet(this, _AllureServiceClient_client, createServiceHttpClient(__classPrivateFieldGet(this, _AllureServiceClient_url, "f"), config?.accessToken), "f");
31
- __classPrivateFieldSet(this, _AllureServiceClient_pollingDelay, config?.pollingDelay ?? 2500, "f");
32
- this.currentProjectUuid = config?.project;
33
- }
34
- setProject(project) {
35
- this.currentProjectUuid = project;
36
- }
37
- async login() {
38
- const clientUrl = await __classPrivateFieldGet(this, _AllureServiceClient_instances, "m", _AllureServiceClient_getClientUrl).call(this);
39
- const exchangeToken = await writeExchangeToken();
40
- const connectUrl = new URL("/connect", clientUrl);
41
- connectUrl.searchParams.set("token", decryptExchangeToken(exchangeToken));
42
- await open(connectUrl.toString());
43
- let currentExchangeAttemptTimeout;
44
- return await new Promise((res) => {
45
- const makeExchangeAttempt = () => {
46
- return globalThis.setTimeout(async () => {
47
- const token = decryptExchangeToken(exchangeToken);
48
- const { accessToken } = await __classPrivateFieldGet(this, _AllureServiceClient_client, "f").post("/auth/exchange", {
49
- headers: {
50
- "Content-Type": "application/json",
51
- },
52
- body: {
53
- token,
54
- },
55
- });
56
- if (!accessToken) {
57
- globalThis.clearTimeout(currentExchangeAttemptTimeout);
58
- currentExchangeAttemptTimeout = makeExchangeAttempt();
59
- return;
60
- }
61
- await writeAccessToken(accessToken);
62
- return res(accessToken);
63
- }, __classPrivateFieldGet(this, _AllureServiceClient_pollingDelay, "f"));
64
- };
65
- currentExchangeAttemptTimeout = makeExchangeAttempt();
66
- });
25
+ const { iss, projectId, url: baseUrl } = this.decodeToken(config.accessToken) ?? {};
26
+ if (iss !== "allure-service" || !baseUrl || !projectId) {
27
+ throw new Error("Invalid access token");
28
+ }
29
+ __classPrivateFieldSet(this, _AllureServiceClient_url, baseUrl, "f");
30
+ __classPrivateFieldSet(this, _AllureServiceClient_client, createServiceHttpClient(__classPrivateFieldGet(this, _AllureServiceClient_url, "f"), config.accessToken), "f");
67
31
  }
68
- async logout() {
69
- await deleteAccessToken();
32
+ decodeToken(token) {
33
+ try {
34
+ const base64Url = token.split(".")[1];
35
+ const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
36
+ return JSON.parse(atob(base64));
37
+ }
38
+ catch {
39
+ return undefined;
40
+ }
70
41
  }
71
42
  async profile() {
72
- const { user } = await __classPrivateFieldGet(this, _AllureServiceClient_client, "f").get("/user/profile");
73
- return user;
43
+ const { user, project } = await __classPrivateFieldGet(this, _AllureServiceClient_client, "f").get("/user/profile");
44
+ return {
45
+ user,
46
+ project,
47
+ };
48
+ }
49
+ async generateNewAccessToken(projectUuid) {
50
+ const { accessToken } = await __classPrivateFieldGet(this, _AllureServiceClient_client, "f").post("/auth/tokens", {
51
+ body: {
52
+ projectId: projectUuid,
53
+ },
54
+ });
55
+ return accessToken;
74
56
  }
75
57
  async projects() {
76
58
  return __classPrivateFieldGet(this, _AllureServiceClient_client, "f").get("/projects");
@@ -78,30 +60,17 @@ export class AllureServiceClient {
78
60
  async project(uuid) {
79
61
  return __classPrivateFieldGet(this, _AllureServiceClient_client, "f").get(`/projects/${uuid}`);
80
62
  }
81
- async createProject(payload) {
82
- const { project } = await __classPrivateFieldGet(this, _AllureServiceClient_client, "f").post("/projects", {
83
- body: payload,
84
- });
85
- return project;
86
- }
87
- async deleteProject(payload) {
88
- return __classPrivateFieldGet(this, _AllureServiceClient_client, "f").delete(`/projects/${payload.id}`);
89
- }
90
- async downloadHistory(branch) {
91
- if (!this.currentProjectUuid) {
92
- throw new Error("Project is not set");
93
- }
94
- const { history } = await __classPrivateFieldGet(this, _AllureServiceClient_client, "f").get(`/projects/${this.currentProjectUuid}/${branch}/history`);
63
+ async downloadHistory(payload) {
64
+ const { branch, limit } = payload;
65
+ const { history } = await __classPrivateFieldGet(this, _AllureServiceClient_client, "f").get(limit
66
+ ? `/projects/history/${encodeURIComponent(branch)}?limit=${encodeURIComponent(limit.toString())}`
67
+ : `/projects/history/${encodeURIComponent(branch)}`);
95
68
  return history;
96
69
  }
97
70
  async createReport(payload) {
98
71
  const { reportName, reportUuid, branch } = payload;
99
- if (!this.currentProjectUuid) {
100
- throw new Error("Project is not set");
101
- }
102
72
  return __classPrivateFieldGet(this, _AllureServiceClient_client, "f").post("/reports", {
103
73
  body: {
104
- projectUuid: this.currentProjectUuid,
105
74
  reportName,
106
75
  reportUuid,
107
76
  branch,
@@ -110,9 +79,6 @@ export class AllureServiceClient {
110
79
  }
111
80
  async completeReport(payload) {
112
81
  const { reportUuid, historyPoint } = payload;
113
- if (!this.currentProjectUuid) {
114
- throw new Error("Project is not set");
115
- }
116
82
  return __classPrivateFieldGet(this, _AllureServiceClient_client, "f").post(`/reports/${reportUuid}/complete`, {
117
83
  body: {
118
84
  historyPoint,
@@ -121,9 +87,6 @@ export class AllureServiceClient {
121
87
  }
122
88
  async deleteReport(payload) {
123
89
  const { reportUuid, pluginId = "" } = payload;
124
- if (!this.currentProjectUuid) {
125
- throw new Error("Project is not set");
126
- }
127
90
  return __classPrivateFieldGet(this, _AllureServiceClient_client, "f").post(`/reports/${reportUuid}/delete`, {
128
91
  body: {
129
92
  pluginId,
@@ -176,7 +139,4 @@ export class AllureServiceClient {
176
139
  return joinPosix(__classPrivateFieldGet(this, _AllureServiceClient_url, "f"), reportUuid, filename);
177
140
  }
178
141
  }
179
- _AllureServiceClient_client = new WeakMap(), _AllureServiceClient_url = new WeakMap(), _AllureServiceClient_pollingDelay = new WeakMap(), _AllureServiceClient_instances = new WeakSet(), _AllureServiceClient_getClientUrl = async function _AllureServiceClient_getClientUrl() {
180
- const { url } = await __classPrivateFieldGet(this, _AllureServiceClient_client, "f").get("/info");
181
- return url;
182
- };
142
+ _AllureServiceClient_client = new WeakMap(), _AllureServiceClient_url = new WeakMap();
@@ -7,7 +7,7 @@ export declare class UnknownError extends Error {
7
7
  stack?: string;
8
8
  constructor(message: string, stack?: string);
9
9
  }
10
- export declare const createServiceHttpClient: (historyServiceURL?: string, accessToken?: string) => {
10
+ export declare const createServiceHttpClient: (serviceUrl: string, accessToken: string) => {
11
11
  get: <T>(endpoint: string, payload?: AxiosRequestConfig & {
12
12
  params?: Record<string, any>;
13
13
  body?: any;
@@ -1,6 +1,4 @@
1
1
  import axios, { isAxiosError } from "axios";
2
- import { DEFAULT_HISTORY_SERVICE_URL } from "../model.js";
3
- import { readAccessToken } from "./token.js";
4
2
  export class KnownError extends Error {
5
3
  constructor(message, status) {
6
4
  super(message);
@@ -15,20 +13,17 @@ export class UnknownError extends Error {
15
13
  this.stack = stack;
16
14
  }
17
15
  }
18
- export const createServiceHttpClient = (historyServiceURL = DEFAULT_HISTORY_SERVICE_URL, accessToken) => {
16
+ export const createServiceHttpClient = (serviceUrl, accessToken) => {
19
17
  const client = axios.create({
20
- baseURL: historyServiceURL,
18
+ baseURL: serviceUrl,
21
19
  withCredentials: true,
22
20
  validateStatus: (status) => status < 400,
23
21
  });
24
22
  const sendRequest = (method) => async (endpoint, payload) => {
25
- const actualAccessToken = accessToken || (await readAccessToken());
26
23
  const headers = {
27
24
  ...(payload?.headers ?? {}),
25
+ Authorization: `Bearer ${accessToken}`,
28
26
  };
29
- if (actualAccessToken) {
30
- headers.Authorization = `Bearer ${actualAccessToken}`;
31
- }
32
27
  try {
33
28
  let res;
34
29
  if (payload?.body) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allurereport/service",
3
- "version": "3.0.0-beta.27",
3
+ "version": "3.0.1",
4
4
  "description": "Allure Service API",
5
5
  "keywords": [
6
6
  "allure",
@@ -30,8 +30,8 @@
30
30
  "test": "rimraf ./out && vitest run"
31
31
  },
32
32
  "dependencies": {
33
- "@allurereport/core-api": "3.0.0-beta.27",
34
- "@allurereport/plugin-api": "3.0.0-beta.27",
33
+ "@allurereport/core-api": "3.0.1",
34
+ "@allurereport/plugin-api": "3.0.1",
35
35
  "axios": "^1.13.1",
36
36
  "open": "^10.1.0"
37
37
  },
@@ -1,12 +0,0 @@
1
- export declare class InvalidTokenError extends Error {
2
- constructor();
3
- }
4
- export declare class ExpiredTokenError extends Error {
5
- constructor();
6
- }
7
- export declare const generateExchangeToken: () => string;
8
- export declare const decryptExchangeToken: (exchangeToken: string) => string;
9
- export declare const writeExchangeToken: () => Promise<string>;
10
- export declare const writeAccessToken: (token: string) => Promise<void>;
11
- export declare const readAccessToken: () => Promise<string | undefined>;
12
- export declare const deleteAccessToken: () => Promise<void>;
@@ -1,56 +0,0 @@
1
- import { randomBytes } from "node:crypto";
2
- import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
3
- import { EOL } from "node:os";
4
- import { ALLURE_ACCESS_TOKEN_PATH, ALLURE_FILES_DIRNAME, ALLURE_LOGIN_EXCHANGE_TOKEN_PATH } from "../model.js";
5
- export class InvalidTokenError extends Error {
6
- constructor() {
7
- super("Invalid token");
8
- this.name = "InvalidTokenError";
9
- }
10
- }
11
- export class ExpiredTokenError extends Error {
12
- constructor() {
13
- super("Expired token");
14
- this.name = "ExpiredTokenError";
15
- }
16
- }
17
- export const generateExchangeToken = () => {
18
- const token = randomBytes(32).toString("hex");
19
- const validTill = Date.now() + 10 * 60 * 1000;
20
- return Buffer.from(`${token}:${validTill}`, "utf8").toString("base64");
21
- };
22
- export const decryptExchangeToken = (exchangeToken) => {
23
- const [token, validTill] = Buffer.from(exchangeToken, "base64").toString("utf8").split(":");
24
- if (!token) {
25
- throw new InvalidTokenError();
26
- }
27
- if (validTill && parseInt(validTill, 10) < Date.now()) {
28
- throw new ExpiredTokenError();
29
- }
30
- return token;
31
- };
32
- export const writeExchangeToken = async () => {
33
- const tempToken = generateExchangeToken();
34
- await mkdir(ALLURE_FILES_DIRNAME, { recursive: true });
35
- await writeFile(ALLURE_LOGIN_EXCHANGE_TOKEN_PATH, tempToken);
36
- return tempToken;
37
- };
38
- export const writeAccessToken = async (token) => {
39
- await mkdir(ALLURE_FILES_DIRNAME, { recursive: true });
40
- await writeFile(ALLURE_ACCESS_TOKEN_PATH, token);
41
- };
42
- export const readAccessToken = async () => {
43
- try {
44
- const accessToken = await readFile(ALLURE_ACCESS_TOKEN_PATH, "utf-8");
45
- return accessToken.replaceAll(EOL, "").trim();
46
- }
47
- catch (e) {
48
- return undefined;
49
- }
50
- };
51
- export const deleteAccessToken = async () => {
52
- try {
53
- await rm(ALLURE_ACCESS_TOKEN_PATH, { force: true });
54
- }
55
- catch (ignore) { }
56
- };