lucid-extension-sdk 0.0.440 → 0.0.441

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.
package/commandtypes.d.ts CHANGED
@@ -53,6 +53,7 @@ export declare const enum CommandName {
53
53
  CreateCollection = "cc",
54
54
  CreateDataSource = "cds",
55
55
  CreateDocumentElement = "cde",
56
+ CreateGraph = "cgr",
56
57
  CreateGroup = "cg",
57
58
  CreateLine = "cl",
58
59
  CreatePage = "cp",
@@ -282,6 +283,10 @@ export type CommandArgs = {
282
283
  query: CreateDocumentElementQuery;
283
284
  result: CreateDocumentElementResult;
284
285
  };
286
+ [CommandName.CreateGraph]: {
287
+ query: CreateGraphQuery;
288
+ result: CreateGraphResult;
289
+ };
285
290
  [CommandName.CreateGroup]: {
286
291
  query: CreateGroupQuery;
287
292
  result: CreateGroupResult;
@@ -1196,6 +1201,20 @@ export type CreateGroupQuery = {
1196
1201
  'i': string[];
1197
1202
  };
1198
1203
  export type CreateGroupResult = string;
1204
+ export type CreateGraphQuery = {
1205
+ /**
1206
+ * By default, we add the graph to the current page. If specified, the
1207
+ * graph will instead be created as a direct child of the given page.
1208
+ */
1209
+ 'p'?: string | undefined;
1210
+ /** Type of graph to create, e.g. 'BarGraphCollectionBlock' or 'LineGraphCollectionBlock' */
1211
+ 't': string;
1212
+ /** ID of the collection */
1213
+ 'col': string;
1214
+ /** Title of the graph */
1215
+ 'ti': string;
1216
+ };
1217
+ export type CreateGraphResult = Promise<string>;
1199
1218
  export type CreateCollectionFieldDefinition = {
1200
1219
  /** Name of the field */
1201
1220
  'n': string;
@@ -1270,6 +1289,9 @@ export type DataActionQuery = {
1270
1289
  's'?: string | undefined;
1271
1290
  /** Data Connector Name */
1272
1291
  'n': string;
1292
+ /**Requested Primary keys or keys of items we
1293
+ * are requesting info for in the data action */
1294
+ 'rpk'?: Record<string, string[]> | undefined;
1273
1295
  };
1274
1296
  export type RawDataActionResult = {
1275
1297
  /** The external service responded with this code */
@@ -29,6 +29,12 @@ export declare enum FieldDisplayType {
29
29
  * Given a URL, display a small image cropped into a square in the lower-left of the card.
30
30
  */
31
31
  SquareImageBadge = "SquareImageBadge",
32
+ /**
33
+ * Displays an icon and value as a badge in the bottom-left of the card. Takes an object containing an iconUrl
34
+ * and value. If value is a string longer than 20 characters, it will be truncated to be a maximum of 20 chars
35
+ * appending '...' to the given value. If value is a number higher than 999, displays 999.
36
+ */
37
+ TagBadge = "TagBadge",
32
38
  /**
33
39
  * Given a date, display a small calendar icon alongside a very short version of the date
34
40
  * as a string, e.g. "Sep 9"
@@ -34,6 +34,12 @@ var FieldDisplayType;
34
34
  * Given a URL, display a small image cropped into a square in the lower-left of the card.
35
35
  */
36
36
  FieldDisplayType["SquareImageBadge"] = "SquareImageBadge";
37
+ /**
38
+ * Displays an icon and value as a badge in the bottom-left of the card. Takes an object containing an iconUrl
39
+ * and value. If value is a string longer than 20 characters, it will be truncated to be a maximum of 20 chars
40
+ * appending '...' to the given value. If value is a number higher than 999, displays 999.
41
+ */
42
+ FieldDisplayType["TagBadge"] = "TagBadge";
37
43
  /**
38
44
  * Given a date, display a small calendar icon alongside a very short version of the date
39
45
  * as a string, e.g. "Sep 9"
@@ -112,7 +112,9 @@ export interface ImportFromSerializedFieldsCallbackParam {
112
112
  }
113
113
  /** @ignore */
114
114
  export interface CanEditItemsParam {
115
- 'ek': string;
116
- 'dk'?: string;
115
+ 'i': Array<{
116
+ 'pk': string;
117
+ 'cid': string;
118
+ }>;
117
119
  }
118
120
  export {};
@@ -1,4 +1,5 @@
1
1
  import { CollectionProxy } from '../../data/collectionproxy';
2
+ import { DataItemProxy } from '../../data/dataitemproxy';
2
3
  import { DataSourceProxy } from '../../data/datasourceproxy';
3
4
  import { TextStyle } from '../../document/text/textstyle';
4
5
  import { EditorClient } from '../../editorclient';
@@ -156,7 +157,8 @@ export declare abstract class LucidCardIntegration {
156
157
  */
157
158
  importFromSerializedFields?: (data: SerializedFields[]) => Promise<ImportCardFromDetails>;
158
159
  /**
159
- * @experimental When defined, allows the extension to make cards that the user can't edit view-only.
160
+ * @experimental If specified, allows the extension to check whether the user can edit the given items.
161
+ * Returns a Map with per-item permission results, keyed by item primary key.
160
162
  */
161
- canEditItems?: (editedKey: string, dependencyKey: string | undefined) => Promise<UserItemEditPermissions>;
163
+ canEditItems?: (items: DataItemProxy[]) => Promise<Map<string, UserItemEditPermissions>>;
162
164
  }
@@ -465,10 +465,12 @@ class LucidCardIntegrationRegistry {
465
465
  }
466
466
  if (cardIntegration.canEditItems) {
467
467
  const canEditItemsActionName = LucidCardIntegrationRegistry.nextHookName();
468
+ const canEditItems = cardIntegration.canEditItems;
468
469
  serialized['cei'] = canEditItemsActionName;
469
- client.registerAction(canEditItemsActionName, async ({ 'ek': editedKey, 'dk': dependencyKey }) => {
470
- const result = await cardIntegration.canEditItems(editedKey, dependencyKey);
471
- return (0, useritemeditpermissions_1.serializeUserItemEditPermissions)(result);
470
+ client.registerAction(canEditItemsActionName, async ({ i }) => {
471
+ const dataItemProxies = i.map((item) => new dataitemproxy_1.DataItemProxy(item['pk'], new collectionproxy_1.CollectionProxy(item['cid'], client), client));
472
+ const result = await canEditItems(dataItemProxies);
473
+ return (0, useritemeditpermissions_1.serializeUserItemEditPermissionsMap)(result);
472
474
  });
473
475
  }
474
476
  client.sendCommand("aci" /* CommandName.AddCardIntegration */, serialized);
@@ -17,10 +17,13 @@ export declare class UserCannotEditItem implements UserItemEditPermissions {
17
17
  readonly hasPermission = false;
18
18
  constraints: never[];
19
19
  }
20
- export declare function serializeUserItemEditPermissions(result: UserItemEditPermissions): {
21
- hp: boolean;
22
- c: {
23
- fn: string;
24
- cs: SerializedFieldConstraint[] | undefined;
20
+ export interface SerializedUserItemEditPermissions {
21
+ 'hp': boolean;
22
+ 'c': {
23
+ 'fn': string;
24
+ 'cs': SerializedFieldConstraint[] | undefined;
25
25
  }[];
26
- };
26
+ }
27
+ export declare function serializeUserItemEditPermissionsMap(map: Map<string, UserItemEditPermissions>): Record<string, SerializedUserItemEditPermissions>;
28
+ export declare function deserializeUserItemEditPermissionsRecord(serializedMap: Record<string, SerializedUserItemEditPermissions>): Map<string, UserItemEditPermissions>;
29
+ export declare function isValidSerializedUserItemEditPermissionsRecord(value: unknown): value is Record<string, SerializedUserItemEditPermissions>;
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.serializeUserItemEditPermissions = exports.UserCannotEditItem = exports.UserCanEditItem = void 0;
3
+ exports.isValidSerializedUserItemEditPermissionsRecord = exports.deserializeUserItemEditPermissionsRecord = exports.serializeUserItemEditPermissionsMap = exports.UserCannotEditItem = exports.UserCanEditItem = void 0;
4
+ const checks_1 = require("../checks");
5
+ const serializedfielddefinition_1 = require("../data/serializedfield/serializedfielddefinition");
6
+ const validators_1 = require("../validators/validators");
4
7
  class UserCanEditItem {
5
8
  constructor() {
6
9
  this.hasPermission = true;
@@ -15,6 +18,13 @@ class UserCannotEditItem {
15
18
  }
16
19
  }
17
20
  exports.UserCannotEditItem = UserCannotEditItem;
21
+ const isSerializedUserItemEditPermissions = (0, validators_1.objectValidator)({
22
+ 'hp': checks_1.isBoolean,
23
+ 'c': (0, validators_1.arrayValidator)((0, validators_1.objectValidator)({
24
+ 'fn': checks_1.isString,
25
+ 'cs': (0, validators_1.option)((0, validators_1.arrayValidator)(serializedfielddefinition_1.isSerializedFieldConstraint)),
26
+ })),
27
+ });
18
28
  function serializeUserItemEditPermissions(result) {
19
29
  return {
20
30
  'hp': result.hasPermission,
@@ -24,4 +34,32 @@ function serializeUserItemEditPermissions(result) {
24
34
  })),
25
35
  };
26
36
  }
27
- exports.serializeUserItemEditPermissions = serializeUserItemEditPermissions;
37
+ function deserializeUserItemEditPermissions(serialized) {
38
+ return {
39
+ hasPermission: serialized['hp'],
40
+ constraints: serialized['c'].map((c) => ({
41
+ fieldName: c['fn'],
42
+ constraints: c['cs'],
43
+ })),
44
+ };
45
+ }
46
+ function serializeUserItemEditPermissionsMap(map) {
47
+ const serializedMap = {};
48
+ for (const [primaryKey, permissions] of map) {
49
+ serializedMap[primaryKey] = serializeUserItemEditPermissions(permissions);
50
+ }
51
+ return serializedMap;
52
+ }
53
+ exports.serializeUserItemEditPermissionsMap = serializeUserItemEditPermissionsMap;
54
+ function deserializeUserItemEditPermissionsRecord(serializedMap) {
55
+ const map = new Map();
56
+ for (const [primaryKey, serializedPermissions] of Object.entries(serializedMap)) {
57
+ map.set(primaryKey, deserializeUserItemEditPermissions(serializedPermissions));
58
+ }
59
+ return map;
60
+ }
61
+ exports.deserializeUserItemEditPermissionsRecord = deserializeUserItemEditPermissionsRecord;
62
+ function isValidSerializedUserItemEditPermissionsRecord(value) {
63
+ return (0, checks_1.isRecord)(isSerializedUserItemEditPermissions)(value);
64
+ }
65
+ exports.isValidSerializedUserItemEditPermissionsRecord = isValidSerializedUserItemEditPermissionsRecord;
@@ -2,7 +2,7 @@ import { ConditionCombination } from './conditions';
2
2
  import { SerializedDataGraphic } from './serializeddatagraphic';
3
3
  import { SerializedStencilGraphic } from './serializedstencilgraphic';
4
4
  export type FormattingInterface = {
5
- [index: string]: string;
5
+ [index: string]: string | undefined;
6
6
  };
7
7
  export type SerializedFormatting = {
8
8
  'Block'?: FormattingInterface;
@@ -4,6 +4,7 @@ import { DataItemProxy } from '../../data/dataitemproxy';
4
4
  import { DataSourceProxy } from '../../data/datasourceproxy';
5
5
  import { FieldDefinition } from '../../data/schemadefinition';
6
6
  import { FieldDescriptor } from '../cardintegration/lucidcardintegration';
7
+ import { UserItemEditPermissions } from '../cardintegration/useritemeditpermissions';
7
8
  import { isArray, isString } from '../checks';
8
9
  import { isSerializedFieldTypeDefinition } from '../data/fieldtypedefinition/fieldtypedefinition';
9
10
  import { SerializedFieldDefinition } from '../data/serializedfield/serializedfielddefinition';
@@ -334,3 +335,10 @@ export declare const isSerializedTagCallbackResult: (subject: unknown) => subjec
334
335
  }>;
335
336
  /** @ignore */
336
337
  export declare function serializeTagCallbackResult(tag: TagCallbackResult): SerializedTagCallbackResult;
338
+ /**
339
+ * The type for a callback function that returns whether the user can edit the given items.
340
+ *
341
+ * @param items - The items to check edit permissions for.
342
+ * @returns A promise that maps items' primary key to their edit permissions.
343
+ */
344
+ export type AsyncCanEditItemCallback = (items: DataItemProxy[]) => Promise<Map<string, UserItemEditPermissions>>;
@@ -257,6 +257,10 @@ export declare const isSize: (subject: unknown) => subject is DestructureGuarded
257
257
  w: typeof isNumber;
258
258
  h: typeof isNumber;
259
259
  }>;
260
+ export declare const isPartialSize: (subject: unknown) => subject is Partial<DestructureGuardedTypeObj<{
261
+ w: typeof isNumber;
262
+ h: typeof isNumber;
263
+ }>>;
260
264
  export declare function isPositiveNumber(x: unknown): x is number;
261
265
  export declare function isDate(x: unknown): x is Date;
262
266
  export declare function maxLengthValidator(max: number): (x: unknown) => x is string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.asAssertion = exports.validatorWithMessage = exports.isEmptyObject = exports.minLengthValidator = exports.maxLengthValidator = exports.isDate = exports.isPositiveNumber = exports.isSize = exports.isPanelSize = exports.isBoundingBox = exports.isPointLike = exports.isOpacity = exports.isFalse = exports.isTrue = exports.isFlag = exports.isRestrictions = exports.isStringOrNegativeOne = exports.isBooleanOrEmptyString = exports.isNumberOrEmptyString = exports.isSet = exports.propertyValidator = exports.exclude = exports.bothWithInvalidFieldTracking = exports.both = exports.either = exports.isNullOption = exports.nullableOption = exports.option = exports.nullableValidatorWithInvalidElementTracking = exports.nullable = exports.objectOfValidatorWithInvalidFieldTracking = exports.objectOfValidator = exports.typedRecordValidator = exports.recordValidator = exports.strictObjectValidator = exports.partialObjectValidator = exports.objectValidatorWithInvalidFieldTracking = exports.objectValidator = exports.mapValidator = exports.someValidator = exports.someValue = exports.tupleValidator = exports.arrayValidatorWithInvalidElementTracking = exports.arrayValidator = exports.rangeValidator = exports.enumValidator = exports.stringEnumValidator = void 0;
3
+ exports.asAssertion = exports.validatorWithMessage = exports.isEmptyObject = exports.minLengthValidator = exports.maxLengthValidator = exports.isDate = exports.isPositiveNumber = exports.isPartialSize = exports.isSize = exports.isPanelSize = exports.isBoundingBox = exports.isPointLike = exports.isOpacity = exports.isFalse = exports.isTrue = exports.isFlag = exports.isRestrictions = exports.isStringOrNegativeOne = exports.isBooleanOrEmptyString = exports.isNumberOrEmptyString = exports.isSet = exports.propertyValidator = exports.exclude = exports.bothWithInvalidFieldTracking = exports.both = exports.either = exports.isNullOption = exports.nullableOption = exports.option = exports.nullableValidatorWithInvalidElementTracking = exports.nullable = exports.objectOfValidatorWithInvalidFieldTracking = exports.objectOfValidator = exports.typedRecordValidator = exports.recordValidator = exports.strictObjectValidator = exports.partialObjectValidator = exports.objectValidatorWithInvalidFieldTracking = exports.objectValidator = exports.mapValidator = exports.someValidator = exports.someValue = exports.tupleValidator = exports.arrayValidatorWithInvalidElementTracking = exports.arrayValidator = exports.rangeValidator = exports.enumValidator = exports.stringEnumValidator = void 0;
4
4
  const checks_1 = require("../checks");
5
5
  /*********************************************************************************
6
6
  * Validator generators: These functions construct new composite validators
@@ -493,6 +493,10 @@ exports.isSize = objectValidator({
493
493
  w: checks_1.isNumber,
494
494
  h: checks_1.isNumber,
495
495
  });
496
+ exports.isPartialSize = partialObjectValidator({
497
+ w: checks_1.isNumber,
498
+ h: checks_1.isNumber,
499
+ });
496
500
  function isPositiveNumber(x) {
497
501
  return (0, checks_1.isNumber)(x) && x >= 0;
498
502
  }
@@ -22,6 +22,6 @@ export declare function getRandomItemPatch(settings: RandomPatchSettings, previo
22
22
  * @param data The Sheet-type to stringify
23
23
  * @returns A custom stringified object
24
24
  */
25
- export declare function orderedStringify(data: unknown): string;
25
+ export declare function orderedStringify(data: unknown): string | undefined;
26
26
  export declare function patchesEqual(patchA: Patch, patchB: Patch): boolean;
27
27
  export {};
@@ -41,8 +41,8 @@ export declare class DataConnectorRequestState {
41
41
  }
42
42
  /** Thrown by any APIs the client didn't recognize when parsing */
43
43
  export declare class DataConnectorResponseError extends Error {
44
- response: string;
45
- constructor(message: string, response: string);
44
+ response: string | undefined;
45
+ constructor(message: string, response: string | undefined);
46
46
  }
47
47
  /** Used to track user collection access when EditorExtensionScope is PERSISTENT_SYNC. */
48
48
  export interface AffectedDocumentCollectionsBody {
@@ -0,0 +1,31 @@
1
+ import { Box } from '../math';
2
+ /**
3
+ * The information required to create a new graph on the current document
4
+ */
5
+ export interface GraphDefinition {
6
+ /**
7
+ * The type of graph to create, e.g. "LineGraphBlock", "BarGraphBlock".
8
+ */
9
+ graphType: GraphType;
10
+ /**
11
+ * The ID of the collection to use for the graph data.
12
+ */
13
+ collectionId: string;
14
+ /**
15
+ * The title of the graph.
16
+ */
17
+ title: string;
18
+ /**
19
+ * The initial location and size of the graph on the page.
20
+ */
21
+ boundingBox?: Box;
22
+ /**
23
+ * By default, we add the graph to the current page. If specified, the
24
+ * graph will instead be created as a direct child of the given page.
25
+ */
26
+ pageId?: string | undefined;
27
+ }
28
+ export declare enum GraphType {
29
+ LineGraph = "LineGraphCollectionBlock",
30
+ BarGraph = "BarGraphCollectionBlock"
31
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GraphType = void 0;
4
+ var GraphType;
5
+ (function (GraphType) {
6
+ GraphType["LineGraph"] = "LineGraphCollectionBlock";
7
+ GraphType["BarGraph"] = "BarGraphCollectionBlock";
8
+ })(GraphType || (exports.GraphType = GraphType = {}));
@@ -5,6 +5,7 @@ import { BlockDefinition } from './blockdefinition';
5
5
  import { BlockProxy } from './blockproxy';
6
6
  import { RuleProxy } from './documentelement/ruleproxy';
7
7
  import { ElementProxy } from './elementproxy';
8
+ import { GraphDefinition } from './graphdefinition';
8
9
  import { GroupProxy } from './groupproxy';
9
10
  import { ImageDefinition } from './imagedefinition';
10
11
  import { ItemProxy } from './itemproxy';
@@ -75,6 +76,17 @@ export declare class PageProxy extends ElementProxy {
75
76
  * All blocks, lines, and groups on the page, including ones inside groups
76
77
  */
77
78
  readonly allItems: MapProxy<string, BlockProxy | LineProxy | GroupProxy>;
79
+ /**
80
+ * Add a new graph to this page.
81
+ *
82
+ * This method uses the CreateGraph command which provides enhanced graph creation
83
+ * capabilities with data collection integration. For custom graph implementations,
84
+ * you may also send a postMessage to the parent window for custom handling.
85
+ * @experimental
86
+ * @param graphDefinition The definition of the new graph to add
87
+ * @returns A promise that resolves to the added graph block
88
+ */
89
+ addGraph(graphDefinition: GraphDefinition): Promise<BlockProxy>;
78
90
  /**
79
91
  * Add a new block to this page.
80
92
  *
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PageProxy = void 0;
4
4
  const commandtypes_1 = require("../commandtypes");
5
+ const checks_1 = require("../core/checks");
5
6
  const ruleproxy_1 = require("./documentelement/ruleproxy");
6
7
  const elementproxy_1 = require("./elementproxy");
7
8
  const groupproxy_1 = require("./groupproxy");
@@ -97,6 +98,29 @@ class PageProxy extends elementproxy_1.ElementProxy {
97
98
  y: result['y'],
98
99
  };
99
100
  }
101
+ /**
102
+ * Add a new graph to this page.
103
+ *
104
+ * This method uses the CreateGraph command which provides enhanced graph creation
105
+ * capabilities with data collection integration. For custom graph implementations,
106
+ * you may also send a postMessage to the parent window for custom handling.
107
+ * @experimental
108
+ * @param graphDefinition The definition of the new graph to add
109
+ * @returns A promise that resolves to the added graph block
110
+ */
111
+ async addGraph(graphDefinition) {
112
+ const id = await this.client.sendCommand("cgr" /* CommandName.CreateGraph */, {
113
+ 'p': graphDefinition.pageId || this.id,
114
+ 't': graphDefinition.graphType,
115
+ 'col': graphDefinition.collectionId,
116
+ 'ti': graphDefinition.title,
117
+ });
118
+ const block = this.client.getBlockProxy(id);
119
+ if ((0, checks_1.isDefAndNotNull)(graphDefinition.boundingBox)) {
120
+ block.setBoundingBox(graphDefinition.boundingBox);
121
+ }
122
+ return block;
123
+ }
100
124
  /**
101
125
  * Add a new block to this page.
102
126
  *
package/editorclient.d.ts CHANGED
@@ -4,6 +4,7 @@ import { JsonObject, UnsafeJsonSerializableOrUndefined } from './core/jsonserial
4
4
  import { UnfurlCallbacks } from './core/unfurl/unfurlcallbacks';
5
5
  import { BinaryXHRResponse, OAuthXHRRequest, TextXHRResponse, XHRRequest, XHRResponse } from './core/xhr';
6
6
  import { CollectionProxy } from './data/collectionproxy';
7
+ import { CollectionId } from './dataconnector/actions/action';
7
8
  import { BlockDefinition } from './document/blockdefinition';
8
9
  import { BlockProxy } from './document/blockproxy';
9
10
  import { ElementProxy } from './document/elementproxy';
@@ -28,6 +29,7 @@ export type DataActionOptions = {
28
29
  actionData?: unknown;
29
30
  syncDataSourceIdNonce?: string;
30
31
  asynchronous?: boolean;
32
+ requestedPrimaryKeys?: Record<CollectionId, string[]>;
31
33
  };
32
34
  export declare class EditorClient {
33
35
  private nextId;
package/editorclient.js CHANGED
@@ -105,6 +105,7 @@ class EditorClient {
105
105
  return this.createUserImage(mediaType, data);
106
106
  }
107
107
  async performDataAction(options) {
108
+ var _a;
108
109
  if (options.asynchronous === undefined) {
109
110
  options.asynchronous = true;
110
111
  }
@@ -114,6 +115,7 @@ class EditorClient {
114
115
  's': options.syncDataSourceIdNonce,
115
116
  'fd': options.actionData,
116
117
  'n': options.dataConnectorName,
118
+ 'rpk': (_a = options.requestedPrimaryKeys) !== null && _a !== void 0 ? _a : undefined,
117
119
  });
118
120
  if ('t' in result) {
119
121
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lucid-extension-sdk",
3
- "version": "0.0.440",
3
+ "version": "0.0.441",
4
4
  "description": "Utility classes for writing Lucid Software editor extensions",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",