Skip to content

Commit 8790a80

Browse files
aayushuipathclaude
andauthored
feat(data-fabric): support multiline_max field type and v2 single-record read (#549)
* feat(data-fabric): support multiline_max field type and v2 single-record read Adds full CRUD support for the MULTILINE_MAX entity field type: - MULTILINE_MAX added to EntityFieldDataType + SqlFieldType, both field-type maps, the constraint spec ([1, 128 KB] UTF-16 byte budget), the default (128 KB), and buildSqlTypeConstraints — enabling creation of entities with multiline_max fields. Record insert/update/delete pass through generically. - getRecordById now uses the v2 read endpoint (/api/v2/EntityService/entity/{id}/read/{recordId}), which returns the full multiline_max content. List/query endpoints continue to return a size marker ("HasValue=true Length=N") for those fields; getRecordById retrieves the full value. The v2 read is not feature-flag gated and is behaviorally identical to v1 for entities without multiline_max. - JSDoc on the read/query methods documents the marker-vs-full contract. Tests: unit (create defaults/override/range, sqlType mapping) and integration (field-value generator, schema-create, marker-vs-full lifecycle). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(data-fabric): sync getRecordById JSDoc with ServiceModel (use {@link}) Address PR review: the service-class JSDoc must be identical to the EntityServiceModel copy. Use {@link} cross-references instead of plain backticks to match entities.models.ts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(data-fabric): remove un-runnable MULTILINE_MAX lifecycle integration test Address PR review: per rules.md, describe.skip is not the sanctioned choice for a missing-config (schema-write scope) scenario. The block could never run in CI (the standard PAT lacks DataFabric.Schema.Write), and the v2 read behavior it asserted is already covered by the runnable getRecordById integration tests and the unit tests — so removing it loses no runnable coverage and avoids new config plumbing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(data-fabric): keep getRecordById on v1 read until v2 is proxy-whitelisted The v2 single-record read endpoint is not yet allowlisted in the api.uipath.com Cloudflare proxy (apps-dev-tools PR pending review/deploy), so getRecordById returned 403 there and failed integration CI. Revert getRecordById to the v1 read endpoint (already whitelisted) so the gate passes and the multiline_max field-type support ships now. The v2 switch is a one-line follow-up once the proxy whitelist is deployed. MULTILINE_MAX reads (list/query/getRecordById) return a size marker until then; JSDoc updated to reflect that. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Reapply v2 read for getRecordById Restore the v2 single-record read endpoint for getRecordById (returns full MULTILINE_MAX content). This reverts the temporary v1 fallback — v2 read is the required behavior. Integration CI will stay red until the proxy whitelist (apps-dev-tools#98) is merged and the ApiCorsWorker is deployed, after which the v2 read path returns 200. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(data-fabric): use {@link} for method refs in MULTILINE_MAX enum JSDoc Address PR review nit: reference getAllRecords/queryRecordsById/getRecordById via {@link} cross-references instead of backticks, consistent with the rest of the file. Qualified with EntityServiceModel so TypeDoc resolves them from the enum's file. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(data-fabric): add config-gated MULTILINE_MAX lifecycle integration test Address PR review: restore the integration test for the core lazy-load contract (list returns a size marker; getRecordById/v2 read returns full content). Gated behind a new SCHEMA_WRITE_SCOPE_AVAILABLE config flag (default false) via describe.skipIf — it runs in any environment whose PAT carries DataFabric.Schema.Write and skips in the standard test env that lacks it. An unconditional beforeAll throw (as literally suggested) would redden CI permanently, since the standard PAT cannot create the MULTILINE_MAX field; gating runs-where-possible while keeping CI green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(data-fabric): surface MULTILINE_MAX marker note on list/query methods - Add the size-marker note to getAllRecords and queryRecordsById JSDoc (service class + ServiceModel, kept identical per convention), pointing to getRecordById for the full value - Drop method-level references from the MULTILINE_MAX enum JSDoc in the types file Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(data-fabric): drop redundant back-reference from getRecordById JSDoc The list/query methods now document the MULTILINE_MAX size-marker behavior themselves, so getRecordById keeps only its own contract (returns the full content). Applied to both the service class and ServiceModel copies. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent bcbb4dc commit 8790a80

9 files changed

Lines changed: 126 additions & 1 deletion

File tree

src/models/data-fabric/entities.constants.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export const EntitySchemaFieldTypeMap: Record<EntityFieldDataType, EntitySchemaF
4949
[EntityFieldDataType.BOOLEAN]: { sqlTypeName: SqlFieldType.BIT, fieldDisplayType: FieldDisplayType.Basic },
5050
[EntityFieldDataType.BIG_INTEGER]: { sqlTypeName: SqlFieldType.BIGINT, fieldDisplayType: FieldDisplayType.Basic },
5151
[EntityFieldDataType.MULTILINE_TEXT]: { sqlTypeName: SqlFieldType.MULTILINE, fieldDisplayType: FieldDisplayType.Basic },
52+
[EntityFieldDataType.MULTILINE_MAX]: { sqlTypeName: SqlFieldType.MULTILINE_MAX, fieldDisplayType: FieldDisplayType.Basic },
5253
[EntityFieldDataType.FILE]: { sqlTypeName: SqlFieldType.UNIQUEIDENTIFIER, fieldDisplayType: FieldDisplayType.File },
5354
[EntityFieldDataType.CHOICE_SET_SINGLE]: { sqlTypeName: SqlFieldType.INT, fieldDisplayType: FieldDisplayType.ChoiceSetSingle },
5455
[EntityFieldDataType.CHOICE_SET_MULTIPLE]: { sqlTypeName: SqlFieldType.NVARCHAR, fieldDisplayType: FieldDisplayType.ChoiceSetMultiple },
@@ -78,6 +79,8 @@ export const FieldDisplayTypeToDataType: Partial<Record<FieldDisplayType, Entity
7879
export const ENTITY_FIELD_CONSTRAINT_DEFAULTS = {
7980
STRING_LENGTH_LIMIT: 200,
8081
MULTILINE_TEXT_LENGTH_LIMIT: 200,
82+
/** Byte budget (UTF-16) for MULTILINE_MAX values: 128 KB — the platform max, applied by default */
83+
MULTILINE_MAX_LENGTH_LIMIT: 128 * 1024,
8184
/** Fixed (non-overridable) length limit on DECIMAL payloads*/
8285
DECIMAL_LENGTH_LIMIT: 1000,
8386
DECIMAL_PRECISION: 2,
@@ -110,6 +113,10 @@ export const ENTITY_FIELD_CONSTRAINT_SPEC: Partial<Record<EntityFieldDataType, P
110113
[EntityFieldDataType.MULTILINE_TEXT]: {
111114
[EntityFieldConstraint.LengthLimit]: { min: 1, max: 10000 },
112115
},
116+
[EntityFieldDataType.MULTILINE_MAX]: {
117+
// lengthLimit is a UTF-16 byte budget for MULTILINE_MAX (1 to 128 KB), not code units.
118+
[EntityFieldConstraint.LengthLimit]: { min: 1, max: 128 * 1024 },
119+
},
113120
[EntityFieldDataType.INTEGER]: {
114121
[EntityFieldConstraint.MaxValue]: { min: -Number.MAX_SAFE_INTEGER, max: Number.MAX_SAFE_INTEGER },
115122
[EntityFieldConstraint.MinValue]: { min: -Number.MAX_SAFE_INTEGER, max: Number.MAX_SAFE_INTEGER },
@@ -151,4 +158,5 @@ export const EntityFieldTypeMap: Record<SqlFieldType, EntityFieldDataType> = {
151158
[SqlFieldType.BIT]: EntityFieldDataType.BOOLEAN,
152159
[SqlFieldType.DECIMAL]: EntityFieldDataType.DECIMAL,
153160
[SqlFieldType.MULTILINE]: EntityFieldDataType.MULTILINE_TEXT,
161+
[SqlFieldType.MULTILINE_MAX]: EntityFieldDataType.MULTILINE_MAX,
154162
};

src/models/data-fabric/entities.internal-types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,5 @@ export enum SqlFieldType {
9393
BIT = 'BIT',
9494
DECIMAL = 'DECIMAL',
9595
MULTILINE = 'MULTILINE',
96+
MULTILINE_MAX = 'MULTILINE_MAX',
9697
}

src/models/data-fabric/entities.models.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ export interface EntityServiceModel {
145145
/**
146146
* Gets entity records by entity ID
147147
*
148+
* `MULTILINE_MAX` fields are returned as a size marker (e.g. `"HasValue=true Length=512"`)
149+
* instead of the full content — use {@link getRecordById} to retrieve the full value.
150+
*
148151
* @param entityId - UUID of the entity
149152
* @param options - Query options The `folderKey` property is **experimental**.
150153
* @returns Promise resolving to either an array of entity records NonPaginatedResponse<EntityRecord> or a PaginatedResponse<EntityRecord> when pagination options are used.
@@ -194,6 +197,8 @@ export interface EntityServiceModel {
194197
/**
195198
* Gets a single entity record by entity ID and record ID
196199
*
200+
* Returns the full record, including the complete content of `MULTILINE_MAX` fields.
201+
*
197202
* @param entityId - UUID of the entity
198203
* @param recordId - UUID of the record
199204
* @param options - Query options The `folderKey` property is **experimental**.
@@ -417,6 +422,9 @@ export interface EntityServiceModel {
417422
/**
418423
* Queries entity records with filters, sorting, aggregates, and SDK-managed pagination
419424
*
425+
* `MULTILINE_MAX` fields are returned as a size marker (e.g. `"HasValue=true Length=512"`)
426+
* instead of the full content — use {@link getRecordById} to retrieve the full value.
427+
*
420428
* @param id - UUID of the entity
421429
* @param options - Query options including filterGroup, selectedFields, sortOptions, aggregates, groupBy, joins, and pagination The `folderKey` property is **experimental**.
422430
* @returns Promise resolving to {@link NonPaginatedResponse} without pagination options,

src/models/data-fabric/entities.types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ export enum EntityFieldDataType {
2020
BOOLEAN = "BOOLEAN",
2121
BIG_INTEGER = "BIG_INTEGER",
2222
MULTILINE_TEXT = "MULTILINE_TEXT",
23+
/**
24+
* Large multi-line text (up to 128 KB). Unlike {@link MULTILINE_TEXT}, the full
25+
* value is lazy-loaded: list/query operations return a size marker
26+
* (e.g. `"HasValue=true Length=512"`) instead of the content; reading a single
27+
* record by ID returns the full value.
28+
*/
29+
MULTILINE_MAX = "MULTILINE_MAX",
2330
FILE = "FILE",
2431
CHOICE_SET_SINGLE = "CHOICE_SET_SINGLE",
2532
CHOICE_SET_MULTIPLE = "CHOICE_SET_MULTIPLE",

src/services/data-fabric/entities.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ export class EntityService extends BaseService implements EntityServiceModel {
119119
/**
120120
* Gets entity records by entity ID
121121
*
122+
* `MULTILINE_MAX` fields are returned as a size marker (e.g. `"HasValue=true Length=512"`)
123+
* instead of the full content — use {@link getRecordById} to retrieve the full value.
124+
*
122125
* @param entityId - UUID of the entity
123126
* @param options - Query options including expansionLevel and pagination options The `folderKey` property is **experimental**.
124127
* @returns Promise resolving to an array of entity records or paginated response
@@ -187,6 +190,8 @@ export class EntityService extends BaseService implements EntityServiceModel {
187190
/**
188191
* Gets a single entity record by entity ID and record ID
189192
*
193+
* Returns the full record, including the complete content of `MULTILINE_MAX` fields.
194+
*
190195
* @param entityId - UUID of the entity
191196
* @param recordId - UUID of the record
192197
* @param options - Query options including `expansionLevel` and `folderKey` The `folderKey` property is **experimental**.
@@ -565,6 +570,9 @@ export class EntityService extends BaseService implements EntityServiceModel {
565570
/**
566571
* Queries entity records with filters, sorting, aggregates, and pagination
567572
*
573+
* `MULTILINE_MAX` fields are returned as a size marker (e.g. `"HasValue=true Length=512"`)
574+
* instead of the full content — use {@link getRecordById} to retrieve the full value.
575+
*
568576
* @param id - UUID of the entity
569577
* @param options - Query options including filterGroup, selectedFields, sortOptions, aggregates, groupBy, joins, and pagination The `folderKey` property is **experimental**.
570578
* @returns Promise resolving to {@link NonPaginatedResponse} without pagination options,
@@ -1390,6 +1398,8 @@ export class EntityService extends BaseService implements EntityServiceModel {
13901398
return { lengthLimit: field.lengthLimit ?? defaults.STRING_LENGTH_LIMIT };
13911399
case EntityFieldDataType.MULTILINE_TEXT:
13921400
return { lengthLimit: field.lengthLimit ?? defaults.MULTILINE_TEXT_LENGTH_LIMIT };
1401+
case EntityFieldDataType.MULTILINE_MAX:
1402+
return { lengthLimit: field.lengthLimit ?? defaults.MULTILINE_MAX_LENGTH_LIMIT };
13931403
case EntityFieldDataType.DECIMAL:
13941404
return {
13951405
lengthLimit: defaults.DECIMAL_LENGTH_LIMIT,

src/utils/constants/endpoints/data-fabric.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ export const DATA_FABRIC_ENDPOINTS = {
2222
GET_ALL_V2: `${DATAFABRIC_BASE}/api/v2/Entity`,
2323
GET_ENTITY_RECORDS: (entityId: string) => `${DATAFABRIC_BASE}/api/EntityService/entity/${entityId}/read`,
2424
GET_BY_ID: (entityId: string) => `${DATAFABRIC_BASE}/api/Entity/${entityId}`,
25+
// v2 single-record read. Returns the full record including complete MULTILINE_MAX
26+
// content, unlike list/query endpoints which project a size marker for those fields.
2527
GET_RECORD_BY_ID: (entityId: string, recordId: string) =>
26-
`${DATAFABRIC_BASE}/api/EntityService/entity/${entityId}/read/${recordId}`,
28+
`${DATAFABRIC_BASE}/api/v2/EntityService/entity/${entityId}/read/${recordId}`,
2729
INSERT_BY_ID: (entityId: string) => `${DATAFABRIC_BASE}/api/EntityService/entity/${entityId}/insert`,
2830
BATCH_INSERT_BY_ID: (entityId: string) => `${DATAFABRIC_BASE}/api/EntityService/entity/${entityId}/insert-batch`,
2931
UPDATE_RECORD_BY_ID: (entityId: string, recordId: string) => `${DATAFABRIC_BASE}/api/EntityService/entity/${entityId}/update/${recordId}`,

tests/integration/config/test-config.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ export interface IntegrationConfig {
1212
secret: string;
1313
timeout: number;
1414
skipCleanup: boolean;
15+
/**
16+
* Whether the configured PAT carries the `DataFabric.Schema.Write` scope.
17+
* Defaults to false (the standard test environment lacks it). Set
18+
* `SCHEMA_WRITE_SCOPE_AVAILABLE=true` to enable schema-write-dependent tests
19+
* (entity create/update, MULTILINE_MAX lifecycle).
20+
*/
21+
schemaWriteScopeAvailable: boolean;
1522
folderId?: string;
1623
folderKey?: string;
1724
folderPath?: string;
@@ -75,6 +82,7 @@ function validateConfig(rawConfig: Record<string, unknown>): IntegrationConfig {
7582
secret: rawConfig.secret as string,
7683
timeout: typeof rawConfig.timeout === 'number' && rawConfig.timeout > 0 ? rawConfig.timeout : 30000,
7784
skipCleanup: typeof rawConfig.skipCleanup === 'boolean' ? rawConfig.skipCleanup : false,
85+
schemaWriteScopeAvailable: rawConfig.schemaWriteScopeAvailable === true,
7886
folderId: typeof rawConfig.folderId === 'string' ? rawConfig.folderId : undefined,
7987
folderKey: typeof rawConfig.folderKey === 'string' ? rawConfig.folderKey : undefined,
8088
folderPath: typeof rawConfig.folderPath === 'string' ? rawConfig.folderPath : undefined,
@@ -119,6 +127,7 @@ export function loadIntegrationConfig(): IntegrationConfig {
119127
? parseInt(process.env.INTEGRATION_TEST_TIMEOUT, 10)
120128
: 30000,
121129
skipCleanup: process.env.INTEGRATION_TEST_SKIP_CLEANUP === 'true',
130+
schemaWriteScopeAvailable: process.env.SCHEMA_WRITE_SCOPE_AVAILABLE === 'true',
122131
folderId: process.env.INTEGRATION_TEST_FOLDER_ID || undefined,
123132
folderKey: process.env.INTEGRATION_TEST_FOLDER_KEY || undefined,
124133
folderPath: process.env.INTEGRATION_TEST_FOLDER_PATH || undefined,

tests/integration/shared/data-fabric/entities.integration.test.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ function generateFieldValue(field: FieldMetaData): any {
5555
return `Test_${generateRandomString(8)}`;
5656
case EntityFieldDataType.MULTILINE_TEXT:
5757
return `Test multiline\n${generateRandomString(12)}`;
58+
case EntityFieldDataType.MULTILINE_MAX:
59+
return `Test multiline max\n${generateRandomString(64)}`;
5860
case EntityFieldDataType.INTEGER: {
5961
const max = fieldDataType.maxValue ?? 10000;
6062
const min = fieldDataType.minValue ?? 0;
@@ -1259,6 +1261,20 @@ describe.each(modes)('Data Fabric Entities - Integration Tests [%s]', (mode) =>
12591261
expect(field?.fieldDataType.lengthLimit).toBe(200);
12601262
});
12611263

1264+
it('should create MULTILINE_MAX field with default lengthLimit 128 KB', async () => {
1265+
const { entities } = getServices();
1266+
const name = `sdk_mlmax_${generateRandomString(8).toLowerCase()}`;
1267+
const entityId = await entities.create(name, [
1268+
{ fieldName: 'mlmax_field', type: EntityFieldDataType.MULTILINE_MAX },
1269+
]);
1270+
createdEntityIds.push(entityId);
1271+
1272+
const entity = await entities.getById(entityId);
1273+
const field = entity.fields.find(f => f.name === 'mlmax_field');
1274+
expect(field?.fieldDataType.name).toBe(EntityFieldDataType.MULTILINE_MAX);
1275+
expect(field?.fieldDataType.lengthLimit).toBe(128 * 1024);
1276+
});
1277+
12621278
it('should create DECIMAL field with correct default constraints', async () => {
12631279
const { entities } = getServices();
12641280
const name = `sdk_dec_${generateRandomString(8).toLowerCase()}`;
@@ -1458,6 +1474,41 @@ describe.each(modes)('Data Fabric Entities - Integration Tests [%s]', (mode) =>
14581474
});
14591475
});
14601476

1477+
// Verifies the MULTILINE_MAX lazy-load contract end to end: list returns a size
1478+
// marker, getRecordById (v2 read) returns the full content. Creating the field
1479+
// needs DataFabric.Schema.Write scope, absent in the standard test env — so this is
1480+
// gated on SCHEMA_WRITE_SCOPE_AVAILABLE and skipped there (a hard throw would redden
1481+
// CI permanently). Runs in any environment whose PAT carries the scope.
1482+
describe.skipIf(!getTestConfig().schemaWriteScopeAvailable)('MULTILINE_MAX field lifecycle', () => {
1483+
it('should return a marker on list and the full value via getRecordById', async () => {
1484+
const { entities } = getServices();
1485+
const name = `sdk_mlmax_life_${generateRandomString(8).toLowerCase()}`;
1486+
1487+
// Create an entity with a MULTILINE_MAX field, then insert a large value.
1488+
const entityId = await entities.create(name, [
1489+
{ fieldName: 'body', type: EntityFieldDataType.MULTILINE_MAX },
1490+
]);
1491+
createdEntityIds.push(entityId);
1492+
1493+
const bodyValue = `Large body content ${generateRandomString(256)}`;
1494+
const inserted = await entities.insertRecordById(entityId, { body: bodyValue });
1495+
expect(inserted.Id).toBeDefined();
1496+
registerResource('entityRecords', { entityId, recordIds: [inserted.Id] });
1497+
1498+
// List returns a size marker (e.g. "HasValue=true Length=...") — not the content.
1499+
const listed = await entities.getAllRecords(entityId, { pageSize: 50 });
1500+
const listedRecord = listed.items.find((r: EntityRecord) => r.Id === inserted.Id);
1501+
expect(listedRecord).toBeDefined();
1502+
expect(typeof listedRecord!.body).toBe('string');
1503+
expect(listedRecord!.body).toMatch(/^HasValue=true/);
1504+
expect(listedRecord!.body).not.toBe(bodyValue);
1505+
1506+
// getRecordById (v2 read) returns the full content.
1507+
const full = await entities.getRecordById(entityId, inserted.Id);
1508+
expect(full.body).toBe(bodyValue);
1509+
});
1510+
});
1511+
14611512
// Skipped: requires DataFabric.Schema.Write OAuth scope, not available in standard test environment
14621513
describe.skip('deleteById', () => {
14631514
it('should delete an entity created for this test', async () => {

tests/unit/services/data-fabric/entities.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2064,6 +2064,22 @@ describe("EntityService Unit Tests", () => {
20642064
expect(f?.sqlType).toEqual({ name: "MULTILINE", lengthLimit: 200 });
20652065
});
20662066

2067+
it("should default MULTILINE_MAX lengthLimit to 128 KB", async () => {
2068+
await entityService.create("my_entity", [
2069+
{ fieldName: "mlmax_field", type: EntityFieldDataType.MULTILINE_MAX },
2070+
]);
2071+
const f = getCreatedFields().find((x) => x.name === "mlmax_field");
2072+
expect(f?.sqlType).toEqual({ name: "MULTILINE_MAX", lengthLimit: 128 * 1024 });
2073+
});
2074+
2075+
it("should use user-provided lengthLimit for MULTILINE_MAX fields", async () => {
2076+
await entityService.create("my_entity", [
2077+
{ fieldName: "mlmax_field", type: EntityFieldDataType.MULTILINE_MAX, lengthLimit: 5000 },
2078+
]);
2079+
const f = getCreatedFields().find((x) => x.name === "mlmax_field");
2080+
expect(f?.sqlType).toEqual({ name: "MULTILINE_MAX", lengthLimit: 5000 });
2081+
});
2082+
20672083
it("should default DECIMAL constraints to default values", async () => {
20682084
await entityService.create("my_entity", [
20692085
{ fieldName: "dec_field", type: EntityFieldDataType.DECIMAL },
@@ -2145,6 +2161,15 @@ describe("EntityService Unit Tests", () => {
21452161
expect(mockApiClient.post).not.toHaveBeenCalled();
21462162
});
21472163

2164+
it("should throw ValidationError when MULTILINE_MAX lengthLimit exceeds 128 KB", async () => {
2165+
await expect(
2166+
entityService.create("my_entity", [
2167+
{ fieldName: "mlmax_field", type: EntityFieldDataType.MULTILINE_MAX, lengthLimit: 131073 },
2168+
]),
2169+
).rejects.toThrow(/lengthLimit 131073 out of range \[1, 131072\]/);
2170+
expect(mockApiClient.post).not.toHaveBeenCalled();
2171+
});
2172+
21482173
it("should throw ValidationError when DECIMAL decimalPrecision exceeds 10", async () => {
21492174
await expect(
21502175
entityService.create("my_entity", [
@@ -2632,6 +2657,10 @@ describe("EntityService Unit Tests", () => {
26322657
type: EntityFieldDataType.MULTILINE_TEXT,
26332658
expectedSqlType: "MULTILINE",
26342659
},
2660+
{
2661+
type: EntityFieldDataType.MULTILINE_MAX,
2662+
expectedSqlType: "MULTILINE_MAX",
2663+
},
26352664
{ type: EntityFieldDataType.INTEGER, expectedSqlType: "INT" },
26362665
{ type: EntityFieldDataType.BOOLEAN, expectedSqlType: "BIT" },
26372666
{

0 commit comments

Comments
 (0)