lucid-extension-sdk 0.0.156 → 0.0.158
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 +10 -0
- package/commandtypes.js +1 -0
- package/core/data/datasource/datasourceutils.d.ts +10 -1
- package/core/data/datasource/datasourceutils.js +124 -40
- package/core/data/datasource/metadatatypes.d.ts +2 -1
- package/core/data/datasource/metadatatypes.js +1 -0
- package/editorclient.d.ts +7 -0
- package/editorclient.js +22 -1
- package/package.json +1 -1
package/commandtypes.d.ts
CHANGED
|
@@ -120,6 +120,7 @@ export declare const enum CommandName {
|
|
|
120
120
|
UnhookSelection = "us",
|
|
121
121
|
UnhookTextEdit = "ute",
|
|
122
122
|
WithMutex = "wm",
|
|
123
|
+
WithSilentActions = "wsa",
|
|
123
124
|
ZOrder = "z"
|
|
124
125
|
}
|
|
125
126
|
/** @ignore */
|
|
@@ -530,6 +531,10 @@ export declare type CommandArgs = {
|
|
|
530
531
|
query: WithMutexQuery;
|
|
531
532
|
result: WithMutexResult;
|
|
532
533
|
};
|
|
534
|
+
[CommandName.WithSilentActions]: {
|
|
535
|
+
query: WithSilentActionsQuery;
|
|
536
|
+
result: WithSilentActionsResult;
|
|
537
|
+
};
|
|
533
538
|
[CommandName.ZOrder]: {
|
|
534
539
|
query: ZOrderQuery;
|
|
535
540
|
result: ZOrderResult;
|
|
@@ -1294,6 +1299,11 @@ export declare type WithMutexQuery = {
|
|
|
1294
1299
|
};
|
|
1295
1300
|
/** Resolves true if operation succeeded, or false if the mutex was held by someone else */
|
|
1296
1301
|
export declare type WithMutexResult = Promise<boolean>;
|
|
1302
|
+
export declare type WithSilentActionsQuery = {
|
|
1303
|
+
/** Name of the synchronous action to run with undo/redo history suppressed */
|
|
1304
|
+
'a': string;
|
|
1305
|
+
};
|
|
1306
|
+
export declare type WithSilentActionsResult = void;
|
|
1297
1307
|
export declare enum ZOrderOperation {
|
|
1298
1308
|
UP = 1,
|
|
1299
1309
|
TOP = 2,
|
package/commandtypes.js
CHANGED
|
@@ -100,6 +100,7 @@ exports.commandTitles = new Map([
|
|
|
100
100
|
["us" /* CommandName.UnhookSelection */, 'UnhookSelection'],
|
|
101
101
|
["ute" /* CommandName.UnhookTextEdit */, 'UnhookTextEdit'],
|
|
102
102
|
["wm" /* CommandName.WithMutex */, 'WithMutex'],
|
|
103
|
+
["wsa" /* CommandName.WithSilentActions */, 'WithSilentActions'],
|
|
103
104
|
["z" /* CommandName.ZOrder */, 'ZOrder'],
|
|
104
105
|
]);
|
|
105
106
|
var GetItemsAtSearchType;
|
|
@@ -5,10 +5,19 @@ import { UpstreamUpdateType } from './upstreamupdatetype';
|
|
|
5
5
|
/** @ignore */
|
|
6
6
|
export declare function alphabetize(n: number): string;
|
|
7
7
|
/** @ignore */
|
|
8
|
+
export declare function normalizeName(name: string): string;
|
|
9
|
+
/** @ignore */
|
|
10
|
+
export declare function makeNameReadablyUnique(originalName: string, usedNamesNormalized: Set<string>, transform?: typeof normalizeName): string;
|
|
11
|
+
/** @ignore */
|
|
8
12
|
export declare const MetadataPK = "__PK__";
|
|
9
13
|
/** @ignore until spreadsheet integration is ready for launch (CHART-51946) */
|
|
10
|
-
export declare function makeSerializedImportedCollection(
|
|
14
|
+
export declare function makeSerializedImportedCollection(name: string, rawFieldNames: string[], data: SerializedFields[], upstreamConfig: {
|
|
15
|
+
[key: string]: any;
|
|
16
|
+
}, metadata?: {
|
|
11
17
|
[key: string]: SerializedFields[];
|
|
18
|
+
}, schemaFromData?: {
|
|
19
|
+
headerRow: number;
|
|
20
|
+
primaryKey: string[];
|
|
12
21
|
}): SerializedImportedCollection;
|
|
13
22
|
/** @ignore until spreadsheet integration is ready for launch (CHART-51946) */
|
|
14
23
|
export declare function makeSerializedImportedDataSource(id: string, name: string, collections: SerializedImportedCollection[]): {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.makeSerializedImportedDataSource = exports.makeSerializedImportedCollection = exports.MetadataPK = exports.alphabetize = void 0;
|
|
3
|
+
exports.makeSerializedImportedDataSource = exports.makeSerializedImportedCollection = exports.MetadataPK = exports.makeNameReadablyUnique = exports.normalizeName = exports.alphabetize = void 0;
|
|
4
|
+
const checks_1 = require("../../checks");
|
|
4
5
|
const scalarfieldtype_1 = require("../fieldtypedefinition/scalarfieldtype");
|
|
5
6
|
const alphabet_1 = require("./alphabet");
|
|
6
7
|
const datasourcetype_1 = require("./datasourcetype");
|
|
@@ -34,23 +35,84 @@ exports.alphabetize = alphabetize;
|
|
|
34
35
|
function normalizeName(name) {
|
|
35
36
|
return name.trim().toLowerCase();
|
|
36
37
|
}
|
|
38
|
+
exports.normalizeName = normalizeName;
|
|
39
|
+
const appendedNumberRegex = /(.*) \(([0-9]+)\)$/;
|
|
40
|
+
/** @ignore */
|
|
41
|
+
function makeNameReadablyUnique(originalName, usedNamesNormalized, transform = normalizeName) {
|
|
42
|
+
if (!usedNamesNormalized.has(transform(originalName))) {
|
|
43
|
+
return originalName;
|
|
44
|
+
}
|
|
45
|
+
const match = appendedNumberRegex.exec(originalName);
|
|
46
|
+
let count = 1;
|
|
47
|
+
if (match && (0, checks_1.isString)(match[1]) && (0, checks_1.isString)(match[2])) {
|
|
48
|
+
originalName = match[1];
|
|
49
|
+
count = Number(match[2]) + 1;
|
|
50
|
+
}
|
|
51
|
+
let newName = originalName;
|
|
52
|
+
do {
|
|
53
|
+
newName = originalName + ` (${count})`;
|
|
54
|
+
count++;
|
|
55
|
+
} while (usedNamesNormalized.has(transform(newName)));
|
|
56
|
+
return newName;
|
|
57
|
+
}
|
|
58
|
+
exports.makeNameReadablyUnique = makeNameReadablyUnique;
|
|
37
59
|
/** @ignore */
|
|
38
60
|
exports.MetadataPK = '__PK__';
|
|
39
61
|
/** @ignore */
|
|
40
|
-
function
|
|
62
|
+
function makePrimaryCollectionSchema(rawSchemaFields, data, schemaFromData) {
|
|
63
|
+
var _a, _b;
|
|
64
|
+
const headerRow = (_a = schemaFromData === null || schemaFromData === void 0 ? void 0 : schemaFromData.headerRow) !== null && _a !== void 0 ? _a : -1;
|
|
65
|
+
const headerRowData = headerRow >= 0 ? data[headerRow] : undefined;
|
|
66
|
+
const headerRowAsStringArray = headerRowData &&
|
|
67
|
+
rawSchemaFields.map((rawSchemaField, index) => {
|
|
68
|
+
var _a;
|
|
69
|
+
const headerRowDataAsString = `${(_a = headerRowData[rawSchemaField]) !== null && _a !== void 0 ? _a : ''}`;
|
|
70
|
+
return headerRowDataAsString.trim() === '' ? alphabetize(index) : headerRowDataAsString;
|
|
71
|
+
});
|
|
72
|
+
const schemaFields = headerRowAsStringArray !== null && headerRowAsStringArray !== void 0 ? headerRowAsStringArray : rawSchemaFields;
|
|
41
73
|
const fields = [];
|
|
42
74
|
const oldToNewFields = new Map();
|
|
43
75
|
const usedFieldsNormalized = new Set([normalizeName(exports.MetadataPK)]);
|
|
44
76
|
schemaFields.forEach((field, index) => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
77
|
+
const finalFieldName = makeNameReadablyUnique(field, usedFieldsNormalized);
|
|
78
|
+
usedFieldsNormalized.add(normalizeName(finalFieldName));
|
|
79
|
+
fields.push({ 'Name': finalFieldName, 'Type': scalarfieldtype_1.ScalarFieldTypeEnum.ANY });
|
|
80
|
+
oldToNewFields.set(rawSchemaFields[index], finalFieldName);
|
|
81
|
+
});
|
|
82
|
+
const oldPrimaryKeys = (_b = schemaFromData === null || schemaFromData === void 0 ? void 0 : schemaFromData.primaryKey) !== null && _b !== void 0 ? _b : [];
|
|
83
|
+
const translatedPrimaryKeys = oldPrimaryKeys
|
|
84
|
+
.map((oldPrimaryKey) => oldToNewFields.get(oldPrimaryKey))
|
|
85
|
+
.filter(checks_1.isDefAndNotNull); // There should be no untranslatable primary keys, but we need to satisfy the type system
|
|
86
|
+
return {
|
|
87
|
+
sheetSchema: {
|
|
88
|
+
'Fields': fields,
|
|
89
|
+
'PrimaryKey': translatedPrimaryKeys,
|
|
90
|
+
},
|
|
91
|
+
oldToNewFields,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function getPrimaryKeysForData(oldToNewFields, data, schemaFromData) {
|
|
95
|
+
if (!schemaFromData || schemaFromData.primaryKey.length === 0) {
|
|
96
|
+
return data.map((row, index) => `${index + 1}`);
|
|
97
|
+
}
|
|
98
|
+
const primaryKey = schemaFromData.primaryKey;
|
|
99
|
+
const primaryKeyInNewFields = primaryKey.map((oldField) => { var _a; return (_a = oldToNewFields.get(oldField)) !== null && _a !== void 0 ? _a : oldField; });
|
|
100
|
+
// For reasons I have forgotten, the actual primary key order is determined by the alphabetized name order.
|
|
101
|
+
const sortedPrimaryKeyInNewFields = primaryKeyInNewFields.slice().sort();
|
|
102
|
+
const sortedPrimaryKey = sortedPrimaryKeyInNewFields.map((newField) => primaryKey[primaryKeyInNewFields.indexOf(newField)]);
|
|
103
|
+
const usedNames = new Set();
|
|
104
|
+
return data.map((serializedField) => {
|
|
105
|
+
const primaryKeyValues = sortedPrimaryKey.map((key) => serializedField[key]);
|
|
106
|
+
const compositeValue = JSON.stringify(primaryKeyValues);
|
|
107
|
+
const nameWithoutContext = compositeValue.slice(1, compositeValue.length - 1);
|
|
108
|
+
let name = nameWithoutContext;
|
|
109
|
+
let dupCount = -1;
|
|
110
|
+
while (usedNames.has(name)) {
|
|
111
|
+
name = `${nameWithoutContext},${++dupCount}`;
|
|
51
112
|
}
|
|
113
|
+
usedNames.add(name);
|
|
114
|
+
return name;
|
|
52
115
|
});
|
|
53
|
-
return { sheetSchema: { 'Fields': fields, 'PrimaryKey': [] }, oldToNewFields };
|
|
54
116
|
}
|
|
55
117
|
/** @ignore */
|
|
56
118
|
function makeMetadataCollection(metadataType, sheetName, dataItems, sheetSchema) {
|
|
@@ -61,11 +123,15 @@ function makeMetadataCollection(metadataType, sheetName, dataItems, sheetSchema)
|
|
|
61
123
|
};
|
|
62
124
|
}
|
|
63
125
|
/** @ignore */
|
|
64
|
-
function makeItemOrderCollection(
|
|
126
|
+
function makeItemOrderCollection(primaryKeys, sheetName, headerRow) {
|
|
65
127
|
const itemOrderItems = {};
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
128
|
+
let rowIndex = 0;
|
|
129
|
+
for (let i = 0; i < primaryKeys.length; i++) {
|
|
130
|
+
const primaryKey = primaryKeys[i];
|
|
131
|
+
if (i !== headerRow) {
|
|
132
|
+
rowIndex++;
|
|
133
|
+
itemOrderItems[`${rowIndex}`] = { 'Key': `${primaryKey}`, 'Order': rowIndex };
|
|
134
|
+
}
|
|
69
135
|
}
|
|
70
136
|
const itemOrderSchema = {
|
|
71
137
|
'Fields': [
|
|
@@ -77,52 +143,70 @@ function makeItemOrderCollection(sheetLength, sheetName) {
|
|
|
77
143
|
return makeMetadataCollection('ItemOrder', sheetName, itemOrderItems, itemOrderSchema);
|
|
78
144
|
}
|
|
79
145
|
/** @ignore */
|
|
80
|
-
function
|
|
146
|
+
function makeHeaderrowMetadataCollection(headerRowPrimaryKey, headerRowData, oldToNewFields, sheetName, schema) {
|
|
147
|
+
const dataItem = {};
|
|
148
|
+
for (const [key, field] of Object.entries(headerRowData)) {
|
|
149
|
+
const newKey = oldToNewFields.get(key);
|
|
150
|
+
if (newKey) {
|
|
151
|
+
dataItem[newKey] = field;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const itemOrderItems = {
|
|
155
|
+
[headerRowPrimaryKey]: dataItem,
|
|
156
|
+
};
|
|
157
|
+
return makeMetadataCollection('HeaderRowMetadata', sheetName, itemOrderItems, schema);
|
|
158
|
+
}
|
|
159
|
+
/** @ignore */
|
|
160
|
+
function makeSerializedItems(primaryKeys, rawItems, oldToNewFields, headerRow, isMetadata = false) {
|
|
81
161
|
const serializedItems = {};
|
|
82
162
|
rawItems.forEach((rawItem, rowIndex) => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
163
|
+
if (isMetadata || rowIndex !== headerRow) {
|
|
164
|
+
const dataItem = {};
|
|
165
|
+
for (const [key, field] of Object.entries(rawItem)) {
|
|
166
|
+
const newKey = oldToNewFields.get(key);
|
|
167
|
+
if (newKey) {
|
|
168
|
+
dataItem[newKey] = field;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const primaryKey = primaryKeys[rowIndex];
|
|
172
|
+
if (isMetadata && Object.keys(dataItem).length > 0) {
|
|
173
|
+
const metadataPrimaryKey = `${primaryKey}`;
|
|
174
|
+
dataItem[exports.MetadataPK] = metadataPrimaryKey;
|
|
175
|
+
serializedItems[`${JSON.stringify(metadataPrimaryKey)}`] = dataItem;
|
|
176
|
+
}
|
|
177
|
+
else if (!isMetadata) {
|
|
178
|
+
serializedItems[primaryKey] = dataItem;
|
|
88
179
|
}
|
|
89
|
-
}
|
|
90
|
-
const primaryKey = rowIndex + 1;
|
|
91
|
-
if (isMetadata && Object.keys(dataItem).length > 0) {
|
|
92
|
-
dataItem[exports.MetadataPK] = `${primaryKey}`;
|
|
93
|
-
serializedItems[`"${primaryKey}"`] = dataItem;
|
|
94
|
-
}
|
|
95
|
-
else if (!isMetadata) {
|
|
96
|
-
serializedItems[primaryKey] = dataItem;
|
|
97
180
|
}
|
|
98
181
|
});
|
|
99
182
|
return serializedItems;
|
|
100
183
|
}
|
|
101
184
|
/** @ignore until spreadsheet integration is ready for launch (CHART-51946) */
|
|
102
|
-
function makeSerializedImportedCollection(
|
|
103
|
-
|
|
185
|
+
function makeSerializedImportedCollection(name, rawFieldNames, data, upstreamConfig, metadata, schemaFromData) {
|
|
186
|
+
var _a;
|
|
187
|
+
const { sheetSchema, oldToNewFields } = makePrimaryCollectionSchema(rawFieldNames, data, schemaFromData);
|
|
188
|
+
const primaryKeys = getPrimaryKeysForData(oldToNewFields, data, schemaFromData);
|
|
189
|
+
const headerRow = (_a = schemaFromData === null || schemaFromData === void 0 ? void 0 : schemaFromData.headerRow) !== null && _a !== void 0 ? _a : -1;
|
|
104
190
|
const metadataCollections = {};
|
|
105
|
-
|
|
106
|
-
|
|
191
|
+
metadataCollections['ItemOrder'] = makeItemOrderCollection(primaryKeys, name, headerRow);
|
|
192
|
+
if (headerRow > -1 && headerRow < data.length) {
|
|
193
|
+
const headerRowData = data[headerRow];
|
|
194
|
+
const headerRowPrimaryKey = primaryKeys[headerRow];
|
|
195
|
+
metadataCollections['HeaderRowMetadata'] = makeHeaderrowMetadataCollection(headerRowPrimaryKey, headerRowData, oldToNewFields, name, sheetSchema);
|
|
196
|
+
}
|
|
107
197
|
if (metadata) {
|
|
108
198
|
const metadataFields = [{ 'Name': exports.MetadataPK, 'Type': scalarfieldtype_1.ScalarFieldTypeEnum.STRING }];
|
|
109
199
|
sheetSchema['Fields'].forEach((field) => metadataFields.push({ 'Name': field['Name'], 'Type': scalarfieldtype_1.ScalarFieldTypeEnum.STRING }));
|
|
110
200
|
const metadataSchema = { 'Fields': metadataFields, 'PrimaryKey': [exports.MetadataPK] };
|
|
111
201
|
for (const [type, data] of Object.entries(metadata)) {
|
|
112
|
-
metadataCollections[type] = makeMetadataCollection(type, name, makeSerializedItems(data, oldToNewFields, true), metadataSchema);
|
|
202
|
+
metadataCollections[type] = makeMetadataCollection(type, name, makeSerializedItems(primaryKeys, data, oldToNewFields, headerRow, true), metadataSchema);
|
|
113
203
|
}
|
|
114
204
|
}
|
|
115
205
|
return {
|
|
116
206
|
'Name': name,
|
|
117
207
|
'Schema': sheetSchema,
|
|
118
|
-
'Items': makeSerializedItems(data, oldToNewFields),
|
|
119
|
-
'UpstreamConfig':
|
|
120
|
-
'properties': {
|
|
121
|
-
'UpstreamType': upstreamupdatetype_1.UpstreamUpdateType.EVENTPULL,
|
|
122
|
-
'sheetId': id,
|
|
123
|
-
'hash': hash,
|
|
124
|
-
},
|
|
125
|
-
},
|
|
208
|
+
'Items': makeSerializedItems(primaryKeys, data, oldToNewFields, headerRow),
|
|
209
|
+
'UpstreamConfig': upstreamConfig,
|
|
126
210
|
'Metadata': metadataCollections,
|
|
127
211
|
};
|
|
128
212
|
}
|
|
@@ -11,4 +11,5 @@ var MetadataTypes;
|
|
|
11
11
|
MetadataTypes["TextColor"] = "TextColor";
|
|
12
12
|
MetadataTypes["Comment"] = "Comment";
|
|
13
13
|
MetadataTypes["Formula"] = "Formula";
|
|
14
|
+
MetadataTypes["HeaderRowMetadata"] = "HeaderRowMetadata";
|
|
14
15
|
})(MetadataTypes = exports.MetadataTypes || (exports.MetadataTypes = {}));
|
package/editorclient.d.ts
CHANGED
|
@@ -325,5 +325,12 @@ export declare class EditorClient {
|
|
|
325
325
|
* @returns A promise resolving to a boolean indicating whether the mutex was successfully locked
|
|
326
326
|
*/
|
|
327
327
|
withIntraDocumentMutex(name: string, callback: () => void | Promise<void>): Promise<boolean>;
|
|
328
|
+
/**
|
|
329
|
+
* @param callback Callback that will be executed with the user's local undo/redo history suppressed. This is
|
|
330
|
+
* useful when you want to make changes to a document that will not be erased if the user uses undo or redo,
|
|
331
|
+
* for example adding shape data onto shapes as a result of a background process that collects data from a
|
|
332
|
+
* remote API.
|
|
333
|
+
*/
|
|
334
|
+
withSilentActions(callback: () => void): void;
|
|
328
335
|
constructor();
|
|
329
336
|
}
|
package/editorclient.js
CHANGED
|
@@ -545,7 +545,28 @@ class EditorClient {
|
|
|
545
545
|
return await this.sendCommand("wm" /* CommandName.WithMutex */, { 'n': name, 'a': action });
|
|
546
546
|
}
|
|
547
547
|
finally {
|
|
548
|
-
this.deleteAction(
|
|
548
|
+
this.deleteAction(action);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* @param callback Callback that will be executed with the user's local undo/redo history suppressed. This is
|
|
553
|
+
* useful when you want to make changes to a document that will not be erased if the user uses undo or redo,
|
|
554
|
+
* for example adding shape data onto shapes as a result of a background process that collects data from a
|
|
555
|
+
* remote API.
|
|
556
|
+
*/
|
|
557
|
+
withSilentActions(callback) {
|
|
558
|
+
const action = this.getUniqueActionName();
|
|
559
|
+
this.registerAction(action, () => {
|
|
560
|
+
const result = callback();
|
|
561
|
+
if ((0, checks_1.isPromise)(result)) {
|
|
562
|
+
throw new Error('withSilentActions cannot be used with an async callback');
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
try {
|
|
566
|
+
this.sendCommand("wsa" /* CommandName.WithSilentActions */, { 'a': action });
|
|
567
|
+
}
|
|
568
|
+
finally {
|
|
569
|
+
this.deleteAction(action);
|
|
549
570
|
}
|
|
550
571
|
}
|
|
551
572
|
}
|