From b7bb17802bf7d4327449f53d5864295bff655c3f Mon Sep 17 00:00:00 2001 From: Roi Cohen <213414225+roicohen326@users.noreply.github.com> Date: Sun, 21 Jun 2026 17:12:19 +0300 Subject: [PATCH 1/8] feat: add keywords field to ingestion layer metadata (MAPCO-8284) --- openapi3.yaml | 4 + tests/integration/ingestion/ingestion.spec.ts | 116 ++++++++++++++++++ tests/mocks/mockFactory.ts | 6 +- .../ingestion/models/ingestionManager.spec.ts | 55 +++++++++ 4 files changed, 177 insertions(+), 4 deletions(-) diff --git a/openapi3.yaml b/openapi3.yaml index 4e68b60..e8e224e 100644 --- a/openapi3.yaml +++ b/openapi3.yaml @@ -459,6 +459,8 @@ components: $ref: ./Schema/core/layerMetadata.yaml#/components/schemas/Description classification: $ref: ./Schema/core/layerMetadata.yaml#/components/schemas/Classification + keywords: + $ref: ./Schema/core/layerMetadata.yaml#/components/schemas/Keywords IngestionNewLayerRequest: type: object required: @@ -487,6 +489,8 @@ components: properties: classification: $ref: ./Schema/core/layerMetadata.yaml#/components/schemas/Classification + keywords: + $ref: ./Schema/core/layerMetadata.yaml#/components/schemas/Keywords IngestionUpdateLayerRequest: type: object required: diff --git a/tests/integration/ingestion/ingestion.spec.ts b/tests/integration/ingestion/ingestion.spec.ts index f225481..8bfecba 100644 --- a/tests/integration/ingestion/ingestion.spec.ts +++ b/tests/integration/ingestion/ingestion.spec.ts @@ -148,6 +148,47 @@ describe('Ingestion', () => { expect(response.status).toBe(httpStatusCodes.OK); expect(response.body).toStrictEqual(expectedResponseBody); }); + + it('should return 200 status code when metadata contains keywords', async () => { + const layerRequest = createNewLayerRequest({ + inputFiles: validInputFiles.inputFiles, + metadata: { keywords: faker.lorem.words({ min: 1, max: 5 }) }, + }); + const newLayerName = getMapServingLayerName(layerRequest.metadata.productId, layerRequest.metadata.productType); + const findJobsParams = createFindJobsParams({ + resourceId: layerRequest.metadata.productId, + productType: layerRequest.metadata.productType, + }); + const newJobRequest = createNewJobRequest({ + ingestionNewLayer: layerRequest, + checksums: validInputFiles.checksums, + }); + nock(jobManagerURL).post('/jobs/find', matches(findJobsParams)).reply(httpStatusCodes.OK, []); + nock(jobManagerURL) + .post('/jobs', matches(JSON.parse(JSON.stringify(newJobRequest)))) + .reply(httpStatusCodes.OK, jobResponse); + nock(catalogServiceURL) + .post('/records/find', { + metadata: { + productId: layerRequest.metadata.productId, + productType: layerRequest.metadata.productType, + }, + }) + .reply(httpStatusCodes.OK, []); + nock(mapProxyApiServiceUrl) + .get(`/layer/${encodeURIComponent(newLayerName)}`) + .reply(httpStatusCodes.NOT_FOUND); + const expectedResponseBody: ResponseId = { + jobId: jobResponse.id, + taskId: jobResponse.taskIds[0]!, + }; + + const response = await requestSender.ingestNewLayer(layerRequest); + + expect(response).toSatisfyApiSpec(); + expect(response.status).toBe(httpStatusCodes.OK); + expect(response.body).toStrictEqual(expectedResponseBody); + }); }); describe('Bad Path', () => { @@ -525,6 +566,24 @@ describe('Ingestion', () => { { metadata: { productSubType: false } } ), }, + { + testCase: 'keywords in metadata in req body is not a string', + badRequest: merge( + createNewLayerRequest({ + inputFiles: validInputFiles.inputFiles, + }), + { metadata: { keywords: false } } + ), + }, + { + testCase: 'keywords in metadata in req body is an array instead of a string', + badRequest: merge( + createNewLayerRequest({ + inputFiles: validInputFiles.inputFiles, + }), + { metadata: { keywords: ['aerial', 'satellite'] } } + ), + }, { testCase: 'ingestionResolution in req body is not set', badRequest: createNewLayerRequest({ @@ -847,6 +906,45 @@ describe('Ingestion', () => { expect(response.body).toStrictEqual(expectedResponseBody); }); + it('should return 200 status code with update request when metadata contains keywords', async () => { + const layerRequest = createUpdateLayerRequest({ + inputFiles: validInputFiles.inputFiles, + callbackUrls: undefined, + metadata: { keywords: faker.lorem.words({ min: 1, max: 5 }) }, + }); + const updatedLayer = createCatalogLayerResponse(); + const updatedLayerMetadata = updatedLayer.metadata; + const updateLayerName = getMapServingLayerName(updatedLayerMetadata.productId, updatedLayerMetadata.productType); + const findJobsParams = createFindJobsParams({ + resourceId: updatedLayerMetadata.productId, + productType: updatedLayerMetadata.productType, + }); + const updateJobRequest = createUpdateJobRequest({ + ingestionUpdateLayer: layerRequest, + rasterLayerMetadata: updatedLayerMetadata, + checksums: validInputFiles.checksums, + }); + + nock(jobManagerURL).post('/jobs/find', matches(findJobsParams)).reply(httpStatusCodes.OK, []); + nock(jobManagerURL) + .post('/jobs', matches(JSON.parse(JSON.stringify(updateJobRequest)))) + .reply(httpStatusCodes.OK, jobResponse); + nock(catalogServiceURL).post('/records/find', { id: updatedLayerMetadata.id }).reply(httpStatusCodes.OK, [updatedLayer]); + nock(mapProxyApiServiceUrl) + .get(`/layer/${encodeURIComponent(updateLayerName)}`) + .reply(httpStatusCodes.OK); + const expectedResponseBody: ResponseId = { + jobId: jobResponse.id, + taskId: jobResponse.taskIds[0]!, + }; + + const response = await requestSender.updateLayer(updatedLayerMetadata.id, layerRequest); + + expect(response).toSatisfyApiSpec(); + expect(response.status).toBe(httpStatusCodes.OK); + expect(response.body).toStrictEqual(expectedResponseBody); + }); + it('should return 200 status code with swap update request when product shapefile is polygon', async () => { const layerRequest = createUpdateLayerRequest({ inputFiles: validInputFiles.inputFiles }); const catalogLayerResponse = createCatalogLayerResponse({ @@ -1091,6 +1189,24 @@ describe('Ingestion', () => { metadata: { classification: '00' }, }), }, + { + testCase: 'keywords in metadata in req body is not a string', + badRequest: merge( + createUpdateLayerRequest({ + inputFiles: validInputFiles.inputFiles, + }), + { metadata: { keywords: false } } + ), + }, + { + testCase: 'keywords in metadata in req body is an array instead of a string', + badRequest: merge( + createUpdateLayerRequest({ + inputFiles: validInputFiles.inputFiles, + }), + { metadata: { keywords: ['aerial', 'satellite'] } } + ), + }, { testCase: 'ingestionResolution in req body is not set', badRequest: createUpdateLayerRequest({ diff --git a/tests/mocks/mockFactory.ts b/tests/mocks/mockFactory.ts index b4e7738..b8cb372 100644 --- a/tests/mocks/mockFactory.ts +++ b/tests/mocks/mockFactory.ts @@ -509,7 +509,7 @@ export const createUpdateJobRequest = ( const { ingestionResolution, inputFiles, - metadata: { classification }, + metadata, callbackUrls, } = ingestionUpdateLayer; const { displayPath, id, productId, productType, productVersion, productName, tileOutputFormat } = rasterLayerMetadata; @@ -524,9 +524,7 @@ export const createUpdateJobRequest = ( status: OperationStatus.PENDING, parameters: { ingestionResolution, - metadata: { - classification, - }, + metadata, inputFiles: { gpkgFilesPath: inputFiles.gpkgFilesPath.map((gpkgFilePath) => relative(sourceMount, join(sourceMount, gpkgFilePath))), metadataShapefilePath: relative(sourceMount, join(sourceMount, inputFiles.metadataShapefilePath)), diff --git a/tests/unit/ingestion/models/ingestionManager.spec.ts b/tests/unit/ingestion/models/ingestionManager.spec.ts index b413703..d6f95da 100644 --- a/tests/unit/ingestion/models/ingestionManager.spec.ts +++ b/tests/unit/ingestion/models/ingestionManager.spec.ts @@ -193,6 +193,33 @@ describe('IngestionManager', () => { ); }); + it('should pass keywords through to the ingestion job params when keywords is set in metadata', async () => { + const keywords = faker.lorem.words({ min: 1, max: 5 }); + const layerRequest = generateNewLayerRequest(); + layerRequest.metadata = { ...layerRequest.metadata, keywords }; + const createJobResponse: ICreateJobResponse = { id: faker.string.uuid(), taskIds: [faker.string.uuid()] }; + mockValidateManager.validateGpkgsSources.mockResolvedValue(undefined); + mockValidateManager.validateShapefiles.mockResolvedValue(undefined); + mockInfoManager.getGpkgsInformation.mockResolvedValue(undefined); + productManager.read.mockResolvedValue(undefined); + mockGeoValidator.validate.mockResolvedValue(undefined); + existsMapproxySpy.mockResolvedValue(false); + existsCatalogSpy.mockResolvedValue(false); + findJobsSpy.mockResolvedValue([]); + calcualteChecksumSpy.mockResolvedValue(generateChecksum()); + createIngestionJobSpy.mockResolvedValue(createJobResponse); + + await ingestionManager.newLayer(layerRequest); + + expect(createIngestionJobSpy).toHaveBeenCalledWith( + expect.objectContaining({ + parameters: expect.objectContaining({ + metadata: expect.objectContaining({ keywords }), + }), + }) + ); + }); + it('should throw unsupported entity error when shapefile not found error', async () => { const layerRequest = generateNewLayerRequest(); const expectedErrorMessage = 'error message'; @@ -431,6 +458,34 @@ describe('IngestionManager', () => { expect(createIngestionJobSpy).toHaveBeenCalledWith(expect.objectContaining({ type: ingestionUpdateJobType })); }); + it('should pass keywords through to the ingestion job params when keywords is set in update layer metadata', async () => { + const keywords = faker.lorem.words({ min: 1, max: 5 }); + const layerRequest = generateUpdateLayerRequest(); + layerRequest.metadata = { ...layerRequest.metadata, keywords }; + const catalogLayerResponse = generateCatalogLayerResponse(); + const createJobResponse: ICreateJobResponse = { id: faker.string.uuid(), taskIds: [faker.string.uuid()] }; + findByIdSpy.mockResolvedValue([catalogLayerResponse]); + mockValidateManager.validateShapefiles.mockResolvedValue(undefined); + mockValidateManager.validateGpkgsSources.mockResolvedValue(undefined); + mockInfoManager.getGpkgsInformation.mockResolvedValue(undefined); + productManager.read.mockResolvedValue(undefined); + mockGeoValidator.validate.mockResolvedValue(undefined); + existsMapproxySpy.mockResolvedValue(true); + findJobsSpy.mockResolvedValue([]); + calcualteChecksumSpy.mockResolvedValue(generateChecksum()); + createIngestionJobSpy.mockResolvedValue(createJobResponse); + + await ingestionManager.updateLayer(catalogLayerResponse.metadata.id, layerRequest); + + expect(createIngestionJobSpy).toHaveBeenCalledWith( + expect.objectContaining({ + parameters: expect.objectContaining({ + metadata: expect.objectContaining({ keywords }), + }), + }) + ); + }); + it('should not throw any errors when the request is valid and create update swap job', async () => { const catalogLayerResponse = generateCatalogLayerResponse(); const layerRequest = { From ba634c679c499cb5e99bdd22de7a88aea2363364 Mon Sep 17 00:00:00 2001 From: Roi Cohen <213414225+roicohen326@users.noreply.github.com> Date: Mon, 22 Jun 2026 11:36:01 +0300 Subject: [PATCH 2/8] fix: define keywords schema inline and remove redundant unit tests --- openapi3.yaml | 6 +- tests/mocks/mockFactory.ts | 7 +-- .../ingestion/models/ingestionManager.spec.ts | 55 ------------------- 3 files changed, 5 insertions(+), 63 deletions(-) diff --git a/openapi3.yaml b/openapi3.yaml index e8e224e..3b4d237 100644 --- a/openapi3.yaml +++ b/openapi3.yaml @@ -460,7 +460,8 @@ components: classification: $ref: ./Schema/core/layerMetadata.yaml#/components/schemas/Classification keywords: - $ref: ./Schema/core/layerMetadata.yaml#/components/schemas/Keywords + type: string + description: Layer's keywords IngestionNewLayerRequest: type: object required: @@ -490,7 +491,8 @@ components: classification: $ref: ./Schema/core/layerMetadata.yaml#/components/schemas/Classification keywords: - $ref: ./Schema/core/layerMetadata.yaml#/components/schemas/Keywords + type: string + description: Layer's keywords IngestionUpdateLayerRequest: type: object required: diff --git a/tests/mocks/mockFactory.ts b/tests/mocks/mockFactory.ts index b8cb372..861227a 100644 --- a/tests/mocks/mockFactory.ts +++ b/tests/mocks/mockFactory.ts @@ -506,12 +506,7 @@ export const createUpdateJobRequest = ( const sourceMount = configMock.get('storageExplorer.layerSourceDir'); const updateJobAction = isSwapUpdate ? swapUpdateJobType : updateJobType; - const { - ingestionResolution, - inputFiles, - metadata, - callbackUrls, - } = ingestionUpdateLayer; + const { ingestionResolution, inputFiles, metadata, callbackUrls } = ingestionUpdateLayer; const { displayPath, id, productId, productType, productVersion, productName, tileOutputFormat } = rasterLayerMetadata; return { diff --git a/tests/unit/ingestion/models/ingestionManager.spec.ts b/tests/unit/ingestion/models/ingestionManager.spec.ts index d6f95da..b413703 100644 --- a/tests/unit/ingestion/models/ingestionManager.spec.ts +++ b/tests/unit/ingestion/models/ingestionManager.spec.ts @@ -193,33 +193,6 @@ describe('IngestionManager', () => { ); }); - it('should pass keywords through to the ingestion job params when keywords is set in metadata', async () => { - const keywords = faker.lorem.words({ min: 1, max: 5 }); - const layerRequest = generateNewLayerRequest(); - layerRequest.metadata = { ...layerRequest.metadata, keywords }; - const createJobResponse: ICreateJobResponse = { id: faker.string.uuid(), taskIds: [faker.string.uuid()] }; - mockValidateManager.validateGpkgsSources.mockResolvedValue(undefined); - mockValidateManager.validateShapefiles.mockResolvedValue(undefined); - mockInfoManager.getGpkgsInformation.mockResolvedValue(undefined); - productManager.read.mockResolvedValue(undefined); - mockGeoValidator.validate.mockResolvedValue(undefined); - existsMapproxySpy.mockResolvedValue(false); - existsCatalogSpy.mockResolvedValue(false); - findJobsSpy.mockResolvedValue([]); - calcualteChecksumSpy.mockResolvedValue(generateChecksum()); - createIngestionJobSpy.mockResolvedValue(createJobResponse); - - await ingestionManager.newLayer(layerRequest); - - expect(createIngestionJobSpy).toHaveBeenCalledWith( - expect.objectContaining({ - parameters: expect.objectContaining({ - metadata: expect.objectContaining({ keywords }), - }), - }) - ); - }); - it('should throw unsupported entity error when shapefile not found error', async () => { const layerRequest = generateNewLayerRequest(); const expectedErrorMessage = 'error message'; @@ -458,34 +431,6 @@ describe('IngestionManager', () => { expect(createIngestionJobSpy).toHaveBeenCalledWith(expect.objectContaining({ type: ingestionUpdateJobType })); }); - it('should pass keywords through to the ingestion job params when keywords is set in update layer metadata', async () => { - const keywords = faker.lorem.words({ min: 1, max: 5 }); - const layerRequest = generateUpdateLayerRequest(); - layerRequest.metadata = { ...layerRequest.metadata, keywords }; - const catalogLayerResponse = generateCatalogLayerResponse(); - const createJobResponse: ICreateJobResponse = { id: faker.string.uuid(), taskIds: [faker.string.uuid()] }; - findByIdSpy.mockResolvedValue([catalogLayerResponse]); - mockValidateManager.validateShapefiles.mockResolvedValue(undefined); - mockValidateManager.validateGpkgsSources.mockResolvedValue(undefined); - mockInfoManager.getGpkgsInformation.mockResolvedValue(undefined); - productManager.read.mockResolvedValue(undefined); - mockGeoValidator.validate.mockResolvedValue(undefined); - existsMapproxySpy.mockResolvedValue(true); - findJobsSpy.mockResolvedValue([]); - calcualteChecksumSpy.mockResolvedValue(generateChecksum()); - createIngestionJobSpy.mockResolvedValue(createJobResponse); - - await ingestionManager.updateLayer(catalogLayerResponse.metadata.id, layerRequest); - - expect(createIngestionJobSpy).toHaveBeenCalledWith( - expect.objectContaining({ - parameters: expect.objectContaining({ - metadata: expect.objectContaining({ keywords }), - }), - }) - ); - }); - it('should not throw any errors when the request is valid and create update swap job', async () => { const catalogLayerResponse = generateCatalogLayerResponse(); const layerRequest = { From 610f54778b8f2a2db9cee14ab0c030a83dbb1b84 Mon Sep 17 00:00:00 2001 From: Roi Cohen <213414225+roicohen326@users.noreply.github.com> Date: Wed, 24 Jun 2026 16:23:12 +0300 Subject: [PATCH 3/8] refactor: reference shared Keywords schema instead of inline definition Replace the temporary inline keywords definition (added while raster-shared lacked the field) with a $ref to the shared Keywords schema, matching every other metadata field. PENDING (do after raster-shared #208 publishes): - bump @map-colonies/raster-shared to the version that includes Keywords - re-run copySchema so Schema/core/layerMetadata.yaml gains Keywords Until then this branch will not build (the $ref target does not yet exist). --- openapi3.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/openapi3.yaml b/openapi3.yaml index 3b4d237..e8e224e 100644 --- a/openapi3.yaml +++ b/openapi3.yaml @@ -460,8 +460,7 @@ components: classification: $ref: ./Schema/core/layerMetadata.yaml#/components/schemas/Classification keywords: - type: string - description: Layer's keywords + $ref: ./Schema/core/layerMetadata.yaml#/components/schemas/Keywords IngestionNewLayerRequest: type: object required: @@ -491,8 +490,7 @@ components: classification: $ref: ./Schema/core/layerMetadata.yaml#/components/schemas/Classification keywords: - type: string - description: Layer's keywords + $ref: ./Schema/core/layerMetadata.yaml#/components/schemas/Keywords IngestionUpdateLayerRequest: type: object required: From 70fd23833590910e7cf9750da52e4e1ca3adcf5d Mon Sep 17 00:00:00 2001 From: Roi Cohen <213414225+roicohen326@users.noreply.github.com> Date: Thu, 25 Jun 2026 10:26:42 +0300 Subject: [PATCH 4/8] feat: concatenate keywords on update, overwrite on swap --- src/ingestion/models/ingestionManager.ts | 15 +++++ src/ingestion/schemas/layerCatalogSchema.ts | 1 + tests/mocks/mockFactory.ts | 1 + .../ingestion/models/ingestionManager.spec.ts | 62 +++++++++++++++++++ 4 files changed, 79 insertions(+) diff --git a/src/ingestion/models/ingestionManager.ts b/src/ingestion/models/ingestionManager.ts index 7f09592..6e3540f 100644 --- a/src/ingestion/models/ingestionManager.ts +++ b/src/ingestion/models/ingestionManager.ts @@ -637,8 +637,13 @@ export class IngestionManager { const relativeChecksums = this.convertChecksumsToRelativePaths(checksums); const taskParameters: IngestionValidationTaskParams = { checksums: relativeChecksums }; + const keywords = isSwapUpdate + ? updateLayer.metadata.keywords + : this.mergeKeywords(rasterLayerMetadata.keywords, updateLayer.metadata.keywords); + const updateLayerRelative = { ...updateLayer, + metadata: { ...updateLayer.metadata, keywords }, ...{ inputFiles: { metadataShapefilePath: updateLayer.inputFiles.metadataShapefilePath.relative, @@ -671,6 +676,16 @@ export class IngestionManager { return createJobRequest; } + private mergeKeywords(existing: string | undefined, incoming: string | undefined): string | undefined { + const toTokens = (value: string | undefined): string[] => + (value ?? '') + .split(',') + .map((keyword) => keyword.trim()) + .filter((keyword) => keyword.length > 0); + const merged = [...new Set([...toTokens(existing), ...toTokens(incoming)])]; + return merged.length > 0 ? merged.join(',') : undefined; + } + @withSpanAsyncV4 private async getChecksum(shapefilePath: string): Promise { const checksums = await Promise.all(getShapefileFiles(shapefilePath).map(async (fileName) => this.getFileChecksum(fileName))); diff --git a/src/ingestion/schemas/layerCatalogSchema.ts b/src/ingestion/schemas/layerCatalogSchema.ts index ebe9c2a..ad52a3c 100644 --- a/src/ingestion/schemas/layerCatalogSchema.ts +++ b/src/ingestion/schemas/layerCatalogSchema.ts @@ -91,6 +91,7 @@ export const rasterLayerCatalogSchema = z message: 'Product bounding box must be of the shape min_x,min_y,max_x,max_y', }) .optional(), + keywords: z.string().optional(), displayPath: z.string().uuid(), transparency: z.nativeEnum(Transparency), tileMimeFormat: tilesMimeFormatSchema, diff --git a/tests/mocks/mockFactory.ts b/tests/mocks/mockFactory.ts index 861227a..d09913c 100644 --- a/tests/mocks/mockFactory.ts +++ b/tests/mocks/mockFactory.ts @@ -272,6 +272,7 @@ export const rasterLayerMetadataGenerators: RasterLayerMetadataPropertiesGenerat description: (): string => generateHebrewAlphanumeric({ min: 0, max: 100 }), producerName: (): string => generateHebrewAlphanumeric({ min: 0, max: 100 }), productSubType: (): string => generateHebrewAlphanumeric({ min: 0, max: 100 }), + keywords: (): string => faker.lorem.words({ min: 1, max: 5 }).split(' ').join(','), scale: (): number => faker.number.int({ min: INGESTION_VALIDATIONS.scale.min, max: INGESTION_VALIDATIONS.scale.max }), srs: (): '4326' => '4326', srsName: (): 'WGS84GEO' => 'WGS84GEO', diff --git a/tests/unit/ingestion/models/ingestionManager.spec.ts b/tests/unit/ingestion/models/ingestionManager.spec.ts index b413703..8d0d7e3 100644 --- a/tests/unit/ingestion/models/ingestionManager.spec.ts +++ b/tests/unit/ingestion/models/ingestionManager.spec.ts @@ -460,6 +460,68 @@ describe('IngestionManager', () => { expect(createIngestionJobSpy).toHaveBeenCalledWith(expect.objectContaining({ type: ingestionSwapUpdateJobType })); }); + it('should concatenate new keywords onto the existing ones, deduplicated, on a regular update', async () => { + const catalogLayerResponse = generateCatalogLayerResponse(); + catalogLayerResponse.metadata.keywords = 'forest,urban'; + const layerRequest = generateUpdateLayerRequest(); + layerRequest.metadata.keywords = 'urban,coast'; + const createJobResponse: ICreateJobResponse = { id: faker.string.uuid(), taskIds: [faker.string.uuid()] }; + findByIdSpy.mockResolvedValue([catalogLayerResponse]); + mockValidateManager.validateShapefiles.mockResolvedValue(undefined); + mockValidateManager.validateGpkgsSources.mockResolvedValue(undefined); + mockInfoManager.getGpkgsInformation.mockResolvedValue(undefined); + productManager.read.mockResolvedValue(undefined); + mockGeoValidator.validate.mockResolvedValue(undefined); + existsMapproxySpy.mockResolvedValue(true); + findJobsSpy.mockResolvedValue([]); + calcualteChecksumSpy.mockResolvedValue(generateChecksum()); + createIngestionJobSpy.mockResolvedValue(createJobResponse); + + await ingestionManager.updateLayer(catalogLayerResponse.metadata.id, layerRequest); + + expect(createIngestionJobSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: ingestionUpdateJobType, + parameters: expect.objectContaining({ metadata: expect.objectContaining({ keywords: 'forest,urban,coast' }) }), + }) + ); + }); + + it('should overwrite keywords with the new value on a swap update', async () => { + const baseCatalogLayerResponse = generateCatalogLayerResponse(); + const catalogLayerResponse = { + ...baseCatalogLayerResponse, + metadata: { + ...baseCatalogLayerResponse.metadata, + productType: ingestionSwapUpdateProductType, + productSubType: ingestionSwapUpdateProductSubType, + keywords: 'forest,urban', + }, + }; + const layerRequest = generateUpdateLayerRequest(); + layerRequest.metadata.keywords = 'urban,coast'; + const createJobResponse: ICreateJobResponse = { id: faker.string.uuid(), taskIds: [faker.string.uuid()] }; + findByIdSpy.mockResolvedValue([catalogLayerResponse]); + mockValidateManager.validateShapefiles.mockResolvedValue(undefined); + mockValidateManager.validateGpkgsSources.mockResolvedValue(undefined); + mockInfoManager.getGpkgsInformation.mockResolvedValue(undefined); + productManager.read.mockResolvedValue(undefined); + mockGeoValidator.validate.mockResolvedValue(undefined); + existsMapproxySpy.mockResolvedValue(true); + findJobsSpy.mockResolvedValue([]); + calcualteChecksumSpy.mockResolvedValue(generateChecksum()); + createIngestionJobSpy.mockResolvedValue(createJobResponse); + + await ingestionManager.updateLayer(catalogLayerResponse.metadata.id, layerRequest); + + expect(createIngestionJobSpy).toHaveBeenCalledWith( + expect.objectContaining({ + type: ingestionSwapUpdateJobType, + parameters: expect.objectContaining({ metadata: expect.objectContaining({ keywords: 'urban,coast' }) }), + }) + ); + }); + it('should throw not found error when there is no layer in catalog', async () => { const layerRequest = generateUpdateLayerRequest(); const catalogLayerResponse = generateCatalogLayerResponse(); From bc2bbb93ad5246c6fa63ddfc10e95d5d2af6866c Mon Sep 17 00:00:00 2001 From: Roi Cohen <213414225+roicohen326@users.noreply.github.com> Date: Wed, 1 Jul 2026 17:39:51 +0300 Subject: [PATCH 5/8] chore: bump @map-colonies/raster-shared to 8.3.0-alpha.0 --- package-lock.json | 216 +++++++++++++++++++++++++++++++--------------- package.json | 2 +- 2 files changed, 149 insertions(+), 69 deletions(-) diff --git a/package-lock.json b/package-lock.json index 54b6b5c..ef92d7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "@map-colonies/mc-utils": "^5.1.0", "@map-colonies/openapi-express-viewer": "^3.0.0", "@map-colonies/prometheus": "^1.0.0", - "@map-colonies/raster-shared": "^8.1.0", + "@map-colonies/raster-shared": "8.3.0-alpha.0", "@map-colonies/read-pkg": "0.0.1", "@map-colonies/schemas": "^1.17.0", "@map-colonies/shapefile-reader": "^1.0.1", @@ -166,7 +166,6 @@ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -946,7 +945,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -959,7 +958,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -2412,7 +2411,6 @@ "resolved": "https://registry.npmjs.org/@map-colonies/error-types/-/error-types-1.3.1.tgz", "integrity": "sha512-ZcXiCYcjk4SBhAxO6JGJZ9cmiCInBULpisrnTViPsdxtfk+1a6XG/sKXop5U5se6xQZ77L43ZEUhiwvE7FsaPA==", "license": "ISC", - "peer": true, "dependencies": { "@map-colonies/error-express-handler": "^2.0.0", "express": "^4.17.1", @@ -2564,7 +2562,6 @@ "resolved": "https://registry.npmjs.org/pino/-/pino-10.3.1.tgz", "integrity": "sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg==", "license": "MIT", - "peer": true, "dependencies": { "@pinojs/redact": "^0.4.0", "atomic-sleep": "^1.0.0", @@ -2718,6 +2715,7 @@ "resolved": "https://registry.npmjs.org/@turf/along/-/along-6.5.0.tgz", "integrity": "sha512-LLyWQ0AARqJCmMcIEAXF4GEu8usmd4Kbz3qk1Oy5HoRNpZX47+i5exQtmIWKdqJ1MMhW26fCTXgpsEs5zgJ5gw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bearing": "^6.5.0", "@turf/destination": "^6.5.0", @@ -2734,6 +2732,7 @@ "resolved": "https://registry.npmjs.org/@turf/angle/-/angle-6.5.0.tgz", "integrity": "sha512-4pXMbWhFofJJAOvTMCns6N4C8CMd5Ih4O2jSAG9b3dDHakj3O4yN1+Zbm+NUei+eVEZ9gFeVp9svE3aMDenIkw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bearing": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -2749,6 +2748,7 @@ "resolved": "https://registry.npmjs.org/@turf/area/-/area-6.5.0.tgz", "integrity": "sha512-xCZdiuojokLbQ+29qR6qoMD89hv+JAgWjLrwSEWL+3JV8IXKeNFl6XkEJz9HGkVpnXvQKJoRz4/liT+8ZZ5Jyg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/meta": "^6.5.0" @@ -2762,6 +2762,7 @@ "resolved": "https://registry.npmjs.org/@turf/bbox/-/bbox-6.5.0.tgz", "integrity": "sha512-RBbLaao5hXTYyyg577iuMtDB8ehxMlUqHEJiMs8jT1GHkFhr6sYre3lmLsPeYEi/ZKj5TP5tt7fkzNdJ4GIVyw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/meta": "^6.5.0" @@ -2775,6 +2776,7 @@ "resolved": "https://registry.npmjs.org/@turf/bbox-clip/-/bbox-clip-6.5.0.tgz", "integrity": "sha512-F6PaIRF8WMp8EmgU/Ke5B1Y6/pia14UAYB5TiBC668w5rVVjy5L8rTm/m2lEkkDMHlzoP9vNY4pxpNthE7rLcQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -2788,6 +2790,7 @@ "resolved": "https://registry.npmjs.org/@turf/bbox-polygon/-/bbox-polygon-6.5.0.tgz", "integrity": "sha512-+/r0NyL1lOG3zKZmmf6L8ommU07HliP4dgYToMoTxqzsWzyLjaj/OzgQ8rBmv703WJX+aS6yCmLuIhYqyufyuw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0" }, @@ -2800,6 +2803,7 @@ "resolved": "https://registry.npmjs.org/@turf/bearing/-/bearing-6.5.0.tgz", "integrity": "sha512-dxINYhIEMzgDOztyMZc20I7ssYVNEpSv04VbMo5YPQsqa80KO3TFvbuCahMsCAW5z8Tncc8dwBlEFrmRjJG33A==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -2813,6 +2817,7 @@ "resolved": "https://registry.npmjs.org/@turf/bezier-spline/-/bezier-spline-6.5.0.tgz", "integrity": "sha512-vokPaurTd4PF96rRgGVm6zYYC5r1u98ZsG+wZEv9y3kJTuJRX/O3xIY2QnTGTdbVmAJN1ouOsD0RoZYaVoXORQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -2826,6 +2831,7 @@ "resolved": "https://registry.npmjs.org/@turf/boolean-clockwise/-/boolean-clockwise-6.5.0.tgz", "integrity": "sha512-45+C7LC5RMbRWrxh3Z0Eihsc8db1VGBO5d9BLTOAwU4jR6SgsunTfRWR16X7JUwIDYlCVEmnjcXJNi/kIU3VIw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -2839,6 +2845,7 @@ "resolved": "https://registry.npmjs.org/@turf/boolean-contains/-/boolean-contains-6.5.0.tgz", "integrity": "sha512-4m8cJpbw+YQcKVGi8y0cHhBUnYT+QRfx6wzM4GI1IdtYH3p4oh/DOBJKrepQyiDzFDaNIjxuWXBh0ai1zVwOQQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bbox": "^6.5.0", "@turf/boolean-point-in-polygon": "^6.5.0", @@ -2855,6 +2862,7 @@ "resolved": "https://registry.npmjs.org/@turf/boolean-crosses/-/boolean-crosses-6.5.0.tgz", "integrity": "sha512-gvshbTPhAHporTlQwBJqyfW+2yV8q/mOTxG6PzRVl6ARsqNoqYQWkd4MLug7OmAqVyBzLK3201uAeBjxbGw0Ng==", "license": "MIT", + "peer": true, "dependencies": { "@turf/boolean-point-in-polygon": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -2871,6 +2879,7 @@ "resolved": "https://registry.npmjs.org/@turf/boolean-disjoint/-/boolean-disjoint-6.5.0.tgz", "integrity": "sha512-rZ2ozlrRLIAGo2bjQ/ZUu4oZ/+ZjGvLkN5CKXSKBcu6xFO6k2bgqeM8a1836tAW+Pqp/ZFsTA5fZHsJZvP2D5g==", "license": "MIT", + "peer": true, "dependencies": { "@turf/boolean-point-in-polygon": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -2887,6 +2896,7 @@ "resolved": "https://registry.npmjs.org/@turf/boolean-equal/-/boolean-equal-6.5.0.tgz", "integrity": "sha512-cY0M3yoLC26mhAnjv1gyYNQjn7wxIXmL2hBmI/qs8g5uKuC2hRWi13ydufE3k4x0aNRjFGlg41fjoYLwaVF+9Q==", "license": "MIT", + "peer": true, "dependencies": { "@turf/clean-coords": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -2902,6 +2912,7 @@ "resolved": "https://registry.npmjs.org/@turf/boolean-intersects/-/boolean-intersects-6.5.0.tgz", "integrity": "sha512-nIxkizjRdjKCYFQMnml6cjPsDOBCThrt+nkqtSEcxkKMhAQj5OO7o2CecioNTaX8EayqwMGVKcsz27oP4mKPTw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/boolean-disjoint": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -2916,6 +2927,7 @@ "resolved": "https://registry.npmjs.org/@turf/boolean-overlap/-/boolean-overlap-6.5.0.tgz", "integrity": "sha512-8btMIdnbXVWUa1M7D4shyaSGxLRw6NjMcqKBcsTXcZdnaixl22k7ar7BvIzkaRYN3SFECk9VGXfLncNS3ckQUw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0", @@ -2933,6 +2945,7 @@ "resolved": "https://registry.npmjs.org/@turf/boolean-parallel/-/boolean-parallel-6.5.0.tgz", "integrity": "sha512-aSHJsr1nq9e5TthZGZ9CZYeXklJyRgR5kCLm5X4urz7+MotMOp/LsGOsvKvK9NeUl9+8OUmfMn8EFTT8LkcvIQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/clean-coords": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -2948,6 +2961,7 @@ "resolved": "https://registry.npmjs.org/@turf/boolean-point-in-polygon/-/boolean-point-in-polygon-6.5.0.tgz", "integrity": "sha512-DtSuVFB26SI+hj0SjrvXowGTUCHlgevPAIsukssW6BG5MlNSBQAo70wpICBNJL6RjukXg8d2eXaAWuD/CqL00A==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -2961,6 +2975,7 @@ "resolved": "https://registry.npmjs.org/@turf/boolean-point-on-line/-/boolean-point-on-line-6.5.0.tgz", "integrity": "sha512-A1BbuQ0LceLHvq7F/P7w3QvfpmZqbmViIUPHdNLvZimFNLo4e6IQunmzbe+8aSStH9QRZm3VOflyvNeXvvpZEQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -2974,6 +2989,7 @@ "resolved": "https://registry.npmjs.org/@turf/boolean-within/-/boolean-within-6.5.0.tgz", "integrity": "sha512-YQB3oU18Inx35C/LU930D36RAVe7LDXk1kWsQ8mLmuqYn9YdPsDQTMTkLJMhoQ8EbN7QTdy333xRQ4MYgToteQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bbox": "^6.5.0", "@turf/boolean-point-in-polygon": "^6.5.0", @@ -2990,6 +3006,7 @@ "resolved": "https://registry.npmjs.org/@turf/buffer/-/buffer-6.5.0.tgz", "integrity": "sha512-qeX4N6+PPWbKqp1AVkBVWFerGjMYMUyencwfnkCesoznU6qvfugFHNAngNqIBVnJjZ5n8IFyOf+akcxnrt9sNg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bbox": "^6.5.0", "@turf/center": "^6.5.0", @@ -3008,6 +3025,7 @@ "resolved": "https://registry.npmjs.org/@turf/center/-/center-6.5.0.tgz", "integrity": "sha512-T8KtMTfSATWcAX088rEDKjyvQCBkUsLnK/Txb6/8WUXIeOZyHu42G7MkdkHRoHtwieLdduDdmPLFyTdG5/e7ZQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bbox": "^6.5.0", "@turf/helpers": "^6.5.0" @@ -3021,6 +3039,7 @@ "resolved": "https://registry.npmjs.org/@turf/center-mean/-/center-mean-6.5.0.tgz", "integrity": "sha512-AAX6f4bVn12pTVrMUiB9KrnV94BgeBKpyg3YpfnEbBpkN/znfVhL8dG8IxMAxAoSZ61Zt9WLY34HfENveuOZ7Q==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bbox": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -3035,6 +3054,7 @@ "resolved": "https://registry.npmjs.org/@turf/center-median/-/center-median-6.5.0.tgz", "integrity": "sha512-dT8Ndu5CiZkPrj15PBvslpuf01ky41DEYEPxS01LOxp5HOUHXp1oJxsPxvc+i/wK4BwccPNzU1vzJ0S4emd1KQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/center-mean": "^6.5.0", "@turf/centroid": "^6.5.0", @@ -3051,6 +3071,7 @@ "resolved": "https://registry.npmjs.org/@turf/center-of-mass/-/center-of-mass-6.5.0.tgz", "integrity": "sha512-EWrriU6LraOfPN7m1jZi+1NLTKNkuIsGLZc2+Y8zbGruvUW+QV7K0nhf7iZWutlxHXTBqEXHbKue/o79IumAsQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/centroid": "^6.5.0", "@turf/convex": "^6.5.0", @@ -3067,6 +3088,7 @@ "resolved": "https://registry.npmjs.org/@turf/centroid/-/centroid-6.5.0.tgz", "integrity": "sha512-MwE1oq5E3isewPprEClbfU5pXljIK/GUOMbn22UM3IFPDJX0KeoyLNwghszkdmFp/qMGL/M13MMWvU+GNLXP/A==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/meta": "^6.5.0" @@ -3080,6 +3102,7 @@ "resolved": "https://registry.npmjs.org/@turf/circle/-/circle-6.5.0.tgz", "integrity": "sha512-oU1+Kq9DgRnoSbWFHKnnUdTmtcRUMmHoV9DjTXu9vOLNV5OWtAAh1VZ+mzsioGGzoDNT/V5igbFOkMfBQc0B6A==", "license": "MIT", + "peer": true, "dependencies": { "@turf/destination": "^6.5.0", "@turf/helpers": "^6.5.0" @@ -3093,6 +3116,7 @@ "resolved": "https://registry.npmjs.org/@turf/clean-coords/-/clean-coords-6.5.0.tgz", "integrity": "sha512-EMX7gyZz0WTH/ET7xV8MyrExywfm9qUi0/MY89yNffzGIEHuFfqwhcCqZ8O00rZIPZHUTxpmsxQSTfzJJA1CPw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -3106,6 +3130,7 @@ "resolved": "https://registry.npmjs.org/@turf/clone/-/clone-6.5.0.tgz", "integrity": "sha512-mzVtTFj/QycXOn6ig+annKrM6ZlimreKYz6f/GSERytOpgzodbQyOgkfwru100O1KQhhjSudKK4DsQ0oyi9cTw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0" }, @@ -3118,6 +3143,7 @@ "resolved": "https://registry.npmjs.org/@turf/clusters/-/clusters-6.5.0.tgz", "integrity": "sha512-Y6gfnTJzQ1hdLfCsyd5zApNbfLIxYEpmDibHUqR5z03Lpe02pa78JtgrgUNt1seeO/aJ4TG1NLN8V5gOrHk04g==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/meta": "^6.5.0" @@ -3131,6 +3157,7 @@ "resolved": "https://registry.npmjs.org/@turf/clusters-dbscan/-/clusters-dbscan-6.5.0.tgz", "integrity": "sha512-SxZEE4kADU9DqLRiT53QZBBhu8EP9skviSyl+FGj08Y01xfICM/RR9ACUdM0aEQimhpu+ZpRVcUK+2jtiCGrYQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/clone": "^6.5.0", "@turf/distance": "^6.5.0", @@ -3147,6 +3174,7 @@ "resolved": "https://registry.npmjs.org/@turf/clusters-kmeans/-/clusters-kmeans-6.5.0.tgz", "integrity": "sha512-DwacD5+YO8kwDPKaXwT9DV46tMBVNsbi1IzdajZu1JDSWoN7yc7N9Qt88oi+p30583O0UPVkAK+A10WAQv4mUw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/clone": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -3163,6 +3191,7 @@ "resolved": "https://registry.npmjs.org/@turf/collect/-/collect-6.5.0.tgz", "integrity": "sha512-4dN/T6LNnRg099m97BJeOcTA5fSI8cu87Ydgfibewd2KQwBexO69AnjEFqfPX3Wj+Zvisj1uAVIZbPmSSrZkjg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bbox": "^6.5.0", "@turf/boolean-point-in-polygon": "^6.5.0", @@ -3178,6 +3207,7 @@ "resolved": "https://registry.npmjs.org/@turf/combine/-/combine-6.5.0.tgz", "integrity": "sha512-Q8EIC4OtAcHiJB3C4R+FpB4LANiT90t17uOd851qkM2/o6m39bfN5Mv0PWqMZIHWrrosZqRqoY9dJnzz/rJxYQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/meta": "^6.5.0" @@ -3191,6 +3221,7 @@ "resolved": "https://registry.npmjs.org/@turf/concave/-/concave-6.5.0.tgz", "integrity": "sha512-I/sUmUC8TC5h/E2vPwxVht+nRt+TnXIPRoztDFvS8/Y0+cBDple9inLSo9nnPXMXidrBlGXZ9vQx/BjZUJgsRQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/clone": "^6.5.0", "@turf/distance": "^6.5.0", @@ -3210,6 +3241,7 @@ "resolved": "https://registry.npmjs.org/@turf/convex/-/convex-6.5.0.tgz", "integrity": "sha512-x7ZwC5z7PJB0SBwNh7JCeCNx7Iu+QSrH7fYgK0RhhNop13TqUlvHMirMLRgf2db1DqUetrAO2qHJeIuasquUWg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/meta": "^6.5.0", @@ -3224,6 +3256,7 @@ "resolved": "https://registry.npmjs.org/@turf/destination/-/destination-6.5.0.tgz", "integrity": "sha512-4cnWQlNC8d1tItOz9B4pmJdWpXqS0vEvv65bI/Pj/genJnsL7evI0/Xw42RvEGROS481MPiU80xzvwxEvhQiMQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -3237,6 +3270,7 @@ "resolved": "https://registry.npmjs.org/@turf/difference/-/difference-6.5.0.tgz", "integrity": "sha512-l8iR5uJqvI+5Fs6leNbhPY5t/a3vipUF/3AeVLpwPQcgmedNXyheYuy07PcMGH5Jdpi5gItOiTqwiU/bUH4b3A==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0", @@ -3251,6 +3285,7 @@ "resolved": "https://registry.npmjs.org/@turf/dissolve/-/dissolve-6.5.0.tgz", "integrity": "sha512-WBVbpm9zLTp0Bl9CE35NomTaOL1c4TQCtEoO43YaAhNEWJOOIhZMFJyr8mbvYruKl817KinT3x7aYjjCMjTAsQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0", @@ -3266,6 +3301,7 @@ "resolved": "https://registry.npmjs.org/@turf/distance/-/distance-6.5.0.tgz", "integrity": "sha512-xzykSLfoURec5qvQJcfifw/1mJa+5UwByZZ5TZ8iaqjGYN0vomhV9aiSLeYdUGtYRESZ+DYC/OzY+4RclZYgMg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -3279,6 +3315,7 @@ "resolved": "https://registry.npmjs.org/@turf/distance-weight/-/distance-weight-6.5.0.tgz", "integrity": "sha512-a8qBKkgVNvPKBfZfEJZnC3DV7dfIsC3UIdpRci/iap/wZLH41EmS90nM+BokAJflUHYy8PqE44wySGWHN1FXrQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/centroid": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -3294,6 +3331,7 @@ "resolved": "https://registry.npmjs.org/@turf/ellipse/-/ellipse-6.5.0.tgz", "integrity": "sha512-kuXtwFviw/JqnyJXF1mrR/cb496zDTSbGKtSiolWMNImYzGGkbsAsFTjwJYgD7+4FixHjp0uQPzo70KDf3AIBw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0", @@ -3309,6 +3347,7 @@ "resolved": "https://registry.npmjs.org/@turf/envelope/-/envelope-6.5.0.tgz", "integrity": "sha512-9Z+FnBWvOGOU4X+fMZxYFs1HjFlkKqsddLuMknRaqcJd6t+NIv5DWvPtDL8ATD2GEExYDiFLwMdckfr1yqJgHA==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bbox": "^6.5.0", "@turf/bbox-polygon": "^6.5.0", @@ -3323,6 +3362,7 @@ "resolved": "https://registry.npmjs.org/@turf/explode/-/explode-6.5.0.tgz", "integrity": "sha512-6cSvMrnHm2qAsace6pw9cDmK2buAlw8+tjeJVXMfMyY+w7ZUi1rprWMsY92J7s2Dar63Bv09n56/1V7+tcj52Q==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/meta": "^6.5.0" @@ -3336,6 +3376,7 @@ "resolved": "https://registry.npmjs.org/@turf/flatten/-/flatten-6.5.0.tgz", "integrity": "sha512-IBZVwoNLVNT6U/bcUUllubgElzpMsNoCw8tLqBw6dfYg9ObGmpEjf9BIYLr7a2Yn5ZR4l7YIj2T7kD5uJjZADQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/meta": "^6.5.0" @@ -3349,6 +3390,7 @@ "resolved": "https://registry.npmjs.org/@turf/flip/-/flip-6.5.0.tgz", "integrity": "sha512-oyikJFNjt2LmIXQqgOGLvt70RgE2lyzPMloYWM7OR5oIFGRiBvqVD2hA6MNw6JewIm30fWZ8DQJw1NHXJTJPbg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/clone": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -3363,6 +3405,7 @@ "resolved": "https://registry.npmjs.org/@turf/great-circle/-/great-circle-6.5.0.tgz", "integrity": "sha512-7ovyi3HaKOXdFyN7yy1yOMa8IyOvV46RC1QOQTT+RYUN8ke10eyqExwBpL9RFUPvlpoTzoYbM/+lWPogQlFncg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -3376,6 +3419,7 @@ "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-6.5.0.tgz", "integrity": "sha512-VbI1dV5bLFzohYYdgqwikdMVpe7pJ9X3E+dlr425wa2/sMJqYDhTO++ec38/pcPvPE6oD9WEEeU3Xu3gza+VPw==", "license": "MIT", + "peer": true, "funding": { "url": "https://opencollective.com/turf" } @@ -3385,6 +3429,7 @@ "resolved": "https://registry.npmjs.org/@turf/hex-grid/-/hex-grid-6.5.0.tgz", "integrity": "sha512-Ln3tc2tgZT8etDOldgc6e741Smg1CsMKAz1/Mlel+MEL5Ynv2mhx3m0q4J9IB1F3a4MNjDeVvm8drAaf9SF33g==", "license": "MIT", + "peer": true, "dependencies": { "@turf/distance": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -3400,6 +3445,7 @@ "resolved": "https://registry.npmjs.org/@turf/interpolate/-/interpolate-6.5.0.tgz", "integrity": "sha512-LSH5fMeiGyuDZ4WrDJNgh81d2DnNDUVJtuFryJFup8PV8jbs46lQGfI3r1DJ2p1IlEJIz3pmAZYeTfMMoeeohw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bbox": "^6.5.0", "@turf/centroid": "^6.5.0", @@ -3422,6 +3468,7 @@ "resolved": "https://registry.npmjs.org/@turf/intersect/-/intersect-6.5.0.tgz", "integrity": "sha512-2legGJeKrfFkzntcd4GouPugoqPUjexPZnOvfez+3SfIMrHvulw8qV8u7pfVyn2Yqs53yoVCEjS5sEpvQ5YRQg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0", @@ -3436,6 +3483,7 @@ "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-6.5.0.tgz", "integrity": "sha512-Wv8PRNCtPD31UVbdJE/KVAWKe7l6US+lJItRR/HOEW3eh+U/JwRCSUl/KZ7bmjM/C+zLNoreM2TU6OoLACs4eg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0" }, @@ -3448,6 +3496,7 @@ "resolved": "https://registry.npmjs.org/@turf/isobands/-/isobands-6.5.0.tgz", "integrity": "sha512-4h6sjBPhRwMVuFaVBv70YB7eGz+iw0bhPRnp+8JBdX1UPJSXhoi/ZF2rACemRUr0HkdVB/a1r9gC32vn5IAEkw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/area": "^6.5.0", "@turf/bbox": "^6.5.0", @@ -3467,6 +3516,7 @@ "resolved": "https://registry.npmjs.org/@turf/isolines/-/isolines-6.5.0.tgz", "integrity": "sha512-6ElhiLCopxWlv4tPoxiCzASWt/jMRvmp6mRYrpzOm3EUl75OhHKa/Pu6Y9nWtCMmVC/RcWtiiweUocbPLZLm0A==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bbox": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -3483,6 +3533,7 @@ "resolved": "https://registry.npmjs.org/@turf/kinks/-/kinks-6.5.0.tgz", "integrity": "sha512-ViCngdPt1eEL7hYUHR2eHR662GvCgTc35ZJFaNR6kRtr6D8plLaDju0FILeFFWSc+o8e3fwxZEJKmFj9IzPiIQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0" }, @@ -3495,6 +3546,7 @@ "resolved": "https://registry.npmjs.org/@turf/length/-/length-6.5.0.tgz", "integrity": "sha512-5pL5/pnw52fck3oRsHDcSGrj9HibvtlrZ0QNy2OcW8qBFDNgZ4jtl6U7eATVoyWPKBHszW3dWETW+iLV7UARig==", "license": "MIT", + "peer": true, "dependencies": { "@turf/distance": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -3509,6 +3561,7 @@ "resolved": "https://registry.npmjs.org/@turf/line-arc/-/line-arc-6.5.0.tgz", "integrity": "sha512-I6c+V6mIyEwbtg9P9zSFF89T7QPe1DPTG3MJJ6Cm1MrAY0MdejwQKOpsvNl8LDU2ekHOlz2kHpPVR7VJsoMllA==", "license": "MIT", + "peer": true, "dependencies": { "@turf/circle": "^6.5.0", "@turf/destination": "^6.5.0", @@ -3523,6 +3576,7 @@ "resolved": "https://registry.npmjs.org/@turf/line-chunk/-/line-chunk-6.5.0.tgz", "integrity": "sha512-i1FGE6YJaaYa+IJesTfyRRQZP31QouS+wh/pa6O3CC0q4T7LtHigyBSYjrbjSLfn2EVPYGlPCMFEqNWCOkC6zg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/length": "^6.5.0", @@ -3538,6 +3592,7 @@ "resolved": "https://registry.npmjs.org/@turf/line-intersect/-/line-intersect-6.5.0.tgz", "integrity": "sha512-CS6R1tZvVQD390G9Ea4pmpM6mJGPWoL82jD46y0q1KSor9s6HupMIo1kY4Ny+AEYQl9jd21V3Scz20eldpbTVA==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0", @@ -3554,6 +3609,7 @@ "resolved": "https://registry.npmjs.org/@turf/line-offset/-/line-offset-6.5.0.tgz", "integrity": "sha512-CEXZbKgyz8r72qRvPchK0dxqsq8IQBdH275FE6o4MrBkzMcoZsfSjghtXzKaz9vvro+HfIXal0sTk2mqV1lQTw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0", @@ -3568,6 +3624,7 @@ "resolved": "https://registry.npmjs.org/@turf/line-overlap/-/line-overlap-6.5.0.tgz", "integrity": "sha512-xHOaWLd0hkaC/1OLcStCpfq55lPHpPNadZySDXYiYjEz5HXr1oKmtMYpn0wGizsLwrOixRdEp+j7bL8dPt4ojQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/boolean-point-on-line": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -3587,6 +3644,7 @@ "resolved": "https://registry.npmjs.org/@turf/line-segment/-/line-segment-6.5.0.tgz", "integrity": "sha512-jI625Ho4jSuJESNq66Mmi290ZJ5pPZiQZruPVpmHkUw257Pew0alMmb6YrqYNnLUuiVVONxAAKXUVeeUGtycfw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0", @@ -3601,6 +3659,7 @@ "resolved": "https://registry.npmjs.org/@turf/line-slice/-/line-slice-6.5.0.tgz", "integrity": "sha512-vDqJxve9tBHhOaVVFXqVjF5qDzGtKWviyjbyi2QnSnxyFAmLlLnBfMX8TLQCAf2GxHibB95RO5FBE6I2KVPRuw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0", @@ -3615,6 +3674,7 @@ "resolved": "https://registry.npmjs.org/@turf/line-slice-along/-/line-slice-along-6.5.0.tgz", "integrity": "sha512-KHJRU6KpHrAj+BTgTNqby6VCTnDzG6a1sJx/I3hNvqMBLvWVA2IrkR9L9DtsQsVY63IBwVdQDqiwCuZLDQh4Ng==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bearing": "^6.5.0", "@turf/destination": "^6.5.0", @@ -3630,6 +3690,7 @@ "resolved": "https://registry.npmjs.org/@turf/line-split/-/line-split-6.5.0.tgz", "integrity": "sha512-/rwUMVr9OI2ccJjw7/6eTN53URtGThNSD5I0GgxyFXMtxWiloRJ9MTff8jBbtPWrRka/Sh2GkwucVRAEakx9Sw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bbox": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -3651,6 +3712,7 @@ "resolved": "https://registry.npmjs.org/@turf/line-to-polygon/-/line-to-polygon-6.5.0.tgz", "integrity": "sha512-qYBuRCJJL8Gx27OwCD1TMijM/9XjRgXH/m/TyuND4OXedBpIWlK5VbTIO2gJ8OCfznBBddpjiObLBrkuxTpN4Q==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bbox": "^6.5.0", "@turf/clone": "^6.5.0", @@ -3666,6 +3728,7 @@ "resolved": "https://registry.npmjs.org/@turf/mask/-/mask-6.5.0.tgz", "integrity": "sha512-RQha4aU8LpBrmrkH8CPaaoAfk0Egj5OuXtv6HuCQnHeGNOQt3TQVibTA3Sh4iduq4EPxnZfDjgsOeKtrCA19lg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "polygon-clipping": "^0.15.3" @@ -3679,6 +3742,7 @@ "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-6.5.0.tgz", "integrity": "sha512-RrArvtsV0vdsCBegoBtOalgdSOfkBrTJ07VkpiCnq/491W67hnMWmDu7e6Ztw0C3WldRYTXkg3SumfdzZxLBHA==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0" }, @@ -3691,6 +3755,7 @@ "resolved": "https://registry.npmjs.org/@turf/midpoint/-/midpoint-6.5.0.tgz", "integrity": "sha512-MyTzV44IwmVI6ec9fB2OgZ53JGNlgOpaYl9ArKoF49rXpL84F9rNATndbe0+MQIhdkw8IlzA6xVP4lZzfMNVCw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bearing": "^6.5.0", "@turf/destination": "^6.5.0", @@ -3706,6 +3771,7 @@ "resolved": "https://registry.npmjs.org/@turf/moran-index/-/moran-index-6.5.0.tgz", "integrity": "sha512-ItsnhrU2XYtTtTudrM8so4afBCYWNaB0Mfy28NZwLjB5jWuAsvyV+YW+J88+neK/ougKMTawkmjQqodNJaBeLQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/distance-weight": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -3720,6 +3786,7 @@ "resolved": "https://registry.npmjs.org/@turf/nearest-point/-/nearest-point-6.5.0.tgz", "integrity": "sha512-fguV09QxilZv/p94s8SMsXILIAMiaXI5PATq9d7YWijLxWUj6Q/r43kxyoi78Zmwwh1Zfqz9w+bCYUAxZ5+euA==", "license": "MIT", + "peer": true, "dependencies": { "@turf/clone": "^6.5.0", "@turf/distance": "^6.5.0", @@ -3735,6 +3802,7 @@ "resolved": "https://registry.npmjs.org/@turf/nearest-point-on-line/-/nearest-point-on-line-6.5.0.tgz", "integrity": "sha512-WthrvddddvmymnC+Vf7BrkHGbDOUu6Z3/6bFYUGv1kxw8tiZ6n83/VG6kHz4poHOfS0RaNflzXSkmCi64fLBlg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bearing": "^6.5.0", "@turf/destination": "^6.5.0", @@ -3753,6 +3821,7 @@ "resolved": "https://registry.npmjs.org/@turf/nearest-point-to-line/-/nearest-point-to-line-6.5.0.tgz", "integrity": "sha512-PXV7cN0BVzUZdjj6oeb/ESnzXSfWmEMrsfZSDRgqyZ9ytdiIj/eRsnOXLR13LkTdXVOJYDBuf7xt1mLhM4p6+Q==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0", @@ -3769,6 +3838,7 @@ "resolved": "https://registry.npmjs.org/@turf/planepoint/-/planepoint-6.5.0.tgz", "integrity": "sha512-R3AahA6DUvtFbka1kcJHqZ7DMHmPXDEQpbU5WaglNn7NaCQg9HB0XM0ZfqWcd5u92YXV+Gg8QhC8x5XojfcM4Q==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -3782,6 +3852,7 @@ "resolved": "https://registry.npmjs.org/@turf/point-grid/-/point-grid-6.5.0.tgz", "integrity": "sha512-Iq38lFokNNtQJnOj/RBKmyt6dlof0yhaHEDELaWHuECm1lIZLY3ZbVMwbs+nXkwTAHjKfS/OtMheUBkw+ee49w==", "license": "MIT", + "peer": true, "dependencies": { "@turf/boolean-within": "^6.5.0", "@turf/distance": "^6.5.0", @@ -3797,6 +3868,7 @@ "resolved": "https://registry.npmjs.org/@turf/point-on-feature/-/point-on-feature-6.5.0.tgz", "integrity": "sha512-bDpuIlvugJhfcF/0awAQ+QI6Om1Y1FFYE8Y/YdxGRongivix850dTeXCo0mDylFdWFPGDo7Mmh9Vo4VxNwW/TA==", "license": "MIT", + "peer": true, "dependencies": { "@turf/boolean-point-in-polygon": "^6.5.0", "@turf/center": "^6.5.0", @@ -3813,6 +3885,7 @@ "resolved": "https://registry.npmjs.org/@turf/point-to-line-distance/-/point-to-line-distance-6.5.0.tgz", "integrity": "sha512-opHVQ4vjUhNBly1bob6RWy+F+hsZDH9SA0UW36pIRzfpu27qipU18xup0XXEePfY6+wvhF6yL/WgCO2IbrLqEA==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bearing": "^6.5.0", "@turf/distance": "^6.5.0", @@ -3832,6 +3905,7 @@ "resolved": "https://registry.npmjs.org/@turf/points-within-polygon/-/points-within-polygon-6.5.0.tgz", "integrity": "sha512-YyuheKqjliDsBDt3Ho73QVZk1VXX1+zIA2gwWvuz8bR1HXOkcuwk/1J76HuFMOQI3WK78wyAi+xbkx268PkQzQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/boolean-point-in-polygon": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -3846,6 +3920,7 @@ "resolved": "https://registry.npmjs.org/@turf/polygon-smooth/-/polygon-smooth-6.5.0.tgz", "integrity": "sha512-LO/X/5hfh/Rk4EfkDBpLlVwt3i6IXdtQccDT9rMjXEP32tRgy0VMFmdkNaXoGlSSKf/1mGqLl4y4wHd86DqKbg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/meta": "^6.5.0" @@ -3859,6 +3934,7 @@ "resolved": "https://registry.npmjs.org/@turf/polygon-tangents/-/polygon-tangents-6.5.0.tgz", "integrity": "sha512-sB4/IUqJMYRQH9jVBwqS/XDitkEfbyqRy+EH/cMRJURTg78eHunvJ708x5r6umXsbiUyQU4eqgPzEylWEQiunw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bbox": "^6.5.0", "@turf/boolean-within": "^6.5.0", @@ -3876,6 +3952,7 @@ "resolved": "https://registry.npmjs.org/@turf/polygon-to-line/-/polygon-to-line-6.5.0.tgz", "integrity": "sha512-5p4n/ij97EIttAq+ewSnKt0ruvuM+LIDzuczSzuHTpq4oS7Oq8yqg5TQ4nzMVuK41r/tALCk7nAoBuw3Su4Gcw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -3889,6 +3966,7 @@ "resolved": "https://registry.npmjs.org/@turf/polygonize/-/polygonize-6.5.0.tgz", "integrity": "sha512-a/3GzHRaCyzg7tVYHo43QUChCspa99oK4yPqooVIwTC61npFzdrmnywMv0S+WZjHZwK37BrFJGFrZGf6ocmY5w==", "license": "MIT", + "peer": true, "dependencies": { "@turf/boolean-point-in-polygon": "^6.5.0", "@turf/envelope": "^6.5.0", @@ -3905,6 +3983,7 @@ "resolved": "https://registry.npmjs.org/@turf/projection/-/projection-6.5.0.tgz", "integrity": "sha512-/Pgh9mDvQWWu8HRxqpM+tKz8OzgauV+DiOcr3FCjD6ubDnrrmMJlsf6fFJmggw93mtVPrZRL6yyi9aYCQBOIvg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/clone": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -3919,6 +3998,7 @@ "resolved": "https://registry.npmjs.org/@turf/random/-/random-6.5.0.tgz", "integrity": "sha512-8Q25gQ/XbA7HJAe+eXp4UhcXM9aOOJFaxZ02+XSNwMvY8gtWSCBLVqRcW4OhqilgZ8PeuQDWgBxeo+BIqqFWFQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0" }, @@ -3931,6 +4011,7 @@ "resolved": "https://registry.npmjs.org/@turf/rectangle-grid/-/rectangle-grid-6.5.0.tgz", "integrity": "sha512-yQZ/1vbW68O2KsSB3OZYK+72aWz/Adnf7m2CMKcC+aq6TwjxZjAvlbCOsNUnMAuldRUVN1ph6RXMG4e9KEvKvg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/boolean-intersects": "^6.5.0", "@turf/distance": "^6.5.0", @@ -3945,6 +4026,7 @@ "resolved": "https://registry.npmjs.org/@turf/rewind/-/rewind-6.5.0.tgz", "integrity": "sha512-IoUAMcHWotBWYwSYuYypw/LlqZmO+wcBpn8ysrBNbazkFNkLf3btSDZMkKJO/bvOzl55imr/Xj4fi3DdsLsbzQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/boolean-clockwise": "^6.5.0", "@turf/clone": "^6.5.0", @@ -3961,6 +4043,7 @@ "resolved": "https://registry.npmjs.org/@turf/rhumb-bearing/-/rhumb-bearing-6.5.0.tgz", "integrity": "sha512-jMyqiMRK4hzREjQmnLXmkJ+VTNTx1ii8vuqRwJPcTlKbNWfjDz/5JqJlb5NaFDcdMpftWovkW5GevfnuzHnOYA==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -3974,6 +4057,7 @@ "resolved": "https://registry.npmjs.org/@turf/rhumb-destination/-/rhumb-destination-6.5.0.tgz", "integrity": "sha512-RHNP1Oy+7xTTdRrTt375jOZeHceFbjwohPHlr9Hf68VdHHPMAWgAKqiX2YgSWDcvECVmiGaBKWus1Df+N7eE4Q==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -3987,6 +4071,7 @@ "resolved": "https://registry.npmjs.org/@turf/rhumb-distance/-/rhumb-distance-6.5.0.tgz", "integrity": "sha512-oKp8KFE8E4huC2Z1a1KNcFwjVOqa99isxNOwfo4g3SUABQ6NezjKDDrnvC4yI5YZ3/huDjULLBvhed45xdCrzg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -4000,6 +4085,7 @@ "resolved": "https://registry.npmjs.org/@turf/sample/-/sample-6.5.0.tgz", "integrity": "sha512-kSdCwY7el15xQjnXYW520heKUrHwRvnzx8ka4eYxX9NFeOxaFITLW2G7UtXb6LJK8mmPXI8Aexv23F2ERqzGFg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0" }, @@ -4012,6 +4098,7 @@ "resolved": "https://registry.npmjs.org/@turf/sector/-/sector-6.5.0.tgz", "integrity": "sha512-cYUOkgCTWqa23SOJBqxoFAc/yGCUsPRdn/ovbRTn1zNTm/Spmk6hVB84LCKOgHqvSF25i0d2kWqpZDzLDdAPbw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/circle": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -4028,6 +4115,7 @@ "resolved": "https://registry.npmjs.org/@turf/shortest-path/-/shortest-path-6.5.0.tgz", "integrity": "sha512-4de5+G7+P4hgSoPwn+SO9QSi9HY5NEV/xRJ+cmoFVRwv2CDsuOPDheHKeuIAhKyeKDvPvPt04XYWbac4insJMg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bbox": "^6.5.0", "@turf/bbox-polygon": "^6.5.0", @@ -4048,6 +4136,7 @@ "resolved": "https://registry.npmjs.org/@turf/simplify/-/simplify-6.5.0.tgz", "integrity": "sha512-USas3QqffPHUY184dwQdP8qsvcVH/PWBYdXY5am7YTBACaQOMAlf6AKJs9FT8jiO6fQpxfgxuEtwmox+pBtlOg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/clean-coords": "^6.5.0", "@turf/clone": "^6.5.0", @@ -4063,6 +4152,7 @@ "resolved": "https://registry.npmjs.org/@turf/square/-/square-6.5.0.tgz", "integrity": "sha512-BM2UyWDmiuHCadVhHXKIx5CQQbNCpOxB6S/aCNOCLbhCeypKX5Q0Aosc5YcmCJgkwO5BERCC6Ee7NMbNB2vHmQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/distance": "^6.5.0", "@turf/helpers": "^6.5.0" @@ -4076,6 +4166,7 @@ "resolved": "https://registry.npmjs.org/@turf/square-grid/-/square-grid-6.5.0.tgz", "integrity": "sha512-mlR0ayUdA+L4c9h7p4k3pX6gPWHNGuZkt2c5II1TJRmhLkW2557d6b/Vjfd1z9OVaajb1HinIs1FMSAPXuuUrA==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/rectangle-grid": "^6.5.0" @@ -4089,6 +4180,7 @@ "resolved": "https://registry.npmjs.org/@turf/standard-deviational-ellipse/-/standard-deviational-ellipse-6.5.0.tgz", "integrity": "sha512-02CAlz8POvGPFK2BKK8uHGUk/LXb0MK459JVjKxLC2yJYieOBTqEbjP0qaWhiBhGzIxSMaqe8WxZ0KvqdnstHA==", "license": "MIT", + "peer": true, "dependencies": { "@turf/center-mean": "^6.5.0", "@turf/ellipse": "^6.5.0", @@ -4106,6 +4198,7 @@ "resolved": "https://registry.npmjs.org/@turf/tag/-/tag-6.5.0.tgz", "integrity": "sha512-XwlBvrOV38CQsrNfrxvBaAPBQgXMljeU0DV8ExOyGM7/hvuGHJw3y8kKnQ4lmEQcmcrycjDQhP7JqoRv8vFssg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/boolean-point-in-polygon": "^6.5.0", "@turf/clone": "^6.5.0", @@ -4121,6 +4214,7 @@ "resolved": "https://registry.npmjs.org/@turf/tesselate/-/tesselate-6.5.0.tgz", "integrity": "sha512-M1HXuyZFCfEIIKkglh/r5L9H3c5QTEsnMBoZOFQiRnGPGmJWcaBissGb7mTFX2+DKE7FNWXh4TDnZlaLABB0dQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "earcut": "^2.0.0" @@ -4134,6 +4228,7 @@ "resolved": "https://registry.npmjs.org/@turf/tin/-/tin-6.5.0.tgz", "integrity": "sha512-YLYikRzKisfwj7+F+Tmyy/LE3d2H7D4kajajIfc9mlik2+esG7IolsX/+oUz1biguDYsG0DUA8kVYXDkobukfg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0" }, @@ -4146,6 +4241,7 @@ "resolved": "https://registry.npmjs.org/@turf/transform-rotate/-/transform-rotate-6.5.0.tgz", "integrity": "sha512-A2Ip1v4246ZmpssxpcL0hhiVBEf4L8lGnSPWTgSv5bWBEoya2fa/0SnFX9xJgP40rMP+ZzRaCN37vLHbv1Guag==", "license": "MIT", + "peer": true, "dependencies": { "@turf/centroid": "^6.5.0", "@turf/clone": "^6.5.0", @@ -4165,6 +4261,7 @@ "resolved": "https://registry.npmjs.org/@turf/transform-scale/-/transform-scale-6.5.0.tgz", "integrity": "sha512-VsATGXC9rYM8qTjbQJ/P7BswKWXHdnSJ35JlV4OsZyHBMxJQHftvmZJsFbOqVtQnIQIzf2OAly6rfzVV9QLr7g==", "license": "MIT", + "peer": true, "dependencies": { "@turf/bbox": "^6.5.0", "@turf/center": "^6.5.0", @@ -4186,6 +4283,7 @@ "resolved": "https://registry.npmjs.org/@turf/transform-translate/-/transform-translate-6.5.0.tgz", "integrity": "sha512-NABLw5VdtJt/9vSstChp93pc6oel4qXEos56RBMsPlYB8hzNTEKYtC146XJvyF4twJeeYS8RVe1u7KhoFwEM5w==", "license": "MIT", + "peer": true, "dependencies": { "@turf/clone": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -4202,6 +4300,7 @@ "resolved": "https://registry.npmjs.org/@turf/triangle-grid/-/triangle-grid-6.5.0.tgz", "integrity": "sha512-2jToUSAS1R1htq4TyLQYPTIsoy6wg3e3BQXjm2rANzw4wPQCXGOxrur1Fy9RtzwqwljlC7DF4tg0OnWr8RjmfA==", "license": "MIT", + "peer": true, "dependencies": { "@turf/distance": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -4216,6 +4315,7 @@ "resolved": "https://registry.npmjs.org/@turf/truncate/-/truncate-6.5.0.tgz", "integrity": "sha512-pFxg71pLk+eJj134Z9yUoRhIi8vqnnKvCYwdT4x/DQl/19RVdq1tV3yqOT3gcTQNfniteylL5qV1uTBDV5sgrg==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/meta": "^6.5.0" @@ -4229,6 +4329,7 @@ "resolved": "https://registry.npmjs.org/@turf/turf/-/turf-6.5.0.tgz", "integrity": "sha512-ipMCPnhu59bh92MNt8+pr1VZQhHVuTMHklciQURo54heoxRzt1neNYZOBR6jdL+hNsbDGAECMuIpAutX+a3Y+w==", "license": "MIT", + "peer": true, "dependencies": { "@turf/along": "^6.5.0", "@turf/angle": "^6.5.0", @@ -4345,6 +4446,7 @@ "resolved": "https://registry.npmjs.org/@turf/union/-/union-6.5.0.tgz", "integrity": "sha512-igYWCwP/f0RFHIlC2c0SKDuM/ObBaqSljI3IdV/x71805QbIvY/BYGcJdyNcgEA6cylIGl/0VSlIbpJHZ9ldhw==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0", @@ -4359,6 +4461,7 @@ "resolved": "https://registry.npmjs.org/@turf/unkink-polygon/-/unkink-polygon-6.5.0.tgz", "integrity": "sha512-8QswkzC0UqKmN1DT6HpA9upfa1HdAA5n6bbuzHy8NJOX8oVizVAqfEPY0wqqTgboDjmBR4yyImsdPGUl3gZ8JQ==", "license": "MIT", + "peer": true, "dependencies": { "@turf/area": "^6.5.0", "@turf/boolean-point-in-polygon": "^6.5.0", @@ -4375,6 +4478,7 @@ "resolved": "https://registry.npmjs.org/@turf/voronoi/-/voronoi-6.5.0.tgz", "integrity": "sha512-C/xUsywYX+7h1UyNqnydHXiun4UPjK88VDghtoRypR9cLlb7qozkiLRphQxxsCM0KxyxpVPHBVQXdAL3+Yurow==", "license": "MIT", + "peer": true, "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0", @@ -4389,6 +4493,7 @@ "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@babel/runtime": "^7.15.4", "is-retry-allowed": "^2.2.0" @@ -4398,13 +4503,15 @@ "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@map-colonies/mc-model-types/node_modules/fast-copy": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz", "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@map-colonies/mc-model-types/node_modules/pino": { "version": "8.21.0", @@ -4434,6 +4541,7 @@ "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", "license": "MIT", + "peer": true, "dependencies": { "readable-stream": "^4.0.0", "split2": "^4.0.0" @@ -4444,6 +4552,7 @@ "resolved": "https://registry.npmjs.org/pino-caller/-/pino-caller-3.4.0.tgz", "integrity": "sha512-2aEjlmhLA7J3lGBXKDSxtlfDY+cBzGh5PnLFP6ZUhvyqCnqKfv28ulpSch6uymGIdo7fzxXHK2hvR5FrdzbhTg==", "license": "MIT", + "peer": true, "dependencies": { "source-map-support": "^0.5.13" }, @@ -4459,6 +4568,7 @@ "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.3.1.tgz", "integrity": "sha512-az8JbIYeN/1iLj2t0jR9DV48/LQ3RC6hZPpapKPkb84Q+yTidMCpgWxIT3N0flnBDilyBQ1luWNpOeJptjdp/g==", "license": "MIT", + "peer": true, "dependencies": { "colorette": "^2.0.7", "dateformat": "^4.6.3", @@ -4483,25 +4593,29 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@map-colonies/mc-model-types/node_modules/process-warning": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@map-colonies/mc-model-types/node_modules/quickselect": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-1.1.1.tgz", "integrity": "sha512-qN0Gqdw4c4KGPsBOQafj6yj/PA6c/L63f6CaZ/DCF/xF4Esu3jVmKLUDYxghFx8Kb/O7y9tI7x2RjTSXwdK1iQ==", - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/@map-colonies/mc-model-types/node_modules/rbush": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/rbush/-/rbush-2.0.2.tgz", "integrity": "sha512-XBOuALcTm+O/H8G90b6pzu6nX6v2zCKiFG4BJho8a+bY6AER6t8uQUZdi5bomQc0AprCWhEGa7ncAbbRap0bRA==", "license": "MIT", + "peer": true, "dependencies": { "quickselect": "^1.0.1" } @@ -4510,13 +4624,15 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/@map-colonies/mc-model-types/node_modules/sonic-boom": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.1.tgz", "integrity": "sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==", "license": "MIT", + "peer": true, "dependencies": { "atomic-sleep": "^1.0.0" } @@ -4526,6 +4642,7 @@ "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.7.0.tgz", "integrity": "sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==", "license": "MIT", + "peer": true, "dependencies": { "real-require": "^0.2.0" } @@ -4550,7 +4667,6 @@ "resolved": "https://registry.npmjs.org/@map-colonies/mc-utils/-/mc-utils-5.1.0.tgz", "integrity": "sha512-4eL4ykgJFrFSPP18AbeJUJklwmzJieormWIvEc8c8PFRXU5eN1lRUal60xAhghpmzEQnudRG1kV3NWIibUjw2w==", "license": "ISC", - "peer": true, "dependencies": { "@map-colonies/types": "^1.9.0", "@turf/turf": "^6.5.0", @@ -6316,9 +6432,9 @@ } }, "node_modules/@map-colonies/raster-shared": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@map-colonies/raster-shared/-/raster-shared-8.1.0.tgz", - "integrity": "sha512-D/otgsJ7X00NnxlMJUSuj6rC9U779ReZDe4pAmtGsIOuQvASRnjjKIGIj/9nFJth6lbOaptppp0RRGImGd0jIw==", + "version": "8.3.0-alpha.0", + "resolved": "https://registry.npmjs.org/@map-colonies/raster-shared/-/raster-shared-8.3.0-alpha.0.tgz", + "integrity": "sha512-xcleqPf+KSOObCqHuKm1nng7WQRAZ0JrX12qe1U8pX8iijZ7pS7QMrHnPM7DFU5cxMoxkgnRC8hVzd1SMLiErQ==", "license": "ISC", "dependencies": { "@map-colonies/mc-priority-queue": "^9.1.0", @@ -6343,8 +6459,7 @@ "version": "1.18.0", "resolved": "https://registry.npmjs.org/@map-colonies/schemas/-/schemas-1.18.0.tgz", "integrity": "sha512-G6OB/xogqzcLrDU+sXok8ECFbdzQDjI9AE+eMZP6Bcl8BZArkkFI/wNz14HCD2NE81p4SNaeAKUuyGZBqzRJyg==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@map-colonies/shapefile-reader": { "version": "1.0.1", @@ -6441,7 +6556,6 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.7.0.tgz", "integrity": "sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==", "license": "Apache-2.0", - "peer": true, "engines": { "node": ">=8.0.0" } @@ -6451,7 +6565,6 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.46.0.tgz", "integrity": "sha512-+9BcqfiEDGPXEIo+o3tso/aqGM5dGbGwAkGVp3FPpZ8GlkK1YlaKRd9gMVyPaeRATwvO5wYGGnCsAc/sMMM9Qw==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@opentelemetry/api": "^1.0.0" }, @@ -6892,7 +7005,6 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.6.0.tgz", "integrity": "sha512-HLM1v2cbZ4TgYN6KEOj+Bbj8rAKriOdkF9Ed3tG25FoprSiQl7kYc+RRT6fUZGOvx0oMi5U67GoFdT+XUn8zEg==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, @@ -7777,7 +7889,6 @@ "resolved": "https://registry.npmjs.org/@map-colonies/types/-/types-1.9.0.tgz", "integrity": "sha512-TUM82wWLCV49vFTs16h4OYo15FjlnhMeMGLE922CeA0QNJyEkyaJG7IHvrM0LG793Ep4qeBMeB1izJQaN2fVYQ==", "license": "ISC", - "peer": true, "dependencies": { "@types/geojson": "^7946.0.16", "@types/mime-types": "^2.1.1", @@ -7946,7 +8057,6 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "license": "Apache-2.0", - "peer": true, "engines": { "node": ">=8.0.0" } @@ -8026,7 +8136,6 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.46.0.tgz", "integrity": "sha512-+9BcqfiEDGPXEIo+o3tso/aqGM5dGbGwAkGVp3FPpZ8GlkK1YlaKRd9gMVyPaeRATwvO5wYGGnCsAc/sMMM9Qw==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@opentelemetry/api": "^1.0.0" }, @@ -8937,7 +9046,6 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.46.0.tgz", "integrity": "sha512-+9BcqfiEDGPXEIo+o3tso/aqGM5dGbGwAkGVp3FPpZ8GlkK1YlaKRd9gMVyPaeRATwvO5wYGGnCsAc/sMMM9Qw==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@opentelemetry/api": "^1.0.0" }, @@ -9247,7 +9355,6 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.46.0.tgz", "integrity": "sha512-+9BcqfiEDGPXEIo+o3tso/aqGM5dGbGwAkGVp3FPpZ8GlkK1YlaKRd9gMVyPaeRATwvO5wYGGnCsAc/sMMM9Qw==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@opentelemetry/api": "^1.0.0" }, @@ -13790,7 +13897,6 @@ "integrity": "sha512-z87aF9GphWp//fnkRsqvtY+inMVPgYW3zSlXH1kJFvRT5H/wiAn+G32qW5l3oEk63KSF1x3Ov0BfHCObAmT8RA==", "hasInstallScript": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.25" @@ -14076,28 +14182,28 @@ "version": "1.0.12", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@turf/along": { @@ -16468,8 +16574,7 @@ "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/kdbush": { "version": "3.0.5", @@ -16838,7 +16943,6 @@ "integrity": "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.57.1", @@ -16878,7 +16982,6 @@ "integrity": "sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.57.1", "@typescript-eslint/types": "8.57.1", @@ -17386,7 +17489,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -17426,7 +17528,7 @@ "version": "8.3.5", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "acorn": "^8.11.0" @@ -17455,7 +17557,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -17814,7 +17915,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/argparse": { @@ -17896,7 +17997,6 @@ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", "license": "MIT", - "peer": true, "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", @@ -18069,7 +18169,6 @@ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", "license": "Apache-2.0", - "peer": true, "peerDependencies": { "bare-abort-controller": "*" }, @@ -18363,7 +18462,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -19289,8 +19387,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/commitlint/node_modules/conventional-changelog-angular": { "version": "6.0.0", @@ -19330,7 +19427,6 @@ "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", @@ -20999,7 +21095,6 @@ "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", @@ -21128,7 +21223,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/cross-env": { @@ -21595,7 +21690,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -21966,7 +22061,6 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -22103,7 +22197,6 @@ "integrity": "sha512-rM9K8UBHcWKpzQzStn1YRN2T5NvdeIfSVoKu/lKF41znQXHAUcBbYXe5wd6GNjZjTrP7viQ49n1D83x/2gYgIw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@package-json/types": "^0.0.12", "@typescript-eslint/types": "^8.56.0", @@ -22141,7 +22234,6 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.0.tgz", "integrity": "sha512-ZCGr7vTH2WSo2hrK5oM2RULFmMruQ7W3cX7YfwoTiPfzTGTFBMmrVIz45jZHd++cGKj/kWf02li/RhTGcANJSA==", "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/utils": "^8.0.0" }, @@ -22474,7 +22566,6 @@ "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", "license": "MIT", - "peer": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -22695,6 +22786,7 @@ "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", "license": "MIT", + "peer": true, "engines": { "node": ">=6" } @@ -24866,7 +24958,6 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -26941,7 +27032,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/make-fetch-happen": { @@ -27398,7 +27489,6 @@ "integrity": "sha512-UczzB+0nnwGotYSgllfARAqWCJ5e/skuV2K/l+Zyck/H6pJIhLXuBnz+6vn2i211o7DtbE78HQtsYEKICHGI+g==", "dev": true, "license": "MIT", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/mobx" @@ -28656,7 +28746,6 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -28678,7 +28767,6 @@ "resolved": "https://registry.npmjs.org/pino/-/pino-9.14.0.tgz", "integrity": "sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==", "license": "MIT", - "peer": true, "dependencies": { "@pinojs/redact": "^0.4.0", "atomic-sleep": "^1.0.0", @@ -29107,7 +29195,6 @@ "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -29266,7 +29353,6 @@ "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-15.1.3.tgz", "integrity": "sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@opentelemetry/api": "^1.4.0", "tdigest": "^0.1.1" @@ -29566,7 +29652,6 @@ "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -29577,7 +29662,6 @@ "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -31289,7 +31373,6 @@ "integrity": "sha512-J72R4ltw0UBVUlEjTzI0gg2STOqlI9JBhQOL4Dxt7aJOnnSesy0qJDn4PYfMCafk9cWOaVg129Pesl5o+DIh0Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@emotion/is-prop-valid": "1.4.0", "@emotion/unitless": "0.10.0", @@ -31962,9 +32045,8 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, + "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -32149,7 +32231,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -32388,7 +32469,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/v8-to-istanbul": { @@ -32730,7 +32811,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -32767,7 +32848,6 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index 638376a..41479f6 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@map-colonies/mc-utils": "^5.1.0", "@map-colonies/openapi-express-viewer": "^3.0.0", "@map-colonies/prometheus": "^1.0.0", - "@map-colonies/raster-shared": "^8.1.0", + "@map-colonies/raster-shared": "8.3.0-alpha.0", "@map-colonies/read-pkg": "0.0.1", "@map-colonies/schemas": "^1.17.0", "@map-colonies/shapefile-reader": "^1.0.1", From 85f1d8306d1fa25f0a923d241bdd148292ea6536 Mon Sep 17 00:00:00 2001 From: Roi Cohen <213414225+roicohen326@users.noreply.github.com> Date: Thu, 2 Jul 2026 10:51:13 +0300 Subject: [PATCH 6/8] style: format ingestionManager keywords line with prettier --- src/ingestion/models/ingestionManager.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ingestion/models/ingestionManager.ts b/src/ingestion/models/ingestionManager.ts index 6e3540f..249bcbf 100644 --- a/src/ingestion/models/ingestionManager.ts +++ b/src/ingestion/models/ingestionManager.ts @@ -637,9 +637,7 @@ export class IngestionManager { const relativeChecksums = this.convertChecksumsToRelativePaths(checksums); const taskParameters: IngestionValidationTaskParams = { checksums: relativeChecksums }; - const keywords = isSwapUpdate - ? updateLayer.metadata.keywords - : this.mergeKeywords(rasterLayerMetadata.keywords, updateLayer.metadata.keywords); + const keywords = isSwapUpdate ? updateLayer.metadata.keywords : this.mergeKeywords(rasterLayerMetadata.keywords, updateLayer.metadata.keywords); const updateLayerRelative = { ...updateLayer, From 9435ca18e08b02111e886e721b5ecbc3d0c47f53 Mon Sep 17 00:00:00 2001 From: Roi Cohen <213414225+roicohen326@users.noreply.github.com> Date: Thu, 2 Jul 2026 10:56:07 +0300 Subject: [PATCH 7/8] test: suppress jest objectContaining no-unsafe-assignment on keywords assertions --- tests/unit/ingestion/models/ingestionManager.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unit/ingestion/models/ingestionManager.spec.ts b/tests/unit/ingestion/models/ingestionManager.spec.ts index 8d0d7e3..8ceea96 100644 --- a/tests/unit/ingestion/models/ingestionManager.spec.ts +++ b/tests/unit/ingestion/models/ingestionManager.spec.ts @@ -482,6 +482,7 @@ describe('IngestionManager', () => { expect(createIngestionJobSpy).toHaveBeenCalledWith( expect.objectContaining({ type: ingestionUpdateJobType, + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment parameters: expect.objectContaining({ metadata: expect.objectContaining({ keywords: 'forest,urban,coast' }) }), }) ); @@ -517,6 +518,7 @@ describe('IngestionManager', () => { expect(createIngestionJobSpy).toHaveBeenCalledWith( expect.objectContaining({ type: ingestionSwapUpdateJobType, + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment parameters: expect.objectContaining({ metadata: expect.objectContaining({ keywords: 'urban,coast' }) }), }) ); From 5f7d5dd18342f25709db5181c06f687741efc4a7 Mon Sep 17 00:00:00 2001 From: Roi Cohen <213414225+roicohen326@users.noreply.github.com> Date: Tue, 7 Jul 2026 15:18:58 +0300 Subject: [PATCH 8/8] refactor: extract mergeKeywords into utils and add unit test --- src/ingestion/models/ingestionManager.ts | 13 +----- src/utils/keywords.ts | 9 ++++ .../ingestion/models/ingestionManager.spec.ts | 2 +- tests/unit/utils/keywords.spec.ts | 45 +++++++++++++++++++ 4 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 src/utils/keywords.ts create mode 100644 tests/unit/utils/keywords.spec.ts diff --git a/src/ingestion/models/ingestionManager.ts b/src/ingestion/models/ingestionManager.ts index 249bcbf..158e468 100644 --- a/src/ingestion/models/ingestionManager.ts +++ b/src/ingestion/models/ingestionManager.ts @@ -38,6 +38,7 @@ import { JobTrackerClient } from '../../serviceClients/jobTrackerClient'; import { MapProxyClient } from '../../serviceClients/mapProxyClient'; import { PolygonPartsManagerClient } from '../../serviceClients/polygonPartsManagerClient'; import { Checksum } from '../../utils/hash/checksum'; +import { mergeKeywords } from '../../utils/keywords'; import { getAbsolutePathInputFiles } from '../../utils/paths'; import { getShapefileFiles } from '../../utils/shapefile'; import { isKeyOf } from '../../utils/typeGuards'; @@ -637,7 +638,7 @@ export class IngestionManager { const relativeChecksums = this.convertChecksumsToRelativePaths(checksums); const taskParameters: IngestionValidationTaskParams = { checksums: relativeChecksums }; - const keywords = isSwapUpdate ? updateLayer.metadata.keywords : this.mergeKeywords(rasterLayerMetadata.keywords, updateLayer.metadata.keywords); + const keywords = isSwapUpdate ? updateLayer.metadata.keywords : mergeKeywords(rasterLayerMetadata.keywords, updateLayer.metadata.keywords); const updateLayerRelative = { ...updateLayer, @@ -674,16 +675,6 @@ export class IngestionManager { return createJobRequest; } - private mergeKeywords(existing: string | undefined, incoming: string | undefined): string | undefined { - const toTokens = (value: string | undefined): string[] => - (value ?? '') - .split(',') - .map((keyword) => keyword.trim()) - .filter((keyword) => keyword.length > 0); - const merged = [...new Set([...toTokens(existing), ...toTokens(incoming)])]; - return merged.length > 0 ? merged.join(',') : undefined; - } - @withSpanAsyncV4 private async getChecksum(shapefilePath: string): Promise { const checksums = await Promise.all(getShapefileFiles(shapefilePath).map(async (fileName) => this.getFileChecksum(fileName))); diff --git a/src/utils/keywords.ts b/src/utils/keywords.ts new file mode 100644 index 0000000..d14f4d0 --- /dev/null +++ b/src/utils/keywords.ts @@ -0,0 +1,9 @@ +export function mergeKeywords(existing: string | undefined, incoming: string | undefined): string | undefined { + const toTokens = (value: string | undefined): string[] => + (value ?? '') + .split(',') + .map((keyword) => keyword.trim()) + .filter((keyword) => keyword.length > 0); + const merged = [...new Set([...toTokens(existing), ...toTokens(incoming)])]; + return merged.length > 0 ? merged.join(',') : undefined; +} diff --git a/tests/unit/ingestion/models/ingestionManager.spec.ts b/tests/unit/ingestion/models/ingestionManager.spec.ts index 8ceea96..790f622 100644 --- a/tests/unit/ingestion/models/ingestionManager.spec.ts +++ b/tests/unit/ingestion/models/ingestionManager.spec.ts @@ -460,7 +460,7 @@ describe('IngestionManager', () => { expect(createIngestionJobSpy).toHaveBeenCalledWith(expect.objectContaining({ type: ingestionSwapUpdateJobType })); }); - it('should concatenate new keywords onto the existing ones, deduplicated, on a regular update', async () => { + it('should concatenate new keywords into the existing ones, deduplicated, on a regular update', async () => { const catalogLayerResponse = generateCatalogLayerResponse(); catalogLayerResponse.metadata.keywords = 'forest,urban'; const layerRequest = generateUpdateLayerRequest(); diff --git a/tests/unit/utils/keywords.spec.ts b/tests/unit/utils/keywords.spec.ts new file mode 100644 index 0000000..e4918b3 --- /dev/null +++ b/tests/unit/utils/keywords.spec.ts @@ -0,0 +1,45 @@ +import { mergeKeywords } from '../../../src/utils/keywords'; + +describe('mergeKeywords', () => { + it('should join merged keywords without spaces around the commas', () => { + const result = mergeKeywords('test', 'test2,test3'); + + expect(result).toBe('test,test2,test3'); + }); + + it('should deduplicate keywords that appear in both existing and incoming', () => { + const result = mergeKeywords('forest,urban', 'urban,coast'); + + expect(result).toBe('forest,urban,coast'); + }); + + it('should trim whitespace around each keyword before merging', () => { + const result = mergeKeywords(' forest , urban ', 'urban , coast '); + + expect(result).toBe('forest,urban,coast'); + }); + + it('should return only the incoming keywords when existing is undefined', () => { + const result = mergeKeywords(undefined, 'test,test2'); + + expect(result).toBe('test,test2'); + }); + + it('should return only the existing keywords when incoming is undefined', () => { + const result = mergeKeywords('test,test2', undefined); + + expect(result).toBe('test,test2'); + }); + + it('should return undefined when both existing and incoming are undefined', () => { + const result = mergeKeywords(undefined, undefined); + + expect(result).toBeUndefined(); + }); + + it('should ignore empty keyword tokens caused by consecutive or trailing commas', () => { + const result = mergeKeywords('test,,test2', 'test3,'); + + expect(result).toBe('test,test2,test3'); + }); +});