@airtable/blocks 1.10.1 → 1.11.0

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.
@@ -1,11 +1,16 @@
1
1
  "use strict";
2
2
 
3
+ require("core-js/modules/es.array.iterator");
4
+
3
5
  require("core-js/modules/es.string.replace");
4
6
 
7
+ require("core-js/modules/web.dom-collections.iterator");
8
+
5
9
  Object.defineProperty(exports, "__esModule", {
6
10
  value: true
7
11
  });
8
12
  exports.spawnError = spawnError;
13
+ exports.logErrorToRollbar = logErrorToRollbar;
9
14
  exports.invariant = invariant;
10
15
  exports.spawnUnknownSwitchCaseError = spawnUnknownSwitchCaseError;
11
16
  exports.spawnAbstractMethodError = spawnAbstractMethodError;
@@ -52,6 +57,26 @@ function spawnError(errorMessageFormat) {
52
57
  }
53
58
 
54
59
  return spawnErrorWithOriginOmittedFromStackTrace(errorMessageFormat, errorMessageArgs, spawnError);
60
+ } // istanbul ignore next
61
+
62
+ /**
63
+ * Logs an error to Rollbar
64
+ *
65
+ * @hidden
66
+ */
67
+
68
+
69
+ function logErrorToRollbar(errorMessageFormat) {
70
+ // See this comment for how to log via Rollbar: https://github.com/Hyperbase/hyperbase/blob/009dcd1dc4c5204277c2939e7f61dfce74535f30/client/run_block_frame.tsx#L548
71
+ var rollbar = window.Rollbar;
72
+
73
+ if (rollbar === null || rollbar === void 0 ? void 0 : rollbar.warn) {
74
+ for (var _len2 = arguments.length, errorMessageArgs = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
75
+ errorMessageArgs[_key2 - 1] = arguments[_key2];
76
+ }
77
+
78
+ rollbar.warn(spawnError(errorMessageFormat, ...errorMessageArgs));
79
+ }
55
80
  }
