From 4c14e663467999fd5233a8ae9359adabb6462800 Mon Sep 17 00:00:00 2001 From: Chihiro Adachi <8196725+chihiro-adachi@users.noreply.github.com> Date: Tue, 7 Jan 2025 08:39:04 +0900 Subject: [PATCH 1/7] feat(rest-api-client): Supports the upsert option --- .../src/client/RecordClient.ts | 48 ++++++++++++++++--- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/packages/rest-api-client/src/client/RecordClient.ts b/packages/rest-api-client/src/client/RecordClient.ts index 36de80a05c..8500e99764 100644 --- a/packages/rest-api-client/src/client/RecordClient.ts +++ b/packages/rest-api-client/src/client/RecordClient.ts @@ -167,6 +167,7 @@ export class RecordClient extends BaseClient { public updateRecords(params: { app: AppID; + upsert?: boolean; records: Array< | { id: RecordID; record?: RecordForParameter; revision?: Revision } | { @@ -175,7 +176,12 @@ export class RecordClient extends BaseClient { revision?: Revision; } >; - }): Promise<{ records: Array<{ id: string; revision: string }> }> { + }): Promise<{ + records: Array< + | { id: string; revision: string } + | { id: string; operation: "INSERT" | "UPDATE"; revision: string } + >; + }> { const path = this.buildPathWithGuestSpaceId({ endpointName: "records", }); @@ -415,6 +421,7 @@ export class RecordClient extends BaseClient { public async updateAllRecords(params: { app: AppID; + upsert?: boolean; records: Array< | { id: RecordID; record?: RecordForParameter; revision?: Revision } | { @@ -423,13 +430,19 @@ export class RecordClient extends BaseClient { revision?: Revision; } >; - }): Promise<{ records: Array<{ id: string; revision: string }> }> { + }): Promise<{ + records: Array< + | { id: string; revision: string } + | { id: string; operation: "INSERT" | "UPDATE"; revision: string } + >; + }> { return this.updateAllRecordsRecursive(params, params.records.length, []); } private async updateAllRecordsRecursive( params: { app: AppID; + upsert?: boolean; records: Array< | { id: RecordID; record?: RecordForParameter; revision?: Revision } | { @@ -440,11 +453,19 @@ export class RecordClient extends BaseClient { >; }, numOfAllRecords: number, - results: Array<{ id: string; revision: string }>, - ): Promise<{ records: Array<{ id: string; revision: string }> }> { + results: Array< + | { id: string; revision: string } + | { id: string; operation: "INSERT" | "UPDATE"; revision: string } + >, + ): Promise<{ + records: Array< + | { id: string; revision: string } + | { id: string; operation: "INSERT" | "UPDATE"; revision: string } + >; + }> { const CHUNK_LENGTH = this.bulkRequestClient.REQUESTS_LENGTH_LIMIT * UPDATE_RECORDS_LIMIT; - const { app, records } = params; + const { app, upsert, records } = params; const recordsChunk = records.slice(0, CHUNK_LENGTH); if (recordsChunk.length === 0) { return { records: results }; @@ -453,6 +474,7 @@ export class RecordClient extends BaseClient { try { newResults = await this.updateAllRecordsWithBulkRequest({ app, + upsert, records: recordsChunk, }); } catch (e: any) { @@ -476,6 +498,7 @@ export class RecordClient extends BaseClient { private async updateAllRecordsWithBulkRequest(params: { app: AppID; + upsert?: boolean; records: Array< | { id: RecordID; record?: RecordForParameter; revision?: Revision } | { @@ -484,7 +507,12 @@ export class RecordClient extends BaseClient { revision?: Revision; } >; - }): Promise> { + }): Promise< + Array< + | { id: string; revision: string } + | { id: string; operation: "INSERT" | "UPDATE"; revision: string } + > + > { const separatedRecords = this.separateArrayRecursive( UPDATE_RECORDS_LIMIT, [], @@ -495,11 +523,17 @@ export class RecordClient extends BaseClient { endpointName: "records" as const, payload: { app: params.app, + upsert: params.upsert, records, }, })); const results = (await this.bulkRequestClient.send({ requests })) - .results as Array<{ records: Array<{ id: string; revision: string }> }>; + .results as Array<{ + records: Array< + | { id: string; revision: string } + | { id: string; operation: "INSERT" | "UPDATE"; revision: string } + >; + }>; return results .map((result) => result.records) .reduce((acc, records) => { From ad8191fac3604af119712cd8821411561bd4f734 Mon Sep 17 00:00:00 2001 From: Chihiro Adachi <8196725+chihiro-adachi@users.noreply.github.com> Date: Tue, 7 Jan 2025 08:52:15 +0900 Subject: [PATCH 2/7] feat(rest-api-client): extract response to type --- .../src/client/RecordClient.ts | 33 ++++--------------- .../src/client/types/record/index.ts | 5 +++ 2 files changed, 12 insertions(+), 26 deletions(-) diff --git a/packages/rest-api-client/src/client/RecordClient.ts b/packages/rest-api-client/src/client/RecordClient.ts index 8500e99764..d91b1b7c61 100644 --- a/packages/rest-api-client/src/client/RecordClient.ts +++ b/packages/rest-api-client/src/client/RecordClient.ts @@ -10,6 +10,7 @@ import type { CommentID, Comment, Mention, + UpdateRecordsForResponse, } from "./types"; import { BaseClient } from "./BaseClient"; @@ -177,10 +178,7 @@ export class RecordClient extends BaseClient { } >; }): Promise<{ - records: Array< - | { id: string; revision: string } - | { id: string; operation: "INSERT" | "UPDATE"; revision: string } - >; + records: UpdateRecordsForResponse; }> { const path = this.buildPathWithGuestSpaceId({ endpointName: "records", @@ -431,10 +429,7 @@ export class RecordClient extends BaseClient { } >; }): Promise<{ - records: Array< - | { id: string; revision: string } - | { id: string; operation: "INSERT" | "UPDATE"; revision: string } - >; + records: UpdateRecordsForResponse; }> { return this.updateAllRecordsRecursive(params, params.records.length, []); } @@ -453,15 +448,9 @@ export class RecordClient extends BaseClient { >; }, numOfAllRecords: number, - results: Array< - | { id: string; revision: string } - | { id: string; operation: "INSERT" | "UPDATE"; revision: string } - >, + results: UpdateRecordsForResponse, ): Promise<{ - records: Array< - | { id: string; revision: string } - | { id: string; operation: "INSERT" | "UPDATE"; revision: string } - >; + records: UpdateRecordsForResponse; }> { const CHUNK_LENGTH = this.bulkRequestClient.REQUESTS_LENGTH_LIMIT * UPDATE_RECORDS_LIMIT; @@ -507,12 +496,7 @@ export class RecordClient extends BaseClient { revision?: Revision; } >; - }): Promise< - Array< - | { id: string; revision: string } - | { id: string; operation: "INSERT" | "UPDATE"; revision: string } - > - > { + }): Promise { const separatedRecords = this.separateArrayRecursive( UPDATE_RECORDS_LIMIT, [], @@ -529,10 +513,7 @@ export class RecordClient extends BaseClient { })); const results = (await this.bulkRequestClient.send({ requests })) .results as Array<{ - records: Array< - | { id: string; revision: string } - | { id: string; operation: "INSERT" | "UPDATE"; revision: string } - >; + records: UpdateRecordsForResponse; }>; return results .map((result) => result.records) diff --git a/packages/rest-api-client/src/client/types/record/index.ts b/packages/rest-api-client/src/client/types/record/index.ts index 0b95da5edc..961e7c7527 100644 --- a/packages/rest-api-client/src/client/types/record/index.ts +++ b/packages/rest-api-client/src/client/types/record/index.ts @@ -26,3 +26,8 @@ export type Comment = { }; export type CommentID = string | number; + +export type UpdateRecordsForResponse = Array< + | { id: string; revision: string } + | { id: string; operation: "INSERT" | "UPDATE"; revision: string } +>; From a91a5292f3253fdf7ec36cd14631d24e9a69ddb6 Mon Sep 17 00:00:00 2001 From: Chihiro Adachi <8196725+chihiro-adachi@users.noreply.github.com> Date: Tue, 7 Jan 2025 14:06:08 +0900 Subject: [PATCH 3/7] feat(rest-api-client): add upsert param --- .../src/client/__tests__/record/AllRecords.test.ts | 1 + .../rest-api-client/src/client/__tests__/record/Record.test.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/rest-api-client/src/client/__tests__/record/AllRecords.test.ts b/packages/rest-api-client/src/client/__tests__/record/AllRecords.test.ts index 70d207f0b7..c7121a02f7 100644 --- a/packages/rest-api-client/src/client/__tests__/record/AllRecords.test.ts +++ b/packages/rest-api-client/src/client/__tests__/record/AllRecords.test.ts @@ -620,6 +620,7 @@ describe("AllRecordsTest", () => { describe("updateAllRecords", () => { const params = { app: APP_ID, + upsert: false, records: Array.from({ length: 3000 }, (_, index) => index + 1).map( (value) => ({ id: value, diff --git a/packages/rest-api-client/src/client/__tests__/record/Record.test.ts b/packages/rest-api-client/src/client/__tests__/record/Record.test.ts index 4b18f7b725..936e281d7d 100644 --- a/packages/rest-api-client/src/client/__tests__/record/Record.test.ts +++ b/packages/rest-api-client/src/client/__tests__/record/Record.test.ts @@ -298,6 +298,7 @@ describe("RecordTest", () => { describe("updateRecords", () => { const params = { app: APP_ID, + upsert: false, records: [{ id: RECORD_ID, record, revision: 5 }], }; beforeEach(async () => { From 70420388b3cf6ea3cee1a49822f589df06f4a9c3 Mon Sep 17 00:00:00 2001 From: Chihiro Adachi <8196725+chihiro-adachi@users.noreply.github.com> Date: Tue, 7 Jan 2025 14:27:31 +0900 Subject: [PATCH 4/7] feat(rest-api-client): fix documentation --- packages/rest-api-client/docs/record.md | 28 ++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/rest-api-client/docs/record.md b/packages/rest-api-client/docs/record.md index 56e950b24d..61eb7523ae 100644 --- a/packages/rest-api-client/docs/record.md +++ b/packages/rest-api-client/docs/record.md @@ -297,8 +297,9 @@ If you'd like to update over 100 records, please consider using [updateAllRecord #### Parameters | Name | Type | Required | Description | -| ------------------------- | :--------------: | :-------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +|---------------------------|:----------------:|:---------------------------:|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | app | Number or String | Yes | The app ID. | +| upsert | Boolean | No | Whether to execute in UPSERT mode. If trueis specified, it will be executed in UPSERT mode. | | records | Array | Yes | Holds an array of objects that include `id`/`updateKey`, `revision` and `record` objects.
Up to 100 records can be specified. | | records[].id | Number or String | Conditionally
Required | The record ID of the record to be updated. Required, if `updateKey` will not be specified. | | records[].updateKey | Object | Conditionally
Required | The unique key of the record to be updated. Required, if `id` will not be specified. To specify this field, the field must have the "Prohibit duplicate values" option turned on. | @@ -309,11 +310,12 @@ If you'd like to update over 100 records, please consider using [updateAllRecord #### Returns -| Name | Type | Description | -| ------------------ | :----: | ------------------------------------------------------------------------------ | -| records | Array | Holds an array of objects that include `id` and `revision` of updated records. | -| records[].id | String | The ID of the record. | -| records[].revision | String | The revision number of the record. | +| Name | Type | Description | +|---------------------| :----: |------------------------------------------------------------------------------------------------------------------------------------| +| records | Array | Holds an array of objects that include `id` and `revision` of updated records. | +| records[].id | String | The ID of the record. | +| records[].revision | String | The revision number of the record. | +| records[].operation | String | The operation performed on the record. This is output when UPSERT mode is enabled. `INSERT` : New registration / `UPDATE` : Update | #### Reference @@ -330,8 +332,9 @@ For more information, please see [an example of KintoneAllRecordsError](errorHan #### Parameters | Name | Type | Required | Description | -| ------------------------- | :--------------: | :-------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +|---------------------------|:----------------:|:---------------------------:|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | app | Number or String | Yes | The app ID. | +| upsert | boolean | No | Whether to execute in UPSERT mode. If trueis specified, it will be executed in UPSERT mode. | | records | Array | Yes | Holds an array of objects that include `id`/`updateKey`, `revision` and `record` objects.
Over 100 records can be specified. | | records[].id | Number or String | Conditionally
Required | The record ID of the record to be updated. Required, if `updateKey` will not be specified. | | records[].updateKey | Object | Conditionally
Required | The unique key of the record to be updated. Required, if `id` will not be specified. To specify this field, the field must have the "Prohibit duplicate values" option turned on. | @@ -342,11 +345,12 @@ For more information, please see [an example of KintoneAllRecordsError](errorHan #### Returns -| Name | Type | Description | -| ------------------ | :----: | ------------------------------------------------------------------------------ | -| records | Array | Holds an array of objects that include `id` and `revision` of updated records. | -| records[].id | String | The ID of the record. | -| records[].revision | String | The revision number of the record. | +| Name | Type | Description | +|---------------------|:------:|------------------------------------------------------------------------------------------------------------------------------------| +| records | Array | Holds an array of objects that include `id` and `revision` of updated records. | +| records[].id | String | The ID of the record. | +| records[].revision | String | The revision number of the record. | +| records[].operation | String | The operation performed on the record. This is output when UPSERT mode is enabled. `INSERT` : New registration / `UPDATE` : Update | ### deleteRecords From 32f7d523c0e36d19f79382b39ecddf8e62ad648b Mon Sep 17 00:00:00 2001 From: Chihiro Adachi <8196725+chihiro-adachi@users.noreply.github.com> Date: Tue, 7 Jan 2025 14:50:38 +0900 Subject: [PATCH 5/7] feat(rest-api-client): pretter --write --- packages/rest-api-client/docs/record.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/rest-api-client/docs/record.md b/packages/rest-api-client/docs/record.md index 61eb7523ae..17c5766a46 100644 --- a/packages/rest-api-client/docs/record.md +++ b/packages/rest-api-client/docs/record.md @@ -297,7 +297,7 @@ If you'd like to update over 100 records, please consider using [updateAllRecord #### Parameters | Name | Type | Required | Description | -|---------------------------|:----------------:|:---------------------------:|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ------------------------- | :--------------: | :-------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | app | Number or String | Yes | The app ID. | | upsert | Boolean | No | Whether to execute in UPSERT mode. If trueis specified, it will be executed in UPSERT mode. | | records | Array | Yes | Holds an array of objects that include `id`/`updateKey`, `revision` and `record` objects.
Up to 100 records can be specified. | @@ -311,7 +311,7 @@ If you'd like to update over 100 records, please consider using [updateAllRecord #### Returns | Name | Type | Description | -|---------------------| :----: |------------------------------------------------------------------------------------------------------------------------------------| +| ------------------- | :----: | ---------------------------------------------------------------------------------------------------------------------------------- | | records | Array | Holds an array of objects that include `id` and `revision` of updated records. | | records[].id | String | The ID of the record. | | records[].revision | String | The revision number of the record. | @@ -332,7 +332,7 @@ For more information, please see [an example of KintoneAllRecordsError](errorHan #### Parameters | Name | Type | Required | Description | -|---------------------------|:----------------:|:---------------------------:|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ------------------------- | :--------------: | :-------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | app | Number or String | Yes | The app ID. | | upsert | boolean | No | Whether to execute in UPSERT mode. If trueis specified, it will be executed in UPSERT mode. | | records | Array | Yes | Holds an array of objects that include `id`/`updateKey`, `revision` and `record` objects.
Over 100 records can be specified. | @@ -346,7 +346,7 @@ For more information, please see [an example of KintoneAllRecordsError](errorHan #### Returns | Name | Type | Description | -|---------------------|:------:|------------------------------------------------------------------------------------------------------------------------------------| +| ------------------- | :----: | ---------------------------------------------------------------------------------------------------------------------------------- | | records | Array | Holds an array of objects that include `id` and `revision` of updated records. | | records[].id | String | The ID of the record. | | records[].revision | String | The revision number of the record. | From 4ac90832832d91803c23b3ec0618c7b3b77f0714 Mon Sep 17 00:00:00 2001 From: Chihiro Adachi <8196725+chihiro-adachi@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:30:00 +0900 Subject: [PATCH 6/7] feat(rest-api-client): fix upsert param --- packages/rest-api-client/src/client/RecordClient.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/rest-api-client/src/client/RecordClient.ts b/packages/rest-api-client/src/client/RecordClient.ts index d91b1b7c61..3ad0a69ef5 100644 --- a/packages/rest-api-client/src/client/RecordClient.ts +++ b/packages/rest-api-client/src/client/RecordClient.ts @@ -478,6 +478,7 @@ export class RecordClient extends BaseClient { return this.updateAllRecordsRecursive( { app, + upsert, records: records.slice(CHUNK_LENGTH), }, numOfAllRecords, From 324325f0ff1fae3acfbbb605bf3dc362441b1af9 Mon Sep 17 00:00:00 2001 From: Chihiro Adachi <8196725+chihiro-adachi@users.noreply.github.com> Date: Wed, 8 Jan 2025 13:00:48 +0900 Subject: [PATCH 7/7] feat(rest-api-client): fix typo --- packages/rest-api-client/docs/record.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rest-api-client/docs/record.md b/packages/rest-api-client/docs/record.md index 17c5766a46..9266bc63e8 100644 --- a/packages/rest-api-client/docs/record.md +++ b/packages/rest-api-client/docs/record.md @@ -299,7 +299,7 @@ If you'd like to update over 100 records, please consider using [updateAllRecord | Name | Type | Required | Description | | ------------------------- | :--------------: | :-------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | app | Number or String | Yes | The app ID. | -| upsert | Boolean | No | Whether to execute in UPSERT mode. If trueis specified, it will be executed in UPSERT mode. | +| upsert | Boolean | No | Whether to execute in UPSERT mode. If true is specified, it will be executed in UPSERT mode. | | records | Array | Yes | Holds an array of objects that include `id`/`updateKey`, `revision` and `record` objects.
Up to 100 records can be specified. | | records[].id | Number or String | Conditionally
Required | The record ID of the record to be updated. Required, if `updateKey` will not be specified. | | records[].updateKey | Object | Conditionally
Required | The unique key of the record to be updated. Required, if `id` will not be specified. To specify this field, the field must have the "Prohibit duplicate values" option turned on. | @@ -334,7 +334,7 @@ For more information, please see [an example of KintoneAllRecordsError](errorHan | Name | Type | Required | Description | | ------------------------- | :--------------: | :-------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | app | Number or String | Yes | The app ID. | -| upsert | boolean | No | Whether to execute in UPSERT mode. If trueis specified, it will be executed in UPSERT mode. | +| upsert | boolean | No | Whether to execute in UPSERT mode. If true is specified, it will be executed in UPSERT mode. | | records | Array | Yes | Holds an array of objects that include `id`/`updateKey`, `revision` and `record` objects.
Over 100 records can be specified. | | records[].id | Number or String | Conditionally
Required | The record ID of the record to be updated. Required, if `updateKey` will not be specified. | | records[].updateKey | Object | Conditionally
Required | The unique key of the record to be updated. Required, if `id` will not be specified. To specify this field, the field must have the "Prohibit duplicate values" option turned on. |