@sprucelabs/data-stores 26.1.1 → 26.1.3

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.
@@ -1,5 +1,5 @@
1
1
  import AbstractMutexer from '../mutexers/AbstractMutexer';
2
- import { Database } from '../types/database.types';
2
+ import { CreateOptions, Database } from '../types/database.types';
3
3
  import { QueryOptions } from '../types/query.types';
4
4
  export default class NeDbDatabase extends AbstractMutexer implements Database {
5
5
  private collections;
@@ -17,8 +17,8 @@ export default class NeDbDatabase extends AbstractMutexer implements Database {
17
17
  private normalizeRecord;
18
18
  private handlePlaceholders;
19
19
  count(collection: string, query?: Record<string, any>): Promise<number>;
20
- createOne(collection: string, values: Record<string, any>): Promise<Record<string, any>>;
21
- create(collection: string, values: Record<string, any>[]): Promise<Record<string, any>[]>;
20
+ createOne(collection: string, values: Record<string, any>, options?: CreateOptions): Promise<Record<string, any>>;
21
+ create(collection: string, values: Record<string, any>[], options?: CreateOptions): Promise<Record<string, any>[]>;
22
22
  private loadCollection;
23
23
  dropCollection(name: string): Promise<void>;
24
24
  dropDatabase(): Promise<void>;
@@ -80,10 +80,11 @@ class NeDbDatabase extends AbstractMutexer_1.default {
80
80
  isConnected() {
81
81
  return this._isConnected;
82
82
  }
83
- normalizeRecord(record) {
83
+ normalizeRecord(record, options) {
84
84
  const { _id } = record, rest = __rest(record, ["_id"]);
85
85
  let values = this.handlePlaceholders(rest, null, (val) => val === null || val === NULL_PLACEHOLDER);
86
- if (!_id) {
86
+ const { primaryFieldNames = ['id'] } = options !== null && options !== void 0 ? options : {};
87
+ if (!_id || !primaryFieldNames.includes('id')) {
87
88
  return values;
88
89
  }
89
90
  return Object.assign({ id: _id }, values);
@@ -125,19 +126,21 @@ class NeDbDatabase extends AbstractMutexer_1.default {
125
126
  });
126
127
  });
127
128
  }
128
- async createOne(collection, values) {
129
+ async createOne(collection, values, options) {
129
130
  await this.randomDelay();
130
- const all = await this.create(collection, [values]);
131
+ const all = await this.create(collection, [values], options);
131
132
  return all[0];
132
133
  }
133
- async create(collection, values) {
134
+ async create(collection, values, options) {
134
135
  const mutexName = 'createMutex';
135
136
  await this.lock(mutexName);
136
137
  await this.randomDelay();
138
+ const { primaryFieldNames = ['id'] } = options !== null && options !== void 0 ? options : {};
139
+ const firstPrimaryFieldName = primaryFieldNames[0] === 'id' ? '_id' : primaryFieldNames[0];
137
140
  const col = this.loadCollection(collection);
138
141
  const mapped = values
139
142
  .map((v) => this.valuesToDocument(v))
140
- .map((v) => (Object.assign({ _id: this.generateId() }, v)));
143
+ .map((v) => (Object.assign({ [firstPrimaryFieldName]: this.generateId() }, v)));
141
144
  try {
142
145
  await Promise.all(mapped.map((m) => this.assertPassesUniqueIndexes(collection, undefined, m, 'create')));
143
146
  }
@@ -152,7 +155,7 @@ class NeDbDatabase extends AbstractMutexer_1.default {
152
155
  reject(err);
153
156
  }
154
157
  else {
155
- resolve(docs.map((doc) => this.normalizeRecord(doc)));
158
+ resolve(docs.map((doc) => this.normalizeRecord(doc, options)));
156
159
  }
157
160
  });
158
161
  });
@@ -1,5 +1,5 @@
1
1
  import AbstractMutexer from '../mutexers/AbstractMutexer';
2
- import { Database } from '../types/database.types';
2
+ import { CreateOptions, Database } from '../types/database.types';
3
3
  import { QueryOptions } from '../types/query.types';
4
4
  export default class NeDbDatabase extends AbstractMutexer implements Database {
5
5
  private collections;
@@ -17,8 +17,8 @@ export default class NeDbDatabase extends AbstractMutexer implements Database {
17
17
  private normalizeRecord;
18
18
  private handlePlaceholders;
19
19
  count(collection: string, query?: Record<string, any>): Promise<number>;
20
- createOne(collection: string, values: Record<string, any>): Promise<Record<string, any>>;
21
- create(collection: string, values: Record<string, any>[]): Promise<Record<string, any>[]>;
20
+ createOne(collection: string, values: Record<string, any>, options?: CreateOptions): Promise<Record<string, any>>;
21
+ create(collection: string, values: Record<string, any>[], options?: CreateOptions): Promise<Record<string, any>[]>;
22
22
  private loadCollection;
23
23
  dropCollection(name: string): Promise<void>;
24
24
  dropDatabase(): Promise<void>;
@@ -92,10 +92,11 @@ export default class NeDbDatabase extends AbstractMutexer {
92
92
  isConnected() {
93
93
  return this._isConnected;
94
94
  }
95
- normalizeRecord(record) {
95
+ normalizeRecord(record, options) {
96
96
  const { _id } = record, rest = __rest(record, ["_id"]);
97
97
  let values = this.handlePlaceholders(rest, null, (val) => val === null || val === NULL_PLACEHOLDER);
98
- if (!_id) {
98
+ const { primaryFieldNames = ['id'] } = options !== null && options !== void 0 ? options : {};
99
+ if (!_id || !primaryFieldNames.includes('id')) {
99
100
  return values;
100
101
  }
101
102
  return Object.assign({ id: _id }, values);
@@ -139,22 +140,24 @@ export default class NeDbDatabase extends AbstractMutexer {
139
140
  });
140
141
  });
141
142
  }
142
- createOne(collection, values) {
143
+ createOne(collection, values, options) {
143
144
  return __awaiter(this, void 0, void 0, function* () {
144
145
  yield this.randomDelay();
145
- const all = yield this.create(collection, [values]);
146
+ const all = yield this.create(collection, [values], options);
146
147
  return all[0];
147
148
  });
148
149
  }
149
- create(collection, values) {
150
+ create(collection, values, options) {
150
151
  return __awaiter(this, void 0, void 0, function* () {
151
152
  const mutexName = 'createMutex';
152
153
  yield this.lock(mutexName);
153
154
  yield this.randomDelay();
155
+ const { primaryFieldNames = ['id'] } = options !== null && options !== void 0 ? options : {};
156
+ const firstPrimaryFieldName = primaryFieldNames[0] === 'id' ? '_id' : primaryFieldNames[0];
154
157
  const col = this.loadCollection(collection);
155
158
  const mapped = values
156
159
  .map((v) => this.valuesToDocument(v))
157
- .map((v) => (Object.assign({ _id: this.generateId() }, v)));
160
+ .map((v) => (Object.assign({ [firstPrimaryFieldName]: this.generateId() }, v)));
158
161
  try {
159
162
  yield Promise.all(mapped.map((m) => this.assertPassesUniqueIndexes(collection, undefined, m, 'create')));
160
163
  }
@@ -169,7 +172,7 @@ export default class NeDbDatabase extends AbstractMutexer {
169
172
  reject(err);
170
173
  }
171
174
  else {
172
- resolve(docs.map((doc) => this.normalizeRecord(doc)));
175
+ resolve(docs.map((doc) => this.normalizeRecord(doc, options)));
173
176
  }
174
177
  });
175
178
  });
@@ -46,10 +46,15 @@ export default class AbstractStore extends AbstractMutexer {
46
46
  return this.collectionName;
47
47
  }
48
48
  prepareAndNormalizeRecord(record, options = {}) {
49
+ var _a, _b;
49
50
  return __awaiter(this, void 0, void 0, function* () {
50
- const preparedRecord = this.prepareRecord
51
+ let preparedRecord = this.prepareRecord
51
52
  ? yield this.prepareRecord(record, options)
52
53
  : record;
54
+ const pluginResults = yield ((_b = (_a = this.plugins[0]) === null || _a === void 0 ? void 0 : _a.prepareRecord) === null || _b === void 0 ? void 0 : _b.call(_a, preparedRecord));
55
+ if (pluginResults === null || pluginResults === void 0 ? void 0 : pluginResults.newValues) {
56
+ preparedRecord = pluginResults.newValues;
57
+ }
53
58
  const isScrambled = this.isScrambled(preparedRecord);
54
59
  if (isScrambled) {
55
60
  return preparedRecord;
@@ -96,14 +101,17 @@ export default class AbstractStore extends AbstractMutexer {
96
101
  var _a;
97
102
  return __awaiter(this, void 0, void 0, function* () {
98
103
  try {
99
- let valuesToMixinBeforeCreate = yield this.handleWillCreatePlugins(values);
100
104
  //@ts-ignore
101
105
  validateSchemaValues(this.createSchema, values);
102
106
  const cleanedValues = this.willCreate
103
107
  ? yield this.willCreate(values)
104
108
  : values;
105
- const toSave = this.normalizeBeforeSave(cleanedValues);
106
- const record = yield this.db.createOne(this.collectionName, Object.assign(Object.assign({}, toSave), valuesToMixinBeforeCreate));
109
+ let { valuesToMixinBeforeCreate, values: nv } = yield this.handleWillCreatePlugins(cleanedValues);
110
+ const newValues = (nv !== null && nv !== void 0 ? nv : cleanedValues);
111
+ const toSave = this.normalizeBeforeSave(newValues);
112
+ const record = yield this.db.createOne(this.collectionName, Object.assign(Object.assign({}, toSave), valuesToMixinBeforeCreate), {
113
+ primaryFieldNames: this.primaryFieldNames,
114
+ });
107
115
  yield ((_a = this.didCreate) === null || _a === void 0 ? void 0 : _a.call(this, record));
108
116
  const normalized = yield this.prepareAndNormalizeRecord(record, options);
109
117
  const mixinValuesOnReturn = yield this.handleDidCreateForPlugins(normalized);
@@ -143,14 +151,18 @@ export default class AbstractStore extends AbstractMutexer {
143
151
  var _a;
144
152
  return __awaiter(this, void 0, void 0, function* () {
145
153
  let valuesToMixinBeforeCreate = {};
154
+ let newValues;
146
155
  for (const plugin of this.plugins) {
147
156
  const r = yield ((_a = plugin.willCreateOne) === null || _a === void 0 ? void 0 : _a.call(plugin, values));
148
- const { valuesToMixinBeforeCreate: v } = r !== null && r !== void 0 ? r : {};
157
+ const { valuesToMixinBeforeCreate: v, newValues: nv } = r !== null && r !== void 0 ? r : {};
158
+ if (nv) {
159
+ newValues = nv;
160
+ }
149
161
  if (v) {
150
162
  valuesToMixinBeforeCreate = Object.assign(Object.assign({}, valuesToMixinBeforeCreate), v);
151
163
  }
152
164
  }
153
- return valuesToMixinBeforeCreate;
165
+ return { valuesToMixinBeforeCreate, values: newValues };
154
166
  });
155
167
  }
156
168
  handleDidCreateForPlugins(record) {
@@ -1,7 +1,5 @@
1
1
  import { Log } from '@sprucelabs/spruce-skill-utils';
2
2
  import { QueryOptions } from './query.types';
3
- export type UniqueIndex = string[];
4
- export type Index = string[];
5
3
  export interface Database {
6
4
  [x: string]: any;
7
5
  syncUniqueIndexes(collectionName: string, indexes: UniqueIndex[]): Promise<void>;
@@ -14,7 +12,7 @@ export interface Database {
14
12
  connect(): Promise<void>;
15
13
  close(): Promise<void>;
16
14
  getShouldAutoGenerateId?(): boolean;
17
- createOne(collection: string, values: Record<string, any>): Promise<Record<string, any>>;
15
+ createOne(collection: string, values: Record<string, any>, options?: CreateOptions): Promise<Record<string, any>>;
18
16
  create(collection: string, values: Record<string, any>[]): Promise<Record<string, any>[]>;
19
17
  dropCollection(name: string): Promise<void>;
20
18
  dropDatabase(): Promise<void>;
@@ -40,3 +38,8 @@ export type TestConnect = (connectionString?: string, dbName?: string) => Promis
40
38
  connectionStringWithRandomBadDatabaseName: string;
41
39
  badDatabaseName: string;
42
40
  }>;
41
+ export type UniqueIndex = string[];
42
+ export type Index = string[];
43
+ export interface CreateOptions {
44
+ primaryFieldNames?: string[];
45
+ }
@@ -37,12 +37,17 @@ export interface DataStorePlugin {
37
37
  willDeleteOne?: (query: Record<string, any>) => Promise<void | DataStorePluginWillDeleteOneResponse>;
38
38
  didFindOne?: (query: Record<string, any>, record: Record<string, any>) => Promise<void | DataStorePluginDidFindOneResponse>;
39
39
  getName(): string;
40
+ prepareRecord?: (record: Record<string, any>) => Promise<void | DataStorePluginPrepareResponse>;
41
+ }
42
+ export interface DataStorePluginPrepareResponse {
43
+ newValues?: Record<string, any>;
40
44
  }
41
45
  export interface DataStorePluginDidCreateOneResponse {
42
46
  valuesToMixinBeforeReturning?: Record<string, any>;
43
47
  }
44
48
  export interface DataStorePluginWillCreateOneResponse {
45
49
  valuesToMixinBeforeCreate?: Record<string, any>;
50
+ newValues?: Record<string, any>;
46
51
  }
47
52
  export interface DataStorePluginWillUpdateOneResponse {
48
53
  query?: Record<string, any>;
@@ -65,9 +65,14 @@ class AbstractStore extends AbstractMutexer_1.default {
65
65
  return this.collectionName;
66
66
  }
67
67
  async prepareAndNormalizeRecord(record, options = {}) {
68
- const preparedRecord = this.prepareRecord
68
+ var _a, _b;
69
+ let preparedRecord = this.prepareRecord
69
70
  ? await this.prepareRecord(record, options)
70
71
  : record;
72
+ const pluginResults = await ((_b = (_a = this.plugins[0]) === null || _a === void 0 ? void 0 : _a.prepareRecord) === null || _b === void 0 ? void 0 : _b.call(_a, preparedRecord));
73
+ if (pluginResults === null || pluginResults === void 0 ? void 0 : pluginResults.newValues) {
74
+ preparedRecord = pluginResults.newValues;
75
+ }
71
76
  const isScrambled = this.isScrambled(preparedRecord);
72
77
  if (isScrambled) {
73
78
  return preparedRecord;
@@ -110,14 +115,17 @@ class AbstractStore extends AbstractMutexer_1.default {
110
115
  async createOne(values, options) {
111
116
  var _a;
112
117
  try {
113
- let valuesToMixinBeforeCreate = await this.handleWillCreatePlugins(values);
114
118
  //@ts-ignore
115
119
  (0, schema_1.validateSchemaValues)(this.createSchema, values);
116
120
  const cleanedValues = this.willCreate
117
121
  ? await this.willCreate(values)
118
122
  : values;
119
- const toSave = this.normalizeBeforeSave(cleanedValues);
120
- const record = await this.db.createOne(this.collectionName, Object.assign(Object.assign({}, toSave), valuesToMixinBeforeCreate));
123
+ let { valuesToMixinBeforeCreate, values: nv } = await this.handleWillCreatePlugins(cleanedValues);
124
+ const newValues = (nv !== null && nv !== void 0 ? nv : cleanedValues);
125
+ const toSave = this.normalizeBeforeSave(newValues);
126
+ const record = await this.db.createOne(this.collectionName, Object.assign(Object.assign({}, toSave), valuesToMixinBeforeCreate), {
127
+ primaryFieldNames: this.primaryFieldNames,
128
+ });
121
129
  await ((_a = this.didCreate) === null || _a === void 0 ? void 0 : _a.call(this, record));
122
130
  const normalized = await this.prepareAndNormalizeRecord(record, options);
123
131
  const mixinValuesOnReturn = await this.handleDidCreateForPlugins(normalized);
@@ -155,14 +163,18 @@ class AbstractStore extends AbstractMutexer_1.default {
155
163
  async handleWillCreatePlugins(values) {
156
164
  var _a;
157
165
  let valuesToMixinBeforeCreate = {};
166
+ let newValues;
158
167
  for (const plugin of this.plugins) {
159
168
  const r = await ((_a = plugin.willCreateOne) === null || _a === void 0 ? void 0 : _a.call(plugin, values));
160
- const { valuesToMixinBeforeCreate: v } = r !== null && r !== void 0 ? r : {};
169
+ const { valuesToMixinBeforeCreate: v, newValues: nv } = r !== null && r !== void 0 ? r : {};
170
+ if (nv) {
171
+ newValues = nv;
172
+ }
161
173
  if (v) {
162
174
  valuesToMixinBeforeCreate = Object.assign(Object.assign({}, valuesToMixinBeforeCreate), v);
163
175
  }
164
176
  }
165
- return valuesToMixinBeforeCreate;
177
+ return { valuesToMixinBeforeCreate, values: newValues };
166
178
  }
167
179
  async handleDidCreateForPlugins(record) {
168
180
  var _a;
@@ -1,7 +1,5 @@
1
1
  import { Log } from '@sprucelabs/spruce-skill-utils';
2
2
  import { QueryOptions } from './query.types';
3
- export type UniqueIndex = string[];
4
- export type Index = string[];
5
3
  export interface Database {
6
4
  [x: string]: any;
7
5
  syncUniqueIndexes(collectionName: string, indexes: UniqueIndex[]): Promise<void>;
@@ -14,7 +12,7 @@ export interface Database {
14
12
  connect(): Promise<void>;
15
13
  close(): Promise<void>;
16
14
  getShouldAutoGenerateId?(): boolean;
17
- createOne(collection: string, values: Record<string, any>): Promise<Record<string, any>>;
15
+ createOne(collection: string, values: Record<string, any>, options?: CreateOptions): Promise<Record<string, any>>;
18
16
  create(collection: string, values: Record<string, any>[]): Promise<Record<string, any>[]>;
19
17
  dropCollection(name: string): Promise<void>;
20
18
  dropDatabase(): Promise<void>;
@@ -40,3 +38,8 @@ export type TestConnect = (connectionString?: string, dbName?: string) => Promis
40
38
  connectionStringWithRandomBadDatabaseName: string;
41
39
  badDatabaseName: string;
42
40
  }>;
41
+ export type UniqueIndex = string[];
42
+ export type Index = string[];
43
+ export interface CreateOptions {
44
+ primaryFieldNames?: string[];
45
+ }
@@ -37,12 +37,17 @@ export interface DataStorePlugin {
37
37
  willDeleteOne?: (query: Record<string, any>) => Promise<void | DataStorePluginWillDeleteOneResponse>;
38
38
  didFindOne?: (query: Record<string, any>, record: Record<string, any>) => Promise<void | DataStorePluginDidFindOneResponse>;
39
39
  getName(): string;
40
+ prepareRecord?: (record: Record<string, any>) => Promise<void | DataStorePluginPrepareResponse>;
41
+ }
42
+ export interface DataStorePluginPrepareResponse {
43
+ newValues?: Record<string, any>;
40
44
  }
41
45
  export interface DataStorePluginDidCreateOneResponse {
42
46
  valuesToMixinBeforeReturning?: Record<string, any>;
43
47
  }
44
48
  export interface DataStorePluginWillCreateOneResponse {
45
49
  valuesToMixinBeforeCreate?: Record<string, any>;
50
+ newValues?: Record<string, any>;
46
51
  }
47
52
  export interface DataStorePluginWillUpdateOneResponse {
48
53
  query?: Record<string, any>;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "26.1.1",
6
+ "version": "26.1.3",
7
7
  "files": [
8
8
  "build/**/*",
9
9
  "!build/__tests__",
@@ -68,23 +68,23 @@
68
68
  "upgrade.packages.test": "yarn upgrade.packages.all && yarn lint && yarn build.dev && yarn test"
69
69
  },
70
70
  "dependencies": {
71
- "@sprucelabs/error": "^5.1.50",
71
+ "@sprucelabs/error": "^5.1.51",
72
72
  "@sprucelabs/globby": "^1.0.3",
73
- "@sprucelabs/schema": "^29.0.93",
74
- "@sprucelabs/spruce-skill-utils": "^30.1.35",
73
+ "@sprucelabs/schema": "^29.1.0",
74
+ "@sprucelabs/spruce-skill-utils": "^30.1.36",
75
75
  "just-clone": "^6.2.0",
76
76
  "lodash": "^4.17.21",
77
77
  "mongodb": "^6.3.0",
78
78
  "nedb": "^1.8.0"
79
79
  },
80
80
  "devDependencies": {
81
- "@sprucelabs/esm-postbuild": "^5.0.104",
82
- "@sprucelabs/jest-json-reporter": "^7.0.129",
81
+ "@sprucelabs/esm-postbuild": "^5.0.105",
82
+ "@sprucelabs/jest-json-reporter": "^7.0.130",
83
83
  "@sprucelabs/jest-sheets-reporter": "^3.0.26",
84
- "@sprucelabs/resolve-path-aliases": "^1.1.267",
84
+ "@sprucelabs/resolve-path-aliases": "^1.1.268",
85
85
  "@sprucelabs/semantic-release": "^4.0.8",
86
- "@sprucelabs/test": "^8.0.33",
87
- "@sprucelabs/test-utils": "^4.0.82",
86
+ "@sprucelabs/test": "^8.0.34",
87
+ "@sprucelabs/test-utils": "^4.0.83",
88
88
  "@types/lodash": "^4.14.202",
89
89
  "@types/nedb": "^1.8.16",
90
90
  "@types/node": "^20.10.3",
@@ -129,10 +129,7 @@
129
129
  {
130
130
  "sheetId": "1DoWM7mYgGDa-PJXptLomrZmbIBZiuxS1YiAsRXU2Gm0",
131
131
  "worksheetId": 843037832,
132
- "testMap": {
133
- "canCountRecords": "I35",
134
- "syncing Unique Index On Duped Fields Throws SpruceError (mongo)": "Y107"
135
- }
132
+ "testMap": {}
136
133
  }
137
134
  ]
138
135
  ]