56
81
  /**
57
82
  * An alternative to facebook's invariant that's safe to use with base data
@@ -62,8 +87,8 @@ function spawnError(errorMessageFormat) {
62
87
 
63
88
  function invariant(condition, errorMessageFormat) {
64
89
  if (!condition) {
65
- for (var _len2 = arguments.length, errorMessageArgs = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
66
- errorMessageArgs[_key2 - 2] = arguments[_key2];
90
+ for (var _len3 = arguments.length, errorMessageArgs = new Array(_len3 > 2 ? _len3 - 2 : 0), _key3 = 2; _key3 < _len3; _key3++) {
91
+ errorMessageArgs[_key3 - 2] = arguments[_key3];
67
92
  }
68
93
 
69
94
  throw spawnErrorWithOriginOmittedFromStackTrace(errorMessageFormat, errorMessageArgs, invariant);
@@ -864,6 +864,21 @@ function (_AbstractModel) {
864
864
  get: function get() {
865
865
  return this._data.name;
866
866
  }
867
+ /**
868
+ * The workspace id of the base.
869
+ *
870
+ * @example
871
+ * ```js
872
+ * import {base} from '@airtable/blocks';
873
+ * console.log('The workspace id of your base is', base.workspaceId);
874
+ * ```
875
+ */
876
+
877
+ }, {
878
+ key: "workspaceId",
879
+ get: function get() {
880
+ return this._data.workspaceId;
881
+ }
867
882
  /**
868
883
  * The color of the base.
869
884
  *
@@ -279,6 +279,101 @@ function (_AbstractModel) {
279
279
  }
280
280
  }, null, this);
281
281
  }
282
+ /**
283
+ * Checks whether the current user has permission to perform the given name update.
284
+ *
285
+ * Accepts partial input, in the same format as {@link updateNameAsync}.
286
+ *
287
+ * Returns `{hasPermission: true}` if the current user can update the specified field,
288
+ * `{hasPermission: false, reasonDisplayString: string}` otherwise. `reasonDisplayString` may be
289
+ * used to display an error message to the user.
290
+ *
291
+ * @param name new name for the field
292
+ *
293
+ * @example
294
+ * ```js
295
+ * const updateFieldCheckResult = field.checkPermissionsForUpdateName();
296
+ *
297
+ * if (!updateFieldCheckResult.hasPermission) {
298
+ * alert(updateFieldCheckResult.reasonDisplayString);
299
+ * }
300
+ * ```
301
+ */
302
+
303
+ }, {
304
+ key: "checkPermissionsForUpdateName",
305
+ value: function checkPermissionsForUpdateName(name) {
306
+ return this._sdk.__mutations.checkPermissionsForMutation({
307
+ type: _mutations.MutationTypes.UPDATE_SINGLE_FIELD_NAME,
308
+ tableId: this.parentTable.id,
309
+ id: this.id,
310
+ name
311
+ });
312
+ }
313
+ /**
314
+ * An alias for `checkPermissionsForUpdateName(options).hasPermission`.
315
+ *
316
+ * Checks whether the current user has permission to perform the name update.
317
+ *
318
+ * Accepts partial input, in the same format as {@link updateNameAsync}.
319
+ *
320
+ * @param name new name for the field
321
+ *
322
+ * @example
323
+ * ```js
324
+ * const canUpdateField = field.hasPermissionToUpdateName();
325
+ *
326
+ * if (!canUpdateField) {
327
+ * alert('not allowed!');
328
+ * }
329
+ * ```
330
+ */
331
+
332
+ }, {
333
+ key: "hasPermissionToUpdateName",
334
+ value: function hasPermissionToUpdateName(name) {
335
+ return this.checkPermissionsForUpdateName(name).hasPermission;
336
+ }
337
+ /**
338
+ * Updates the name for this field.
339
+ *
340
+ * Throws an error if the user does not have permission to update the field, or if an invalid
341
+ * name is provided.
342
+ *
343
+ * This action is asynchronous. Unlike updates to cell values, updates to field name are
344
+ * **not** applied optimistically locally. You must `await` the returned promise before
345
+ * relying on the change in your app.
346
+ *
347
+ * @param name new name for the field
348
+ *
349
+ * @example
350
+ * ```js
351
+ * await myTextField.updateNameAsync('My New Name');
352
+ * ```
353
+ */
354
+
355
+ }, {
356
+ key: "updateNameAsync",
357
+ value: function updateNameAsync(name) {
358
+ return _regenerator.default.async(function updateNameAsync$(_context2) {
359
+ while (1) {
360
+ switch (_context2.prev = _context2.next) {
361
+ case 0:
362
+ _context2.next = 2;
363
+ return _regenerator.default.awrap(this._sdk.__mutations.applyMutationAsync({
364
+ type: _mutations.MutationTypes.UPDATE_SINGLE_FIELD_NAME,
365
+ tableId: this.parentTable.id,
366
+ id: this.id,
367
+ name
368
+ }));
369
+
370
+ case 2:
371
+ case "end":
372
+ return _context2.stop();
373
+ }
374
+ }
375
+ }, null, this);
376
+ }
282
377
  /**
283
378
  * Checks whether the current user has permission to perform the given description update.
284
379
  *
@@ -358,11 +453,11 @@ function (_AbstractModel) {
358
453
  }, {
359
454
  key: "updateDescriptionAsync",
360
455
  value: function updateDescriptionAsync(description) {
361
- return _regenerator.default.async(function updateDescriptionAsync$(_context2) {
456
+ return _regenerator.default.async(function updateDescriptionAsync$(_context3) {
362
457
  while (1) {
363
- switch (_context2.prev = _context2.next) {
458
+ switch (_context3.prev = _context3.next) {
364
459
  case 0:
365
- _context2.next = 2;
460
+ _context3.next = 2;
366
461
  return _regenerator.default.awrap(this._sdk.__mutations.applyMutationAsync({
367
462
  type: _mutations.MutationTypes.UPDATE_SINGLE_FIELD_DESCRIPTION,
368
463
  tableId: this.parentTable.id,
@@ -372,7 +467,7 @@ function (_AbstractModel) {
372
467
 
373
468
  case 2:
374
469
  case "end":
375
- return _context2.stop();
470
+ return _context3.stop();
376
471
  }
377
472
  }
378
473
  }, null, this);
@@ -520,12 +520,17 @@ function (_RecordQueryResult) {
520
520
  }, {
521
521
  key: "_onLinkedRecordIdsChange",
522
522
  value: function _onLinkedRecordIdsChange() {
523
- (0, _error_utils.invariant)(this.isValid, 'watch key change event whilst invalid');
524
-
525
- if (!this.isDataLoaded) {
523
+ if (!this.isDataLoaded || this._record.isDeleted) {
524
+ //TODO(jamesmoody-at): Adding this._dataOrNullIfDeleted as an exit condition here is a temporary fix to address an issue where
525
+ // we are not reseting isValid to true while restoring deleted records that contain linked record fields. It seems the only way
526
+ // to do this is by creating a new LinkRecordsQueryResult instance but it seems like we might be reusing the original instance
527
+ // that we've already set isValid to false with. We'll need to do more investigating to figure out the right way to restore these
528
+ // records while keeping the behavior of isValid consistent
526
529
  return;
527
530
  }
528
531
 
532
+ (0, _error_utils.invariant)(this.isValid, 'watch key change event whilst invalid');
533
+
529
534
  this._invalidateComputedData(); // we don't actually know at this stage whether anything changed or
530
535
  // not. it may have done though, so notify watchers
531
536
 
@@ -610,15 +615,19 @@ function (_RecordQueryResult) {
610
615
  }, {
611
616
  key: "_onOriginCellValueChange",
612
617
  value: function _onOriginCellValueChange() {
613
- (0, _error_utils.invariant)(this.isValid, 'watch key change event whilst invalid');
614
-
615
- if (!this.isDataLoaded) {
618
+ if (!this.isDataLoaded || this._field.isDeleted) {
619
+ //TODO(jamesmoody-at): Adding this._dataOrNullIfDeleted as an exit condition here is a temporary fix to address an issue where
620
+ // we are not resetting isValid to true while restoring deleted records that contain linked record fields. It seems the only way
621
+ // to do this is by creating a new LinkRecordsQueryResult instance but it seems like we might be reusing the original instance
622
+ // that we've already set isValid to false with. We'll need to do more investigating to figure out the right way to restore these
623
+ // records while keeping the behavior of isValid consistent
616
624
  return;
617
- } // when the origin cell value (listing all the linked records) changes,
625
+ }
626
+
627
+ (0, _error_utils.invariant)(this.isValid, 'watch key change event whilst invalid'); // when the origin cell value (listing all the linked records) changes,
618
628
  // invalidate all the data we have stored - we need to completely
619
629
  // regenerate it
620
630
 
621
-
622
631
  this._invalidateComputedData(); // notify watchers that our set of linked records has changed
623
632
 
624
633
 
@@ -231,6 +231,26 @@ function () {
231
231
  }
232
232
  /** @internal */
233
233
 
234
+ }, {
235
+ key: "_assertFieldNameIsValidForMutation",
236
+ value: function _assertFieldNameIsValidForMutation(name, table) {
237
+ if (!name) {
238
+ throw (0, _error_utils.spawnError)("Can't create or update field: must provide non-empty name");
239
+ }
240
+
241
+ if (name.length > _mutation_constants.MAX_FIELD_NAME_LENGTH) {
242
+ throw (0, _error_utils.spawnError)("Can't create or update field: name '%s' exceeds maximum length of %s characters", name, _mutation_constants.MAX_FIELD_NAME_LENGTH);
243
+ } // Verify the new name doesn't collide with any existing field name.
244
+
245
+
246
+ var existingLowercaseFieldNames = table.fields.map(field => field.name.toLowerCase());
247
+
248
+ if (existingLowercaseFieldNames.includes(name.toLowerCase())) {
249
+ throw (0, _error_utils.spawnError)("Can't create or update field: field with name '%s' already exists", name);
250
+ }
251
+ }
252
+ /** @internal */
253
+
234
254
  }, {
235
255
  key: "_assertMutationIsValid",
236
256
  value: function _assertMutationIsValid(mutation) {
@@ -455,19 +475,7 @@ function () {
455
475
  throw (0, _error_utils.spawnError)("Can't create field: table already has the maximum of %s fields", _mutation_constants.MAX_NUM_FIELDS_PER_TABLE);
456
476
  }
457
477
 
458
- if (!name) {
459
- throw (0, _error_utils.spawnError)("Can't create field: must provide non-empty name");
460
- }
461
-
462
- if (name.length > _mutation_constants.MAX_FIELD_NAME_LENGTH) {
463
- throw (0, _error_utils.spawnError)("Can't create field: name '%s' exceeds maximum length of %s characters", name, _mutation_constants.MAX_FIELD_NAME_LENGTH);
464
- }
465
-
466
- var existingLowercaseFieldNames = _table3.fields.map(field => field.name.toLowerCase());
467
-
468
- if (existingLowercaseFieldNames.includes(name.toLowerCase())) {
469
- throw (0, _error_utils.spawnError)("Can't create field: field with name '%s' already exists", name);
470
- } // Current config / field data is null since the field doesn't exist.
478
+ this._assertFieldNameIsValidForMutation(name, _table3); // Current config / field data is null since the field doesn't exist.
471
479
 
472
480
 
473
481
  var _validationResult2 = this._airtableInterface.fieldTypeProvider.validateConfigForUpdate(appInterface, config, null, null, billingPlanGrouping);
@@ -541,23 +549,51 @@ function () {
541
549
  return;
542
550
  }
543
551
 
552
+ case _mutations.MutationTypes.UPDATE_SINGLE_FIELD_NAME:
553
+ {
554
+ var _tableId6 = mutation.tableId,
555
+ _id2 = mutation.id,
556
+ _name = mutation.name;
557
+
558
+ var _table6 = this._base.getTableByIdIfExists(_tableId6);
559
+
560
+ if (!_table6) {
561
+ throw (0, _error_utils.spawnError)("Can't update field: No table with id %s exists", _tableId6);
562
+ }
563
+
564
+ var _field4 = _table6.getFieldByIdIfExists(_id2);
565
+
566
+ if (!_field4) {
567
+ throw (0, _error_utils.spawnError)("Can't update field: No field with id %s exists", _id2);
568
+ } // We skip name validation if it's the same name:
569
+ // If it's exactly same name, this will result in no-op;
570
+ // If it's only case change, we allow update and we know this name is already validated before;
571
+
572
+
573
+ if (_field4.name.toLowerCase() !== _name.toLowerCase()) {
574
+ this._assertFieldNameIsValidForMutation(_name, _table6);
575
+ }
576
+
577
+ return;
578
+ }
579
+
544
580
  case _mutations.MutationTypes.CREATE_SINGLE_TABLE:
545
581
  {
546
- var _name = mutation.name,
582
+ var _name2 = mutation.name,
547
583
  fields = mutation.fields;
548
584
 
549
- if (!_name) {
585
+ if (!_name2) {
550
586
  throw (0, _error_utils.spawnError)("Can't create table: must provide non-empty name");
551
587
  }
552
588
 
553
- if (_name.length > _mutation_constants.MAX_TABLE_NAME_LENGTH) {
554
- throw (0, _error_utils.spawnError)("Can't create table: name '%s' exceeds maximum length of %s characters", _name, _mutation_constants.MAX_TABLE_NAME_LENGTH);
589
+ if (_name2.length > _mutation_constants.MAX_TABLE_NAME_LENGTH) {
590
+ throw (0, _error_utils.spawnError)("Can't create table: name '%s' exceeds maximum length of %s characters", _name2, _mutation_constants.MAX_TABLE_NAME_LENGTH);
555
591
  }
556
592
 
557
593
  var existingLowercaseTableNames = this._base.tables.map(table => table.name.toLowerCase());
558
594
 
559
- if (existingLowercaseTableNames.includes(_name.toLowerCase())) {
560
- throw (0, _error_utils.spawnError)("Can't create table: table with name '%s' already exists", _name);
595
+ if (existingLowercaseTableNames.includes(_name2.toLowerCase())) {
596
+ throw (0, _error_utils.spawnError)("Can't create table: table with name '%s' already exists", _name2);
561
597
  }
562
598
 
563
599
  if (fields.length === 0) {
@@ -575,32 +611,32 @@ function () {
575
611
 
576
612
  try {
577
613
  for (var _iterator4 = fields[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
578
- var _field4 = _step4.value;
614
+ var _field5 = _step4.value;
579
615
 
580
- if (!_field4.name) {
616
+ if (!_field5.name) {
581
617
  throw (0, _error_utils.spawnError)("Can't create table: must provide non-empty name for every field");
582
618
  }
583
619
 
584
- if (_field4.name.length > _mutation_constants.MAX_FIELD_NAME_LENGTH) {
585
- throw (0, _error_utils.spawnError)("Can't create table: field name '%s' exceeds maximum length of %s characters", _field4.name, _mutation_constants.MAX_FIELD_NAME_LENGTH);
620
+ if (_field5.name.length > _mutation_constants.MAX_FIELD_NAME_LENGTH) {
621
+ throw (0, _error_utils.spawnError)("Can't create table: field name '%s' exceeds maximum length of %s characters", _field5.name, _mutation_constants.MAX_FIELD_NAME_LENGTH);
586
622
  }
587
623
 
588
- var lowercaseFieldName = _field4.name.toLowerCase();
624
+ var lowercaseFieldName = _field5.name.toLowerCase();
589
625
 
590
626
  if (lowercaseFieldNames.has(lowercaseFieldName)) {
591
- throw (0, _error_utils.spawnError)("Can't create table: duplicate field name '%s'", _field4.name);
627
+ throw (0, _error_utils.spawnError)("Can't create table: duplicate field name '%s'", _field5.name);
592
628
  }
593
629
 
594
630
  lowercaseFieldNames.add(lowercaseFieldName); // Current config / field data is null since the field doesn't exist.
595
631
 
596
- var _validationResult4 = this._airtableInterface.fieldTypeProvider.validateConfigForUpdate(appInterface, _field4.config, null, null, billingPlanGrouping);
632
+ var _validationResult4 = this._airtableInterface.fieldTypeProvider.validateConfigForUpdate(appInterface, _field5.config, null, null, billingPlanGrouping);
597
633
 
598
634
  if (!_validationResult4.isValid) {
599
- throw (0, _error_utils.spawnError)("Can't create table: invalid field config for field '%s'.\n%s", _field4.name, _validationResult4.reason);
635
+ throw (0, _error_utils.spawnError)("Can't create table: invalid field config for field '%s'.\n%s", _field5.name, _validationResult4.reason);
600
636
  }
601
637
 
602
- if (_field4.description && _field4.description.length > _mutation_constants.MAX_FIELD_DESCRIPTION_LENGTH) {
603
- throw (0, _error_utils.spawnError)("Can't create table: description for field '%s' exceeds maximum length of %s characters", _field4.name, _mutation_constants.MAX_FIELD_DESCRIPTION_LENGTH);
638
+ if (_field5.description && _field5.description.length > _mutation_constants.MAX_FIELD_DESCRIPTION_LENGTH) {
639
+ throw (0, _error_utils.spawnError)("Can't create table: description for field '%s' exceeds maximum length of %s characters", _field5.name, _mutation_constants.MAX_FIELD_DESCRIPTION_LENGTH);
604
640
  }
605
641
  }
606
642
  } catch (err) {
@@ -629,7 +665,7 @@ function () {
629
665
 
630
666
  case _mutations.MutationTypes.UPDATE_VIEW_METADATA:
631
667
  {
632
- var _tableId6 = mutation.tableId,
668
+ var _tableId7 = mutation.tableId,
633
669
  viewId = mutation.viewId;
634
670
  var runContext = this._airtableInterface.sdkInitData.runContext;
635
671
 
@@ -637,17 +673,17 @@ function () {
637
673
  throw (0, _error_utils.spawnError)('Setting view metadata is only valid for views');
638
674
  }
639
675
 
640
- if (runContext.viewId !== viewId || runContext.tableId !== _tableId6) {
676
+ if (runContext.viewId !== viewId || runContext.tableId !== _tableId7) {
641
677
  throw (0, _error_utils.spawnError)('Custom views can only set view metadata on themselves');
642
678
  }
643
679
 
644
- var _table6 = this._base.getTableByIdIfExists(_tableId6);
680
+ var _table7 = this._base.getTableByIdIfExists(_tableId7);
645
681
 
646
- if (!_table6) {
647
- throw (0, _error_utils.spawnError)("Can't update metadata: No table with id %s exists", _tableId6);
682
+ if (!_table7) {
683
+ throw (0, _error_utils.spawnError)("Can't update metadata: No table with id %s exists", _tableId7);
648
684
  }
649
685
 
650
- var view = _table6.getViewByIdIfExists(viewId);
686
+ var view = _table7.getViewByIdIfExists(viewId);
651
687
 
652
688
  if (!view) {
653
689
  throw (0, _error_utils.spawnError)("Can't update metadata: No view with id %s exists", viewId);
@@ -705,19 +741,19 @@ function () {
705
741
 
706
742
  case _mutations.MutationTypes.DELETE_MULTIPLE_RECORDS:
707
743
  {
708
- var _tableId7 = mutation.tableId,
744
+ var _tableId8 = mutation.tableId,
709
745
  recordIds = mutation.recordIds;
710
746
 
711
- var _recordStore2 = this._base.__getRecordStore(_tableId7);
747
+ var _recordStore2 = this._base.__getRecordStore(_tableId8);
712
748
 
713
749
  if (!_recordStore2.isRecordMetadataLoaded) {
714
750
  return [];
715
751
  }
716
752
 
717
753
  return [...recordIds.map(recordId => ({
718
- path: ['tablesById', _tableId7, 'recordsById', recordId],
754
+ path: ['tablesById', _tableId8, 'recordsById', recordId],
719
755
  value: undefined
720
- })), ...this._base.getTableById(_tableId7).views.flatMap(view => {
756
+ })), ...this._base.getTableById(_tableId8).views.flatMap(view => {
721
757
  var viewDataStore = _recordStore2.getViewDataStore(view.id);
722
758
 
723
759
  if (!viewDataStore.isDataLoaded) {
@@ -730,10 +766,10 @@ function () {
730
766
 
731
767
  case _mutations.MutationTypes.CREATE_MULTIPLE_RECORDS:
732
768
  {
733
- var _tableId8 = mutation.tableId,
769
+ var _tableId9 = mutation.tableId,
734
770
  _records2 = mutation.records;
735
771
 
736
- var _recordStore3 = this._base.__getRecordStore(_tableId8);
772
+ var _recordStore3 = this._base.__getRecordStore(_tableId9);
737
773
 
738
774
  if (!_recordStore3.isRecordMetadataLoaded) {
739
775
  return [];
@@ -772,7 +808,7 @@ function () {
772
808
  }
773
809
 
774
810
  return {
775
- path: ['tablesById', _tableId8, 'recordsById', record.id],
811
+ path: ['tablesById', _tableId9, 'recordsById', record.id],
776
812
  value: {
777
813
  id: record.id,
778
814
  cellValuesByFieldId: filteredCellValuesByFieldId,
@@ -780,7 +816,7 @@ function () {
780
816
  createdTime: new Date().toJSON()
781
817
  }
782
818
  };
783
- }), ...this._base.getTableById(_tableId8).views.flatMap(view => {
819
+ }), ...this._base.getTableById(_tableId9).views.flatMap(view => {
784
820
  var viewDataStore = _recordStore3.getViewDataStore(view.id);
785
821
 
786
822
  if (!viewDataStore.isDataLoaded) {
@@ -802,6 +838,7 @@ function () {
802
838
  case _mutations.MutationTypes.CREATE_SINGLE_FIELD:
803
839
  case _mutations.MutationTypes.UPDATE_SINGLE_FIELD_CONFIG:
804
840
  case _mutations.MutationTypes.UPDATE_SINGLE_FIELD_DESCRIPTION:
841
+ case _mutations.MutationTypes.UPDATE_SINGLE_FIELD_NAME:
805
842
  case _mutations.MutationTypes.UPDATE_VIEW_METADATA:
806
843
  case _mutations.MutationTypes.CREATE_SINGLE_TABLE:
807
844
  {
@@ -515,7 +515,7 @@ function (_AbstractModelWithAsy) {
515
515
  }, {
516
516
  key: "_loadCellValuesInFieldIdsAsync",
517
517
  value: function _loadCellValuesInFieldIdsAsync(fieldIds) {
518
- var _ref, newRecordsById, existingRecordsById, _iteratorNormalCompletion7, _didIteratorError7, _iteratorError7, _iterator7, _step7, _step7$value, recordId, newRecordObj, existingRecordObj, existingCellValuesByFieldId, i, fieldId, changedKeys;
518
+ var _ref, newRecordsById, existingRecordsById, _iteratorNormalCompletion7, _didIteratorError7, _iteratorError7, _iterator7, _step7, _step7$value, recordId, newRecordObj, existingRecordObj, isCommentCountTypesSame, isCreatedTimeTypesSame, existingCellValuesByFieldId, i, fieldId, changedKeys;
519
519
 
520
520
  return _regenerator.default.async(function _loadCellValuesInFieldIdsAsync$(_context3) {
521
521
  while (1) {
@@ -545,12 +545,22 @@ function (_AbstractModelWithAsy) {
545
545
  if (!(0, _private_utils.has)(existingRecordsById, recordId)) {
546
546
  existingRecordsById[recordId] = newRecordObj;
547
547
  } else {
548
- existingRecordObj = existingRecordsById[recordId]; // Metadata (createdTime, commentCount) should already be up to date,
549
- // but just verify for sanity. If this doesn't catch anything, can
550
- // remove it for perf.
548
+ existingRecordObj = existingRecordsById[recordId]; // Metadata (createdTime, commentCount) should generally be up to date,
549
+ // but can be out of date in the rare scenario where realtime
550
+ // data has not yet been delivered to the SDK, but is populated in hyperbase
551
+ // at the time this new fetch is executed.
552
+ // istanbul ignore next
551
553
 
552
- (0, _error_utils.invariant)(existingRecordObj.commentCount === newRecordObj.commentCount, 'comment count out of sync');
553
- (0, _error_utils.invariant)(existingRecordObj.createdTime === newRecordObj.createdTime, 'created time out of sync');
554
+ if (existingRecordObj.commentCount !== newRecordObj.commentCount) {
555
+ isCommentCountTypesSame = typeof existingRecordObj.commentCount !== typeof newRecordObj.commentCount;
556
+ (0, _error_utils.logErrorToRollbar)('comment count out of sync - types are same: %s', isCommentCountTypesSame);
557
+ } // istanbul ignore next
558
+
559
+
560
+ if (existingRecordObj.createdTime !== newRecordObj.createdTime) {
561
+ isCreatedTimeTypesSame = typeof existingRecordObj.createdTime !== typeof newRecordObj.createdTime;
562
+ (0, _error_utils.logErrorToRollbar)('created time out of sync - types are same: %s', isCreatedTimeTypesSame);
563
+ }
554
564
 
555
565
  if (!existingRecordObj.cellValuesByFieldId) {
556
566
  existingRecordObj.cellValuesByFieldId = {};
package/dist/cjs/sdk.js CHANGED
@@ -330,4 +330,4 @@ function () {
330
330
  }();
331
331
 
332
332
  exports.default = BlockSdk;
333
- (0, _defineProperty2.default)(BlockSdk, "VERSION", "1.10.1");
333
+ (0, _defineProperty2.default)(BlockSdk, "VERSION", "1.11.0");
@@ -18,6 +18,7 @@ var MutationTypes = Object.freeze({
18
18
  CREATE_SINGLE_FIELD: 'createSingleField',
19
19
  UPDATE_SINGLE_FIELD_CONFIG: 'updateSingleFieldConfig',
20
20
  UPDATE_SINGLE_FIELD_DESCRIPTION: 'updateSingleFieldDescription',
21
+ UPDATE_SINGLE_FIELD_NAME: 'updateSingleFieldName',
21
22
  CREATE_SINGLE_TABLE: 'createSingleTable',
22
23
  UPDATE_VIEW_METADATA: 'updateViewMetadata'
23
24
  });
@@ -2,6 +2,12 @@
2
2
  * @hidden
3
3
  */
4
4
  export declare function spawnError(errorMessageFormat: string, ...errorMessageArgs: ReadonlyArray<unknown>): Error;
5
+ /**
6
+ * Logs an error to Rollbar
7
+ *
8
+ * @hidden
9
+ */
10
+ export declare function logErrorToRollbar(errorMessageFormat: string, ...errorMessageArgs: ReadonlyArray<unknown>): void;
5
11
  /**
6
12
  * An alternative to facebook's invariant that's safe to use with base data
7
13
  *
@@ -1 +1 @@
1
- {"version":3,"file":"error_utils.d.ts","sourceRoot":"","sources":["../../../src/error_utils.ts"],"names":[],"mappings":"AAsCA;;GAEG;AACH,wBAAgB,UAAU,CACtB,kBAAkB,EAAE,MAAM,EAC1B,GAAG,gBAAgB,EAAE,aAAa,CAAC,OAAO,CAAC,SAO9C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACrB,SAAS,EAAE,OAAO,EAClB,kBAAkB,EAAE,MAAM,EAC1B,GAAG,gBAAgB,EAAE,KAAK,CAAC,OAAO,CAAC,GACpC,OAAO,CAAC,SAAS,CAQnB"}
1
+ {"version":3,"file":"error_utils.d.ts","sourceRoot":"","sources":["../../../src/error_utils.ts"],"names":[],"mappings":"AAsCA;;GAEG;AACH,wBAAgB,UAAU,CACtB,kBAAkB,EAAE,MAAM,EAC1B,GAAG,gBAAgB,EAAE,aAAa,CAAC,OAAO,CAAC,SAO9C;AAGD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC7B,kBAAkB,EAAE,MAAM,EAC1B,GAAG,gBAAgB,EAAE,aAAa,CAAC,OAAO,CAAC,QAO9C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACrB,SAAS,EAAE,OAAO,EAClB,kBAAkB,EAAE,MAAM,EAC1B,GAAG,gBAAgB,EAAE,KAAK,CAAC,OAAO,CAAC,GACpC,OAAO,CAAC,SAAS,CAQnB"}
@@ -48,6 +48,16 @@ declare class Base extends AbstractModel<BaseData, WatchableBaseKey> {
48
48
  * ```
49
49
  */
50
50
  get name(): string;
51
+ /**
52
+ * The workspace id of the base.
53
+ *
54
+ * @example
55
+ * ```js
56
+ * import {base} from '@airtable/blocks';
57
+ * console.log('The workspace id of your base is', base.workspaceId);
58
+ * ```
59
+ */
60
+ get workspaceId(): string;
51
61
  /**
52
62
  * The color of the base.
53
63
  *
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/models/base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/models/base.ts"],"names":[],"mappings":"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"}
@@ -168,6 +168,64 @@ declare class Field extends AbstractModel<FieldData, WatchableFieldKey> {
168
168
  * ```
169
169
  */
170
170
  updateOptionsAsync(options: FieldOptions, opts?: UpdateFieldOptionsOpts): Promise<void>;
171
+ /**
172
+ * Checks whether the current user has permission to perform the given name update.
173
+ *
174
+ * Accepts partial input, in the same format as {@link updateNameAsync}.
175
+ *
176
+ * Returns `{hasPermission: true}` if the current user can update the specified field,
177
+ * `{hasPermission: false, reasonDisplayString: string}` otherwise. `reasonDisplayString` may be
178
+ * used to display an error message to the user.
179
+ *
180
+ * @param name new name for the field
181
+ *
182
+ * @example
183
+ * ```js
184
+ * const updateFieldCheckResult = field.checkPermissionsForUpdateName();
185
+ *
186
+ * if (!updateFieldCheckResult.hasPermission) {
187
+ * alert(updateFieldCheckResult.reasonDisplayString);
188
+ * }
189
+ * ```
190
+ */
191
+ checkPermissionsForUpdateName(name?: string): PermissionCheckResult;
192
+ /**
193
+ * An alias for `checkPermissionsForUpdateName(options).hasPermission`.
194
+ *
195
+ * Checks whether the current user has permission to perform the name update.
196
+ *
197
+ * Accepts partial input, in the same format as {@link updateNameAsync}.
198
+ *
199
+ * @param name new name for the field
200
+ *
201
+ * @example
202
+ * ```js
203
+ * const canUpdateField = field.hasPermissionToUpdateName();
204
+ *
205
+ * if (!canUpdateField) {
206
+ * alert('not allowed!');
207
+ * }
208
+ * ```
209
+ */
210
+ hasPermissionToUpdateName(name?: string): boolean;
211
+ /**
212
+ * Updates the name for this field.
213
+ *
214
+ * Throws an error if the user does not have permission to update the field, or if an invalid
215
+ * name is provided.
216
+ *
217
+ * This action is asynchronous. Unlike updates to cell values, updates to field name are
218
+ * **not** applied optimistically locally. You must `await` the returned promise before
219
+ * relying on the change in your app.
220
+ *
221
+ * @param name new name for the field
222
+ *
223
+ * @example
224
+ * ```js
225
+ * await myTextField.updateNameAsync('My New Name');
226
+ * ```
227
+ */
228
+ updateNameAsync(name: string): Promise<void>;
171
229
  /**
172
230
  * Checks whether the current user has permission to perform the given description update.
173
231
  *