@rippling/rippling-sdk 0.2.0-alpha.44 → 0.2.0-alpha.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/examples/manifest/dental-practice-management/dental-practice-management.ts +0 -7
  2. package/examples/manifest/dental-practice-management/manifest.json +0 -7
  3. package/examples/manifest/existing-manifest-mutations/existing-manifest-mutations.ts +6 -7
  4. package/examples/manifest/gym-membership-management/gym-membership-management.ts +0 -7
  5. package/examples/manifest/gym-membership-management/manifest.json +0 -7
  6. package/lib/manifest/custom-object-field-section.d.mts +2 -2
  7. package/lib/manifest/custom-object-field-section.d.ts +2 -2
  8. package/lib/manifest/custom-object-field-section.js +2 -2
  9. package/lib/manifest/custom-object-field-section.mjs +2 -2
  10. package/lib/manifest/custom-object-page-layout.d.mts +78 -37
  11. package/lib/manifest/custom-object-page-layout.d.mts.map +1 -1
  12. package/lib/manifest/custom-object-page-layout.d.ts +78 -37
  13. package/lib/manifest/custom-object-page-layout.d.ts.map +1 -1
  14. package/lib/manifest/custom-object-page-layout.js +263 -66
  15. package/lib/manifest/custom-object-page-layout.js.map +1 -1
  16. package/lib/manifest/custom-object-page-layout.mjs +263 -66
  17. package/lib/manifest/custom-object-page-layout.mjs.map +1 -1
  18. package/lib/manifest/custom-object.d.mts +6 -0
  19. package/lib/manifest/custom-object.d.mts.map +1 -1
  20. package/lib/manifest/custom-object.d.ts +6 -0
  21. package/lib/manifest/custom-object.d.ts.map +1 -1
  22. package/lib/manifest/custom-object.js +6 -0
  23. package/lib/manifest/custom-object.js.map +1 -1
  24. package/lib/manifest/custom-object.mjs +6 -0
  25. package/lib/manifest/custom-object.mjs.map +1 -1
  26. package/lib/manifest/existing-manifest-context.d.mts +0 -1
  27. package/lib/manifest/existing-manifest-context.d.mts.map +1 -1
  28. package/lib/manifest/existing-manifest-context.d.ts +0 -1
  29. package/lib/manifest/existing-manifest-context.d.ts.map +1 -1
  30. package/lib/manifest/existing-manifest-context.js +5 -10
  31. package/lib/manifest/existing-manifest-context.js.map +1 -1
  32. package/lib/manifest/existing-manifest-context.mjs +5 -10
  33. package/lib/manifest/existing-manifest-context.mjs.map +1 -1
  34. package/lib/manifest/field.d.mts +6 -3
  35. package/lib/manifest/field.d.mts.map +1 -1
  36. package/lib/manifest/field.d.ts +6 -3
  37. package/lib/manifest/field.d.ts.map +1 -1
  38. package/lib/manifest/field.js +26 -6
  39. package/lib/manifest/field.js.map +1 -1
  40. package/lib/manifest/field.mjs +26 -6
  41. package/lib/manifest/field.mjs.map +1 -1
  42. package/package.json +1 -1
  43. package/src/lib/manifest/custom-object-field-section.ts +2 -2
  44. package/src/lib/manifest/custom-object-page-layout.ts +477 -93
  45. package/src/lib/manifest/custom-object.ts +6 -0
  46. package/src/lib/manifest/existing-manifest-context.ts +5 -12
  47. package/src/lib/manifest/field.ts +45 -9
  48. package/src/version.ts +1 -1
  49. package/version.d.mts +1 -1
  50. package/version.d.ts +1 -1
  51. package/version.js +1 -1
  52. package/version.mjs +1 -1
@@ -271,10 +271,16 @@ export interface CustomObjectProps {
271
271
  * });
272
272
  *
273
273
  * // The object is now a scope — children register through it:
274
+ * const memberProfileSection = new CustomObjectFieldSection(memberObj, {
275
+ * name: 'Profile',
276
+ * sectionId: 'sec_gm_profile',
277
+ * });
278
+ *
274
279
  * const firstName = new TextField(memberObj, {
275
280
  * apiName: 'first_name__c',
276
281
  * displayName: 'First name',
277
282
  * required: true,
283
+ * section: memberProfileSection,
278
284
  * });
