import { Category } from "./category.mjs"; import { type ExistingManifestContextOptions } from "./existing-manifest-context.mjs"; import { Field } from "./field.mjs"; import type { ManifestComponent, ManifestComponentDeletion, ManifestScope } from "./manifest-builder.mjs"; /** Specs for the 9 standard fields every CO ships with. Order matches the backend constant. */ declare const STANDARD_FIELD_SPECS: readonly [{ readonly key: "id"; readonly apiName: "id"; readonly displayName: "ID"; readonly description: "The Rippling ID of a record"; readonly dataType: { readonly field_type: "TEXT"; }; readonly required: true; readonly unique: true; }, { readonly key: "createdAt"; readonly apiName: "created_at"; readonly displayName: "Created Date"; readonly description: "The date and time a record was created"; readonly dataType: { readonly field_type: "DATETIME"; }; readonly required: false; readonly unique: false; }, { readonly key: "updatedAt"; readonly apiName: "updated_at"; readonly displayName: "Last Modified Date"; readonly description: "The date and time a record was last updated"; readonly dataType: { readonly field_type: "DATETIME"; }; readonly required: false; readonly unique: false; }, { readonly key: "systemUpdatedAt"; readonly apiName: "system_updated_at"; readonly displayName: "System Modified At"; readonly description: "The date and time a record was last updated by the system"; readonly dataType: { readonly field_type: "DATETIME"; }; readonly required: false; readonly unique: false; }, { readonly key: "externalId"; readonly apiName: "external_id"; readonly displayName: "External ID"; readonly description: "The external identifier for a record used in third party integrations"; readonly dataType: { readonly field_type: "TEXT"; }; readonly required: false; readonly unique: true; }, { readonly key: "name"; readonly apiName: "name"; readonly displayName: "Name"; readonly description: "A string used to describe a record. This is used for display purposes as well as search"; readonly dataType: { readonly field_type: "TEXT"; }; readonly required: true; readonly unique: false; }, { readonly key: "ownerRole"; readonly apiName: "owner_role"; readonly displayName: "Owner"; readonly description: "The Employee responsible for the record. This is used by Permissions to determine who has ability to view, edit, and delete data"; readonly dataType: { readonly field_type: "NATIVE_EDGE"; readonly og_model_rql_name: "Employee"; readonly db_model_name: "RoleWithCompany"; readonly reference_column_storage_type: "STRING"; }; readonly required: false; readonly unique: false; }, { readonly key: "lastModifiedBy"; readonly apiName: "last_modified_by"; readonly displayName: "Last Modified by"; readonly description: "The Employee who made the latest change."; readonly dataType: { readonly field_type: "NATIVE_EDGE"; readonly og_model_rql_name: "Employee"; readonly db_model_name: "RoleWithCompany"; readonly reference_column_storage_type: "STRING"; }; readonly required: false; readonly unique: false; }, { readonly key: "createdBy"; readonly apiName: "created_by"; readonly displayName: "Created by"; readonly description: "The Employee who created the record"; readonly dataType: { readonly field_type: "NATIVE_EDGE"; readonly og_model_rql_name: "Employee"; readonly db_model_name: "RoleWithCompany"; readonly reference_column_storage_type: "STRING"; }; readonly required: false; readonly unique: false; }]; type StandardFieldSpec = (typeof STANDARD_FIELD_SPECS)[number]; export type CustomObjectStandardFieldKey = StandardFieldSpec['key']; export type CustomObjectStandardFieldApiName = StandardFieldSpec['apiName']; export type CustomObjectStandardFieldIdentifier = CustomObjectStandardFieldKey | CustomObjectStandardFieldApiName; export type CustomObjectStandardFields = Readonly>; export type CustomObjectFieldInput = Field | CustomObjectStandardFieldIdentifier; /** * Icon displayed next to the custom object name in the Rippling UI. */ export interface IconConfig { /** * A Unicode emoji character, e.g. `'🏋️'`. * * Optional. Omit all four sources (or pass `null`) to show no icon. */ emoji?: string | null; /** * Name of a built-in Rippling icon asset. * * Optional. */ ripplingIcon?: string | null; /** * S3 bucket for a custom image asset. * * Optional. Must be set together with `s3Key`. */ s3Bucket?: string; /** * S3 key (path) within `s3Bucket`. * * Optional. Must be set together with `s3Bucket`. */ s3Key?: string; } /** * Initialization properties for {@link CustomObject}. */ export interface CustomObjectProps { /** * Unique identifier for this custom object. * * Required. Must end with `__c` (e.g. `'gym_member__c'`). The constructor throws * immediately if this suffix is missing. */ apiName: string; /** * Singular display name shown in the Rippling UI (e.g. `'Member'`). * * Required. */ name: string; /** * The category this object belongs to. * * Required. Pass a {@link Category} instance defined or loaded in the same manifest. */ category: Category; /** * Human-readable description of what this entity represents. * * Required. */ description: string; /** * Icon shown next to the object name in the Rippling UI. * * Optional. @default null */ icon?: IconConfig | null; /** * Plural form of the display name, used in list headings (e.g. `'Members'`). * * Optional. @default null */ pluralLabel?: string | null; /** * Overrides for the auto-number name field — controls the format string and starting number. * Leave `null` to use the default name field behavior. * * Example: * ```ts * nameFieldDetails: { * is_autonumber_field: true, * starting_number: 1, * autonumber_format: 'EXP-{0000}', * } * ``` * * @remarks * The backend auto-appends `{0000}` to `autonumber_format` if the format string * doesn't already contain a sequence token — so `'EXP-'` becomes `'EXP-{0000}'` * on the wire. Include the token explicitly when you want a different width * (e.g. `'EXP-{00000}'`). * * Optional. @default null */ nameFieldDetails?: Record | null; /** * API name of the field section that newly created fields are grouped into by default. * * Optional. @default null */ defaultFieldSectionName?: string | null; } /** * Defines a custom object and registers it with the manifest. * * A custom object is a new entity type with its own fields, validations, rules, list views, * and page layouts. You would normally define all custom objects near the top of your manifest * file, then define their children (fields, sections, rules, etc.) below. Each child takes * the `CustomObject` instance as its first argument and registers automatically. * * @example * ```ts * const manifest = new ManifestBuilder({ * key: 'gym_membership_management', * name: 'Gym Membership Management', * }); * * const gymCategory = new Category(manifest, { apiName: 'gym__c', name: 'Gym', description: 'Gym domain' }); * * const memberObj = new CustomObject(manifest, { * apiName: 'gym_member__c', * name: 'Member', * pluralLabel: 'Members', * category: gymCategory, * description: 'Gym member profile, contact, and membership status', * icon: { emoji: '🏋️' }, * }); * * // The object is now a scope — children register through it: * const memberProfileSection = new CustomObjectFieldSection(memberObj, { * name: 'Profile', * sectionId: 'sec_gm_profile', * }); * * const firstName = new TextField(memberObj, { * apiName: 'first_name__c', * displayName: 'First name', * required: true, * section: memberProfileSection, * }); * ``` * * @remarks * **Required: every `CustomObject` must have at least one `CustomObjectPageLayout` in the * manifest.** Omitting it passes component-level validation but fails at the package level * with `DEPENDENCY_ERROR: Page layout config for CO (api_name=...) not found in package * configs. CO requires at least one page layout in the package.` * Use {@link CustomObjectPageLayout.basic} for a minimal single-tab layout. * * **Consider defining at least one {@link ListViewDef}.** Without a list view, * the records page has nothing to display by default — users land on an empty grid. * Consider shipping a "default" view with the columns most users want to see * (typically `name`, the status / category field, owner, and `created_at`), sorted * however the records are most commonly browsed. * * **Consider system fields before authoring new ones.** Every CO ships with * `owner_role`, `created_by`, and `last_modified_by` (all `Employee` references), * plus `name`, `created_at`, `updated_at`, `external_id`, and `id`. For any * "the employee responsible for this record" semantics, consider using * `owner_role` rather than adding a new {@link LookupField} targeting `'Employee'`. * `owner_role` drives Rippling's record-level permissions, so a parallel field * can fragment ownership and complicate the permission story. */ export declare class CustomObject implements ManifestScope { static readonly componentType: "CUSTOM_OBJECT"; static toDeletionIdentifier(apiName: string): ManifestComponentDeletion; private readonly _scope; private readonly _apiName; private readonly _name; private readonly _category; private _description; private _icon; private _pluralLabel; private _nameFieldDetails; private _defaultFieldSectionName; private readonly _standardFieldRefs; private _standardFieldResolver; readonly standardFields: CustomObjectStandardFields; /** * @param scope - The manifest or parent scope to register this object with. * @param props - Initialization properties. * @throws {Error} If `props.apiName` does not end with `__c`. */ constructor(scope: ManifestScope, props: CustomObjectProps); /** * Loads this custom object from the active existing-manifest JSON context. */ static loadFromExisting(apiName: string, options?: ExistingManifestContextOptions): CustomObject; /** @internal Hydrates a custom object from existing manifest wire JSON. */ static _fromExistingComponent(scope: ManifestScope, component: Record, resolveCategory: (apiName: string) => Category): CustomObject; /** Returns a platform-managed standard field on this custom object. */ standardField(identifier: CustomObjectStandardFieldIdentifier): Field; /** Alias for {@link standardField}. */ field(identifier: CustomObjectStandardFieldIdentifier): Field; /** @internal Resolves object-scoped field inputs accepted by layout/list-view APIs. */ _resolveField(field: CustomObjectFieldInput): Field; /** @internal Lets loaded objects return existing standard field refs when present. */ _setStandardFieldResolver(resolve: (apiName: CustomObjectStandardFieldApiName) => Field): void; private static iconFromExistingComponent; /** @internal Scope hook — forwards child registration up to the root builder. */ _register(component: ManifestComponent): void; /** * Returns the api_name of this custom object (e.g. `'gym_member__c'`). * * Use the return value wherever a field or layout needs to reference this object by name. */ getApiName(): string; /** * Returns the singular display name of this custom object (e.g. `'Member'`). */ getName(): string; /** * Serializes this custom object to the wire format consumed by the manifest install endpoint. * * @returns A plain object with `type: 'CUSTOM_OBJECT'` and all configured fields. * Optional fields are omitted when `null`. An `icon` with no populated keys is omitted entirely. */ toDict(): Record; } export {}; //# sourceMappingURL=custom-object.d.mts.map