@acodeninja/persist 3.0.0-next.12 → 3.0.0-next.13
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/README.md +58 -4
- package/docs/code-quirks.md +6 -6
- package/docs/defining-models.md +61 -0
- package/docs/future-interface.md +29 -0
- package/docs/http.openapi.yml +138 -0
- package/docs/{model-property-types.md → model-properties.md} +37 -35
- package/docs/models-as-properties.md +40 -40
- package/docs/search-queries.md +3 -5
- package/docs/storage-engines.md +15 -32
- package/docs/structured-queries.md +56 -45
- package/docs/transactions.md +6 -7
- package/exports/storage/http.js +3 -0
- package/exports/storage/s3.js +3 -0
- package/jest.config.cjs +8 -12
- package/package.json +2 -2
- package/src/Connection.js +610 -0
- package/src/Persist.js +27 -30
- package/src/Schema.js +166 -0
- package/src/{Query.js → data/FindIndex.js} +37 -22
- package/src/{type → data}/Model.js +14 -30
- package/src/data/Property.js +19 -0
- package/src/data/SearchIndex.js +19 -4
- package/src/{type/complex → data/properties}/ArrayType.js +1 -1
- package/src/{type/simple → data/properties}/BooleanType.js +1 -1
- package/src/{type/complex → data/properties}/CustomType.js +1 -1
- package/src/{type/simple → data/properties}/DateType.js +1 -1
- package/src/{type/simple → data/properties}/NumberType.js +1 -1
- package/src/{type/resolved → data/properties}/ResolvedType.js +3 -2
- package/src/{type/simple → data/properties}/StringType.js +1 -1
- package/src/engine/storage/HTTPStorageEngine.js +149 -253
- package/src/engine/storage/S3StorageEngine.js +108 -195
- package/src/engine/storage/StorageEngine.js +114 -550
- package/exports/engine/storage/file.js +0 -3
- package/exports/engine/storage/http.js +0 -3
- package/exports/engine/storage/s3.js +0 -3
- package/src/SchemaCompiler.js +0 -196
- package/src/Transactions.js +0 -145
- package/src/engine/StorageEngine.js +0 -517
- package/src/engine/storage/FileStorageEngine.js +0 -213
- package/src/type/index.js +0 -32
- /package/src/{type/resolved → data/properties}/SlugType.js +0 -0
- /package/src/{type → data/properties}/Type.js +0 -0
@@ -1,213 +0,0 @@
|
|
1
|
-
import StorageEngine, { EngineError, MissConfiguredError } from './StorageEngine.js';
|
2
|
-
import { dirname, join } from 'node:path';
|
3
|
-
import fs from 'node:fs/promises';
|
4
|
-
|
5
|
-
/**
|
6
|
-
* Custom error class for FileStorageEngine-related errors.
|
7
|
-
* Extends the base `EngineError` class.
|
8
|
-
*/
|
9
|
-
class FileStorageEngineError extends EngineError {}
|
10
|
-
|
11
|
-
/**
|
12
|
-
* Error thrown when writing to a file fails in `FileStorageEngine`.
|
13
|
-
* Extends the `FileStorageEngineError` class.
|
14
|
-
*/
|
15
|
-
class FailedWriteFileStorageEngineError extends FileStorageEngineError {}
|
16
|
-
|
17
|
-
/**
|
18
|
-
* `FileStorageEngine` class extends the base `StorageEngine` class to implement
|
19
|
-
* file system-based storage and retrieval of model data.
|
20
|
-
*
|
21
|
-
* @class FileStorageEngine
|
22
|
-
* @extends StorageEngine
|
23
|
-
*/
|
24
|
-
class FileStorageEngine extends StorageEngine {
|
25
|
-
/**
|
26
|
-
* Configures the FileStorageEngine with a given configuration object.
|
27
|
-
* Adds default `filesystem` configuration if not provided.
|
28
|
-
*
|
29
|
-
* @param {Object} configuration - Configuration settings for FileStorageEngine.
|
30
|
-
* @param {Object} [configuration.filesystem] - Custom filesystem module (default: Node.js fs/promises).
|
31
|
-
* @param {Object} [configuration.path] - The absolute path on the filesystem to write models to.
|
32
|
-
* @returns {FileStorageEngine} A configured instance of FileStorageEngine.
|
33
|
-
*/
|
34
|
-
static configure(configuration) {
|
35
|
-
if (!configuration.filesystem) {
|
36
|
-
configuration.filesystem = fs;
|
37
|
-
}
|
38
|
-
return super.configure(configuration);
|
39
|
-
}
|
40
|
-
|
41
|
-
/**
|
42
|
-
* Checks if the FileStorageEngine has been configured correctly.
|
43
|
-
* Ensures that `path` and `filesystem` settings are present.
|
44
|
-
*
|
45
|
-
* @throws {MissConfiguredError} Throws if required configuration is missing.
|
46
|
-
*/
|
47
|
-
static checkConfiguration() {
|
48
|
-
if (!this.configuration?.path || !this.configuration?.filesystem) {
|
49
|
-
throw new MissConfiguredError(this.configuration);
|
50
|
-
}
|
51
|
-
}
|
52
|
-
|
53
|
-
/**
|
54
|
-
* Retrieves a model by its ID from the file system.
|
55
|
-
*
|
56
|
-
* @param {string} id - The ID of the model to retrieve.
|
57
|
-
* @returns {Promise<Object>} The parsed model data.
|
58
|
-
* @throws {Error} Throws if the file cannot be read or parsed.
|
59
|
-
*/
|
60
|
-
static getById(id) {
|
61
|
-
return this.configuration.filesystem
|
62
|
-
.readFile(join(this.configuration.path, `${id}.json`))
|
63
|
-
.then((b) => b.toString())
|
64
|
-
.then(JSON.parse);
|
65
|
-
}
|
66
|
-
|
67
|
-
/**
|
68
|
-
* Deletes a model by its ID from the file system.
|
69
|
-
*
|
70
|
-
* @param {string} id - The ID of the model to delete.
|
71
|
-
* @returns {Promise<void>} Resolves when the model has been deleted.
|
72
|
-
* @throws {Error} Throws if the file cannot be deleted.
|
73
|
-
*/
|
74
|
-
static deleteById(id) {
|
75
|
-
return this.configuration.filesystem.rm(join(this.configuration.path, `${id}.json`));
|
76
|
-
}
|
77
|
-
|
78
|
-
/**
|
79
|
-
* Retrieves the index for a given model from the file system.
|
80
|
-
*
|
81
|
-
* @param {Model.constructor?} model - The model for which the index is retrieved.
|
82
|
-
* @returns {Promise<Object>} The parsed index data.
|
83
|
-
* @throws {Error} Throws if the file cannot be read.
|
84
|
-
*/
|
85
|
-
static getIndex(model) {
|
86
|
-
return this.configuration.filesystem
|
87
|
-
.readFile(join(this.configuration.path, model.toString(), '_index.json'))
|
88
|
-
.then((b) => b.toString())
|
89
|
-
.catch(() => '{}')
|
90
|
-
.then(JSON.parse);
|
91
|
-
}
|
92
|
-
|
93
|
-
/**
|
94
|
-
* Saves a model to the file system.
|
95
|
-
*
|
96
|
-
* @param {Model} model - The model to save.
|
97
|
-
* @throws {FailedWriteFileStorageEngineError} Throws if the model cannot be written to the file system.
|
98
|
-
*/
|
99
|
-
static async putModel(model) {
|
100
|
-
const filePath = join(this.configuration.path, `${model.id}.json`);
|
101
|
-
try {
|
102
|
-
await this.configuration.filesystem.mkdir(dirname(filePath), { recursive: true });
|
103
|
-
await this.configuration.filesystem.writeFile(filePath, JSON.stringify(model.toData()));
|
104
|
-
} catch (error) {
|
105
|
-
throw new FailedWriteFileStorageEngineError(`Failed to put file://${filePath}`, error);
|
106
|
-
}
|
107
|
-
}
|
108
|
-
|
109
|
-
/**
|
110
|
-
* Saves the index for multiple models to the file system.
|
111
|
-
*
|
112
|
-
* @param {Object} index - An object where keys are locations and values are key value pairs of models and their ids.
|
113
|
-
* @throws {FailedWriteFileStorageEngineError} Throws if the index cannot be written to the file system.
|
114
|
-
*/
|
115
|
-
static async putIndex(index) {
|
116
|
-
/**
|
117
|
-
* Process an index of models
|
118
|
-
* @param {string} location
|
119
|
-
* @param {Array<Model>} models
|
120
|
-
* @throws FailedWriteFileStorageEngineError
|
121
|
-
* @return {Promise<void>}
|
122
|
-
*/
|
123
|
-
const processIndex = async (location, models) => {
|
124
|
-
const filePath = join(this.configuration.path, location, '_index.json');
|
125
|
-
const currentIndex = JSON.parse((await this.configuration.filesystem.readFile(filePath).catch(() => '{}')).toString());
|
126
|
-
|
127
|
-
try {
|
128
|
-
await this.configuration.filesystem.writeFile(filePath, JSON.stringify({
|
129
|
-
...currentIndex,
|
130
|
-
...Object.fromEntries(
|
131
|
-
Object.entries(models).map(([k, v]) => [k, v?.toIndexData?.() || v]),
|
132
|
-
),
|
133
|
-
}));
|
134
|
-
} catch (error) {
|
135
|
-
throw new FailedWriteFileStorageEngineError(`Failed to put file://${filePath}`, error);
|
136
|
-
}
|
137
|
-
};
|
138
|
-
|
139
|
-
for (const [location, models] of Object.entries(index)) {
|
140
|
-
await processIndex(location, models);
|
141
|
-
}
|
142
|
-
|
143
|
-
await processIndex('', Object.values(index).reduce((accumulator, currentValue) => {
|
144
|
-
Object.keys(currentValue).forEach(key => {
|
145
|
-
accumulator[key] = currentValue[key];
|
146
|
-
});
|
147
|
-
return accumulator;
|
148
|
-
}, {}));
|
149
|
-
}
|
150
|
-
|
151
|
-
/**
|
152
|
-
* Retrieves the compiled search index for a model from the file system.
|
153
|
-
*
|
154
|
-
* @param {Model.constructor} model - The model for which the search index is retrieved.
|
155
|
-
* @returns {Promise<Object>} The parsed compiled search index.
|
156
|
-
* @throws {Error} Throws if the file cannot be read.
|
157
|
-
*/
|
158
|
-
static getSearchIndexCompiled(model) {
|
159
|
-
return this.configuration.filesystem
|
160
|
-
.readFile(join(this.configuration.path, model.toString(), '_search_index.json'))
|
161
|
-
.then((b) => b.toString())
|
162
|
-
.then(JSON.parse);
|
163
|
-
}
|
164
|
-
|
165
|
-
/**
|
166
|
-
* Retrieves the raw search index for a model from the file system.
|
167
|
-
*
|
168
|
-
* @param {Model.constructor} model - The model for which the raw search index is retrieved.
|
169
|
-
* @returns {Promise<Object>} The parsed raw search index.
|
170
|
-
* @throws {Error} Throws if the file cannot be read.
|
171
|
-
*/
|
172
|
-
static getSearchIndexRaw(model) {
|
173
|
-
return this.configuration.filesystem
|
174
|
-
.readFile(join(this.configuration.path, model.toString(), '_search_index_raw.json'))
|
175
|
-
.then((b) => b.toString())
|
176
|
-
.then(JSON.parse)
|
177
|
-
.catch(() => ({}));
|
178
|
-
}
|
179
|
-
|
180
|
-
/**
|
181
|
-
* Saves the compiled search index for a model to the file system.
|
182
|
-
*
|
183
|
-
* @param {Model.constructor} model - The model for which the compiled search index is saved.
|
184
|
-
* @param {Object} compiledIndex - The compiled search index to save.
|
185
|
-
* @throws {FailedWriteFileStorageEngineError} Throws if the compiled index cannot be written to the file system.
|
186
|
-
*/
|
187
|
-
static async putSearchIndexCompiled(model, compiledIndex) {
|
188
|
-
const filePath = join(this.configuration.path, model.toString(), '_search_index.json');
|
189
|
-
try {
|
190
|
-
await this.configuration.filesystem.writeFile(filePath, JSON.stringify(compiledIndex));
|
191
|
-
} catch (error) {
|
192
|
-
throw new FailedWriteFileStorageEngineError(`Failed to put file://${filePath}`, error);
|
193
|
-
}
|
194
|
-
}
|
195
|
-
|
196
|
-
/**
|
197
|
-
* Saves the raw search index for a model to the file system.
|
198
|
-
*
|
199
|
-
* @param {Model.constructor} model - The model for which the raw search index is saved.
|
200
|
-
* @param {Object} rawIndex - The raw search index to save.
|
201
|
-
* @throws {FailedWriteFileStorageEngineError} Throws if the raw index cannot be written to the file system.
|
202
|
-
*/
|
203
|
-
static async putSearchIndexRaw(model, rawIndex) {
|
204
|
-
const filePath = join(this.configuration.path, model.toString(), '_search_index_raw.json');
|
205
|
-
try {
|
206
|
-
await this.configuration.filesystem.writeFile(filePath, JSON.stringify(rawIndex));
|
207
|
-
} catch (error) {
|
208
|
-
throw new FailedWriteFileStorageEngineError(`Failed to put file://${filePath}`, error);
|
209
|
-
}
|
210
|
-
}
|
211
|
-
}
|
212
|
-
|
213
|
-
export default FileStorageEngine;
|
package/src/type/index.js
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
import ArrayType from './complex/ArrayType.js';
|
2
|
-
import BooleanType from './simple/BooleanType.js';
|
3
|
-
import CustomType from './complex/CustomType.js';
|
4
|
-
import DateType from './simple/DateType.js';
|
5
|
-
import Model from './Model.js';
|
6
|
-
import NumberType from './simple/NumberType.js';
|
7
|
-
import SlugType from './resolved/SlugType.js';
|
8
|
-
import StringType from './simple/StringType.js';
|
9
|
-
|
10
|
-
/**
|
11
|
-
* @class Type
|
12
|
-
* @property {StringType} String
|
13
|
-
* @property {NumberType} Number
|
14
|
-
* @property {BooleanType} Boolean
|
15
|
-
* @property {DateType} Date
|
16
|
-
* @property {ArrayType} Array
|
17
|
-
* @property {CustomType} Custom
|
18
|
-
* @property {{Slug: SlugType}} Resolved
|
19
|
-
* @property {Model} Model
|
20
|
-
*/
|
21
|
-
class Type {
|
22
|
-
static Model = Model;
|
23
|
-
static String = StringType;
|
24
|
-
static Number = NumberType;
|
25
|
-
static Boolean = BooleanType;
|
26
|
-
static Date = DateType;
|
27
|
-
static Array = ArrayType;
|
28
|
-
static Custom = CustomType;
|
29
|
-
static Resolved = {Slug: SlugType};
|
30
|
-
}
|
31
|
-
|
32
|
-
export default Type;
|
File without changes
|
File without changes
|