279
285
  * ```
280
286
  *
@@ -415,7 +415,11 @@ export class ExistingManifestContext {
415
415
  return this.getOrLoad(cacheKey, () => {
416
416
  const customObject = this.loadCustomObject(customObjectApiName);
417
417
  this.loadPageLayoutDependencies(customObjectApiName, component);
418
- return CustomObjectPageLayout._fromExistingComponent(customObject, component);
418
+ return CustomObjectPageLayout._fromExistingComponent(customObject, component, (fieldApiName) => {
419
+ const fieldComponent = this.findFieldComponent(customObjectApiName, fieldApiName);
420
+ const sectionId = fieldComponent?.['section'];
421
+ return typeof sectionId === 'string' ? sectionId : undefined;
422
+ });
419
423
  });
420
424
  }
421
425
 
@@ -651,7 +655,6 @@ export class ExistingManifestContext {
651
655
  private loadSectionDependencies(customObjectApiName: string, section: unknown): void {
652
656
  if (section == null || typeof section !== 'object') return;
653
657
  const sectionRecord = section as Record<string, any>;
654
- this.loadFieldSectionIfPresent(customObjectApiName, sectionRecord['key']);
655
658
  for (const field of sectionRecord['fields'] ?? []) {
656
659
  this.loadSerializedFieldDependency(customObjectApiName, field);
657
660
  }
@@ -683,16 +686,6 @@ export class ExistingManifestContext {
683
686
  }
684
687
  }
685
688
 
686
- private loadFieldSectionIfPresent(customObjectApiName: string, sectionId: unknown): void {
687
- if (typeof sectionId !== 'string') return;
688
- const component = this.ofType('CUSTOM_OBJECT_FIELD_SECTION').find(
689
- (candidate) => candidate['model_name'] === customObjectApiName && candidate['section_id'] === sectionId,
690
- );
691
- if (component != null) {
692
- this.loadFieldSectionComponent(component);
693
- }
694
- }
695
-
696
689
  private loadRequiredFieldSection(customObjectApiName: string, sectionId: string, ownerLabel: string): void {
697
690
  const component = this.ofType('CUSTOM_OBJECT_FIELD_SECTION').find(
698
691
  (candidate) => candidate['model_name'] === customObjectApiName && candidate['section_id'] === sectionId,
@@ -6,7 +6,7 @@ import {
6
6
  type SummaryFilterOperator,
7
7
  } from './_helpers';
8
8
  import type { CustomObject } from './custom-object';
9
- import type { CustomObjectFieldSection } from './custom-object-field-section';
9
+ import { CustomObjectFieldSection } from './custom-object-field-section';
10
10
  import { getExistingManifestContext, type ExistingManifestContextOptions } from './existing-manifest-context';
11
11
  import type { ManifestComponentDeletion } from './manifest-builder';
12
12
  import { requireObjectComponentField, requireStringComponentField } from './_existing-component-fields';
@@ -71,7 +71,7 @@ interface CommonFieldProps {
71
71
  apiName: string;
72
72
  displayName: string;
73
73
  description?: string;
74
- section?: CustomObjectFieldSection;
74
+ section: CustomObjectFieldSection;
75
75
  }
76
76
 
77
77
  /**
@@ -94,7 +94,7 @@ export interface FieldProps {
94
94
  formulaAttrMetas?: Record<string, any> | null | undefined;
95
95
  derivedAggregatedField?: Record<string, any> | null | undefined;
96
96
  derivedFieldFormula?: string | null | undefined;
97
- section?: CustomObjectFieldSection | null | undefined;
97
+ section: CustomObjectFieldSection;
98
98
  maxLength?: number | undefined;
99
99
  decimalPlaces?: number | undefined;
100
100
  currency?: string | undefined;
@@ -107,14 +107,34 @@ export interface FieldLoadFromExistingOptions extends ExistingManifestContextOpt
107
107
  customObjectApiName?: string;
108
108
  }
109
109
 
110
- function normalizeSectionInput(section: CustomObjectFieldSection | string | null | undefined): string | null {
111
- if (section == null) return null;
110
+ const EXISTING_FIELD_SECTION_ID = Symbol('Field.existingFieldSectionId');
111
+
112
+ function normalizeSectionInput(
113
+ customObject: CustomObject,
114
+ fieldApiName: string,
115
+ section: CustomObjectFieldSection | string | null | undefined,
116
+ ): string {
117
+ if (section == null) {
118
+ throw new Error(
119
+ `Field "${fieldApiName}" requires a CustomObjectFieldSection. ` +
120
+ 'Create a CustomObjectFieldSection for the custom object and pass it as section.',
121
+ );
122
+ }
112
123
  if (typeof section === 'string') {
113
124
  throw new TypeError(
114
125
  `Field section must be a CustomObjectFieldSection object; received raw section id "${section}". ` +
115
126
  'Load/include the existing field section first.',
116
127
  );
117
128
  }
129
+ if (!(section instanceof CustomObjectFieldSection)) {
130
+ throw new TypeError('Field section must be a CustomObjectFieldSection object.');
131
+ }
132
+ if (section.getModelApiName() !== customObject.getApiName()) {
133
+ throw new Error(
134
+ `Field "${fieldApiName}" section "${section.getSectionId()}" belongs to ` +
135
+ `"${section.getModelApiName()}", but the field belongs to "${customObject.getApiName()}".`,
136
+ );
137
+ }
118
138
  return section.getSectionId();
119
139
  }
120
140
 
@@ -196,6 +216,7 @@ class ExistingFieldReference {
196
216
  * displayName: 'First name',
197
217
  * required: true,
198
218
  * maxLength: 80,
219
+ * section: profileSection,
199
220
  * });
200
221
  * ```
