@looker/wholly-artifact 0.1.1

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.
@@ -0,0 +1,320 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.compareDates = exports.WhollyArtifact = exports.TypedRows = void 0;
7
+ var _sdkRtl = require("@looker/sdk-rtl");
8
+ var _sdk = require("@looker/sdk");
9
+ var _RowModel = require("./RowModel");
10
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
11
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
12
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
13
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
14
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
15
+ var compareDates = (a, b) => a.getTime() - b.getTime();
16
+ exports.compareDates = compareDates;
17
+ class TypedRows {
18
+ constructor(rows, Maker) {
19
+ _defineProperty(this, "rows", []);
20
+ if (Maker) {
21
+ this.rows = rows.map(v => new Maker(v));
22
+ } else {
23
+ this.rows = rows;
24
+ }
25
+ }
26
+ add(value) {
27
+ this.rows.push(value);
28
+ }
29
+ where(predicate) {
30
+ return TypedRows.from(this.rows.filter(predicate));
31
+ }
32
+ select(selector) {
33
+ return TypedRows.from(this.rows.map(selector));
34
+ }
35
+ toArray() {
36
+ return this.rows;
37
+ }
38
+ static from(values) {
39
+ return new TypedRows(values);
40
+ }
41
+ static create(values) {
42
+ return new TypedRows(values !== null && values !== void 0 ? values : []);
43
+ }
44
+ }
45
+ exports.TypedRows = TypedRows;
46
+ class WhollyArtifact extends TypedRows {
47
+ constructor(sdk, table) {
48
+ var keyColumn = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '_id';
49
+ super([]);
50
+ this.sdk = sdk;
51
+ this.table = table;
52
+ this.keyColumn = keyColumn;
53
+ _defineProperty(this, "index", {});
54
+ _defineProperty(this, "namespace", '');
55
+ _defineProperty(this, "tableName", '');
56
+ _defineProperty(this, "_displayHeader", []);
57
+ this.loadRows(table.rows);
58
+ var meta = this.typeRow();
59
+ this.namespace = meta.namespace();
60
+ this.tableName = meta.tableName();
61
+ }
62
+ loadRows(rows) {
63
+ this.rows = this.typeRows(rows);
64
+ this.checkHeader();
65
+ this.createIndex();
66
+ return this.rows;
67
+ }
68
+ refresh(values) {
69
+ var _this = this;
70
+ return _asyncToGenerator(function* () {
71
+ if (!values) {
72
+ values = yield _this.sdk.ok((0, _sdk.search_artifacts)(_this.sdk, {
73
+ namespace: _this.namespace,
74
+ key: "".concat(_this.tableName, ":%")
75
+ }));
76
+ }
77
+ _this.rows = _this.typeRows(values);
78
+ _this.createIndex();
79
+ return _this.rows;
80
+ })();
81
+ }
82
+ typeRows(rows) {
83
+ var result = [];
84
+ var pos = 1;
85
+ rows.forEach(r => {
86
+ var row = this.typeRow(r);
87
+ pos++;
88
+ if (!row[_RowModel.rowPosition]) row[_RowModel.rowPosition] = pos;
89
+ result.push(row);
90
+ });
91
+ return result;
92
+ }
93
+ static toAT(value) {
94
+ if (value) return value;
95
+ return undefined;
96
+ }
97
+ checkHeader() {
98
+ if (this.rows.length === 0) return true;
99
+ var row = this.rows[0];
100
+ var rowHeader = row.header().join();
101
+ var tableHeader = this.table.header.join();
102
+ if (tableHeader !== rowHeader) throw new _sdkRtl.LookerSDKError("Expected ".concat(this.tableName, " header to be ").concat(rowHeader, " not ").concat(tableHeader));
103
+ return true;
104
+ }
105
+ get header() {
106
+ return this.table.header;
107
+ }
108
+ get nextRow() {
109
+ return this.rows.length + 2;
110
+ }
111
+ createIndex() {
112
+ this.index = {};
113
+ this.rows.forEach(r => {
114
+ this.index[r[this.keyColumn]] = r;
115
+ });
116
+ }
117
+ values(model) {
118
+ var result = [];
119
+ this.header.forEach(h => {
120
+ result.push((0, _RowModel.stringer)(model[h]));
121
+ });
122
+ return result;
123
+ }
124
+ allValues() {
125
+ var values = [this.header];
126
+ values.push(...this.rows.map(r => this.values(r)));
127
+ return values;
128
+ }
129
+ save(model) {
130
+ var _arguments = arguments,
131
+ _this2 = this;
132
+ return _asyncToGenerator(function* () {
133
+ var force = _arguments.length > 1 && _arguments[1] !== undefined ? _arguments[1] : false;
134
+ switch (model.$action) {
135
+ case _RowModel.RowAction.Delete:
136
+ {
137
+ yield _this2.sdk.ok(_this2.sdk.delete_artifact(_this2.namespace, model[_this2.keyColumn]));
138
+ return model;
139
+ }
140
+ case _RowModel.RowAction.Update:
141
+ {
142
+ return yield _this2.update(model, force);
143
+ }
144
+ case _RowModel.RowAction.None:
145
+ {
146
+ return model;
147
+ }
148
+ }
149
+ return yield _this2.create(model);
150
+ })();
151
+ }
152
+ checkId(model) {
153
+ if (!model[this.keyColumn]) throw new _sdkRtl.LookerSDKError("\"".concat(this.keyColumn, "\" must be assigned for ").concat(this.tableName, " row ").concat(model._row));
154
+ }
155
+ create(model) {
156
+ var _this3 = this;
157
+ return _asyncToGenerator(function* () {
158
+ if (model._row > 0) throw new _sdkRtl.LookerSDKError("create needs ".concat(_this3.tableName, " \"").concat(model[_this3.keyColumn], "\" row to be < 1, not ").concat(model._row));
159
+ model.prepare();
160
+ _this3.checkId(model);
161
+ yield _this3.createUpdateBatch([model]);
162
+ return _this3.index[model[_this3.keyColumn]];
163
+ })();
164
+ }
165
+ update(model) {
166
+ var _arguments2 = arguments,
167
+ _this4 = this;
168
+ return _asyncToGenerator(function* () {
169
+ var _force = _arguments2.length > 1 && _arguments2[1] !== undefined ? _arguments2[1] : false;
170
+ if (!model._row) throw new _sdkRtl.LookerSDKError("".concat(_this4.tableName, " \"").concat(model[_this4.keyColumn], "\" row must be > 0 to update"));
171
+ model.prepare();
172
+ _this4.checkId(model);
173
+ yield _this4.createUpdateBatch([model]);
174
+ return _this4.index[model[_this4.keyColumn]];
175
+ })();
176
+ }
177
+ find(value, columnName) {
178
+ if (!value) return undefined;
179
+ var key = columnName || this.keyColumn;
180
+ if (typeof value === 'number') {
181
+ if (!columnName) key = '_row';
182
+ }
183
+ if (columnName === this.keyColumn) {
184
+ return WhollyArtifact.toAT(this.index[value.toString()]);
185
+ }
186
+ return WhollyArtifact.toAT(this.rows.find(r => r[key] === value));
187
+ }
188
+ get displayHeader() {
189
+ if (this._displayHeader.length === 0) {
190
+ this._displayHeader = this.header.filter(colName => this.displayable(colName));
191
+ }
192
+ return this._displayHeader;
193
+ }
194
+ delete(model) {
195
+ var _arguments3 = arguments,
196
+ _this5 = this;
197
+ return _asyncToGenerator(function* () {
198
+ var force = _arguments3.length > 1 && _arguments3[1] !== undefined ? _arguments3[1] : false;
199
+ if (!force) yield _this5.checkOutdated(model);
200
+ yield _this5.deleteBatch([model]);
201
+ return true;
202
+ })();
203
+ }
204
+ displayable(columnName) {
205
+ return !(columnName.startsWith('_') || columnName.startsWith('$'));
206
+ }
207
+ checkOutdated(model, source) {
208
+ var _this6 = this;
209
+ return _asyncToGenerator(function* () {
210
+ if (model[_RowModel.rowPosition] < 1) return false;
211
+ var errors = [];
212
+ if (!source) {
213
+ var art = yield _this6.sdk.ok((0, _sdk.artifact)(_this6.sdk, {
214
+ namespace: _this6.namespace,
215
+ key: model[_this6.keyColumn]
216
+ }));
217
+ if (art.length === 1) source = _this6.typeRow(art[0]);
218
+ }
219
+ if (!source) {
220
+ errors.push("Row not found");
221
+ } else {
222
+ if (source.$artifact.version !== model.$artifact.version) {
223
+ errors.push("version ".concat(source.$artifact.version, " != ").concat(model.$artifact.version));
224
+ }
225
+ }
226
+ if (errors.length > 0) throw new _sdkRtl.LookerSDKError("".concat(_this6.tableName, " row ").concat(model[_this6.keyColumn], " is outdated: ").concat(errors.join()));
227
+ return false;
228
+ })();
229
+ }
230
+ fromObject(obj) {
231
+ this.loadRows(obj);
232
+ return this.rows;
233
+ }
234
+ toObject() {
235
+ return this.rows.map(r => r.toObject());
236
+ }
237
+ batchUpdate() {
238
+ var _arguments4 = arguments,
239
+ _this7 = this;
240
+ return _asyncToGenerator(function* () {
241
+ var _force = _arguments4.length > 0 && _arguments4[0] !== undefined ? _arguments4[0] : false;
242
+ var updates = _this7.rows.filter(r => r.$action === _RowModel.RowAction.Update || r.$action === _RowModel.RowAction.Create);
243
+ var deletes = _this7.rows.filter(r => r.$action === _RowModel.RowAction.Delete);
244
+ yield _this7.createUpdateBatch(updates);
245
+ yield _this7.deleteBatch(deletes);
246
+ return _this7.rows;
247
+ })();
248
+ }
249
+ getDelta() {
250
+ var updates = this.rows.filter(r => r.$action === _RowModel.RowAction.Update);
251
+ var deletes = this.rows.filter(r => r.$action === _RowModel.RowAction.Delete).sort((a, b) => b._row - a._row);
252
+ var creates = this.rows.filter(r => r.$action === _RowModel.RowAction.Create);
253
+ return {
254
+ updates: updates,
255
+ deletes: deletes,
256
+ creates: creates
257
+ };
258
+ }
259
+ mergePurge(values, delta) {
260
+ delta.updates.forEach(u => values[u._row - 1] = this.values(u));
261
+ delta.deletes.forEach(d => values.splice(d._row - 1, 1));
262
+ delta.creates.forEach(c => values.push(this.values(c)));
263
+ return values;
264
+ }
265
+ prepareBatch(values, delta, force) {
266
+ if (!force) {
267
+ var errors = [];
268
+ try {
269
+ delta.updates.forEach(u => this.checkOutdated(u, this.typeRow(values[u._row - 1])));
270
+ delta.deletes.forEach(d => this.checkOutdated(d, this.typeRow(values[d._row - 1])));
271
+ } catch (e) {
272
+ errors.push(e.message);
273
+ }
274
+ if (errors.length > 0) throw new _sdkRtl.LookerSDKError(errors.join('\n'));
275
+ }
276
+ delta.updates.forEach(u => u.prepare());
277
+ delta.creates.forEach(c => c.prepare());
278
+ return true;
279
+ }
280
+ createUpdateBatch(items) {
281
+ var _this8 = this;
282
+ return _asyncToGenerator(function* () {
283
+ if (items.length < 1) return Promise.resolve(_this8.rows);
284
+ var namespace = items[0].namespace();
285
+ var arts = items.map(i => i.toArtifact());
286
+ var result = yield _this8.sdk.ok((0, _sdk.update_artifacts)(_this8.sdk, namespace, arts));
287
+ result.forEach(r => {
288
+ var row = _this8.typeRow(r);
289
+ var key = row[_this8.keyColumn];
290
+ _this8.index[key] = row;
291
+ });
292
+ _this8.updateRowsFromIndex();
293
+ return Promise.resolve(_this8.rows);
294
+ })();
295
+ }
296
+ updateRowsFromIndex() {
297
+ var result = [];
298
+ Object.entries(this.index).forEach((_ref, index) => {
299
+ var [_key, row] = _ref;
300
+ row[_RowModel.rowPosition] = index + 1;
301
+ result.push(row);
302
+ });
303
+ this.rows = result;
304
+ return this.rows;
305
+ }
306
+ deleteBatch(items) {
307
+ var _this9 = this;
308
+ return _asyncToGenerator(function* () {
309
+ if (items.length < 1) return Promise.resolve(_this9.rows);
310
+ var namespace = items[0].namespace();
311
+ var keys = items.map(r => r[_this9.keyColumn]);
312
+ yield _this9.sdk.ok((0, _sdk.delete_artifact)(_this9.sdk, namespace, keys.join()));
313
+ keys.forEach(k => delete _this9.index[k]);
314
+ _this9.updateRowsFromIndex();
315
+ return Promise.resolve(_this9.rows);
316
+ })();
317
+ }
318
+ }
319
+ exports.WhollyArtifact = WhollyArtifact;
320
+ //# sourceMappingURL=WhollyArtifact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WhollyArtifact.js","names":["compareDates","a","b","getTime","TypedRows","constructor","rows","Maker","map","v","add","value","push","where","predicate","from","filter","select","selector","toArray","values","create","WhollyArtifact","sdk","table","keyColumn","loadRows","meta","typeRow","namespace","tableName","typeRows","checkHeader","createIndex","refresh","ok","search_artifacts","key","result","pos","forEach","r","row","rowPosition","toAT","undefined","length","rowHeader","header","join","tableHeader","LookerSDKError","nextRow","index","model","h","stringer","allValues","save","force","$action","RowAction","Delete","delete_artifact","Update","update","None","checkId","_row","prepare","createUpdateBatch","_force","find","columnName","toString","displayHeader","_displayHeader","colName","displayable","delete","checkOutdated","deleteBatch","startsWith","source","errors","art","artifact","$artifact","version","fromObject","obj","toObject","batchUpdate","updates","Create","deletes","getDelta","sort","creates","mergePurge","delta","u","d","splice","c","prepareBatch","e","message","items","Promise","resolve","arts","i","toArtifact","update_artifacts","updateRowsFromIndex","Object","entries","_key","keys","k"],"sources":["../src/WhollyArtifact.ts"],"sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\nimport { LookerSDKError } from '@looker/sdk-rtl'\nimport type { IArtifact, ILooker40SDK, IUpdateArtifact } from '@looker/sdk'\nimport {\n artifact,\n delete_artifact,\n search_artifacts,\n update_artifacts,\n} from '@looker/sdk'\nimport type { ColumnHeaders, IRowModel, SheetValues } from './RowModel'\nimport { RowAction, rowPosition, stringer } from './RowModel'\n\n/**\n * Compare dates without running into numeric comparison problems\n * @param a first date to compare\n * @param b second date to compare\n * @returns 0 if dates are equal, positive if a > b, negative if a < b\n */\nexport const compareDates = (a: Date, b: Date) => a.getTime() - b.getTime()\n\nexport interface IMaker<T> {\n new (values?: any): T\n}\n\nexport interface IRowDelta<T extends IRowModel> {\n updates: T[]\n deletes: T[]\n creates: T[]\n}\n\n// TODO maybe get a technique from https://stackoverflow.com/a/34698946 or\n// https://www.logicbig.com/tutorials/misc/typescript/generic-constraints.html\n\n// TODO refactor WhollyArtifact<T> into something a bit cleaner\n// ref https://www.smashingmagazine.com/2020/10/understanding-typescript-generics/\nexport class TypedRows<T> {\n rows: T[] = []\n\n constructor(rows: T[], Maker?: IMaker<T>) {\n if (Maker) {\n this.rows = rows.map((v) => new Maker(v))\n } else {\n this.rows = rows\n }\n }\n\n public add(value: T): void {\n this.rows.push(value)\n }\n\n public where(predicate: (value: T) => boolean): TypedRows<T> {\n return TypedRows.from<T>(this.rows.filter(predicate))\n }\n\n public select<U>(selector: (value: T) => U): TypedRows<U> {\n return TypedRows.from<U>(this.rows.map(selector))\n }\n\n public toArray(): T[] {\n return this.rows\n }\n\n public static from<U>(values: U[]): TypedRows<U> {\n // Perhaps we perform some logic here.\n // ...\n\n return new TypedRows<U>(values)\n }\n\n public static create<U>(values?: U[]): TypedRows<U> {\n return new TypedRows<U>(values ?? [])\n }\n\n // Other collection functions.\n // ..\n}\n\nexport interface IWhollyArtifact<T extends IRowModel, P> {\n /** Initialized REST-based GSheets SDK */\n sdk: ILooker40SDK\n\n /** Namespace of this collection. Retrieved from IRowModel descendant */\n namespace: string\n\n /**\n * Name of this artifact \"table\". Used for table-level processing of the artifacts in a namespace.\n * Retrieved from IRowModel descendant\n */\n tableName: string\n\n /**\n /**\n * Header column names for reading from/writing to the sheet.\n * The order of the column names **must** match the order of the columns in the sheet.\n * The values used to read and write the sheet are always in column order position.\n */\n header: ColumnHeaders\n /** Column names to display */\n displayHeader: ColumnHeaders\n /** Name of the key column that represents the \"id\" */\n keyColumn: string\n /** All data in the sheet */\n rows: T[]\n /** Keyed row retrieval */\n index: Record<string, T>\n /** What's the next row of the sheet? */\n nextRow: number\n\n // TODO figure out init generic typing issue\n // init(values?: any): (values?: any) => T\n\n /**\n * Verify the column order in the sheet matches the key order of the row type\n * @param header array of column names in order\n */\n checkHeader(header: ColumnHeaders): boolean\n\n /**\n * True if the column name should be displayed in a UI\n *\n * False if it's an \"internal\" column name\n *\n * @param columnName to check for display\n */\n displayable(columnName: string): boolean\n\n /**\n * Gets the row's values in table.header column order\n * @param model row to introspect\n */\n values(model: T): SheetValues\n\n /**\n * Returns a 2D array of all row values based on the current rows collection.\n * The result include the header row\n */\n allValues(): SheetValues\n\n /**\n * Create a new row of this type\n * @param values either a value array or an object\n */\n typeRow<T extends IRowModel>(values?: any): T\n\n /**\n * Converts raw rows into typed rows.\n *\n * @param rows array of data to convert. Either value arrays or a collection of objects\n */\n typeRows<T extends IRowModel>(rows: SheetValues): T[]\n\n /**\n * Reload the entire tab by fetching all its values from the GSheet\n * @param values to use for refresh. If not provided, artifacts for the namespace will be searched\n */\n refresh<T extends IRowModel>(values?: any): Promise<T[]>\n\n /**\n * Save the specified row to the sheet.\n *\n * This routine determines whether to call update or create based on whether the row position is < 1\n *\n * @param model row to save\n * @param force true to skip checking for outdated values. Defaults to false.\n */\n save<T extends IRowModel>(model: T, force?: boolean): Promise<T>\n\n /**\n * Create a row in the sheet\n *\n * If the row position is > 0 an error is thrown\n *\n * @param model row to create in sheet\n */\n create<T extends IRowModel>(model: T): Promise<T>\n\n /**\n * Update a row in the sheet\n *\n * If the row position is < 1 an error is thrown\n *\n * If the row is checkOutdated an error is thrown\n *\n * @param model row to create in sheet\n * @param force true to skip checking for outdated values. Defaults to false.\n */\n update<T extends IRowModel>(model: T, force?: boolean): Promise<T>\n\n /**\n * Delete a row if it still exists\n * @param model to delete\n * @param force true to skip checking for outdated values. Defaults to false.\n */\n delete<T extends IRowModel>(model: T, force?: boolean): Promise<boolean>\n\n /**\n * If the row is out of date, it throws a LookerSDKError\n * @param model row for status check\n * @param source row to compare against\n */\n checkOutdated<T extends IRowModel>(model: T, source?: T): Promise<boolean>\n\n /**\n * Find the matching row. If columnName is the primary key field, indexed retrieval is used\n *\n * @param value to find\n * @param columnName in which to find the value. Defaults to primary key. If primary key, indexed retrieval is use.\n */\n find(value: any, columnName?: string): T | undefined\n\n /**\n * Reassigns collection rows, checks header, and reindexes\n * @param rows to overwrite current list\n */\n loadRows<T extends IRowModel>(rows: SheetValues): T[]\n\n /** Converts the row collection to a plain javascript object array */\n toObject(): P[]\n\n /** Assigns the passed object[] to the rows collection */\n fromObject<T extends IRowModel>(obj: P[]): T[]\n\n /** Gets the delta rows for a batch update */\n getDelta<T extends IRowModel>(): IRowDelta<T>\n\n /**\n * Processes a delta change against the tab values snapshot\n * @param tab SheetValues to update (includes header row)\n * @param delta row changes to apply\n */\n mergePurge<T extends IRowModel>(\n tab: SheetValues,\n delta: IRowDelta<T>\n ): SheetValues\n\n /**\n * Prepare a batch for processing\n *\n * If `force` is false and update rows are outdated, a LookerSDKError with outdated list is thrown\n * @param tab of sheet values to use for update checks (includes header row)\n * @param delta change to merge and purge\n * @param force prepare each row but don't worry about outdated rows\n */\n prepareBatch<T extends IRowModel>(\n tab: SheetValues,\n delta: IRowDelta<T>,\n force?: boolean\n ): boolean\n\n /**\n * collect all rows to be updated or created and submit the request\n * and returns the updated collection\n *\n * @param items list of items to update or create\n */\n createUpdateBatch<T extends IRowModel>(items: T[]): Promise<T[]>\n\n /**\n * removes all rows marked for deletion and returns the updated collection\n *\n * @param items list of items to delete\n */\n deleteBatch<T extends IRowModel>(items: T[]): Promise<T[]>\n\n /**\n * Perform a batch update by retrieving the delta for the sheet, check for outdated update rows,\n * and update the entire tab sheet with the changes\n * @param force true to skip checking for outdated update rows\n */\n batchUpdate<T extends IRowModel>(force?: boolean): Promise<T[]>\n}\n\n/**\n * Keyed data for a tab, and the tab's header row\n * TODO delete this bad boy\n */\nexport interface ITabTable {\n /** Array of header names, in column order */\n header: ColumnHeaders\n /** Parsed data for the tab */\n rows: IRowModel[]\n}\n\n/** CRUDS operations for a GSheet tab */\nexport abstract class WhollyArtifact<T extends IRowModel, P>\n extends TypedRows<T>\n implements IWhollyArtifact<T, P>\n{\n index: Record<string, T> = {}\n namespace = ''\n tableName = ''\n\n constructor(\n public readonly sdk: ILooker40SDK,\n public readonly table: ITabTable,\n public readonly keyColumn: string = '_id' // TODO change to `key`\n ) {\n super([])\n this.loadRows(table.rows)\n const meta = this.typeRow()\n this.namespace = meta.namespace()\n this.tableName = meta.tableName()\n }\n\n loadRows<T extends IRowModel>(rows: SheetValues): T[] {\n this.rows = this.typeRows(rows)\n this.checkHeader()\n this.createIndex()\n return this.rows as unknown as T[]\n }\n\n async refresh<T extends IRowModel>(values?: any): Promise<T[]> {\n if (!values) {\n values = await this.sdk.ok(\n search_artifacts(this.sdk, {\n namespace: this.namespace,\n key: `${this.tableName}:%`,\n })\n )\n }\n this.rows = this.typeRows(values)\n this.createIndex()\n return this.rows as unknown as T[]\n }\n\n abstract typeRow<T extends IRowModel>(values?: any): T\n\n typeRows<T extends IRowModel>(rows: SheetValues): T[] {\n const result: T[] = []\n let pos = 1\n\n rows.forEach((r) => {\n const row: T = this.typeRow(r)\n pos++\n // fixup row position?\n if (!row[rowPosition]) row[rowPosition] = pos\n result.push(row)\n })\n\n return result\n }\n\n // // TODO figure out init generic typing issue\n // init(values?: any): T {\n // const result: T = new this.NewItem(values)\n // return result\n // }\n\n /**\n * convert value to the strong type, or undefined if not value\n * @param value to strongly type\n * @private\n */\n private static toAT<T extends IRowModel>(value: unknown): T | undefined {\n if (value) return value as T\n return undefined\n }\n\n checkHeader() {\n // Nothing to check\n if (this.rows.length === 0) return true\n const row = this.rows[0]\n const rowHeader = row.header().join()\n const tableHeader = this.table.header.join()\n if (tableHeader !== rowHeader)\n throw new LookerSDKError(\n `Expected ${this.tableName} header to be ${rowHeader} not ${tableHeader}`\n )\n return true\n }\n\n get header() {\n return this.table.header\n }\n\n get nextRow() {\n // +1 for header row\n // +1 for 1-based rows\n return this.rows.length + 2\n }\n\n private createIndex() {\n this.index = {}\n this.rows.forEach((r) => {\n this.index[r[this.keyColumn]] = r\n })\n }\n\n values<T extends IRowModel>(model: T) {\n const result: SheetValues = []\n this.header.forEach((h) => {\n result.push(stringer(model[h]))\n })\n return result\n }\n\n allValues(): SheetValues {\n const values: SheetValues = [this.header]\n values.push(...this.rows.map((r) => this.values(r)))\n return values\n }\n\n async save<T extends IRowModel>(model: T, force = false): Promise<T> {\n switch (model.$action) {\n case RowAction.Delete: {\n await this.sdk.ok(\n this.sdk.delete_artifact(this.namespace, model[this.keyColumn])\n )\n return model\n }\n case RowAction.Update: {\n return await this.update<T>(model, force)\n }\n case RowAction.None: {\n return model\n }\n }\n return (await this.create<T>(model)) as unknown as T\n }\n\n checkId<T extends IRowModel>(model: T) {\n if (!model[this.keyColumn])\n throw new LookerSDKError(\n `\"${this.keyColumn}\" must be assigned for ${this.tableName} row ${model._row}`\n )\n }\n\n async create<T extends IRowModel>(model: T): Promise<T> {\n if (model._row > 0)\n throw new LookerSDKError(\n `create needs ${this.tableName} \"${\n model[this.keyColumn]\n }\" row to be < 1, not ${model._row}`\n )\n model.prepare()\n this.checkId(model)\n await this.createUpdateBatch([model])\n return this.index[model[this.keyColumn]] as unknown as T\n }\n\n async update<T extends IRowModel>(model: T, _force = false): Promise<T> {\n if (!model._row)\n throw new LookerSDKError(\n `${this.tableName} \"${model[this.keyColumn]}\" row must be > 0 to update`\n )\n\n model.prepare()\n this.checkId(model)\n await this.createUpdateBatch([model])\n return this.index[model[this.keyColumn]] as unknown as T\n }\n\n find(value: any, columnName?: string): T | undefined {\n if (!value) return undefined\n let key = columnName || this.keyColumn\n if (typeof value === 'number') {\n // Default key to row\n if (!columnName) key = '_row'\n }\n if (columnName === this.keyColumn) {\n // Find by index\n return WhollyArtifact.toAT(this.index[value.toString()])\n }\n return WhollyArtifact.toAT(this.rows.find((r) => r[key] === value))\n }\n\n private _displayHeader: ColumnHeaders = []\n get displayHeader(): ColumnHeaders {\n if (this._displayHeader.length === 0) {\n this._displayHeader = this.header.filter((colName) =>\n this.displayable(colName)\n )\n }\n return this._displayHeader\n }\n\n async delete<T extends IRowModel>(model: T, force = false) {\n if (!force) await this.checkOutdated(model)\n await this.deleteBatch([model])\n return true\n }\n\n displayable(columnName: string): boolean {\n return !(columnName.startsWith('_') || columnName.startsWith('$'))\n }\n\n async checkOutdated<T extends IRowModel>(model: T, source?: T) {\n if (model[rowPosition] < 1) return false\n const errors: string[] = []\n if (!source) {\n const art = await this.sdk.ok(\n artifact(this.sdk, {\n namespace: this.namespace,\n key: model[this.keyColumn],\n })\n )\n // artifact returns an array, so get the one row this should be\n if (art.length === 1) source = this.typeRow(art[0]) as unknown as T\n }\n if (!source) {\n errors.push(`Row not found`)\n } else {\n if (source.$artifact.version !== model.$artifact.version) {\n errors.push(\n `version ${source.$artifact.version} != ${model.$artifact.version}`\n )\n }\n }\n if (errors.length > 0)\n throw new LookerSDKError(\n `${this.tableName} row ${\n model[this.keyColumn]\n } is outdated: ${errors.join()}`\n )\n return false\n }\n\n fromObject<T extends IRowModel>(obj: P[]): T[] {\n this.loadRows(obj)\n return this.rows as unknown as T[]\n }\n\n toObject(): P[] {\n return this.rows.map((r) => r.toObject() as unknown as P)\n }\n\n async batchUpdate<T extends IRowModel>(_force = false): Promise<T[]> {\n // Updates and creates are processed in the same call\n const updates = this.rows.filter(\n (r) => r.$action === RowAction.Update || r.$action === RowAction.Create\n )\n const deletes = this.rows.filter((r) => r.$action === RowAction.Delete)\n\n await this.createUpdateBatch(updates)\n await this.deleteBatch(deletes)\n return this.rows as unknown as T[]\n }\n\n getDelta<T extends IRowModel>(): IRowDelta<T> {\n const updates = this.rows.filter((r) => r.$action === RowAction.Update)\n // Sort deletions in descending row order\n const deletes = this.rows\n .filter((r) => r.$action === RowAction.Delete)\n .sort((a, b) => b._row - a._row)\n const creates = this.rows.filter((r) => r.$action === RowAction.Create)\n\n return {\n updates: updates as unknown as T[],\n deletes: deletes as unknown as T[],\n creates: creates as unknown as T[],\n }\n }\n\n mergePurge<T extends IRowModel>(\n values: SheetValues,\n delta: IRowDelta<T>\n ): SheetValues {\n delta.updates.forEach((u) => (values[u._row - 1] = this.values(u)))\n delta.deletes.forEach((d) => values.splice(d._row - 1, 1))\n delta.creates.forEach((c) => values.push(this.values(c)))\n return values\n }\n\n prepareBatch<T extends IRowModel>(\n values: SheetValues,\n delta: IRowDelta<T>,\n force?: boolean\n ): boolean {\n if (!force) {\n const errors = []\n try {\n delta.updates.forEach((u) =>\n this.checkOutdated(u, this.typeRow(values[u._row - 1]))\n )\n delta.deletes.forEach((d) =>\n this.checkOutdated(d, this.typeRow(values[d._row - 1]))\n )\n } catch (e: any) {\n errors.push(e.message)\n }\n if (errors.length > 0) throw new LookerSDKError(errors.join('\\n'))\n }\n delta.updates.forEach((u) => u.prepare())\n delta.creates.forEach((c) => c.prepare())\n return true\n }\n\n async createUpdateBatch<T extends IRowModel>(items: T[]): Promise<T[]> {\n if (items.length < 1) return Promise.resolve(this.rows as unknown as T[])\n const namespace = items[0].namespace()\n const arts: Partial<IArtifact>[] = items.map((i) => i.toArtifact())\n /** This will throw an error if the request fails */\n const result = await this.sdk.ok(\n update_artifacts(this.sdk, namespace, arts as IUpdateArtifact[])\n )\n result.forEach((r) => {\n const row: T = this.typeRow(r)\n const key = row[this.keyColumn]\n this.index[key] = row as any // TODO why is this the only thing that works?\n })\n this.updateRowsFromIndex()\n return Promise.resolve(this.rows as unknown as T[])\n }\n\n /**\n * Repopulates the row collection based exclusively on the values in the index\n * @private\n */\n private updateRowsFromIndex<T extends IRowModel>(): T[] {\n const result: any[] = []\n Object.entries(this.index).forEach(([_key, row], index) => {\n row[rowPosition] = index + 1\n result.push(row)\n })\n this.rows = result as any[] // TODO why is this the only thing that works?\n return this.rows as unknown as T[]\n }\n\n async deleteBatch<T extends IRowModel>(items: T[]): Promise<T[]> {\n if (items.length < 1) return Promise.resolve(this.rows as unknown as T[])\n const namespace = items[0].namespace()\n const keys = items.map((r) => r[this.keyColumn])\n await this.sdk.ok(delete_artifact(this.sdk, namespace, keys.join()))\n // Remove deleted items from the collections\n keys.forEach((k) => delete this.index[k])\n this.updateRowsFromIndex()\n return Promise.resolve(this.rows as unknown as T[])\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.stringer = exports.rowPosition = exports.noDate = exports.nilCell = exports.addMinutes = exports.RowModel = exports.RowAction = exports.APP_JSON = void 0;
7
+ var _uuid = require("uuid");
8
+ var _sdkRtl = require("@looker/sdk-rtl");
9
+ var _omit = _interopRequireDefault(require("lodash/omit"));
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
12
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
13
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
14
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
15
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
16
+ var noDate = new Date(-8640000000000000);
17
+ exports.noDate = noDate;
18
+ var APP_JSON = 'application/json';
19
+ exports.APP_JSON = APP_JSON;
20
+ var nilCell = '\0';
21
+ exports.nilCell = nilCell;
22
+ var addMinutes = (date, minutes) => {
23
+ return new Date(date.getTime() + minutes * 60000);
24
+ };
25
+ exports.addMinutes = addMinutes;
26
+ var stringer = value => {
27
+ if (value === undefined || value === null) return nilCell;
28
+ if (value instanceof Date) {
29
+ if (value === noDate) return nilCell;
30
+ return value.toISOString();
31
+ }
32
+ return value.toString();
33
+ };
34
+ exports.stringer = stringer;
35
+ var rowPosition = '_row';
36
+ exports.rowPosition = rowPosition;
37
+ var RowAction;
38
+ exports.RowAction = RowAction;
39
+ (function (RowAction) {
40
+ RowAction[RowAction["None"] = 0] = "None";
41
+ RowAction[RowAction["Create"] = 1] = "Create";
42
+ RowAction[RowAction["Update"] = 2] = "Update";
43
+ RowAction[RowAction["Delete"] = 3] = "Delete";
44
+ })(RowAction || (exports.RowAction = RowAction = {}));
45
+ class RowModel {
46
+ constructor(values) {
47
+ _defineProperty(this, "_row", 0);
48
+ _defineProperty(this, "_id", '');
49
+ _defineProperty(this, "_updated", noDate);
50
+ _defineProperty(this, "$artifact", {
51
+ version: 0
52
+ });
53
+ _defineProperty(this, "$_action", RowAction.None);
54
+ this.initValues(values);
55
+ if (!this.key) {
56
+ this.key = this.makey();
57
+ this.$_action = RowAction.Create;
58
+ }
59
+ }
60
+ isNew() {
61
+ return this.$artifact.version < 1;
62
+ }
63
+ isStored() {
64
+ return !this.isNew();
65
+ }
66
+ initFromArray(values) {
67
+ if (Array.isArray(values)) {
68
+ var _keys = this.header();
69
+ if (Array.isArray(values)) {
70
+ values.forEach((val, index) => {
71
+ if (val !== undefined && val !== null && index < _keys.length) {
72
+ var _key = _keys[index];
73
+ this[_key] = this.typeCast(_key, val);
74
+ }
75
+ });
76
+ }
77
+ return true;
78
+ }
79
+ return false;
80
+ }
81
+ initValues(values) {
82
+ if (this.initFromArray(values)) return;
83
+ if (typeof values === 'object' && values !== null && values !== undefined) {
84
+ var nested = ('value' in values);
85
+ var _value = nested ? values.value : values;
86
+ if (nested) {
87
+ this.$artifact = values;
88
+ }
89
+ if (typeof _value === 'string') {
90
+ try {
91
+ _value = JSON.parse(_value);
92
+ } catch (e) {
93
+ var _values$$artifact, _values$$artifact$con;
94
+ if (((_values$$artifact = values.$artifact) === null || _values$$artifact === void 0 ? void 0 : (_values$$artifact$con = _values$$artifact.content_type) === null || _values$$artifact$con === void 0 ? void 0 : _values$$artifact$con.localeCompare(APP_JSON, 'en', {
95
+ sensitivity: 'base'
96
+ })) === 0) {
97
+ throw new _sdkRtl.LookerSDKError("Expected ".concat(APP_JSON, " but got ").concat(e));
98
+ } else {
99
+ throw new _sdkRtl.LookerSDKError(e);
100
+ }
101
+ }
102
+ }
103
+ Object.keys(_value).forEach(k => {
104
+ this[k] = this.typeCast(k, _value[k]);
105
+ if (typeof this[k] === 'string') {
106
+ this[k] = decodeURI(this[k]);
107
+ }
108
+ });
109
+ if (values.key) this.key = values.key;
110
+ return true;
111
+ }
112
+ return false;
113
+ }
114
+ tableName() {
115
+ return this.constructor.name;
116
+ }
117
+ makey() {
118
+ return "".concat(this.tableName(), ":").concat((0, _uuid.v4)());
119
+ }
120
+ get key() {
121
+ return this._id;
122
+ }
123
+ set key(value) {
124
+ this._id = value;
125
+ this.$artifact.key = value;
126
+ }
127
+ oops(message) {
128
+ throw new _sdkRtl.LookerSDKError("".concat(this.key, ": ").concat(message));
129
+ }
130
+ get $action() {
131
+ if (this.$_action === RowAction.None && this.isNew()) return RowAction.Create;
132
+ return this.$_action;
133
+ }
134
+ set $action(value) {
135
+ switch (value) {
136
+ case RowAction.Create:
137
+ {
138
+ if (this.isStored()) this.oops("can't create an existing item");
139
+ break;
140
+ }
141
+ case RowAction.Delete:
142
+ {
143
+ if (this.isNew()) {
144
+ this.oops("can't delete a new item");
145
+ }
146
+ break;
147
+ }
148
+ case RowAction.Update:
149
+ {
150
+ if (this.isNew()) {
151
+ this.oops("can't update a new item");
152
+ }
153
+ break;
154
+ }
155
+ case RowAction.None:
156
+ {
157
+ if (this.isNew()) {
158
+ this.oops("Action must be assigned for a new item");
159
+ }
160
+ break;
161
+ }
162
+ }
163
+ this.$_action = value;
164
+ }
165
+ setCreate() {
166
+ this.$action = RowAction.Create;
167
+ return true;
168
+ }
169
+ setUpdate() {
170
+ this.$action = RowAction.Update;
171
+ return true;
172
+ }
173
+ setDelete() {
174
+ this.$action = RowAction.Delete;
175
+ return true;
176
+ }
177
+ keys() {
178
+ return Object.keys(this);
179
+ }
180
+ header() {
181
+ var keys = this.keys();
182
+ var result = keys.filter(v => !(v.startsWith('$') || RowModel.hide.has(v)));
183
+ return result;
184
+ }
185
+ displayHeader() {
186
+ return this.header().filter(v => !(v.startsWith('_') || RowModel.hide.has(v)));
187
+ }
188
+ prepare() {
189
+ if (!this.key) {
190
+ this.key = this.makey();
191
+ this.$action = RowAction.Create;
192
+ }
193
+ this._updated = new Date();
194
+ return this;
195
+ }
196
+ values() {
197
+ var result = [];
198
+ var keys = this.header();
199
+ keys.forEach(key => {
200
+ result.push(stringer(this[key]));
201
+ });
202
+ return result;
203
+ }
204
+ typeCast(key, value) {
205
+ if (value === undefined || value === null) value = '';
206
+ var type = typeof this[key];
207
+ var fromType = typeof value;
208
+ if (type === fromType) {
209
+ return value;
210
+ }
211
+ if (type === 'string') {
212
+ return value.toString();
213
+ }
214
+ if (type === 'number') {
215
+ if (value === '') return 0;
216
+ var isInt = /^([+-]?[1-9]\d*|0)$/;
217
+ if (value.toString().match(isInt)) {
218
+ return parseInt(value, 10);
219
+ }
220
+ return parseFloat(value);
221
+ }
222
+ if (type === 'boolean') {
223
+ return (0, _sdkRtl.boolDefault)(value, false);
224
+ }
225
+ if (this[key] instanceof Date) {
226
+ if (value) return new Date(value);
227
+ return noDate;
228
+ }
229
+ if (Array.isArray(this[key])) {
230
+ if (!value) return [];
231
+ return value.toString().split(',');
232
+ }
233
+ return value;
234
+ }
235
+ assign(values) {
236
+ if (values) {
237
+ this.initValues(values);
238
+ }
239
+ return this;
240
+ }
241
+ validate() {
242
+ return undefined;
243
+ }
244
+ toObject() {
245
+ return (0, _omit.default)(_objectSpread({}, this), ['$_action']);
246
+ }
247
+ fromObject(obj) {
248
+ return this.assign(obj);
249
+ }
250
+ fromArtifact(obj) {
251
+ return this.assign(obj);
252
+ }
253
+ storageValues() {
254
+ var result = {};
255
+ var keys = this.header();
256
+ for (var _key2 of keys) {
257
+ var val = typeof this[_key2] === 'string' ? encodeURI(this[_key2]) : this[_key2];
258
+ result[_key2] = val;
259
+ }
260
+ return result;
261
+ }
262
+ toArtifact() {
263
+ var _this$$artifact$versi;
264
+ return {
265
+ key: this.key,
266
+ value: JSON.stringify(this.storageValues()),
267
+ version: (_this$$artifact$versi = this.$artifact.version) !== null && _this$$artifact$versi !== void 0 ? _this$$artifact$versi : 0,
268
+ content_type: APP_JSON
269
+ };
270
+ }
271
+ }
272
+ exports.RowModel = RowModel;
273
+ _defineProperty(RowModel, "hide", new Set(['_row']));
274
+ //# sourceMappingURL=RowModel.js.map