✨ Share with me endpoint (#77)
* 🛠️ remove babel from dependencies * 🛠️ removes some of the redundant dependencies + versions update * ✨ separate endpoint for "shared with me"
This commit is contained in:
@@ -1 +1 @@
|
||||
12
|
||||
18
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [["@babel/preset-env", { targets: { node: "current" } }], "@babel/preset-typescript"],
|
||||
plugins: [
|
||||
["@babel/plugin-proposal-decorators", { legacy: true }],
|
||||
["@babel/plugin-proposal-class-properties", { loose: true }],
|
||||
["@babel/plugin-proposal-private-property-in-object", { loose: true }],
|
||||
"babel-plugin-parameter-decorator",
|
||||
],
|
||||
};
|
||||
Generated
+6499
-5853
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,7 @@
|
||||
"kill": "kill $(lsof -t -i:3000) | exit 0"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "ts-jest",
|
||||
"collectCoverage": true,
|
||||
"coverageReporters": [
|
||||
"json",
|
||||
@@ -57,47 +58,29 @@
|
||||
"tdrive-cli": "bin/tdrive-cli"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.22.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||
"@babel/plugin-proposal-private-property-in-object": "^7.18.6",
|
||||
"@babel/plugin-proposal-decorators": "^7.18.10",
|
||||
"@babel/preset-env": "^7.19.4",
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@types/amqp-connection-manager": "^2.0.10",
|
||||
"@types/analytics-node": "^3.1.5",
|
||||
"@types/archiver": "^5.3.1",
|
||||
"@types/bcrypt": "^5.0.0",
|
||||
"@types/busboy": "^0.2.3",
|
||||
"@types/chai": "^4.2.12",
|
||||
"@types/cli-table": "^0.3.0",
|
||||
"@types/config": "0.0.36",
|
||||
"@types/eslint": "^7.2.3",
|
||||
"@types/fastify-multipart": "^0.7.0",
|
||||
"@types/fastify-static": "^2.2.1",
|
||||
"@types/fluent-ffmpeg": "^2.1.20",
|
||||
"@types/html-to-text": "^8.1.1",
|
||||
"@types/jest": "^29.1.0",
|
||||
"@types/lodash": "^4.14.165",
|
||||
"@types/minio": "^7.0.7",
|
||||
"@types/mongodb": "^4.0.7",
|
||||
"@types/node": "^18.11",
|
||||
"@types/node-cron": "^3.0.0",
|
||||
"@types/node-fetch": "^2.5.12",
|
||||
"@types/node-uuid": "^0.0.28",
|
||||
"@types/pdf-image": "^2.0.1",
|
||||
"@types/pino": "^6.3.2",
|
||||
"@types/probe-image-size": "^7.0.1",
|
||||
"@types/pump": "^1.1.1",
|
||||
"@types/random-useragent": "^0.3.1",
|
||||
"@types/socket.io-client": "^1.4.34",
|
||||
"@types/supertest": "2.0.4",
|
||||
"@types/socket.io-client": "^1.4.36",
|
||||
"@types/uuid": "^8.3.0",
|
||||
"@types/ws": "^7.2.7",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.9",
|
||||
"@typescript-eslint/parser": "^5.59.9",
|
||||
"babel-jest": "^29.1.0",
|
||||
"babel-plugin-parameter-decorator": "^1.0.16",
|
||||
"chai": "^4.2.0",
|
||||
"cpy-cli": "^4.2.0",
|
||||
"eslint": "^8.42.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
@@ -106,17 +89,16 @@
|
||||
"form-auto-content": "^2.2.0",
|
||||
"jest": "^29.1.0",
|
||||
"jest-mock-extended": "^3.0.4",
|
||||
"nodemon": "2.0.4",
|
||||
"nodemon": "^2.0.22",
|
||||
"pino-pretty": "^10.0.0",
|
||||
"prettier": "^2.1.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"supertest": "4.0.2",
|
||||
"ts-jest": "^29.1.0",
|
||||
"ts-node": "^9.0.0",
|
||||
"ts-node-dev": "^1.1.8",
|
||||
"tsc-watch": "^4.2.9",
|
||||
"typescript": "^4.9.5",
|
||||
"tsconfig-paths": "^3.14.1"
|
||||
"tsconfig-paths": "^3.14.1",
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@elastic/elasticsearch": "7",
|
||||
@@ -126,7 +108,7 @@
|
||||
"@ffprobe-installer/ffprobe": "^1.4.1",
|
||||
"@sentry/node": "^6.19.7",
|
||||
"@sentry/tracing": "^6.19.7",
|
||||
"@socket.io/redis-adapter": "^7.1.0",
|
||||
"@socket.io/redis-adapter": "^7.2.0",
|
||||
"@types/http-proxy": "^1.17.11",
|
||||
"@types/pdf-parse": "^1.1.1",
|
||||
"@types/redis": "^4.0.11",
|
||||
@@ -144,7 +126,7 @@
|
||||
"config": "^3.3.2",
|
||||
"deep-object-diff": "^1.1.0",
|
||||
"emoji-name-map": "^1.2.9",
|
||||
"eta": "^1.12.3",
|
||||
"eta": "^2.2.0",
|
||||
"fastify": "^3.29.4",
|
||||
"fastify-cors": "^4.1.0",
|
||||
"fastify-formbody": "^5.0.0",
|
||||
@@ -156,7 +138,6 @@
|
||||
"fastify-static": "^4.7.0",
|
||||
"fastify-swagger": "^4.12.6",
|
||||
"fastify-websocket": "^2.0.11",
|
||||
"find-my-way": "^5.2.0",
|
||||
"fluent-ffmpeg": "^2.1.2",
|
||||
"fold-to-ascii": "^5.0.0",
|
||||
"free-email-domains": "1.0.26",
|
||||
@@ -165,12 +146,10 @@
|
||||
"html-metadata-parser": "^2.0.4",
|
||||
"html-to-text": "^8.2.1",
|
||||
"idtoken-verifier": "^2.2.3",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"jwks-rsa": "^3.0.1",
|
||||
"keyv": "^4.5.0",
|
||||
"lodash": "^4.17.21",
|
||||
"match-all": "^1.2.6",
|
||||
"minio": "^7.0.18",
|
||||
"minio": "7.0.18",
|
||||
"moment": "^2.29.4",
|
||||
"mongodb": "^5.6.0",
|
||||
"multistream": "^4.1.0",
|
||||
@@ -179,7 +158,6 @@
|
||||
"node-cache": "^5.1.2",
|
||||
"node-cron": "^3.0.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"node-uuid": "^1.4.8",
|
||||
"openid-client": "^5.4.0",
|
||||
"ora": "^5.4.0",
|
||||
"pdf-parse": "^1.1.1",
|
||||
@@ -193,7 +171,7 @@
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rxjs": "^6.6.3",
|
||||
"sharp": "^0.30.5",
|
||||
"socket.io": "4",
|
||||
"socket.io": "^4.6.2",
|
||||
"socket.io-client": "^3.0.0",
|
||||
"unoconv-promise": "^1.0.8",
|
||||
"uuid": "^8.3.2",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as cron from "node-cron";
|
||||
import uuid from "node-uuid";
|
||||
import uuid from "uuid";
|
||||
|
||||
import { TdriveService } from "../../framework";
|
||||
import { CronAPI, CronJob, CronExpression, CronTask } from "./api";
|
||||
|
||||
@@ -168,12 +168,12 @@ export const getAccessLevel = async (
|
||||
const prevalidatedPublicTokenDocumentId = context?.user?.public_token_document_id;
|
||||
|
||||
try {
|
||||
item =
|
||||
item ||
|
||||
(await repository.findOne({
|
||||
if (!item) {
|
||||
item = await repository.findOne({
|
||||
id,
|
||||
company_id: context.company.id,
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
if (!item) {
|
||||
throw Error("Drive item doesn't exist");
|
||||
|
||||
@@ -2,8 +2,8 @@ import SearchRepository from "../../../core/platform/services/search/repository"
|
||||
import { getLogger, logger, TdriveLogger } from "../../../core/platform/framework";
|
||||
import { CrudException, ListResult } from "../../../core/platform/framework/api/crud-service";
|
||||
import Repository, {
|
||||
inType,
|
||||
comparisonType,
|
||||
inType,
|
||||
} from "../../../core/platform/services/database/services/orm/repository/repository";
|
||||
import { PublicFile } from "../../../services/files/entities/file";
|
||||
import globalResolver from "../../../services/global-resolver";
|
||||
@@ -16,15 +16,15 @@ import {
|
||||
TYPE as DriveTdriveTabRepoType,
|
||||
} from "../entities/drive-tdrive-tab";
|
||||
import {
|
||||
DriveExecutionContext,
|
||||
CompanyExecutionContext,
|
||||
DocumentsMessageQueueRequest,
|
||||
DriveExecutionContext,
|
||||
DriveFileAccessLevel,
|
||||
DriveItemDetails,
|
||||
DriveTdriveTab,
|
||||
RootType,
|
||||
SearchDocumentsOptions,
|
||||
TrashType,
|
||||
CompanyExecutionContext,
|
||||
DriveTdriveTab,
|
||||
DriveFileAccessLevel,
|
||||
} from "../types";
|
||||
import {
|
||||
addDriveItemToArchive,
|
||||
@@ -783,7 +783,9 @@ export class DocumentsService {
|
||||
limitStr: "100",
|
||||
},
|
||||
$in: [
|
||||
["access_entities", [context.user.id, context.company.id]],
|
||||
...(options.onlyDirectlyShared
|
||||
? [["access_entities", [context.user.id, context.company.id]] as inType]
|
||||
: []),
|
||||
...(options.company_id ? [["company_id", [options.company_id]] as inType] : []),
|
||||
...(options.creator ? [["creator", [options.creator]] as inType] : []),
|
||||
...(options.mime_type
|
||||
@@ -819,24 +821,31 @@ export class DocumentsService {
|
||||
context,
|
||||
);
|
||||
|
||||
// Use Promise.all to check access on each item in parallel
|
||||
const filteredResult = await Promise.all(
|
||||
result.getEntities().filter(async item => {
|
||||
// if this flag is on, the access permissions were checked inside the database
|
||||
if (!options.onlyDirectlyShared) {
|
||||
const filteredResult = await this.filter(result.getEntities(), async item => {
|
||||
try {
|
||||
// Check access for each item
|
||||
const hasAccess = await checkAccess(item.id, null, "read", this.repository, context);
|
||||
// Return true if the user has access
|
||||
return hasAccess;
|
||||
return await checkAccess(item.id, null, "read", this.repository, context);
|
||||
} catch (error) {
|
||||
this.logger.warn("failed to check item access", error);
|
||||
return false;
|
||||
}
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
return new ListResult(result.type, filteredResult, result.nextPage);
|
||||
return new ListResult(result.type, filteredResult, result.nextPage);
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
private async filter(arr, callback) {
|
||||
const fail = Symbol();
|
||||
return (
|
||||
await Promise.all(arr.map(async item => ((await callback(item)) ? item : fail)))
|
||||
).filter(i => i !== fail);
|
||||
}
|
||||
|
||||
getTab = async (tabId: string, context: CompanyExecutionContext): Promise<DriveTdriveTab> => {
|
||||
const tab = await this.driveTdriveTabRepository.findOne(
|
||||
{ company_id: context.company.id, tab_id: tabId },
|
||||
|
||||
@@ -47,6 +47,7 @@ export type SearchDocumentsOptions = {
|
||||
sort?: SortType;
|
||||
view?: string;
|
||||
fields?: string[];
|
||||
onlyDirectlyShared?: boolean;
|
||||
};
|
||||
|
||||
export type SearchDocumentsBody = {
|
||||
|
||||
@@ -55,6 +55,7 @@ export class DocumentsController {
|
||||
filename: q.resumableFilename || q.filename || file?.filename || undefined,
|
||||
type: q.resumableType || q.type || file?.mimetype || undefined,
|
||||
waitForThumbnail: !!q.thumbnail_sync,
|
||||
ignoreThumbnails: false,
|
||||
};
|
||||
|
||||
createdFile = await globalResolver.services.files.save(null, file, options, context);
|
||||
@@ -140,6 +141,35 @@ export class DocumentsController {
|
||||
};
|
||||
};
|
||||
|
||||
sharedWithMe = async (
|
||||
request: FastifyRequest<{
|
||||
Params: RequestParams;
|
||||
Body: SearchDocumentsBody;
|
||||
Querystring: { public_token?: string };
|
||||
}>,
|
||||
): Promise<ListResult<DriveFileDTO>> => {
|
||||
try {
|
||||
const context = getDriveExecutionContext(request);
|
||||
|
||||
const options: SearchDocumentsOptions = {
|
||||
...request.body,
|
||||
company_id: request.body.company_id || context.company.id,
|
||||
onlyDirectlyShared: true,
|
||||
};
|
||||
|
||||
if (!Object.keys(options).length) {
|
||||
this.throw500Search();
|
||||
}
|
||||
|
||||
const fileList = await globalResolver.services.documents.documents.search(options, context);
|
||||
|
||||
return this.driveFileDTOBuilder.build(fileList, context, options.fields, options.view);
|
||||
} catch (error) {
|
||||
logger.error({ error: `${error}` }, "error while searching for document");
|
||||
this.throw500Search();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return access level of a given user on a given item
|
||||
*/
|
||||
@@ -352,6 +382,7 @@ export class DocumentsController {
|
||||
const options: SearchDocumentsOptions = {
|
||||
...request.body,
|
||||
company_id: request.body.company_id || context.company.id,
|
||||
onlyDirectlyShared: false,
|
||||
};
|
||||
|
||||
if (!Object.keys(options).length) {
|
||||
|
||||
@@ -13,7 +13,27 @@ import { getSharedByUser } from "../../services/access-check";
|
||||
|
||||
export class DriveFileDTOBuilder {
|
||||
private views: Map<string, string[]> = new Map([
|
||||
["default", Object.getOwnPropertyNames(new DriveFile())],
|
||||
[
|
||||
"default",
|
||||
[
|
||||
"company_id",
|
||||
"id",
|
||||
"parent_id",
|
||||
"is_in_trash",
|
||||
"is_directory",
|
||||
"name",
|
||||
"extension",
|
||||
"description",
|
||||
"added",
|
||||
"last_modified",
|
||||
"size",
|
||||
"last_version_cache",
|
||||
"tags",
|
||||
"access_info",
|
||||
"content_keywords",
|
||||
"creator",
|
||||
],
|
||||
],
|
||||
[
|
||||
"shared_with_me",
|
||||
[
|
||||
@@ -39,6 +59,8 @@ export class DriveFileDTOBuilder {
|
||||
fields?: string[],
|
||||
view?: string,
|
||||
): Promise<ListResult<DriveFileDTO>> {
|
||||
const file = new DriveFile();
|
||||
file.id = "1";
|
||||
if (view) {
|
||||
fields = this.views.get(view);
|
||||
}
|
||||
|
||||
@@ -87,6 +87,13 @@ const routes: FastifyPluginCallback = (fastify: FastifyInstance, _options, next)
|
||||
handler: documentsController.search.bind(documentsController),
|
||||
});
|
||||
|
||||
fastify.route({
|
||||
method: "POST",
|
||||
url: `${baseUrl}/shared-with-me`,
|
||||
preValidation: [fastify.authenticate],
|
||||
handler: documentsController.sharedWithMe.bind(documentsController),
|
||||
});
|
||||
|
||||
fastify.route({
|
||||
method: "GET",
|
||||
url: `${baseUrl}/tabs/:tab_id`,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { logger, TwakeContext } from "../../../../../core/platform/framework";
|
||||
import { logger, TdriveContext } from "../../../../../core/platform/framework";
|
||||
import { PreviewClearMessageQueueRequest, PreviewMessageQueueCallback } from "../../../types";
|
||||
import gr from "../../../../global-resolver";
|
||||
import { MessageQueueHandler } from "../../../../../core/platform/services/message-queue/api";
|
||||
@@ -22,7 +22,7 @@ export class ClearProcessor
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
init?(context?: TwakeContext): Promise<this> {
|
||||
init?(context?: TdriveContext): Promise<this> {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@ import {
|
||||
} from "../../../../../utils/mime";
|
||||
import { PreviewMessageQueueRequest, ThumbnailResult } from "../../../types";
|
||||
import { generateVideoPreview } from "./video";
|
||||
import { Initializable, TwakeServiceProvider } from "../../../../../core/platform/framework";
|
||||
import { Initializable, TdriveServiceProvider } from "../../../../../core/platform/framework";
|
||||
import { cleanFiles } from "../../../../../utils/files";
|
||||
|
||||
export class PreviewProcessService implements TwakeServiceProvider, Initializable {
|
||||
export class PreviewProcessService implements TdriveServiceProvider, Initializable {
|
||||
name: "PreviewProcessService";
|
||||
version: "1";
|
||||
|
||||
|
||||
@@ -125,10 +125,10 @@ async function getVideoDimensions(videoPath: string): Promise<{ width: number; h
|
||||
ffmpeg.ffprobe(videoPath, (err, metadata) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
const { width, height } = metadata.streams[0];
|
||||
resolve({ width, height });
|
||||
}
|
||||
|
||||
const { width, height } = metadata.streams[0];
|
||||
resolve({ width, height });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -73,11 +73,11 @@ export default class TestHelpers {
|
||||
|
||||
const filesUploadRaw = await this.platform.app.inject({
|
||||
method: "POST",
|
||||
url: `${url}/companies/${this.platform.workspace.company_id}/files?thumbnail_sync=1`,
|
||||
url: `${url}/companies/${this.platform.workspace.company_id}/files?thumbnail_sync=0`,
|
||||
...form,
|
||||
});
|
||||
|
||||
const filesUpload: ResourceUpdateResponse<File> = deserialize(
|
||||
const filesUpload: ResourceUpdateResponse<File> = deserialize<ResourceUpdateResponse<File>>(
|
||||
ResourceUpdateResponse,
|
||||
filesUploadRaw.body,
|
||||
);
|
||||
@@ -188,5 +188,22 @@ export default class TestHelpers {
|
||||
response.body)
|
||||
};
|
||||
|
||||
async sharedWithMeDocuments (
|
||||
payload: Record<string, any>
|
||||
){
|
||||
const response = await this.platform.app.inject({
|
||||
method: "POST",
|
||||
url: `${TestHelpers.DOC_URL}/companies/${this.platform.workspace.company_id}/shared-with-me`,
|
||||
headers: {
|
||||
authorization: `Bearer ${this.jwt}`,
|
||||
},
|
||||
payload,
|
||||
});
|
||||
|
||||
return deserialize<SearchResultMockClass>(
|
||||
SearchResultMockClass,
|
||||
response.body)
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ describe("the Drive feature", () => {
|
||||
});
|
||||
currentUser = await TestHelpers.getInstance(platform);
|
||||
dbService = await TestDbService.getInstance(platform, true);
|
||||
});
|
||||
}, 300000000);
|
||||
|
||||
afterAll(async () => {
|
||||
await platform?.tearDown();
|
||||
@@ -294,7 +294,6 @@ describe("the Drive feature", () => {
|
||||
});
|
||||
|
||||
it("did search a file shared by another user", async () => {
|
||||
jest.setTimeout(30000);
|
||||
//given:
|
||||
const oneUser = await TestHelpers.getInstance(platform, true);
|
||||
const anotherUser = await TestHelpers.getInstance(platform, true);
|
||||
@@ -304,7 +303,7 @@ describe("the Drive feature", () => {
|
||||
await new Promise(r => setTimeout(r, 5000));
|
||||
|
||||
//then:: files are not searchable for user without permissions
|
||||
expect((await anotherUser.searchDocument({})).entities).toHaveLength(0);
|
||||
expect((await anotherUser.sharedWithMeDocuments({})).entities).toHaveLength(0);
|
||||
|
||||
//and searchable for user that have
|
||||
expect((await oneUser.searchDocument({})).entities).toHaveLength(TestHelpers.ALL_FILES.length);
|
||||
@@ -320,8 +319,8 @@ describe("the Drive feature", () => {
|
||||
await new Promise(r => setTimeout(r, 3000));
|
||||
|
||||
//then file become searchable
|
||||
expect((await anotherUser.searchDocument({})).entities).toHaveLength(1);
|
||||
});
|
||||
expect((await anotherUser.sharedWithMeDocuments({})).entities).toHaveLength(1);
|
||||
}, 30000000);
|
||||
|
||||
it("did search a file by file owner", async () => {
|
||||
jest.setTimeout(30000);
|
||||
@@ -387,7 +386,6 @@ describe("the Drive feature", () => {
|
||||
});
|
||||
|
||||
it("did search order by name", async () => {
|
||||
jest.setTimeout(10000);
|
||||
const user = await TestHelpers.getInstance(platform, true);
|
||||
// given:: all the sample files uploaded and documents for them created
|
||||
await user.uploadAllFilesAndCreateDocuments();
|
||||
@@ -404,7 +402,7 @@ describe("the Drive feature", () => {
|
||||
|
||||
//then all the files are sorted properly by name
|
||||
expect(documents.entities.map(e => e.name)).toEqual(TestHelpers.ALL_FILES.sort());
|
||||
});
|
||||
}, 30000);
|
||||
|
||||
it("did search order by name desc", async () => {
|
||||
jest.setTimeout(10000);
|
||||
|
||||
@@ -56,7 +56,7 @@ describe("The Tag feature", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const tagResult: ResourceCreateResponse<Tag> = deserialize(
|
||||
const tagResult: ResourceCreateResponse<Tag> = deserialize<ResourceCreateResponse<Tag>>(
|
||||
ResourceCreateResponse,
|
||||
createTag.body,
|
||||
);
|
||||
@@ -98,7 +98,7 @@ describe("The Tag feature", () => {
|
||||
});
|
||||
expect(createTag.statusCode).toBe(401);
|
||||
|
||||
const tagResult: ResourceCreateResponse<Tag> = deserialize(
|
||||
const tagResult: ResourceCreateResponse<Tag> = deserialize<ResourceCreateResponse<Tag>>(
|
||||
ResourceCreateResponse,
|
||||
createTag.body,
|
||||
);
|
||||
@@ -121,7 +121,7 @@ describe("The Tag feature", () => {
|
||||
});
|
||||
expect(getTag.statusCode).toBe(200);
|
||||
|
||||
const getResult: ResourceGetResponse<Tag> = deserialize(ResourceGetResponse, getTag.body);
|
||||
const getResult: ResourceGetResponse<Tag> = deserialize<ResourceGetResponse<Tag>>(ResourceGetResponse, getTag.body);
|
||||
expect(getResult.resource).toBeDefined();
|
||||
expect(getResult.resource.name).toBe("test0");
|
||||
expect(getResult.resource.colour).toBe("#000000");
|
||||
@@ -144,7 +144,7 @@ describe("The Tag feature", () => {
|
||||
});
|
||||
expect(getTag.statusCode).toBe(200);
|
||||
|
||||
const getResult: ResourceGetResponse<Tag> = deserialize(ResourceGetResponse, getTag.body);
|
||||
const getResult: ResourceGetResponse<Tag> = deserialize<ResourceGetResponse<Tag>>(ResourceGetResponse, getTag.body);
|
||||
expect(getResult.resource).toBe(null);
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ describe("The Tag feature", () => {
|
||||
});
|
||||
expect(updateTag.statusCode).toBe(201);
|
||||
|
||||
const tagUpdatedResult: ResourceCreateResponse<Tag> = deserialize(
|
||||
const tagUpdatedResult: ResourceCreateResponse<Tag> = deserialize<ResourceCreateResponse<Tag>>(
|
||||
ResourceCreateResponse,
|
||||
updateTag.body,
|
||||
);
|
||||
@@ -210,7 +210,7 @@ describe("The Tag feature", () => {
|
||||
});
|
||||
expect(createTag.statusCode).toBe(401);
|
||||
|
||||
const tagResult: ResourceCreateResponse<Tag> = deserialize(
|
||||
const tagResult: ResourceCreateResponse<any> = deserialize(
|
||||
ResourceCreateResponse,
|
||||
createTag.body,
|
||||
);
|
||||
@@ -236,7 +236,7 @@ describe("The Tag feature", () => {
|
||||
});
|
||||
expect(listTag.statusCode).toBe(200);
|
||||
|
||||
const tagResult: ResourceListResponse<Tag> = deserialize(ResourceListResponse, listTag.body);
|
||||
const tagResult: ResourceListResponse<any> = deserialize(ResourceListResponse, listTag.body);
|
||||
expect(tagResult.resources).toBeDefined();
|
||||
for (const tag of tagResult.resources) {
|
||||
expect(tag.name).toBeDefined();
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"target": "es6",
|
||||
"noImplicitAny": true,
|
||||
"noImplicitAny": false,
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"outDir": "dist",
|
||||
|
||||
+523
-2217
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user