@kwiz/node 1.0.15 → 1.0.17
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/.github/workflows/npm-publish.yml +24 -0
- package/.madgerc +2 -2
- package/LICENSE +21 -21
- package/README.md +2 -2
- package/dist/exports-index.d.ts +1 -0
- package/dist/exports-index.js +1 -0
- package/dist/exports-index.js.map +1 -1
- package/dist/get-with-cache.d.ts +12 -0
- package/dist/get-with-cache.js +43 -0
- package/dist/get-with-cache.js.map +1 -0
- package/fix-folder-imports.js +26 -26
- package/package.json +78 -78
- package/src/SPO/common.ts +16 -16
- package/src/auth/discovery.test.js +8 -8
- package/src/auth/discovery.ts +60 -60
- package/src/auth/msal.ts +43 -43
- package/src/axios.ts +44 -44
- package/src/exports-index.ts +1 -0
- package/src/get-with-cache.ts +38 -0
- package/src/graph/graph.ts +17 -17
- package/src/index.ts +1 -1
- package/src/storage/common.ts +15 -15
- package/src/storage/odata.ts +86 -86
- package/src/storage/table-storage.test.js +134 -134
- package/src/storage/table-storage.ts +313 -313
- package/__azurite_db_blob__.json +0 -1
- package/__azurite_db_blob_extent__.json +0 -1
- package/__azurite_db_queue__.json +0 -1
- package/__azurite_db_queue_extent__.json +0 -1
- package/__azurite_db_table__.json +0 -1
- package/dist/SPO/index.d.ts +0 -1
- package/dist/SPO/index.js +0 -18
- package/dist/SPO/index.js.map +0 -1
- package/dist/auth/index.d.ts +0 -2
- package/dist/auth/index.js +0 -19
- package/dist/auth/index.js.map +0 -1
|
@@ -1,314 +1,314 @@
|
|
|
1
|
-
//https://www.npmjs.com/package/@azure/storage-blob
|
|
2
|
-
//https://www.npmjs.com/package/@azure/storage-queue
|
|
3
|
-
//https://www.npmjs.com/package/@azure/storage-file-share
|
|
4
|
-
//https://www.npmjs.com/package/@azure/data-tables
|
|
5
|
-
//https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite?tabs=visual-studio-code
|
|
6
|
-
import { FullOperationResponse } from "@azure/core-client";
|
|
7
|
-
import { ListTableEntitiesOptions, TableClient, TableServiceClient, UpdateMode, odata } from "@azure/data-tables";
|
|
8
|
-
import { isNullOrEmptyString, isNullOrUndefined } from "@kwiz/common";
|
|
9
|
-
import { IOdataFilterStatement, getOdataFilter } from "./odata";
|
|
10
|
-
|
|
11
|
-
var connectionString: string = null;
|
|
12
|
-
export function ConfigureTableStorage(config: { connectionString: string; }) {
|
|
13
|
-
connectionString = config.connectionString;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function getTableService() {
|
|
17
|
-
if (isNullOrEmptyString(connectionString)) throw Error("Call ConfigureTableStorage first");
|
|
18
|
-
return TableServiceClient.fromConnectionString(connectionString);
|
|
19
|
-
}
|
|
20
|
-
function getTableClient(tableName: string) {
|
|
21
|
-
if (isNullOrEmptyString(connectionString)) throw Error("Call ConfigureTableStorage first");
|
|
22
|
-
return TableClient.fromConnectionString(connectionString, tableName);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
interface IODataError {
|
|
26
|
-
odataError: {
|
|
27
|
-
code: string | "TableAlreadyExists" | "EntityAlreadyExists" | "TableNotFound" | "",
|
|
28
|
-
message: {
|
|
29
|
-
lang: string | "en-US",
|
|
30
|
-
value: string
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
type TableEntityBase = {
|
|
36
|
-
/**
|
|
37
|
-
* The PartitionKey property of the entity.
|
|
38
|
-
* Does not allow / \ # ? any control characted (like \n)
|
|
39
|
-
*/
|
|
40
|
-
partitionKey: string;
|
|
41
|
-
/**
|
|
42
|
-
* The RowKey property of the entity.
|
|
43
|
-
*/
|
|
44
|
-
rowKey: string;
|
|
45
|
-
}
|
|
46
|
-
//correctly limits the column types...
|
|
47
|
-
export type TableEntityType<DataType extends TableEntityBase> = {
|
|
48
|
-
[P in keyof DataType]: string | boolean | Date | number;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export async function findTable(tableName: string) {
|
|
52
|
-
const tableService = getTableService();
|
|
53
|
-
|
|
54
|
-
let found = false;
|
|
55
|
-
try {
|
|
56
|
-
const tables = tableService.listTables({
|
|
57
|
-
queryOptions: {
|
|
58
|
-
//Tag function - read more https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
|
|
59
|
-
filter: odata`TableName eq ${tableName}`
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
for await (const table of tables) {
|
|
63
|
-
found = true;
|
|
64
|
-
}
|
|
65
|
-
} catch (e) {
|
|
66
|
-
//console.log(e);
|
|
67
|
-
}
|
|
68
|
-
return found;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export async function listTables() {
|
|
72
|
-
const tableService = getTableService();
|
|
73
|
-
|
|
74
|
-
let arr: string[] = [];
|
|
75
|
-
try {
|
|
76
|
-
const tables = tableService.listTables();
|
|
77
|
-
for await (const table of tables) {
|
|
78
|
-
arr.push(table.name);
|
|
79
|
-
}
|
|
80
|
-
} catch (e) {
|
|
81
|
-
//console.log(e);
|
|
82
|
-
}
|
|
83
|
-
return arr;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// async function ensureTableObsolete(name: string) {
|
|
87
|
-
// const tableService = getTableService();
|
|
88
|
-
// //create table
|
|
89
|
-
// // If the table 'newTable' already exists, createTable doesn't throw
|
|
90
|
-
// let success = false;
|
|
91
|
-
// try {
|
|
92
|
-
// await tableService.createTable(name, {
|
|
93
|
-
// onResponse: raw => {
|
|
94
|
-
// let error = isError(raw);
|
|
95
|
-
// success = error.isError !== true;
|
|
96
|
-
// if (error.isError) console.log(error.message);
|
|
97
|
-
// }
|
|
98
|
-
// });
|
|
99
|
-
// }
|
|
100
|
-
// catch (e) {
|
|
101
|
-
// success = false;
|
|
102
|
-
// }
|
|
103
|
-
|
|
104
|
-
// return success;
|
|
105
|
-
// }
|
|
106
|
-
|
|
107
|
-
export async function ensureTable(tableName: string) {
|
|
108
|
-
const table = getTableClient(tableName);
|
|
109
|
-
let success = false;
|
|
110
|
-
try {
|
|
111
|
-
await table.createTable({
|
|
112
|
-
onResponse: raw => {
|
|
113
|
-
let error = isError(raw);
|
|
114
|
-
success = error.isError !== true || error.message === "TableAlreadyExists";
|
|
115
|
-
//if (error.isError) console.error(error.message);
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
} catch (e) {
|
|
119
|
-
//console.error(e);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return success;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export async function deleteTable(tableName: string) {
|
|
126
|
-
const table = getTableClient(tableName);
|
|
127
|
-
let success = false;
|
|
128
|
-
try {
|
|
129
|
-
await table.deleteTable({
|
|
130
|
-
onResponse: raw => {
|
|
131
|
-
let error = isError(raw);
|
|
132
|
-
success = error.isError !== true;
|
|
133
|
-
//if (error.isError) console.log(error.message);
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
} catch (e) {
|
|
137
|
-
//console.log(e);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return success;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
//https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/tables/data-tables/samples/v13/typescript/src/queryEntities.ts
|
|
144
|
-
export async function getItems<DataType extends TableEntityBase & TableEntityType<DataType>>(tableName: string, options?: {
|
|
145
|
-
filterStatment?: IOdataFilterStatement<DataType>;
|
|
146
|
-
postFilter?: (item: DataType) => boolean;
|
|
147
|
-
}) {
|
|
148
|
-
const table = getTableClient(tableName);
|
|
149
|
-
let result: DataType[] = [];
|
|
150
|
-
try {
|
|
151
|
-
let o: ListTableEntitiesOptions;
|
|
152
|
-
if (options) {
|
|
153
|
-
if (!isNullOrUndefined(options.filterStatment)) {
|
|
154
|
-
let filterStatment = getOdataFilter(options.filterStatment);
|
|
155
|
-
if (!isNullOrEmptyString(filterStatment))
|
|
156
|
-
o = {
|
|
157
|
-
queryOptions: {
|
|
158
|
-
filter: filterStatment
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
let items = table.listEntities<DataType>(o);
|
|
164
|
-
for await (const item of items) {
|
|
165
|
-
//console.dir(item);
|
|
166
|
-
if (!options || typeof options.postFilter !== "function" || options.postFilter(item))
|
|
167
|
-
result.push(item as DataType);
|
|
168
|
-
}
|
|
169
|
-
} catch (e) {
|
|
170
|
-
//console.log(e);
|
|
171
|
-
}
|
|
172
|
-
return result;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
export async function addItem<DataType extends TableEntityBase & TableEntityType<DataType>>(tableName: string, item: DataType) {
|
|
176
|
-
const table = getTableClient(tableName);
|
|
177
|
-
let success = false;
|
|
178
|
-
try {
|
|
179
|
-
let result = await table.createEntity(item, {
|
|
180
|
-
onResponse: raw => {
|
|
181
|
-
let error = isError(raw);
|
|
182
|
-
success = error.isError !== true;
|
|
183
|
-
//if (error.isError) console.log(error.message);
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
//console.log(result);
|
|
187
|
-
success = true;
|
|
188
|
-
} catch (e) { success = false; }
|
|
189
|
-
return success;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
export async function deleteItem(tableName: string, partitionKey: string, rowKey: string) {
|
|
193
|
-
const table = getTableClient(tableName);
|
|
194
|
-
let success = false;
|
|
195
|
-
try {
|
|
196
|
-
let result = await table.deleteEntity(partitionKey, rowKey, {
|
|
197
|
-
onResponse: raw => {
|
|
198
|
-
let error = isError(raw);
|
|
199
|
-
success = error.isError !== true || error.message === "ResourceNotFound";
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
//console.log(result);
|
|
203
|
-
success = true;
|
|
204
|
-
} catch (e) {
|
|
205
|
-
//success = false;
|
|
206
|
-
}
|
|
207
|
-
return success;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
export async function upsertItem<DataType extends TableEntityBase & TableEntityType<DataType>>(tableName: string, item: DataType, options?: {
|
|
211
|
-
mode?: UpdateMode
|
|
212
|
-
}) {
|
|
213
|
-
const table = getTableClient(tableName);
|
|
214
|
-
let success = false;
|
|
215
|
-
try {
|
|
216
|
-
let result = await table.upsertEntity(item, options?.mode || "Replace", {
|
|
217
|
-
onResponse: raw => {
|
|
218
|
-
let error = isError(raw);
|
|
219
|
-
success = error.isError !== true;
|
|
220
|
-
//if (error.isError) console.log(error.message);
|
|
221
|
-
}
|
|
222
|
-
});
|
|
223
|
-
//console.log(result);
|
|
224
|
-
success = true;
|
|
225
|
-
} catch (e) {
|
|
226
|
-
console.error(e);
|
|
227
|
-
success = false;
|
|
228
|
-
}
|
|
229
|
-
return success;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
export class Table<KeysType extends TableEntityBase,
|
|
233
|
-
GetKeysParam,
|
|
234
|
-
SavedRow extends KeysType & TableEntityType<SavedRow>,
|
|
235
|
-
ParsedRow = SavedRow>{
|
|
236
|
-
private tableName: string;
|
|
237
|
-
private transform: {
|
|
238
|
-
save: (parsed: ParsedRow, table: Table<KeysType, GetKeysParam, SavedRow, ParsedRow>) => SavedRow;
|
|
239
|
-
load: (saved: SavedRow, table: Table<KeysType, GetKeysParam, SavedRow, ParsedRow>) => ParsedRow;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
public getKeys: (p: GetKeysParam) => KeysType = null;
|
|
243
|
-
|
|
244
|
-
/** If your type contains complex values, provide a transforer to serialize/deserialize those complex columns */
|
|
245
|
-
public constructor(tableName: string, options: {
|
|
246
|
-
getKeys: (p: GetKeysParam) => KeysType,
|
|
247
|
-
transform?: {
|
|
248
|
-
save: (parsed: ParsedRow, table: Table<KeysType, GetKeysParam, SavedRow, ParsedRow>) => SavedRow;
|
|
249
|
-
load: (saved: SavedRow, table: Table<KeysType, GetKeysParam, SavedRow, ParsedRow>) => ParsedRow;
|
|
250
|
-
}
|
|
251
|
-
}) {
|
|
252
|
-
this.tableName = tableName;
|
|
253
|
-
this.getKeys = options.getKeys;
|
|
254
|
-
this.transform = options.transform || {
|
|
255
|
-
save: v => v as any as SavedRow,
|
|
256
|
-
load: v => v as any as ParsedRow
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
public delete() {
|
|
260
|
-
return deleteTable(this.tableName);
|
|
261
|
-
}
|
|
262
|
-
public ensure() {
|
|
263
|
-
return ensureTable(this.tableName);
|
|
264
|
-
}
|
|
265
|
-
public async getItems(options?: {
|
|
266
|
-
filterStatment?: IOdataFilterStatement<SavedRow>;
|
|
267
|
-
postFilter?: (item: SavedRow) => boolean;
|
|
268
|
-
}) {
|
|
269
|
-
let items = await getItems<SavedRow>(this.tableName, options);
|
|
270
|
-
return items.map(i => this.transform.load(i, this));
|
|
271
|
-
}
|
|
272
|
-
public async addItem(item: ParsedRow) {
|
|
273
|
-
await this.ensure();
|
|
274
|
-
|
|
275
|
-
return addItem<SavedRow>(this.tableName, this.transform.save(item, this));
|
|
276
|
-
}
|
|
277
|
-
public async upsertItem(item: ParsedRow, options?: {
|
|
278
|
-
mode?: UpdateMode
|
|
279
|
-
}) {
|
|
280
|
-
await this.ensure();
|
|
281
|
-
|
|
282
|
-
return upsertItem<SavedRow>(this.tableName, this.transform.save(item, this), options);
|
|
283
|
-
}
|
|
284
|
-
public deleteItemByKey(param: GetKeysParam) {
|
|
285
|
-
let keys = this.getKeys(param);
|
|
286
|
-
return this.deleteItem(keys);
|
|
287
|
-
}
|
|
288
|
-
public deleteItem(item: KeysType) {
|
|
289
|
-
return deleteItem(this.tableName, item.partitionKey, item.rowKey);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
function isError(raw: FullOperationResponse) {
|
|
294
|
-
let isError = false;
|
|
295
|
-
let message: string = null;
|
|
296
|
-
|
|
297
|
-
//201 - table created successfully
|
|
298
|
-
//204 - entity created successfully
|
|
299
|
-
//409 - table/entity already exists
|
|
300
|
-
//400 - table name not allowed
|
|
301
|
-
//404 - TableNotFound when adding item
|
|
302
|
-
if (raw.status >= 400) {
|
|
303
|
-
isError = true;
|
|
304
|
-
let error = raw.parsedBody as IODataError;
|
|
305
|
-
message = error && error.odataError && !isNullOrEmptyString(error.odataError.code)
|
|
306
|
-
? error.odataError.code
|
|
307
|
-
: `Unknown error`;//for some errors like table name too short, error code is empty
|
|
308
|
-
}
|
|
309
|
-
else {
|
|
310
|
-
isError = false;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
return { isError, message };
|
|
1
|
+
//https://www.npmjs.com/package/@azure/storage-blob
|
|
2
|
+
//https://www.npmjs.com/package/@azure/storage-queue
|
|
3
|
+
//https://www.npmjs.com/package/@azure/storage-file-share
|
|
4
|
+
//https://www.npmjs.com/package/@azure/data-tables
|
|
5
|
+
//https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite?tabs=visual-studio-code
|
|
6
|
+
import { FullOperationResponse } from "@azure/core-client";
|
|
7
|
+
import { ListTableEntitiesOptions, TableClient, TableServiceClient, UpdateMode, odata } from "@azure/data-tables";
|
|
8
|
+
import { isNullOrEmptyString, isNullOrUndefined } from "@kwiz/common";
|
|
9
|
+
import { IOdataFilterStatement, getOdataFilter } from "./odata";
|
|
10
|
+
|
|
11
|
+
var connectionString: string = null;
|
|
12
|
+
export function ConfigureTableStorage(config: { connectionString: string; }) {
|
|
13
|
+
connectionString = config.connectionString;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function getTableService() {
|
|
17
|
+
if (isNullOrEmptyString(connectionString)) throw Error("Call ConfigureTableStorage first");
|
|
18
|
+
return TableServiceClient.fromConnectionString(connectionString);
|
|
19
|
+
}
|
|
20
|
+
function getTableClient(tableName: string) {
|
|
21
|
+
if (isNullOrEmptyString(connectionString)) throw Error("Call ConfigureTableStorage first");
|
|
22
|
+
return TableClient.fromConnectionString(connectionString, tableName);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface IODataError {
|
|
26
|
+
odataError: {
|
|
27
|
+
code: string | "TableAlreadyExists" | "EntityAlreadyExists" | "TableNotFound" | "",
|
|
28
|
+
message: {
|
|
29
|
+
lang: string | "en-US",
|
|
30
|
+
value: string
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
type TableEntityBase = {
|
|
36
|
+
/**
|
|
37
|
+
* The PartitionKey property of the entity.
|
|
38
|
+
* Does not allow / \ # ? any control characted (like \n)
|
|
39
|
+
*/
|
|
40
|
+
partitionKey: string;
|
|
41
|
+
/**
|
|
42
|
+
* The RowKey property of the entity.
|
|
43
|
+
*/
|
|
44
|
+
rowKey: string;
|
|
45
|
+
}
|
|
46
|
+
//correctly limits the column types...
|
|
47
|
+
export type TableEntityType<DataType extends TableEntityBase> = {
|
|
48
|
+
[P in keyof DataType]: string | boolean | Date | number;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export async function findTable(tableName: string) {
|
|
52
|
+
const tableService = getTableService();
|
|
53
|
+
|
|
54
|
+
let found = false;
|
|
55
|
+
try {
|
|
56
|
+
const tables = tableService.listTables({
|
|
57
|
+
queryOptions: {
|
|
58
|
+
//Tag function - read more https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
|
|
59
|
+
filter: odata`TableName eq ${tableName}`
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
for await (const table of tables) {
|
|
63
|
+
found = true;
|
|
64
|
+
}
|
|
65
|
+
} catch (e) {
|
|
66
|
+
//console.log(e);
|
|
67
|
+
}
|
|
68
|
+
return found;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export async function listTables() {
|
|
72
|
+
const tableService = getTableService();
|
|
73
|
+
|
|
74
|
+
let arr: string[] = [];
|
|
75
|
+
try {
|
|
76
|
+
const tables = tableService.listTables();
|
|
77
|
+
for await (const table of tables) {
|
|
78
|
+
arr.push(table.name);
|
|
79
|
+
}
|
|
80
|
+
} catch (e) {
|
|
81
|
+
//console.log(e);
|
|
82
|
+
}
|
|
83
|
+
return arr;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// async function ensureTableObsolete(name: string) {
|
|
87
|
+
// const tableService = getTableService();
|
|
88
|
+
// //create table
|
|
89
|
+
// // If the table 'newTable' already exists, createTable doesn't throw
|
|
90
|
+
// let success = false;
|
|
91
|
+
// try {
|
|
92
|
+
// await tableService.createTable(name, {
|
|
93
|
+
// onResponse: raw => {
|
|
94
|
+
// let error = isError(raw);
|
|
95
|
+
// success = error.isError !== true;
|
|
96
|
+
// if (error.isError) console.log(error.message);
|
|
97
|
+
// }
|
|
98
|
+
// });
|
|
99
|
+
// }
|
|
100
|
+
// catch (e) {
|
|
101
|
+
// success = false;
|
|
102
|
+
// }
|
|
103
|
+
|
|
104
|
+
// return success;
|
|
105
|
+
// }
|
|
106
|
+
|
|
107
|
+
export async function ensureTable(tableName: string) {
|
|
108
|
+
const table = getTableClient(tableName);
|
|
109
|
+
let success = false;
|
|
110
|
+
try {
|
|
111
|
+
await table.createTable({
|
|
112
|
+
onResponse: raw => {
|
|
113
|
+
let error = isError(raw);
|
|
114
|
+
success = error.isError !== true || error.message === "TableAlreadyExists";
|
|
115
|
+
//if (error.isError) console.error(error.message);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
} catch (e) {
|
|
119
|
+
//console.error(e);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return success;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export async function deleteTable(tableName: string) {
|
|
126
|
+
const table = getTableClient(tableName);
|
|
127
|
+
let success = false;
|
|
128
|
+
try {
|
|
129
|
+
await table.deleteTable({
|
|
130
|
+
onResponse: raw => {
|
|
131
|
+
let error = isError(raw);
|
|
132
|
+
success = error.isError !== true;
|
|
133
|
+
//if (error.isError) console.log(error.message);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
} catch (e) {
|
|
137
|
+
//console.log(e);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return success;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
//https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/tables/data-tables/samples/v13/typescript/src/queryEntities.ts
|
|
144
|
+
export async function getItems<DataType extends TableEntityBase & TableEntityType<DataType>>(tableName: string, options?: {
|
|
145
|
+
filterStatment?: IOdataFilterStatement<DataType>;
|
|
146
|
+
postFilter?: (item: DataType) => boolean;
|
|
147
|
+
}) {
|
|
148
|
+
const table = getTableClient(tableName);
|
|
149
|
+
let result: DataType[] = [];
|
|
150
|
+
try {
|
|
151
|
+
let o: ListTableEntitiesOptions;
|
|
152
|
+
if (options) {
|
|
153
|
+
if (!isNullOrUndefined(options.filterStatment)) {
|
|
154
|
+
let filterStatment = getOdataFilter(options.filterStatment);
|
|
155
|
+
if (!isNullOrEmptyString(filterStatment))
|
|
156
|
+
o = {
|
|
157
|
+
queryOptions: {
|
|
158
|
+
filter: filterStatment
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
let items = table.listEntities<DataType>(o);
|
|
164
|
+
for await (const item of items) {
|
|
165
|
+
//console.dir(item);
|
|
166
|
+
if (!options || typeof options.postFilter !== "function" || options.postFilter(item))
|
|
167
|
+
result.push(item as DataType);
|
|
168
|
+
}
|
|
169
|
+
} catch (e) {
|
|
170
|
+
//console.log(e);
|
|
171
|
+
}
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export async function addItem<DataType extends TableEntityBase & TableEntityType<DataType>>(tableName: string, item: DataType) {
|
|
176
|
+
const table = getTableClient(tableName);
|
|
177
|
+
let success = false;
|
|
178
|
+
try {
|
|
179
|
+
let result = await table.createEntity(item, {
|
|
180
|
+
onResponse: raw => {
|
|
181
|
+
let error = isError(raw);
|
|
182
|
+
success = error.isError !== true;
|
|
183
|
+
//if (error.isError) console.log(error.message);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
//console.log(result);
|
|
187
|
+
success = true;
|
|
188
|
+
} catch (e) { success = false; }
|
|
189
|
+
return success;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export async function deleteItem(tableName: string, partitionKey: string, rowKey: string) {
|
|
193
|
+
const table = getTableClient(tableName);
|
|
194
|
+
let success = false;
|
|
195
|
+
try {
|
|
196
|
+
let result = await table.deleteEntity(partitionKey, rowKey, {
|
|
197
|
+
onResponse: raw => {
|
|
198
|
+
let error = isError(raw);
|
|
199
|
+
success = error.isError !== true || error.message === "ResourceNotFound";
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
//console.log(result);
|
|
203
|
+
success = true;
|
|
204
|
+
} catch (e) {
|
|
205
|
+
//success = false;
|
|
206
|
+
}
|
|
207
|
+
return success;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export async function upsertItem<DataType extends TableEntityBase & TableEntityType<DataType>>(tableName: string, item: DataType, options?: {
|
|
211
|
+
mode?: UpdateMode
|
|
212
|
+
}) {
|
|
213
|
+
const table = getTableClient(tableName);
|
|
214
|
+
let success = false;
|
|
215
|
+
try {
|
|
216
|
+
let result = await table.upsertEntity(item, options?.mode || "Replace", {
|
|
217
|
+
onResponse: raw => {
|
|
218
|
+
let error = isError(raw);
|
|
219
|
+
success = error.isError !== true;
|
|
220
|
+
//if (error.isError) console.log(error.message);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
//console.log(result);
|
|
224
|
+
success = true;
|
|
225
|
+
} catch (e) {
|
|
226
|
+
console.error(e);
|
|
227
|
+
success = false;
|
|
228
|
+
}
|
|
229
|
+
return success;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export class Table<KeysType extends TableEntityBase,
|
|
233
|
+
GetKeysParam,
|
|
234
|
+
SavedRow extends KeysType & TableEntityType<SavedRow>,
|
|
235
|
+
ParsedRow = SavedRow>{
|
|
236
|
+
private tableName: string;
|
|
237
|
+
private transform: {
|
|
238
|
+
save: (parsed: ParsedRow, table: Table<KeysType, GetKeysParam, SavedRow, ParsedRow>) => SavedRow;
|
|
239
|
+
load: (saved: SavedRow, table: Table<KeysType, GetKeysParam, SavedRow, ParsedRow>) => ParsedRow;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
public getKeys: (p: GetKeysParam) => KeysType = null;
|
|
243
|
+
|
|
244
|
+
/** If your type contains complex values, provide a transforer to serialize/deserialize those complex columns */
|
|
245
|
+
public constructor(tableName: string, options: {
|
|
246
|
+
getKeys: (p: GetKeysParam) => KeysType,
|
|
247
|
+
transform?: {
|
|
248
|
+
save: (parsed: ParsedRow, table: Table<KeysType, GetKeysParam, SavedRow, ParsedRow>) => SavedRow;
|
|
249
|
+
load: (saved: SavedRow, table: Table<KeysType, GetKeysParam, SavedRow, ParsedRow>) => ParsedRow;
|
|
250
|
+
}
|
|
251
|
+
}) {
|
|
252
|
+
this.tableName = tableName;
|
|
253
|
+
this.getKeys = options.getKeys;
|
|
254
|
+
this.transform = options.transform || {
|
|
255
|
+
save: v => v as any as SavedRow,
|
|
256
|
+
load: v => v as any as ParsedRow
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
public delete() {
|
|
260
|
+
return deleteTable(this.tableName);
|
|
261
|
+
}
|
|
262
|
+
public ensure() {
|
|
263
|
+
return ensureTable(this.tableName);
|
|
264
|
+
}
|
|
265
|
+
public async getItems(options?: {
|
|
266
|
+
filterStatment?: IOdataFilterStatement<SavedRow>;
|
|
267
|
+
postFilter?: (item: SavedRow) => boolean;
|
|
268
|
+
}) {
|
|
269
|
+
let items = await getItems<SavedRow>(this.tableName, options);
|
|
270
|
+
return items.map(i => this.transform.load(i, this));
|
|
271
|
+
}
|
|
272
|
+
public async addItem(item: ParsedRow) {
|
|
273
|
+
await this.ensure();
|
|
274
|
+
|
|
275
|
+
return addItem<SavedRow>(this.tableName, this.transform.save(item, this));
|
|
276
|
+
}
|
|
277
|
+
public async upsertItem(item: ParsedRow, options?: {
|
|
278
|
+
mode?: UpdateMode
|
|
279
|
+
}) {
|
|
280
|
+
await this.ensure();
|
|
281
|
+
|
|
282
|
+
return upsertItem<SavedRow>(this.tableName, this.transform.save(item, this), options);
|
|
283
|
+
}
|
|
284
|
+
public deleteItemByKey(param: GetKeysParam) {
|
|
285
|
+
let keys = this.getKeys(param);
|
|
286
|
+
return this.deleteItem(keys);
|
|
287
|
+
}
|
|
288
|
+
public deleteItem(item: KeysType) {
|
|
289
|
+
return deleteItem(this.tableName, item.partitionKey, item.rowKey);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function isError(raw: FullOperationResponse) {
|
|
294
|
+
let isError = false;
|
|
295
|
+
let message: string = null;
|
|
296
|
+
|
|
297
|
+
//201 - table created successfully
|
|
298
|
+
//204 - entity created successfully
|
|
299
|
+
//409 - table/entity already exists
|
|
300
|
+
//400 - table name not allowed
|
|
301
|
+
//404 - TableNotFound when adding item
|
|
302
|
+
if (raw.status >= 400) {
|
|
303
|
+
isError = true;
|
|
304
|
+
let error = raw.parsedBody as IODataError;
|
|
305
|
+
message = error && error.odataError && !isNullOrEmptyString(error.odataError.code)
|
|
306
|
+
? error.odataError.code
|
|
307
|
+
: `Unknown error`;//for some errors like table name too short, error code is empty
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
isError = false;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return { isError, message };
|
|
314
314
|
}
|
package/__azurite_db_blob__.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"filename":"C:\\Repos\\@kwiz\\node\\__azurite_db_blob__.json","collections":[{"name":"$SERVICES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{},"constraints":null,"uniqueNames":["accountName"],"transforms":{},"objType":"$SERVICES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]},{"name":"$CONTAINERS_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"accountName":{"name":"accountName","dirty":false,"values":[]},"name":{"name":"name","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$CONTAINERS_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]},{"name":"$BLOBS_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"accountName":{"name":"accountName","dirty":false,"values":[]},"containerName":{"name":"containerName","dirty":false,"values":[]},"name":{"name":"name","dirty":false,"values":[]},"snapshot":{"name":"snapshot","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$BLOBS_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]},{"name":"$BLOCKS_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"accountName":{"name":"accountName","dirty":false,"values":[]},"containerName":{"name":"containerName","dirty":false,"values":[]},"blobName":{"name":"blobName","dirty":false,"values":[]},"name":{"name":"name","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$BLOCKS_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]}],"databaseVersion":1.5,"engineVersion":1.5,"autosave":true,"autosaveInterval":5000,"autosaveHandle":null,"throttledSaves":true,"options":{"persistenceMethod":"fs","autosave":true,"autosaveInterval":5000,"serializationMethod":"normal","destructureDelimiter":"$<\n"},"persistenceMethod":"fs","persistenceAdapter":null,"verbose":false,"events":{"init":[null],"loaded":[],"flushChanges":[],"close":[],"changes":[],"warning":[]},"ENV":"NODEJS"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"filename":"C:\\Repos\\@kwiz\\node\\__azurite_db_blob_extent__.json","collections":[{"name":"$EXTENTS_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"id":{"name":"id","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$EXTENTS_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]}],"databaseVersion":1.5,"engineVersion":1.5,"autosave":true,"autosaveInterval":5000,"autosaveHandle":null,"throttledSaves":true,"options":{"persistenceMethod":"fs","autosave":true,"autosaveInterval":5000,"serializationMethod":"normal","destructureDelimiter":"$<\n"},"persistenceMethod":"fs","persistenceAdapter":null,"verbose":false,"events":{"init":[null],"loaded":[],"flushChanges":[],"close":[],"changes":[],"warning":[]},"ENV":"NODEJS"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"filename":"C:\\Repos\\@kwiz\\node\\__azurite_db_queue__.json","collections":[{"name":"$SERVICES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{},"constraints":null,"uniqueNames":["accountName"],"transforms":{},"objType":"$SERVICES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]},{"name":"$QUEUES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"accountName":{"name":"accountName","dirty":false,"values":[]},"name":{"name":"name","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$QUEUES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]},{"name":"$MESSAGES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"accountName":{"name":"accountName","dirty":false,"values":[]},"queueName":{"name":"queueName","dirty":false,"values":[]},"messageId":{"name":"messageId","dirty":false,"values":[]},"visibleTime":{"name":"visibleTime","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$MESSAGES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]}],"databaseVersion":1.5,"engineVersion":1.5,"autosave":true,"autosaveInterval":5000,"autosaveHandle":null,"throttledSaves":true,"options":{"persistenceMethod":"fs","autosave":true,"autosaveInterval":5000,"serializationMethod":"normal","destructureDelimiter":"$<\n"},"persistenceMethod":"fs","persistenceAdapter":null,"verbose":false,"events":{"init":[null],"loaded":[],"flushChanges":[],"close":[],"changes":[],"warning":[]},"ENV":"NODEJS"}
|