Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/models/data-fabric/entities.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ export const EntityMap = {
createTime: 'createdTime',
updateTime: 'updatedTime',
sqlType: 'fieldDataType',
fieldDefinition: 'fieldMetaData'
fieldDefinition: 'fieldMetaData',
// API returns `isInsightsEnabled`; expose it under the SDK name `isAnalyticsEnabled`.
isInsightsEnabled: 'isAnalyticsEnabled'
};

/**
Expand Down
30 changes: 15 additions & 15 deletions src/models/data-fabric/entities.models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -665,29 +665,29 @@ export interface EntityServiceModel {
* const entities = new Entities(sdk);
*
* const id = await entities.create("product_catalog", [
* { fieldName: "product_name", type: EntityFieldDataType.STRING, isRequired: true, isUnique: true },
* { fieldName: "price", type: EntityFieldDataType.INTEGER, defaultValue: "0" },
* { name: "product_name", type: EntityFieldDataType.STRING, isRequired: true, isUnique: true },
* { name: "price", type: EntityFieldDataType.INTEGER, defaultValue: "0" },
* ], { displayName: "Product Catalog", description: "Our product catalog", isRbacEnabled: true });
*
* // With advanced sqlType constraints (lengthLimit, decimalPrecision, maxValue, minValue) and defaultValue
* const ordersId = await entities.create("orders", [
* { fieldName: "product_name", type: EntityFieldDataType.STRING, isRequired: true, isUnique: true, lengthLimit: 500 },
* { fieldName: "price", type: EntityFieldDataType.DECIMAL, decimalPrecision: 4, maxValue: 999999, minValue: 0 },
* { fieldName: "quantity", type: EntityFieldDataType.INTEGER, maxValue: 10000, minValue: 1, defaultValue: "0" },
* { name: "product_name", type: EntityFieldDataType.STRING, isRequired: true, isUnique: true, lengthLimit: 500 },
* { name: "price", type: EntityFieldDataType.DECIMAL, decimalPrecision: 4, maxValue: 999999, minValue: 0 },
* { name: "quantity", type: EntityFieldDataType.INTEGER, maxValue: 10000, minValue: 1, defaultValue: "0" },
* ]);
*
* // Cross-folder references — link a folder-scoped entity to entities and
* // system choice sets that live in another folder or at the tenant level.
* await entities.create("orderLine", [
* {
* fieldName: "order",
* name: "order",
* type: EntityFieldDataType.RELATIONSHIP,
* referenceEntityId: "<orderEntityId>",
* referenceFieldId: "<orderEntityPkId>",
* referenceFolderKey: "<otherFolderKey>", // target lives in a different folder
* },
* {
* fieldName: "userType",
* name: "userType",
* type: EntityFieldDataType.CHOICE_SET_SINGLE,
* choiceSetId: "<systemUserTypeChoiceSetId>", // tenant-level system choice set
* // referenceFolderKey omitted → SDK looks up the target at tenant scope
Expand Down Expand Up @@ -730,8 +730,8 @@ export interface EntityServiceModel {
* ```typescript
* // Schema-only: add a field and remove another
* await entities.updateById(<id>, {
* addFields: [{ fieldName: "notes", type: EntityFieldDataType.MULTILINE_TEXT }],
* removeFields: [{ fieldName: "old_field" }],
* addFields: [{ name: "notes", type: EntityFieldDataType.MULTILINE_TEXT }],
* removeFields: [{ name: "old_field" }],
* });
*
* // Metadata-only: rename the entity
Expand All @@ -749,8 +749,8 @@ export interface EntityServiceModel {
* // Add a STRING/DECIMAL field with explicit advanced sqlType constraints and defaultValue
* await entities.updateById(<id>, {
* addFields: [
* { fieldName: "summary", type: EntityFieldDataType.STRING, lengthLimit: 500, defaultValue: "summary" },
* { fieldName: "amount", type: EntityFieldDataType.DECIMAL, decimalPrecision: 4, maxValue: 999999, minValue: 0 },
* { name: "summary", type: EntityFieldDataType.STRING, lengthLimit: 500, defaultValue: "summary" },
* { name: "amount", type: EntityFieldDataType.DECIMAL, decimalPrecision: 4, maxValue: 999999, minValue: 0 },
* ],
* updateFields: [
* { id: <fieldId>, lengthLimit: 1000 },
Expand All @@ -760,7 +760,7 @@ export interface EntityServiceModel {
* // Folder-scoped entity: add a field to an entity that lives in a non-tenant folder
* await entities.updateById(<id>, {
* folderKey: "<folderKey>",
* addFields: [{ fieldName: "notes", type: EntityFieldDataType.MULTILINE_TEXT }],
* addFields: [{ name: "notes", type: EntityFieldDataType.MULTILINE_TEXT }],
* });
* ```
* @internal
Expand Down Expand Up @@ -1033,14 +1033,14 @@ export interface EntityMethods {
* const entity = await entities.getById(<id>);
* await entity.update({
* displayName: "Updated Name",
* addFields: [{ fieldName: "notes", type: EntityFieldDataType.MULTILINE_TEXT }],
* addFields: [{ name: "notes", type: EntityFieldDataType.MULTILINE_TEXT }],
* });
*
* // Add a STRING/DECIMAL field with explicit advanced sqlType constraints
* await entity.update({
* addFields: [
* { fieldName: "summary", type: EntityFieldDataType.STRING, lengthLimit: 500, defaultValue: "string" },
* { fieldName: "amount", type: EntityFieldDataType.DECIMAL, decimalPrecision: 4, maxValue: 999999, minValue: 0 },
* { name: "summary", type: EntityFieldDataType.STRING, lengthLimit: 500, defaultValue: "string" },
* { name: "amount", type: EntityFieldDataType.DECIMAL, decimalPrecision: 4, maxValue: 999999, minValue: 0 },
* ],
* });
* ```
Expand Down
19 changes: 15 additions & 4 deletions src/models/data-fabric/entities.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,9 @@ export interface EntityCreateFieldOptions extends EntityFieldBase {
/**
* Field name — must start with a letter and contain only
* letters, numbers, and underscores (e.g., `"productName"`).
* Matches the `name` field returned by `getById`.
*/
fieldName: string;
name: string;
/** Field data type — one of the {@link EntityFieldDataType} values (default: STRING) */
type?: EntityFieldDataType;
/** Choice set ID for choice-set fields */
Expand Down Expand Up @@ -393,7 +394,12 @@ export interface EntityCreateOptions extends EntityFolderScopedOptions {
description?: string;
/** Whether role-based access control is enabled for this entity (default: false) */
isRbacEnabled?: boolean;
/** Whether Analytics integration is enabled for this entity (default: false) */
/**
* Whether Analytics integration is enabled for this entity (default: false).
* Surfaced by `getById` as `isAnalyticsEnabled`.
*
* @experimental Analytics integration is in preview — the contract may change.
*/
isAnalyticsEnabled?: boolean;
/** External field source definitions (default: empty) */
externalFields?: ExternalField[];
Expand All @@ -412,7 +418,7 @@ export interface EntityFieldUpdateOptions extends EntityFieldBase {
*/
export interface EntityRemoveFieldOptions {
/** Name of the field to remove */
fieldName: string;
name: string;
}

/**
Expand Down Expand Up @@ -729,7 +735,12 @@ export interface RawEntityGetResponse {
usedStorageSizeInMB?: number;
attachmentSizeInByte?: number;
isRbacEnabled: boolean;
isInsightsEnabled?: boolean;
/**
* Whether Analytics integration is enabled for this entity.
*
* @experimental Analytics integration is in preview — the contract may change.
*/
isAnalyticsEnabled?: boolean;
id: string;
createdBy: string;
createdTime: string;
Expand Down
14 changes: 8 additions & 6 deletions src/services/data-fabric/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ export class EntityService extends BaseService implements EntityServiceModel {

// Filter out removed fields
if (options.removeFields?.length) {
const removeSet = new Set(options.removeFields.map(r => r.fieldName));
const removeSet = new Set(options.removeFields.map(r => r.name));
fields = fields.filter(f => !removeSet.has(f.name));
}

Expand Down Expand Up @@ -511,7 +511,9 @@ export class EntityService extends BaseService implements EntityServiceModel {
fields: [...fields, ...newFields],
folderId: raw.folderId ?? DATA_FABRIC_TENANT_FOLDER_ID,
isRbacEnabled: raw.isRbacEnabled ?? false,
isInsightsEnabled: raw.isInsightsEnabled ?? false,
// `raw` is the untransformed GET response, so read the wire key `isInsightsEnabled`
// directly (it is not on the public type, which exposes it as `isAnalyticsEnabled`).
isInsightsEnabled: (raw as { isInsightsEnabled?: boolean }).isInsightsEnabled ?? false,
externalFields: raw.externalFields ?? [],
},
},
Expand Down Expand Up @@ -653,12 +655,12 @@ export class EntityService extends BaseService implements EntityServiceModel {
refMeta?: ResolvedReferenceMeta,
): FieldSchemaPayload {
const fieldType = field.type ?? EntityFieldDataType.STRING;
this.validateFieldConstraints(fieldType, field, field.fieldName);
this.validateFieldConstraints(fieldType, field, field.name);
const isRelationship = fieldType === EntityFieldDataType.RELATIONSHIP;
const isFile = fieldType === EntityFieldDataType.FILE;
if (isRelationship && (!field.referenceEntityId || !field.referenceFieldId)) {
throw new ValidationError({
message: `Field '${field.fieldName}' of type ${fieldType} requires both referenceEntityId and referenceFieldId (UUIDs of the target entity and field).`,
message: `Field '${field.name}' of type ${fieldType} requires both referenceEntityId and referenceFieldId (UUIDs of the target entity and field).`,
});
}
const mapping = EntitySchemaFieldTypeMap[fieldType];
Expand All @@ -667,8 +669,8 @@ export class EntityService extends BaseService implements EntityServiceModel {
const referenceEntityBody = refMeta?.referenceEntity ?? (field.referenceEntityId === undefined ? undefined : { id: field.referenceEntityId });
const referenceChoiceSetBody = refMeta?.referenceChoiceSet;
return {
name: field.fieldName,
displayName: field.displayName ?? field.fieldName,
name: field.name,
displayName: field.displayName ?? field.name,
sqlType: {
name: mapping.sqlTypeName,
...this.buildSqlTypeConstraints(fieldType, field),
Expand Down
Loading
Loading