From e7c18647c0f56ba31f9568d359cde6bd19c38087 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Tue, 7 Jan 2025 17:17:24 -0500 Subject: [PATCH] remove tscpaths to avoid security vulnerabilities --- package.json | 4 +--- src/client/httpClient.ts | 8 +++---- src/collections/client.ts | 6 +++--- src/collections/db.ts | 2 +- src/collections/utils.ts | 4 ++-- src/driver/collection.ts | 12 +++++------ src/driver/connection.ts | 4 ++-- tests/client/deserialize.test.ts | 2 +- tests/client/httpClient.test.ts | 2 +- tests/collections/client.test.ts | 8 +++---- tests/collections/collection.test.ts | 14 ++++++------ tests/collections/cursor.test.ts | 10 ++++----- tests/collections/db.test.ts | 32 ++++++++++++++-------------- tests/collections/options.test.ts | 2 +- tests/collections/utils.test.ts | 4 ++-- tests/driver/api.test.ts | 26 +++++++++++----------- tests/driver/index.test.ts | 18 ++++++++-------- tests/fixtures.ts | 2 +- tests/mongooseFixtures.ts | 8 +++---- tests/setup.ts | 4 ++-- tsconfig.json | 6 +----- 21 files changed, 86 insertions(+), 92 deletions(-) diff --git a/package.json b/package.json index 97c9782a..4355825c 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "test-astra": "env TEST_DOC_DB=astra nyc ts-mocha --forbid-only --paths -p tsconfig.json tests/**/*.test.ts", "test-dataapi": "env TEST_DOC_DB=dataapi nyc ts-mocha --forbid-only --paths -p tsconfig.json tests/**/*.test.ts", "preinstall": "npm run update-version-file", - "build": "npm run update-version-file && tsc --project tsconfig.build.json && tscpaths -p tsconfig.build.json -s ./src -o ./dist", + "build": "npm run update-version-file && tsc --project tsconfig.build.json", "build:docs": "jsdoc2md -t APIReference.hbs --files src/**/*.ts --configure ./jsdoc2md.json > APIReference.md", "update-version-file": "node -p \"'export const LIB_NAME = \\'' + require('./package.json').name + '\\';'\" > src/version.ts && node -p \"'export const LIB_VERSION = \\'' + require('./package.json').version + '\\';'\" >> src/version.ts" }, @@ -81,8 +81,6 @@ "sinon": "15.2.0", "ts-mocha": "^10.0.0", "ts-node": "^10.8.1", - "tscpaths": "^0.0.9", - "tsconfig-paths": "^4.0.0", "typescript": "^4.7.2", "typescript-eslint": "~8.11" }, diff --git a/src/client/httpClient.ts b/src/client/httpClient.ts index 7cf946be..37f0010e 100644 --- a/src/client/httpClient.ts +++ b/src/client/httpClient.ts @@ -14,13 +14,13 @@ import http from 'http'; import axios, { AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios'; -import { logger, setLevel } from '@/src/logger'; +import { logger, setLevel } from '../logger'; import { inspect } from 'util'; import { LIB_NAME, LIB_VERSION } from '../version'; import { getStargateAccessToken } from '../collections/utils'; import http2 from 'http2'; import { StargateMongooseError } from '../collections/collection'; -import { deserialize } from './deserialize'; +import { deserialize } from './deserialize'; import { serialize } from './serialize'; const REQUESTED_WITH = LIB_NAME + '/' + LIB_VERSION; @@ -138,7 +138,7 @@ class HTTP2Session { } } - request(path: string, token: string, body: Record, timeout: number, additionalParams: Record): Promise<{ status: number, data: Record }> { + request(path: string, token: string, body: Record, timeout: number, additionalParams: Record): Promise<{ status: number, data: Record }> { return new Promise((resolve, reject) => { if (!this.closed && this.session.closed) { this._createSession(); @@ -150,7 +150,7 @@ class HTTP2Session { if (logger.isLevelEnabled('http')) { logger.http(`--- request POST ${this.origin}${path} ${serialize(body, true)}`); } - + const timer = setTimeout( () => { if (!done) { diff --git a/src/collections/client.ts b/src/collections/client.ts index 3a6b22a7..7698f7ed 100644 --- a/src/collections/client.ts +++ b/src/collections/client.ts @@ -14,9 +14,9 @@ import { Db } from './db'; import { createNamespace, executeOperation, parseUri } from './utils'; -import { HTTPClient } from '@/src/client'; -import { logger } from '@/src/logger'; -import {OperationNotSupportedError} from '@/src/driver'; +import { HTTPClient } from '../client'; +import { logger } from '../logger'; +import {OperationNotSupportedError} from '../driver'; import { retainNoOptions } from './options'; export interface ClientOptions { diff --git a/src/collections/db.ts b/src/collections/db.ts index 9b920393..2820a71d 100644 --- a/src/collections/db.ts +++ b/src/collections/db.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { HTTPClient } from '@/src/client'; +import { HTTPClient } from '../client'; import { CreateCollectionOptions, createCollectionOptionsKeys, diff --git a/src/collections/utils.ts b/src/collections/utils.ts index 3b43e1c4..c06cc51e 100644 --- a/src/collections/utils.ts +++ b/src/collections/utils.ts @@ -14,8 +14,8 @@ import { Types } from 'mongoose'; import url from 'url'; -import { logger } from '@/src/logger'; -import { HTTPClient, handleIfErrorResponse } from '@/src/client/httpClient'; +import { logger } from '../logger'; +import { HTTPClient, handleIfErrorResponse } from '../client/httpClient'; interface ParsedUri { baseUrl: string; diff --git a/src/driver/collection.ts b/src/driver/collection.ts index 763ee929..11ecc63d 100644 --- a/src/driver/collection.ts +++ b/src/driver/collection.ts @@ -35,7 +35,7 @@ import { UpdateManyOptions, UpdateOneOptions, UpdateOneOptionsForDataAPI -} from '@/src/collections/options'; +} from '../collections/options'; import { DataAPIDeleteResult } from '../collections/collection'; import { version } from 'mongoose'; @@ -263,7 +263,7 @@ export class Collection extends MongooseCollection { * @param options * @param callback */ - deleteOne(filter: Record, options?: DeleteOneOptions, callback?: NodeCallback) { + deleteOne(filter: Record, options?: DeleteOneOptions, callback?: NodeCallback) { let requestOptions: DeleteOneOptionsForDataAPI | undefined = undefined; if (options != null && options.sort != null) { requestOptions = { ...options, sort: processSortOption(options.sort) }; @@ -271,7 +271,7 @@ export class Collection extends MongooseCollection { requestOptions = { ...options, sort: undefined }; delete requestOptions.sort; } - + const promise = this.collection.deleteOne(filter, requestOptions); if (callback != null) { @@ -386,10 +386,10 @@ export class Collection extends MongooseCollection { /** * Create index not supported. - * + * * Async because Mongoose `createIndexes()` throws an unhandled error if `createIndex()` throws a sync error * See Automattic/mongoose#14995 - * + * * @param fieldOrSpec * @param options */ @@ -433,7 +433,7 @@ function processSortOption(sort: SortOption): SortOptionInternal { result[key] = $meta; } } - + return result; } diff --git a/src/driver/connection.ts b/src/driver/connection.ts index 3982111f..d8119753 100644 --- a/src/driver/connection.ts +++ b/src/driver/connection.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Client } from '@/src/collections/client'; +import { Client } from '../collections/client'; import { Collection } from './collection'; import { default as MongooseConnection } from 'mongoose/lib/connection'; import { STATES, Model, Mongoose, ConnectOptions } from 'mongoose'; @@ -182,4 +182,4 @@ export class Connection extends MongooseConnection { } return this; } -} \ No newline at end of file +} diff --git a/tests/client/deserialize.test.ts b/tests/client/deserialize.test.ts index 64bcee8d..97733ba1 100644 --- a/tests/client/deserialize.test.ts +++ b/tests/client/deserialize.test.ts @@ -14,7 +14,7 @@ import { ObjectId } from 'bson'; import assert from 'assert'; -import { deserialize } from '@/src/client/deserialize'; +import { deserialize } from '../../src/client/deserialize'; describe('StargateMongoose - client.deserialize', () => { describe('deserialize', () => { diff --git a/tests/client/httpClient.test.ts b/tests/client/httpClient.test.ts index b370f3d2..48304a48 100644 --- a/tests/client/httpClient.test.ts +++ b/tests/client/httpClient.test.ts @@ -13,7 +13,7 @@ // limitations under the License. import assert from 'assert'; -import { HTTPClient } from '@/src/client/httpClient'; +import { HTTPClient } from '../../src/client/httpClient'; describe('StargateMongoose - client.HTTPClient', () => { describe('HTTPClient Operations', () => { diff --git a/tests/collections/client.test.ts b/tests/collections/client.test.ts index 0efb8a0f..2db1a9a9 100644 --- a/tests/collections/client.test.ts +++ b/tests/collections/client.test.ts @@ -13,9 +13,9 @@ // limitations under the License. import assert from 'assert'; -import { Client } from '@/src/collections/client'; -import { testClient } from '@/tests/fixtures'; -import { parseUri } from '@/src/collections/utils'; +import { Client } from '../../src/collections/client'; +import { testClient } from '../../tests/fixtures'; +import { parseUri } from '../../src/collections/utils'; const localBaseUrl = 'http://localhost:8181'; @@ -158,7 +158,7 @@ describe('StargateMongoose clients test', () => { const AUTH_TOKEN_TO_CHECK = '123'; const KEYSPACE_TO_CHECK = 'testks1'; const AUTH_HEADER_NAME_TO_CHECK = 'x-token'; - + const client = await Client.connect(baseUrl + '/' + KEYSPACE_TO_CHECK, { applicationToken: AUTH_TOKEN_TO_CHECK, authHeaderName: AUTH_HEADER_NAME_TO_CHECK, diff --git a/tests/collections/collection.test.ts b/tests/collections/collection.test.ts index d79681fb..ee45dfcd 100644 --- a/tests/collections/collection.test.ts +++ b/tests/collections/collection.test.ts @@ -13,9 +13,9 @@ // limitations under the License. import assert from 'assert'; -import { Db } from '@/src/collections/db'; -import { Collection, StargateMongooseError } from '@/src/collections/collection'; -import { Client } from '@/src/collections/client'; +import { Db } from '../../src/collections/db'; +import { Collection, StargateMongooseError } from '../../src/collections/collection'; +import { Client } from '../../src/collections/client'; import { testClient, testClientName, @@ -25,8 +25,8 @@ import { createSampleDoc3WithMultiLevel, createSampleDocWithMultiLevelWithId, TEST_COLLECTION_NAME -} from '@/tests/fixtures'; -import { StargateServerError } from '@/src/client/httpClient'; +} from '../../tests/fixtures'; +import { StargateServerError } from '../../src/client/httpClient'; describe(`StargateMongoose - ${testClientName} Connection - collections.collection`, async () => { const isAstra: boolean = testClientName === 'astra'; @@ -131,7 +131,7 @@ describe(`StargateMongoose - ${testClientName} Connection - collections.collecti const error: Error | null = await collection.insertOne(docToInsert).then(() => null, error => error); assert.ok(error instanceof StargateServerError); assert.strictEqual( - error.errors[0].message, + error.errors[0].message, 'Document size limitation violated: number of properties an indexable Object (property \'null\') has (1002) exceeds maximum allowed (1000)' ); }); @@ -1603,7 +1603,7 @@ describe(`StargateMongoose - ${testClientName} Connection - collections.collecti }); }); it('should rename a field when $rename is used in update and updateMany', async () => { - const numDocs = 19; + const numDocs = 19; const docList = Array.from({ length: numDocs }, () => ({ _id: 'id', username: 'username', diff --git a/tests/collections/cursor.test.ts b/tests/collections/cursor.test.ts index 66152fef..aae9f659 100644 --- a/tests/collections/cursor.test.ts +++ b/tests/collections/cursor.test.ts @@ -13,11 +13,11 @@ // limitations under the License. import assert from 'assert'; -import { Db } from '@/src/collections/db'; -import { FindCursor } from '@/src/collections/cursor'; -import { Collection } from '@/src/collections/collection'; -import { Client } from '@/src/collections/client'; -import { testClient, sampleUsersList, TEST_COLLECTION_NAME } from '@/tests/fixtures'; +import { Db } from '../../src/collections/db'; +import { FindCursor } from '../../src/collections/cursor'; +import { Collection } from '../../src/collections/collection'; +import { Client } from '../../src/collections/client'; +import { testClient, sampleUsersList, TEST_COLLECTION_NAME } from '../fixtures'; describe(`StargateMongoose - ${testClient} Connection - collections.cursor`, async () => { let astraClient: Client | null; diff --git a/tests/collections/db.test.ts b/tests/collections/db.test.ts index 3b7f05e5..356ddfaf 100644 --- a/tests/collections/db.test.ts +++ b/tests/collections/db.test.ts @@ -13,15 +13,15 @@ // limitations under the License. import assert from 'assert'; -import { Db } from '@/src/collections/db'; -import { Client } from '@/src/collections/client'; -import { parseUri, createNamespace } from '@/src/collections/utils'; -import { testClient, TEST_COLLECTION_NAME } from '@/tests/fixtures'; -import { createMongooseCollections } from '@/tests/mongooseFixtures'; -import {HTTPClient} from '@/src/client'; +import { Db } from '../../src/collections/db'; +import { Client } from '../../src/collections/client'; +import { parseUri, createNamespace } from '../../src/collections/utils'; +import { testClient, TEST_COLLECTION_NAME } from '../fixtures'; +import { createMongooseCollections } from '../mongooseFixtures'; +import {HTTPClient} from '../../src/client'; import { randomBytes } from 'crypto'; import mongoose from 'mongoose'; -import { StargateServerError } from '@/src/client/httpClient'; +import { StargateServerError } from '../../src/client/httpClient'; const randString = (length: number) => randomBytes(Math.ceil(length / 2)).toString('hex').slice(0, length); @@ -144,23 +144,23 @@ describe('StargateMongoose - collections.Db', async () => { try { let collections = await db.findCollections().then(res => res.status.collections); assert.ok(!collections.includes(collectionName)); - + const res = await db.createCollection( collectionName, { indexing: { deny: ['description'] } } ); assert.ok(res); assert.strictEqual(res.status.ok, 1); - + collections = await db.findCollections().then(res => res.status.collections); assert.ok(collections.includes(collectionName)); - + await db.collection(collectionName).insertOne({ name: 'test', description: 'test' }); await assert.rejects( () => db.collection(collectionName).findOne({ description: 'test' }), /filter path 'description' is not indexed/ ); - + const doc = await db.collection(collectionName).findOne({ name: 'test' }); assert.equal(doc!.description, 'test'); } finally { @@ -175,17 +175,17 @@ describe('StargateMongoose - collections.Db', async () => { try { let collections = await db.findCollections().then(res => res.status.collections); assert.ok(!collections.includes(collectionName)); - + const res = await db.createCollection( collectionName, { defaultId: { type: 'objectId' } } ); assert.ok(res); assert.strictEqual(res.status.ok, 1); - + collections = await db.findCollections().then(res => res.status.collections); assert.ok(collections.includes(collectionName)); - + const { insertedId } = await db.collection(collectionName).insertOne({ name: 'test' }); assert.ok(insertedId instanceof mongoose.Types.ObjectId); @@ -230,7 +230,7 @@ describe('StargateMongoose - collections.Db', async () => { return this.skip(); } const db = new Db(httpClient, keyspaceName); - + await db.createCollection(`test_db_collection_${suffix}`); const res = await db.dropDatabase(); assert.strictEqual(res.status?.ok, 1); @@ -289,4 +289,4 @@ describe('StargateMongoose - collections.Db', async () => { } }); }); -}); \ No newline at end of file +}); diff --git a/tests/collections/options.test.ts b/tests/collections/options.test.ts index 8420775f..b1048515 100644 --- a/tests/collections/options.test.ts +++ b/tests/collections/options.test.ts @@ -14,7 +14,7 @@ import assert from 'assert'; import mongoose from 'mongoose'; -import { Product } from '@/tests/mongooseFixtures'; +import { Product } from '../mongooseFixtures'; describe('Options tests', async () => { beforeEach(async function() { diff --git a/tests/collections/utils.test.ts b/tests/collections/utils.test.ts index c636c8f2..858a97fe 100644 --- a/tests/collections/utils.test.ts +++ b/tests/collections/utils.test.ts @@ -13,7 +13,7 @@ // limitations under the License. import assert from 'assert'; -import { createAstraUri } from '@/src/collections/utils'; +import { createAstraUri } from '../../src/collections/utils'; describe('Utils test', () => { it('createProdAstraUriDefaultKeyspace', () => { @@ -42,4 +42,4 @@ describe('Utils test', () => { const uri: string = createAstraUri(apiEndpoint,'myToken','testks1','apis'); assert.strictEqual(uri, 'https://a5cf1913-b80b-4f44-ab9f-a8b1c98469d0-ap-south-1.apps.astra.datastax.com/apis/testks1?applicationToken=myToken'); }); -}); \ No newline at end of file +}); diff --git a/tests/driver/api.test.ts b/tests/driver/api.test.ts index c8d044a1..57e4b102 100644 --- a/tests/driver/api.test.ts +++ b/tests/driver/api.test.ts @@ -13,19 +13,19 @@ // limitations under the License. import assert from 'assert'; -import {Db} from '@/src/collections/db'; -import {Client} from '@/src/collections/client'; +import {Db} from '../../src/collections/db'; +import {Client} from '../../src/collections/client'; import { testClient, TEST_COLLECTION_NAME -} from '@/tests/fixtures'; +} from '../../tests/fixtures'; import mongoose, { Schema, InferSchemaType, InsertManyResult } from 'mongoose'; import { once } from 'events'; -import * as StargateMongooseDriver from '@/src/driver'; +import * as StargateMongooseDriver from '../../src/driver'; import {randomUUID} from 'crypto'; -import {OperationNotSupportedError} from '@/src/driver'; -import { Product, Cart, mongooseInstance, productSchema } from '@/tests/mongooseFixtures'; -import { StargateServerError } from '@/src/client/httpClient'; +import {OperationNotSupportedError} from '../../src/driver'; +import { Product, Cart, mongooseInstance, productSchema } from '../mongooseFixtures'; +import { StargateServerError } from '../../src/client/httpClient'; describe('Mongoose Model API level tests', async () => { let astraClient: Client | null; @@ -336,13 +336,13 @@ describe('Mongoose Model API level tests', async () => { assert.ok(err instanceof OperationNotSupportedError); assert.strictEqual(err.message, 'distinct() Not Implemented'); }); - + it('API ops tests Model.estimatedDocumentCount()', async function() { const product1 = new Product({name: 'Product 1', price: 10, isCertified: true, category: 'cat 1'}); const product2 = new Product({name: 'Product 2', price: 10, isCertified: true, category: 'cat 2'}); const product3 = new Product({name: 'Product 3', price: 10, isCertified: true, category: 'cat 1'}); await Product.create([product1, product2, product3]); - + const count = await Product.estimatedDocumentCount(); assert.equal(typeof count, 'number'); assert.ok(count >= 0); @@ -578,7 +578,7 @@ describe('Mongoose Model API level tests', async () => { await Product.create(product1); //UpdateOne await Product.updateOne({ _id: product1._id }, { $push: { tags: { name: 'Home & Garden' } } }); - + const { tags } = await Product.findById(product1._id).orFail(); assert.deepStrictEqual(tags.toObject(), [{ name: 'Electronics' }, { name: 'Home & Garden' }]); }); @@ -591,7 +591,7 @@ describe('Mongoose Model API level tests', async () => { await cart.save(); //UpdateOne await Cart.updateOne({ _id: cart._id }, { $set: { user: { name: 'test updated subdoc' } } }); - + const { user } = await Cart.findById(cart._id).orFail(); assert.deepStrictEqual(user.toObject(), { name: 'test updated subdoc' }); }); @@ -834,9 +834,9 @@ describe('Mongoose Model API level tests', async () => { .find({}, null, { includeSortVector: true }) .sort({ $vector: { $meta: [1, 99] } }) .cursor(); - + await once(cursor, 'cursor'); - assert.deepStrictEqual(await cursor.cursor.getSortVector(), [1, 99]); + assert.deepStrictEqual(await cursor.cursor.getSortVector(), [1, 99]); }); it('supports sort() and similarity score with $meta with findOne()', async function() { diff --git a/tests/driver/index.test.ts b/tests/driver/index.test.ts index e8353897..76b81cdb 100644 --- a/tests/driver/index.test.ts +++ b/tests/driver/index.test.ts @@ -14,13 +14,13 @@ import assert from 'assert'; import mongoose from 'mongoose'; -import * as StargateMongooseDriver from '@/src/driver'; -import { testClient, TEST_COLLECTION_NAME } from '@/tests/fixtures'; -import { logger } from '@/src/logger'; -import { parseUri } from '@/src/collections/utils'; -import { HTTPClient } from '@/src/client'; -import { Client } from '@/src/collections'; -import { Product, Cart, mongooseInstance } from '@/tests/mongooseFixtures'; +import * as StargateMongooseDriver from '../../src/driver'; +import { testClient, TEST_COLLECTION_NAME } from '../fixtures'; +import { logger } from '../../src/logger'; +import { parseUri } from '../../src/collections/utils'; +import { HTTPClient } from '../../src/client'; +import { Client } from '../../src/collections'; +import { Product, Cart, mongooseInstance } from '../mongooseFixtures'; describe('Driver based tests', async () => { let dbUri: string; @@ -238,7 +238,7 @@ describe('Driver based tests', async () => { await mongooseInstance.disconnect(); }); - + it('handles listCollections()', async () => { const collections = await mongooseInstance!.connection.listCollections(); const collectionNames = collections.map(({ name }) => name); @@ -265,7 +265,7 @@ describe('Driver based tests', async () => { mongooseInstance.set('autoCreate', false); mongooseInstance.set('autoIndex', false); const options = isAstra ? { isAstra: true } : { username: process.env.STARGATE_USERNAME, password: process.env.STARGATE_PASSWORD }; - + //split dbUri by / and replace last element with newKeyspaceName const dbUriSplit = dbUri.split('/'); const token = parseUri(dbUri).applicationToken; diff --git a/tests/fixtures.ts b/tests/fixtures.ts index 769f19c6..d1a88dfd 100644 --- a/tests/fixtures.ts +++ b/tests/fixtures.ts @@ -13,7 +13,7 @@ // limitations under the License. import assert from 'assert'; -import { Client, ClientOptions } from '@/src/collections/client'; +import { Client, ClientOptions } from '../src/collections/client'; export const TEST_COLLECTION_NAME = 'collection1'; diff --git a/tests/mongooseFixtures.ts b/tests/mongooseFixtures.ts index e1909c10..0fb3445e 100644 --- a/tests/mongooseFixtures.ts +++ b/tests/mongooseFixtures.ts @@ -1,8 +1,8 @@ import { isAstra, testClient } from './fixtures'; import { Schema, Mongoose } from 'mongoose'; -import * as StargateMongooseDriver from '@/src/driver'; -import { parseUri, createNamespace } from '@/src/collections/utils'; -import { plugins } from '@/src/driver'; +import * as StargateMongooseDriver from '../src/driver'; +import { parseUri, createNamespace } from '../src/collections/utils'; +import { plugins } from '../src/driver'; const cartSchema = new Schema({ name: String, @@ -67,4 +67,4 @@ before(createMongooseCollections); after(async function disconnectMongooseFixtures() { await mongooseInstance.disconnect(); -}); \ No newline at end of file +}); diff --git a/tests/setup.ts b/tests/setup.ts index 26324a55..b382c612 100644 --- a/tests/setup.ts +++ b/tests/setup.ts @@ -17,9 +17,9 @@ import dotenv from 'dotenv'; dotenv.config(); -import { logger, setLevel } from '@/src/logger'; +import { logger, setLevel } from '../src/logger'; if (process.env.D) { setLevel('http'); } else { logger.silent = true; -} \ No newline at end of file +} diff --git a/tsconfig.json b/tsconfig.json index 0367311a..181c80e4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,11 +10,7 @@ "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, - "skipLibCheck": true, - "paths": { - "@/src/*": ["./src/*"], - "@/tests/*": ["./tests/*"] - } + "skipLibCheck": true }, "include": ["tests/**/*", "src/**/*"] }