201
222
  *
@@ -256,8 +277,11 @@ export class Field {
256
277
  this._derivedFieldFormula = props.derivedFieldFormula ?? null;
257
278
  this._summarySpec = props.summarySpec ?? null;
258
279
 
280
+ const existingSectionId = (
281
+ props as unknown as Record<typeof EXISTING_FIELD_SECTION_ID, string | undefined>
282
+ )[EXISTING_FIELD_SECTION_ID];
259
283
  const rawSection = props.section as CustomObjectFieldSection | string | null | undefined;
260
- this._section = normalizeSectionInput(rawSection);
284
+ this._section = existingSectionId ?? normalizeSectionInput(customObject, props.apiName, rawSection);
261
285
 
262
286
  customObject._register(this);
263
287
  }
@@ -274,11 +298,11 @@ export class Field {
274
298
 
275
299
  /** @internal Hydrates a custom object field from existing manifest wire JSON. */
276
300
  static _fromExistingComponent(customObject: CustomObject, component: Record<string, any>): Field {
277
- const props: FieldProps = {
301
+ const props = {
278
302
  apiName: requireStringComponentField(component, 'field_api_name', Field.componentType),
279
303
  displayName: requireStringComponentField(component, 'field_display_name', Field.componentType),
280
304
  dataType: cloneJson(requireObjectComponentField(component, 'data_type', Field.componentType)),
281
- };
305
+ } as FieldProps;
282
306
  if (component['description'] !== undefined) props.description = component['description'];
283
307
  if (component['is_required'] !== undefined) props.required = component['is_required'];
284
308
  if (component['is_unique'] !== undefined) props.unique = component['is_unique'];
@@ -291,8 +315,18 @@ export class Field {
291
315
  }
292
316
  if (component['derived_field_formula'] !== undefined)
293
317
  props.derivedFieldFormula = component['derived_field_formula'];
318
+ const sectionId = component['section'];
319
+ if (typeof sectionId !== 'string' || sectionId.length === 0) {
320
+ throw new Error(
321
+ `CUSTOM_OBJECT_FIELD ${customObject.getApiName()}.${
322
+ props.apiName
323
+ } is missing required field section. ` +
324
+ 'Add a CUSTOM_OBJECT_FIELD_SECTION component and set the field section to its section_id.',
325
+ );
326
+ }
327
+ (props as unknown as Record<typeof EXISTING_FIELD_SECTION_ID, string>)[EXISTING_FIELD_SECTION_ID] =
328
+ sectionId;
294
329
  const field = new Field(customObject, props);
295
- if (typeof component['section'] === 'string') field._assignSection(component['section']);
296
330
  return field;
297
331
  }
298
332
 
@@ -829,6 +863,7 @@ export interface FormulaFieldProps extends CommonFieldProps {
829
863
  * fieldType: 'TEXT',
830
864
  * maxLength: 200,
831
865
  * formula: "CONCATENATE(TRIM(first_name__c), ' ', TRIM(last_name__c))",
866
+ * section: profileSection,
832
867
  * });
833
868
  * ```
834
869
  */
@@ -900,6 +935,7 @@ export interface SummaryFieldProps extends CommonFieldProps {
900
935
  * aggregates: enrollmentMemberRef,
901
936
  * using: 'COUNT',
902
937
  * lookup: enrollmentSessionRef, // ParentChildField on enrollmentObj → sessionObj
938
+ * section: sessionStatsSection,
903
939
  * });
904
940
  * ```
905
941
  *
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = '0.2.0-alpha.44'; // x-release-please-version
1
+ export const VERSION = '0.2.0-alpha.45'; // x-release-please-version
package/version.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.2.0-alpha.44";
1
+ export declare const VERSION = "0.2.0-alpha.45";
2
2
  //# sourceMappingURL=version.d.mts.map
package/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.2.0-alpha.44";
1
+ export declare const VERSION = "0.2.0-alpha.45";
2
2
  //# sourceMappingURL=version.d.ts.map
package/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
- exports.VERSION = '0.2.0-alpha.44'; // x-release-please-version
4
+ exports.VERSION = '0.2.0-alpha.45'; // x-release-please-version
5
5
  //# sourceMappingURL=version.js.map
package/version.mjs CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = '0.2.0-alpha.44'; // x-release-please-version
1
+ export const VERSION = '0.2.0-alpha.45'; // x-release-please-version
2
2
  //# sourceMappingURL=version.mjs.map