lucid-extension-sdk 0.0.157 → 0.0.159

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.
@@ -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(id: string, hash: string, name: string, rawSchema: string[], data: SerializedFields[], metadata?: {
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 makeSchema(schemaFields) {
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
- // don't add duplicates
46
- if (!usedFieldsNormalized.has(normalizeName(field))) {
47
- usedFieldsNormalized.add(normalizeName(field));
48
- // for now we're changing all schema to the alphabet until preview data can be skipped
49
- fields.push({ 'Name': alphabetize(index), 'Type': scalarfieldtype_1.ScalarFieldTypeEnum.ANY });
50
- oldToNewFields.set(field, alphabetize(index));
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(sheetLength, sheetName) {
126
+ function makeItemOrderCollection(primaryKeys, sheetName, headerRow) {
65
127
  const itemOrderItems = {};
66
- for (let i = 1; i <= sheetLength; ++i) {
67
- const rowIndex = i;
68
- itemOrderItems[`${rowIndex}`] = { 'Key': `${rowIndex}`, 'Order': rowIndex };
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 makeSerializedItems(rawItems, oldToNewFields, isMetadata = false) {
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
- const dataItem = {};
84
- for (const [key, field] of Object.entries(rawItem)) {
85
- const newKey = oldToNewFields.get(key);
86
- if (newKey) {
87
- dataItem[newKey] = field;
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(id, hash, name, rawSchema, data, metadata) {
103
- const { sheetSchema, oldToNewFields } = makeSchema(rawSchema);
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
- const itemOrderCollection = makeItemOrderCollection(data.length, name);
106
- metadataCollections['ItemOrder'] = itemOrderCollection;
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
  }
@@ -4,5 +4,6 @@ export declare enum MetadataTypes {
4
4
  FillColor = "FillColor",
5
5
  TextColor = "TextColor",
6
6
  Comment = "Comment",
7
- Formula = "Formula"
7
+ Formula = "Formula",
8
+ HeaderRowMetadata = "HeaderRowMetadata"
8
9
  }
@@ -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 = {}));
@@ -21,14 +21,7 @@ class DataSourceClient {
21
21
  const dataSyncUrl = urls.dataSync;
22
22
  this.metadataUrl = (0, checks_1.isString)(dataSyncUrl) ? `${dataSyncUrl}dataSource/metadata` : undefined;
23
23
  }
24
- formatBody({ updateFilterType, dataSourceName, collections }) {
25
- const upstreamConfig = updateFilterType
26
- ? {
27
- 'upstreamConfig': {
28
- 'UpdateType': updateFilterType,
29
- },
30
- }
31
- : {};
24
+ formatBody({ dataSourceName, collections }) {
32
25
  const updateData = {};
33
26
  for (const collectionId in collections) {
34
27
  updateData[collectionId] = (0, datasourceupdatetypes_1.serializeCollectionPatch)(collections[collectionId]);
@@ -24,7 +24,5 @@ export declare class SignatureValidator {
24
24
  }
25
25
  /** Mock signature validator, always returns true. */
26
26
  export declare class MockSignatureValidator {
27
- private publicKey;
28
- /** Returns true */
29
27
  validate(): boolean;
30
28
  }
@@ -33,10 +33,6 @@ class SignatureValidator {
33
33
  exports.SignatureValidator = SignatureValidator;
34
34
  /** Mock signature validator, always returns true. */
35
35
  class MockSignatureValidator {
36
- constructor() {
37
- this.publicKey = false;
38
- }
39
- /** Returns true */
40
36
  validate() {
41
37
  return true;
42
38
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lucid-extension-sdk",
3
- "version": "0.0.157",
3
+ "version": "0.0.159",
4
4
  "description": "Utility classes for writing Lucid Software editor extensions",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",