@openstax/ts-utils 1.8.0 → 1.9.0
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/dist/cjs/misc/hashValue.d.ts +2 -3
- package/dist/cjs/services/documentStore/dynamoEncoding.d.ts +10 -0
- package/dist/cjs/services/documentStore/dynamoEncoding.js +52 -0
- package/dist/cjs/services/documentStore/index.d.ts +14 -0
- package/dist/cjs/services/documentStore/unversioned/dynamodb.d.ts +13 -0
- package/dist/cjs/services/documentStore/unversioned/dynamodb.js +51 -0
- package/dist/cjs/services/documentStore/unversioned/file-system.d.ts +15 -0
- package/dist/cjs/services/documentStore/unversioned/file-system.js +81 -0
- package/dist/cjs/services/documentStore/unversioned/index.d.ts +2 -0
- package/dist/cjs/services/documentStore/unversioned/index.js +2 -0
- package/dist/cjs/services/{versionedDocumentStore → documentStore/versioned}/dynamodb.d.ts +5 -7
- package/dist/cjs/services/{versionedDocumentStore → documentStore/versioned}/dynamodb.js +14 -57
- package/dist/{esm/services/versionedDocumentStore → cjs/services/documentStore/versioned}/file-system.d.ts +5 -7
- package/dist/cjs/services/{versionedDocumentStore → documentStore/versioned}/file-system.js +3 -3
- package/dist/cjs/services/{versionedDocumentStore → documentStore/versioned}/index.d.ts +2 -8
- package/dist/cjs/services/documentStore/versioned/index.js +2 -0
- package/dist/cjs/tsconfig.without-specs.cjs.tsbuildinfo +1 -1
- package/dist/esm/misc/hashValue.d.ts +2 -3
- package/dist/esm/services/documentStore/dynamoEncoding.d.ts +10 -0
- package/dist/esm/services/documentStore/dynamoEncoding.js +45 -0
- package/dist/esm/services/documentStore/index.d.ts +14 -0
- package/dist/esm/services/documentStore/unversioned/dynamodb.d.ts +13 -0
- package/dist/esm/services/documentStore/unversioned/dynamodb.js +47 -0
- package/dist/esm/services/documentStore/unversioned/file-system.d.ts +15 -0
- package/dist/esm/services/documentStore/unversioned/file-system.js +51 -0
- package/dist/esm/services/documentStore/unversioned/index.d.ts +2 -0
- package/dist/esm/services/documentStore/unversioned/index.js +1 -0
- package/dist/esm/services/{versionedDocumentStore → documentStore/versioned}/dynamodb.d.ts +5 -7
- package/dist/esm/services/{versionedDocumentStore → documentStore/versioned}/dynamodb.js +4 -47
- package/dist/{cjs/services/versionedDocumentStore → esm/services/documentStore/versioned}/file-system.d.ts +5 -7
- package/dist/esm/services/{versionedDocumentStore → documentStore/versioned}/file-system.js +3 -3
- package/dist/esm/services/{versionedDocumentStore → documentStore/versioned}/index.d.ts +2 -8
- package/dist/esm/services/documentStore/versioned/index.js +1 -0
- package/dist/esm/tsconfig.without-specs.esm.tsbuildinfo +1 -1
- package/package.json +15 -5
- /package/dist/cjs/services/{versionedDocumentStore → documentStore}/index.js +0 -0
- /package/dist/esm/services/{versionedDocumentStore → documentStore}/index.js +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
declare type HashValue = string | number | boolean | null | HashCompoundValue;
|
|
2
|
-
declare type HashCompoundValue = Array<HashValue> | {
|
|
1
|
+
export declare type HashValue = string | number | boolean | null | HashCompoundValue;
|
|
2
|
+
export declare type HashCompoundValue = Array<HashValue> | {
|
|
3
3
|
[key: string]: HashValue;
|
|
4
4
|
};
|
|
5
5
|
/**
|
|
@@ -8,4 +8,3 @@ declare type HashCompoundValue = Array<HashValue> | {
|
|
|
8
8
|
* @example hashValue({someKey: 'someValue'})
|
|
9
9
|
*/
|
|
10
10
|
export declare const hashValue: (value: HashValue) => string;
|
|
11
|
-
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AttributeValue } from '@aws-sdk/client-dynamodb';
|
|
2
|
+
import { DocumentBaseType, DocumentBaseValueTypes } from '.';
|
|
3
|
+
export declare const encodeDynamoAttribute: (value: DocumentBaseValueTypes) => AttributeValue;
|
|
4
|
+
export declare const encodeDynamoDocument: (base: DocumentBaseType) => {
|
|
5
|
+
[k: string]: AttributeValue;
|
|
6
|
+
};
|
|
7
|
+
export declare const decodeDynamoAttribute: (value: AttributeValue) => DocumentBaseValueTypes;
|
|
8
|
+
export declare const decodeDynamoDocument: <T extends DocumentBaseType>(document: {
|
|
9
|
+
[key: string]: AttributeValue;
|
|
10
|
+
}) => T;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.decodeDynamoDocument = exports.decodeDynamoAttribute = exports.encodeDynamoDocument = exports.encodeDynamoAttribute = void 0;
|
|
4
|
+
const guards_1 = require("../../guards");
|
|
5
|
+
const encodeDynamoAttribute = (value) => {
|
|
6
|
+
if (typeof value === 'string') {
|
|
7
|
+
return { S: value };
|
|
8
|
+
}
|
|
9
|
+
if (typeof value === 'number') {
|
|
10
|
+
return { N: value.toString() };
|
|
11
|
+
}
|
|
12
|
+
if (typeof value === 'boolean') {
|
|
13
|
+
return { BOOL: value };
|
|
14
|
+
}
|
|
15
|
+
if (value === null) {
|
|
16
|
+
return { NULL: true };
|
|
17
|
+
}
|
|
18
|
+
if (value instanceof Array) {
|
|
19
|
+
return { L: value.map(exports.encodeDynamoAttribute) };
|
|
20
|
+
}
|
|
21
|
+
if ((0, guards_1.isPlainObject)(value)) {
|
|
22
|
+
return { M: (0, exports.encodeDynamoDocument)(value) };
|
|
23
|
+
}
|
|
24
|
+
throw new Error(`unknown attribute type ${typeof value} with value ${value}.`);
|
|
25
|
+
};
|
|
26
|
+
exports.encodeDynamoAttribute = encodeDynamoAttribute;
|
|
27
|
+
const encodeDynamoDocument = (base) => Object.fromEntries(Object.entries(base).map(([key, value]) => ([key, (0, exports.encodeDynamoAttribute)(value)])));
|
|
28
|
+
exports.encodeDynamoDocument = encodeDynamoDocument;
|
|
29
|
+
const decodeDynamoAttribute = (value) => {
|
|
30
|
+
if (value.S !== undefined) {
|
|
31
|
+
return value.S;
|
|
32
|
+
}
|
|
33
|
+
if (value.N !== undefined) {
|
|
34
|
+
return parseFloat(value.N);
|
|
35
|
+
}
|
|
36
|
+
if (value.BOOL !== undefined) {
|
|
37
|
+
return value.BOOL;
|
|
38
|
+
}
|
|
39
|
+
if (value.NULL !== undefined) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
if (value.L !== undefined) {
|
|
43
|
+
return value.L.map(exports.decodeDynamoAttribute);
|
|
44
|
+
}
|
|
45
|
+
if (value.M !== undefined) {
|
|
46
|
+
return (0, exports.decodeDynamoDocument)(value.M);
|
|
47
|
+
}
|
|
48
|
+
throw new Error(`unknown attribute type: ${JSON.stringify(value)}.`);
|
|
49
|
+
};
|
|
50
|
+
exports.decodeDynamoAttribute = decodeDynamoAttribute;
|
|
51
|
+
const decodeDynamoDocument = (document) => Object.fromEntries(Object.entries(document).map(([key, value]) => ([key, (0, exports.decodeDynamoAttribute)(value)])));
|
|
52
|
+
exports.decodeDynamoDocument = decodeDynamoDocument;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare type Config = {
|
|
2
|
+
tableName: string;
|
|
3
|
+
};
|
|
4
|
+
export declare type DocumentBaseMapType = {
|
|
5
|
+
[key: string]: DocumentBaseValueTypes;
|
|
6
|
+
};
|
|
7
|
+
export declare type DocumentBaseListType = DocumentBaseValueTypes[];
|
|
8
|
+
export declare type DocumentBaseValueTypes = number | boolean | string | null | DocumentBaseMapType | DocumentBaseListType;
|
|
9
|
+
export declare type DocumentBaseType = {
|
|
10
|
+
[key: string]: DocumentBaseValueTypes;
|
|
11
|
+
};
|
|
12
|
+
export declare type TDocument<T> = {
|
|
13
|
+
[k in keyof T]: DocumentBaseValueTypes;
|
|
14
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Config, TDocument } from '..';
|
|
2
|
+
import { ConfigProviderForConfig } from '../../../config';
|
|
3
|
+
interface Initializer<C> {
|
|
4
|
+
configSpace?: C;
|
|
5
|
+
}
|
|
6
|
+
export declare const dynamoUnversionedDocumentStore: <C extends string = "dynamodb">(initializer?: Initializer<C> | undefined) => <T extends TDocument<T>>() => (configProvider: { [key in C]: {
|
|
7
|
+
tableName: import("../../../config").ConfigValueProvider<string>;
|
|
8
|
+
}; }) => <K extends keyof T>(_: {}, hashKey: K) => {
|
|
9
|
+
loadAllDocumentsTheBadWay: () => Promise<T[]>;
|
|
10
|
+
getItem: (id: T[K]) => Promise<T | undefined>;
|
|
11
|
+
putItem: (item: T) => Promise<T>;
|
|
12
|
+
};
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dynamoUnversionedDocumentStore = void 0;
|
|
4
|
+
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
5
|
+
const __1 = require("../../..");
|
|
6
|
+
const config_1 = require("../../../config");
|
|
7
|
+
const guards_1 = require("../../../guards");
|
|
8
|
+
const dynamoEncoding_1 = require("../dynamoEncoding");
|
|
9
|
+
const dynamodb = (0, __1.once)(() => new client_dynamodb_1.DynamoDB({ apiVersion: '2012-08-10' }));
|
|
10
|
+
const dynamoUnversionedDocumentStore = (initializer) => () => (configProvider) => (_, hashKey) => {
|
|
11
|
+
const options = (0, guards_1.ifDefined)(initializer, {});
|
|
12
|
+
const tableName = (0, __1.once)(() => (0, config_1.resolveConfigValue)(configProvider[(0, guards_1.ifDefined)(options.configSpace, 'dynamodb')].tableName));
|
|
13
|
+
return {
|
|
14
|
+
loadAllDocumentsTheBadWay: async () => {
|
|
15
|
+
const loadAllResults = async (ExclusiveStartKey) => {
|
|
16
|
+
var _a;
|
|
17
|
+
const cmd = new client_dynamodb_1.ScanCommand({ TableName: await tableName(), ExclusiveStartKey });
|
|
18
|
+
const result = await dynamodb().send(cmd);
|
|
19
|
+
const resultItems = ((_a = result.Items) === null || _a === void 0 ? void 0 : _a.map(dynamoEncoding_1.decodeDynamoDocument)) || [];
|
|
20
|
+
if (result.LastEvaluatedKey) {
|
|
21
|
+
return [...resultItems, ...await loadAllResults(result.LastEvaluatedKey)];
|
|
22
|
+
}
|
|
23
|
+
return resultItems;
|
|
24
|
+
};
|
|
25
|
+
return loadAllResults();
|
|
26
|
+
},
|
|
27
|
+
getItem: async (id) => {
|
|
28
|
+
const cmd = new client_dynamodb_1.QueryCommand({
|
|
29
|
+
TableName: await tableName(),
|
|
30
|
+
KeyConditionExpression: '#hk = :hkv',
|
|
31
|
+
ExpressionAttributeNames: { '#hk': hashKey.toString() },
|
|
32
|
+
ExpressionAttributeValues: { ':hkv': (0, dynamoEncoding_1.encodeDynamoAttribute)(id) },
|
|
33
|
+
ScanIndexForward: false,
|
|
34
|
+
Limit: 1
|
|
35
|
+
});
|
|
36
|
+
return dynamodb().send(cmd).then(result => {
|
|
37
|
+
var _a;
|
|
38
|
+
return (_a = result.Items) === null || _a === void 0 ? void 0 : _a.map(dynamoEncoding_1.decodeDynamoDocument)[0];
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
/* saves a new version of a document with the given data */
|
|
42
|
+
putItem: async (item) => {
|
|
43
|
+
const cmd = new client_dynamodb_1.PutItemCommand({
|
|
44
|
+
TableName: await tableName(),
|
|
45
|
+
Item: (0, dynamoEncoding_1.encodeDynamoDocument)(item),
|
|
46
|
+
});
|
|
47
|
+
return dynamodb().send(cmd).then(() => item);
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
exports.dynamoUnversionedDocumentStore = dynamoUnversionedDocumentStore;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Config, TDocument } from '..';
|
|
2
|
+
import { ConfigProviderForConfig } from '../../../config';
|
|
3
|
+
interface Initializer<C> {
|
|
4
|
+
dataDir: string;
|
|
5
|
+
fs?: Pick<typeof import('fs'), 'mkdir' | 'readdir' | 'readFile' | 'writeFile'>;
|
|
6
|
+
configSpace?: C;
|
|
7
|
+
}
|
|
8
|
+
export declare const fileSystemUnversionedDocumentStore: <C extends string = "fileSystem">(initializer: Initializer<C>) => <T extends TDocument<T>>() => (configProvider: { [key in C]: {
|
|
9
|
+
tableName: import("../../../config").ConfigValueProvider<string>;
|
|
10
|
+
}; }) => <K extends keyof T>(_: {}, hashKey: K) => {
|
|
11
|
+
loadAllDocumentsTheBadWay: () => Promise<T[]>;
|
|
12
|
+
getItem: (id: T[K]) => Promise<T | undefined>;
|
|
13
|
+
putItem: (item: T) => Promise<T>;
|
|
14
|
+
};
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.fileSystemUnversionedDocumentStore = void 0;
|
|
30
|
+
const fsModule = __importStar(require("fs"));
|
|
31
|
+
const path_1 = __importDefault(require("path"));
|
|
32
|
+
const __1 = require("../../..");
|
|
33
|
+
const config_1 = require("../../../config");
|
|
34
|
+
const guards_1 = require("../../../guards");
|
|
35
|
+
const fileSystemUnversionedDocumentStore = (initializer) => () => (configProvider) => (_, hashKey) => {
|
|
36
|
+
const tableName = (0, config_1.resolveConfigValue)(configProvider[initializer.configSpace || 'fileSystem'].tableName);
|
|
37
|
+
const tablePath = tableName.then((table) => path_1.default.join(initializer.dataDir, table));
|
|
38
|
+
const { mkdir, readdir, readFile, writeFile } = (0, guards_1.ifDefined)(initializer.fs, fsModule);
|
|
39
|
+
const mkTableDir = new Promise((resolve, reject) => tablePath.then((path) => mkdir(path, { recursive: true }, (err) => err ? reject(err) : resolve())));
|
|
40
|
+
const hashFilename = (value) => `${(0, __1.hashValue)(value)}.json`;
|
|
41
|
+
const filePath = async (filename) => path_1.default.join(await tablePath, filename);
|
|
42
|
+
const load = async (filename) => {
|
|
43
|
+
const path = await filePath(filename);
|
|
44
|
+
await mkTableDir;
|
|
45
|
+
return new Promise((resolve, reject) => {
|
|
46
|
+
readFile(path, (err, readData) => {
|
|
47
|
+
if (err) {
|
|
48
|
+
err.code === 'ENOENT' ? resolve(undefined) : reject(err);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
try {
|
|
52
|
+
const data = JSON.parse(readData.toString());
|
|
53
|
+
typeof data === 'object' ? resolve(data) : reject(new Error('unexpected non-object JSON'));
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
reject(err);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
loadAllDocumentsTheBadWay: async () => {
|
|
64
|
+
const path = await tablePath;
|
|
65
|
+
await mkTableDir;
|
|
66
|
+
return new Promise((resolve, reject) => readdir(path, (err, files) => err ?
|
|
67
|
+
reject(err) :
|
|
68
|
+
Promise.all(files.map((file) => load(file)))
|
|
69
|
+
.then((allData) => resolve(allData.filter(guards_1.isDefined)), (err) => reject(err))));
|
|
70
|
+
},
|
|
71
|
+
getItem: (id) => load(hashFilename(id)),
|
|
72
|
+
putItem: async (item) => {
|
|
73
|
+
const path = await filePath(hashFilename(item[hashKey]));
|
|
74
|
+
await mkTableDir;
|
|
75
|
+
return new Promise((resolve, reject) => {
|
|
76
|
+
writeFile(path, JSON.stringify(item, null, 2), (err) => err ? reject(err) : resolve(item));
|
|
77
|
+
});
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
exports.fileSystemUnversionedDocumentStore = fileSystemUnversionedDocumentStore;
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
tableName: string;
|
|
5
|
-
};
|
|
1
|
+
import { Config } from '..';
|
|
2
|
+
import { ConfigProviderForConfig } from '../../../config';
|
|
3
|
+
import { VersionedDocumentAuthor, VersionedTDocument } from '.';
|
|
6
4
|
interface Initializer<C> {
|
|
7
5
|
configSpace?: C;
|
|
8
6
|
}
|
|
9
|
-
export declare const dynamoVersionedDocumentStore: <C extends string = "dynamodb">(initializer?: Initializer<C> | undefined) => <T extends
|
|
10
|
-
tableName: import("
|
|
7
|
+
export declare const dynamoVersionedDocumentStore: <C extends string = "dynamodb">(initializer?: Initializer<C> | undefined) => <T extends VersionedTDocument<T>>() => (configProvider: { [key in C]: {
|
|
8
|
+
tableName: import("../../../config").ConfigValueProvider<string>;
|
|
11
9
|
}; }) => <K extends keyof T, A extends ((...a: any[]) => Promise<VersionedDocumentAuthor>) | undefined>(_: {}, hashKey: K, getAuthor: A) => {
|
|
12
10
|
loadAllDocumentsTheBadWay: () => Promise<T[]>;
|
|
13
11
|
getVersions: (id: T[K], startVersion?: number | undefined) => Promise<{
|
|
@@ -2,54 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.dynamoVersionedDocumentStore = void 0;
|
|
4
4
|
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
5
|
-
const __1 = require("
|
|
6
|
-
const config_1 = require("
|
|
7
|
-
const guards_1 = require("
|
|
5
|
+
const __1 = require("../../..");
|
|
6
|
+
const config_1 = require("../../../config");
|
|
7
|
+
const guards_1 = require("../../../guards");
|
|
8
|
+
const dynamoEncoding_1 = require("../dynamoEncoding");
|
|
8
9
|
const dynamodb = (0, __1.once)(() => new client_dynamodb_1.DynamoDB({ apiVersion: '2012-08-10' }));
|
|
9
|
-
const encodeDynamoAttribute = (value) => {
|
|
10
|
-
if (typeof value === 'string') {
|
|
11
|
-
return { S: value };
|
|
12
|
-
}
|
|
13
|
-
if (typeof value === 'number') {
|
|
14
|
-
return { N: value.toString() };
|
|
15
|
-
}
|
|
16
|
-
if (typeof value === 'boolean') {
|
|
17
|
-
return { BOOL: value };
|
|
18
|
-
}
|
|
19
|
-
if (value === null) {
|
|
20
|
-
return { NULL: true };
|
|
21
|
-
}
|
|
22
|
-
if (value instanceof Array) {
|
|
23
|
-
return { L: value.map(encodeDynamoAttribute) };
|
|
24
|
-
}
|
|
25
|
-
if ((0, guards_1.isPlainObject)(value)) {
|
|
26
|
-
return { M: encodeDynamoDocument(value) };
|
|
27
|
-
}
|
|
28
|
-
throw new Error(`unknown attribute type ${typeof value} with value ${value}.`);
|
|
29
|
-
};
|
|
30
|
-
const encodeDynamoDocument = (base) => Object.fromEntries(Object.entries(base).map(([key, value]) => ([key, encodeDynamoAttribute(value)])));
|
|
31
|
-
const decodeDynamoAttribute = (value) => {
|
|
32
|
-
if (value.S !== undefined) {
|
|
33
|
-
return value.S;
|
|
34
|
-
}
|
|
35
|
-
if (value.N !== undefined) {
|
|
36
|
-
return parseFloat(value.N);
|
|
37
|
-
}
|
|
38
|
-
if (value.BOOL !== undefined) {
|
|
39
|
-
return value.BOOL;
|
|
40
|
-
}
|
|
41
|
-
if (value.NULL !== undefined) {
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
if (value.L !== undefined) {
|
|
45
|
-
return value.L.map(decodeDynamoAttribute);
|
|
46
|
-
}
|
|
47
|
-
if (value.M !== undefined) {
|
|
48
|
-
return decodeDynamoDocument(value.M);
|
|
49
|
-
}
|
|
50
|
-
throw new Error(`unknown attribute type: ${JSON.stringify(value)}.`);
|
|
51
|
-
};
|
|
52
|
-
const decodeDynamoDocument = (document) => Object.fromEntries(Object.entries(document).map(([key, value]) => ([key, decodeDynamoAttribute(value)])));
|
|
53
10
|
// i'm not really excited about getAuthor being required, but ts is getting confused about the type when unspecified
|
|
54
11
|
const dynamoVersionedDocumentStore = (initializer) => () => (configProvider) => (_, hashKey, getAuthor) => {
|
|
55
12
|
const options = (0, guards_1.ifDefined)(initializer, {});
|
|
@@ -60,7 +17,7 @@ const dynamoVersionedDocumentStore = (initializer) => () => (configProvider) =>
|
|
|
60
17
|
var _a;
|
|
61
18
|
const cmd = new client_dynamodb_1.ScanCommand({ TableName: await tableName(), ExclusiveStartKey });
|
|
62
19
|
const result = await dynamodb().send(cmd);
|
|
63
|
-
const resultItems = ((_a = result.Items) === null || _a === void 0 ? void 0 : _a.map(decodeDynamoDocument)) || [];
|
|
20
|
+
const resultItems = ((_a = result.Items) === null || _a === void 0 ? void 0 : _a.map(dynamoEncoding_1.decodeDynamoDocument)) || [];
|
|
64
21
|
if (result.LastEvaluatedKey) {
|
|
65
22
|
return [...resultItems, ...await loadAllResults(result.LastEvaluatedKey)];
|
|
66
23
|
}
|
|
@@ -80,14 +37,14 @@ const dynamoVersionedDocumentStore = (initializer) => () => (configProvider) =>
|
|
|
80
37
|
TableName: await tableName(),
|
|
81
38
|
KeyConditionExpression: '#hk = :hkv',
|
|
82
39
|
ExpressionAttributeValues: {
|
|
83
|
-
':hkv': encodeDynamoAttribute(id)
|
|
40
|
+
':hkv': (0, dynamoEncoding_1.encodeDynamoAttribute)(id)
|
|
84
41
|
},
|
|
85
42
|
ExpressionAttributeNames: {
|
|
86
43
|
'#hk': hashKey.toString()
|
|
87
44
|
},
|
|
88
45
|
...(startVersion
|
|
89
46
|
? { ExclusiveStartKey: {
|
|
90
|
-
[hashKey]: encodeDynamoAttribute(id),
|
|
47
|
+
[hashKey]: (0, dynamoEncoding_1.encodeDynamoAttribute)(id),
|
|
91
48
|
timestamp: { N: startVersion.toString() }
|
|
92
49
|
} }
|
|
93
50
|
: {}),
|
|
@@ -95,13 +52,13 @@ const dynamoVersionedDocumentStore = (initializer) => () => (configProvider) =>
|
|
|
95
52
|
});
|
|
96
53
|
return dynamodb().send(cmd).then(result => {
|
|
97
54
|
var _a;
|
|
98
|
-
const items = (_a = result.Items) === null || _a === void 0 ? void 0 : _a.map(decodeDynamoDocument);
|
|
55
|
+
const items = (_a = result.Items) === null || _a === void 0 ? void 0 : _a.map(dynamoEncoding_1.decodeDynamoDocument);
|
|
99
56
|
if (!items || items.length === 0) {
|
|
100
57
|
return undefined;
|
|
101
58
|
}
|
|
102
59
|
return {
|
|
103
60
|
items,
|
|
104
|
-
nextPageToken: result.LastEvaluatedKey ? decodeDynamoDocument(result.LastEvaluatedKey).timestamp : undefined
|
|
61
|
+
nextPageToken: result.LastEvaluatedKey ? (0, dynamoEncoding_1.decodeDynamoDocument)(result.LastEvaluatedKey).timestamp : undefined
|
|
105
62
|
};
|
|
106
63
|
});
|
|
107
64
|
},
|
|
@@ -111,12 +68,12 @@ const dynamoVersionedDocumentStore = (initializer) => () => (configProvider) =>
|
|
|
111
68
|
'#hk': hashKey.toString()
|
|
112
69
|
};
|
|
113
70
|
const expressionAttributeValues = {
|
|
114
|
-
':hkv': encodeDynamoAttribute(id)
|
|
71
|
+
':hkv': (0, dynamoEncoding_1.encodeDynamoAttribute)(id)
|
|
115
72
|
};
|
|
116
73
|
if (timestamp) {
|
|
117
74
|
keyConditionExpression += ' and #ts = :tsv';
|
|
118
75
|
expressionAttributeNames['#ts'] = 'timestamp';
|
|
119
|
-
expressionAttributeValues[':tsv'] = encodeDynamoAttribute(timestamp);
|
|
76
|
+
expressionAttributeValues[':tsv'] = (0, dynamoEncoding_1.encodeDynamoAttribute)(timestamp);
|
|
120
77
|
}
|
|
121
78
|
const cmd = new client_dynamodb_1.QueryCommand({
|
|
122
79
|
TableName: await tableName(),
|
|
@@ -128,7 +85,7 @@ const dynamoVersionedDocumentStore = (initializer) => () => (configProvider) =>
|
|
|
128
85
|
});
|
|
129
86
|
return dynamodb().send(cmd).then(result => {
|
|
130
87
|
var _a;
|
|
131
|
-
return (_a = result.Items) === null || _a === void 0 ? void 0 : _a.map(decodeDynamoDocument)[0];
|
|
88
|
+
return (_a = result.Items) === null || _a === void 0 ? void 0 : _a.map(dynamoEncoding_1.decodeDynamoDocument)[0];
|
|
132
89
|
});
|
|
133
90
|
},
|
|
134
91
|
/* prepares a new version of a document with the given data, then allows some additional
|
|
@@ -150,7 +107,7 @@ const dynamoVersionedDocumentStore = (initializer) => () => (configProvider) =>
|
|
|
150
107
|
};
|
|
151
108
|
const cmd = new client_dynamodb_1.PutItemCommand({
|
|
152
109
|
TableName: await tableName(),
|
|
153
|
-
Item: encodeDynamoDocument(document),
|
|
110
|
+
Item: (0, dynamoEncoding_1.encodeDynamoDocument)(document),
|
|
154
111
|
});
|
|
155
112
|
return dynamodb().send(cmd)
|
|
156
113
|
.then(() => document);
|
|
@@ -168,7 +125,7 @@ const dynamoVersionedDocumentStore = (initializer) => () => (configProvider) =>
|
|
|
168
125
|
};
|
|
169
126
|
const cmd = new client_dynamodb_1.PutItemCommand({
|
|
170
127
|
TableName: await tableName(),
|
|
171
|
-
Item: encodeDynamoDocument(document),
|
|
128
|
+
Item: (0, dynamoEncoding_1.encodeDynamoDocument)(document),
|
|
172
129
|
});
|
|
173
130
|
return dynamodb().send(cmd)
|
|
174
131
|
.then(() => document);
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
tableName: string;
|
|
5
|
-
};
|
|
1
|
+
import { Config } from '..';
|
|
2
|
+
import { ConfigProviderForConfig } from '../../../config';
|
|
3
|
+
import { VersionedDocumentAuthor, VersionedTDocument } from '.';
|
|
6
4
|
interface Initializer<C> {
|
|
7
5
|
dataDir: string;
|
|
8
6
|
fs?: Pick<typeof import('fs'), 'readFile' | 'writeFile'>;
|
|
9
7
|
configSpace?: C;
|
|
10
8
|
}
|
|
11
|
-
export declare const fileSystemVersionedDocumentStore: <C extends string = "fileSystem">(initializer: Initializer<C>) => <T extends
|
|
12
|
-
tableName: import("
|
|
9
|
+
export declare const fileSystemVersionedDocumentStore: <C extends string = "fileSystem">(initializer: Initializer<C>) => <T extends VersionedTDocument<T>>() => (configProvider: { [key in C]: {
|
|
10
|
+
tableName: import("../../../config").ConfigValueProvider<string>;
|
|
13
11
|
}; }) => <K extends keyof T, A extends ((...a: any[]) => Promise<VersionedDocumentAuthor>) | undefined>(_: {}, hashKey: K, getAuthor: A) => {
|
|
14
12
|
loadAllDocumentsTheBadWay: () => Promise<T[]>;
|
|
15
13
|
getVersions: (id: T[K], startVersion?: number | undefined) => Promise<{
|
|
@@ -29,9 +29,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
exports.fileSystemVersionedDocumentStore = void 0;
|
|
30
30
|
const fsModule = __importStar(require("fs"));
|
|
31
31
|
const path_1 = __importDefault(require("path"));
|
|
32
|
-
const __1 = require("
|
|
33
|
-
const config_1 = require("
|
|
34
|
-
const guards_1 = require("
|
|
32
|
+
const __1 = require("../../..");
|
|
33
|
+
const config_1 = require("../../../config");
|
|
34
|
+
const guards_1 = require("../../../guards");
|
|
35
35
|
const PAGE_LIMIT = 5;
|
|
36
36
|
const fileSystemVersionedDocumentStore = (initializer) => () => (configProvider) => (_, hashKey, getAuthor) => {
|
|
37
37
|
const tableName = (0, config_1.resolveConfigValue)(configProvider[initializer.configSpace || 'fileSystem'].tableName);
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
+
import { TDocument } from '..';
|
|
1
2
|
import { dynamoVersionedDocumentStore } from './dynamodb';
|
|
2
|
-
export declare type DocumentBaseValueTypes = number | boolean | string | null | DocumentBaseMapType | DocumentBaseListType;
|
|
3
|
-
export declare type DocumentBaseMapType = {
|
|
4
|
-
[key: string]: DocumentBaseValueTypes;
|
|
5
|
-
};
|
|
6
|
-
export declare type DocumentBaseListType = DocumentBaseValueTypes[];
|
|
7
3
|
export declare type VersionedDocumentAuthor = {
|
|
8
4
|
type: 'user';
|
|
9
5
|
uuid: string;
|
|
@@ -17,7 +13,5 @@ export declare type VersionedDocumentRequiredFields = {
|
|
|
17
13
|
timestamp: number;
|
|
18
14
|
author: VersionedDocumentAuthor;
|
|
19
15
|
};
|
|
20
|
-
export declare type
|
|
21
|
-
[k in keyof T]: DocumentBaseValueTypes;
|
|
22
|
-
} & VersionedDocumentRequiredFields;
|
|
16
|
+
export declare type VersionedTDocument<T> = TDocument<T> & VersionedDocumentRequiredFields;
|
|
23
17
|
export declare type VersionedDocumentStoreCreator = typeof dynamoVersionedDocumentStore;
|