@bedrockio/model 0.15.0 → 0.16.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/CHANGELOG.md +4 -0
- package/README.md +67 -14
- package/dist/cjs/upsert.js +15 -4
- package/dist/cjs/validation-schemas.js +1 -1
- package/package.json +1 -1
- package/src/upsert.js +19 -4
- package/src/validation-schemas.js +1 -1
- package/types/upsert.d.ts.map +1 -1
- package/types/validation-schemas.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -931,6 +931,20 @@ caller does not need to know whether the path contains subdocuments or foreign
|
|
|
931
931
|
references. As Bedrock has knowledge of the schemas, it is able to build the
|
|
932
932
|
appropriate call to `populate` for you.
|
|
933
933
|
|
|
934
|
+
#### Include Syntax
|
|
935
|
+
|
|
936
|
+
| Example | Type | Populated | Description |
|
|
937
|
+
| ----------------- | --------- | --------- | ---------------------------------------------------- |
|
|
938
|
+
| `shop` | Inclusive | shop | Populates top level document. |
|
|
939
|
+
| `shop.user` | Inclusive | shop/user | Populates two levels deep. |
|
|
940
|
+
| `^name` | Exclusive | | Selects only `name`. |
|
|
941
|
+
| `^shop.name` | Exclusive | shop | Selects only `shop.name`. |
|
|
942
|
+
| `^shop.user.name` | Exclusive | shop/user | Selects only `shop.user.name`. |
|
|
943
|
+
| `shop.^user.name` | Exclusive | shop/user | Selects root fields and `shop.user.name`. |
|
|
944
|
+
| `shop.user.^name` | Exclusive | shop/user | Selects root and `shop` fields and `shop.user.name`. |
|
|
945
|
+
| `*Name` | Wildcard | | Matches any root field ending with `Name`. |
|
|
946
|
+
| `**Name` | Wildcard | | Matches any root or nested field ending with `Name`. |
|
|
947
|
+
|
|
934
948
|
#### Exclusive Fields
|
|
935
949
|
|
|
936
950
|
By default, arguments to `include` are for population. However often field
|
|
@@ -1650,35 +1664,52 @@ string, both of which would be stored in the database if naively assigned with
|
|
|
1650
1664
|
|
|
1651
1665
|
### Upsert
|
|
1652
1666
|
|
|
1653
|
-
This module adds
|
|
1654
|
-
|
|
1655
|
-
|
|
1667
|
+
This module adds two similar methods:
|
|
1668
|
+
|
|
1669
|
+
- `upsert`
|
|
1670
|
+
- `findOrCreate`
|
|
1671
|
+
|
|
1672
|
+
The `upsert` method is used when documents must always be overwritten with the
|
|
1673
|
+
latest data.
|
|
1656
1674
|
|
|
1657
1675
|
```js
|
|
1658
|
-
const shop = await Shop.
|
|
1659
|
-
|
|
1660
|
-
|
|
1676
|
+
const shop = await Shop.upsert(
|
|
1677
|
+
{
|
|
1678
|
+
name: 'My Shop',
|
|
1679
|
+
},
|
|
1680
|
+
{
|
|
1681
|
+
name: 'My Shop',
|
|
1682
|
+
slug: 'my-shop',
|
|
1683
|
+
},
|
|
1684
|
+
);
|
|
1685
|
+
|
|
1686
|
+
// This is equivalent to:
|
|
1661
1687
|
|
|
1662
|
-
// This is equivalent to running:
|
|
1663
1688
|
let shop = await Shop.findOne({
|
|
1664
1689
|
name: 'My Shop',
|
|
1665
1690
|
});
|
|
1666
1691
|
|
|
1667
|
-
if (
|
|
1692
|
+
if (shop) {
|
|
1693
|
+
shop.assign({
|
|
1694
|
+
name: 'My Shop',
|
|
1695
|
+
slug: 'my-shop',
|
|
1696
|
+
});
|
|
1697
|
+
await shop.save();
|
|
1698
|
+
} else {
|
|
1668
1699
|
shop = await Shop.create({
|
|
1669
1700
|
name: 'My Shop',
|
|
1701
|
+
slug: 'my-shop',
|
|
1670
1702
|
});
|
|
1671
1703
|
}
|
|
1672
1704
|
```
|
|
1673
1705
|
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
of which is the query:
|
|
1706
|
+
The `findOrCreate` method does just whan the name implies and will return the
|
|
1707
|
+
document it finds without modifying it.
|
|
1677
1708
|
|
|
1678
1709
|
```js
|
|
1679
1710
|
const shop = await Shop.findOrCreate(
|
|
1680
1711
|
{
|
|
1681
|
-
|
|
1712
|
+
name: 'My Shop',
|
|
1682
1713
|
},
|
|
1683
1714
|
{
|
|
1684
1715
|
name: 'My Shop',
|
|
@@ -1686,9 +1717,10 @@ const shop = await Shop.findOrCreate(
|
|
|
1686
1717
|
},
|
|
1687
1718
|
);
|
|
1688
1719
|
|
|
1689
|
-
// This is equivalent to
|
|
1720
|
+
// This is equivalent to:
|
|
1721
|
+
|
|
1690
1722
|
let shop = await Shop.findOne({
|
|
1691
|
-
|
|
1723
|
+
name: 'My Shop',
|
|
1692
1724
|
});
|
|
1693
1725
|
|
|
1694
1726
|
if (!shop) {
|
|
@@ -1699,6 +1731,27 @@ if (!shop) {
|
|
|
1699
1731
|
}
|
|
1700
1732
|
```
|
|
1701
1733
|
|
|
1734
|
+
Note that a single argument can also be passed as a shortcut to both the query
|
|
1735
|
+
and the update for simple cases:
|
|
1736
|
+
|
|
1737
|
+
```js
|
|
1738
|
+
const shop = await Shop.findOrCreate({
|
|
1739
|
+
name: 'My Shop',
|
|
1740
|
+
});
|
|
1741
|
+
|
|
1742
|
+
// This is equivalent to:
|
|
1743
|
+
|
|
1744
|
+
let shop = await Shop.findOne({
|
|
1745
|
+
name: 'My Shop',
|
|
1746
|
+
});
|
|
1747
|
+
|
|
1748
|
+
if (!shop) {
|
|
1749
|
+
shop = await Shop.create({
|
|
1750
|
+
name: 'My Shop',
|
|
1751
|
+
});
|
|
1752
|
+
}
|
|
1753
|
+
```
|
|
1754
|
+
|
|
1702
1755
|
### Clone
|
|
1703
1756
|
|
|
1704
1757
|
Adds a single `clone` method on documents. This is an async method mostly for
|
package/dist/cjs/upsert.js
CHANGED
|
@@ -5,11 +5,22 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.applyUpsert = applyUpsert;
|
|
7
7
|
function applyUpsert(schema) {
|
|
8
|
-
// Note:
|
|
9
|
-
//
|
|
10
|
-
// means however that we cannot always return a query here
|
|
11
|
-
// operations are inherently different.
|
|
8
|
+
// Note: Avoiding the findOneAndUpdate approach here as this
|
|
9
|
+
// will prevent hooks from being run on the document. This
|
|
10
|
+
// means however that we cannot always return a query here
|
|
11
|
+
// as the operations are inherently different.
|
|
12
12
|
|
|
13
|
+
schema.static('upsert', async function upsert(query, fields) {
|
|
14
|
+
fields ||= query;
|
|
15
|
+
let doc = await this.findOne(query);
|
|
16
|
+
if (doc) {
|
|
17
|
+
doc.assign(fields);
|
|
18
|
+
await doc.save();
|
|
19
|
+
} else {
|
|
20
|
+
doc = await this.create(fields);
|
|
21
|
+
}
|
|
22
|
+
return doc;
|
|
23
|
+
});
|
|
13
24
|
schema.static('findOrCreate', async function findOrCreate(query, fields) {
|
|
14
25
|
fields ||= query;
|
|
15
26
|
let doc = await this.findOne(query);
|
|
@@ -70,6 +70,6 @@ An object with an \`id\` field may also be passed, which will be converted into
|
|
|
70
70
|
const INCLUDE_FIELD_SCHEMA = exports.INCLUDE_FIELD_SCHEMA = _yada.default.object({
|
|
71
71
|
include: _yada.default.allow(_yada.default.string(), _yada.default.array(_yada.default.string())).tag({
|
|
72
72
|
'x-schema': 'Includes',
|
|
73
|
-
'x-description': 'A `string` or `array` of fields to be selected or populated using [includes syntax](
|
|
73
|
+
'x-description': 'A `string` or `array` of fields to be selected or populated using [includes syntax](https://bit.ly/4mZwSq4).'
|
|
74
74
|
})
|
|
75
75
|
});
|
package/package.json
CHANGED
package/src/upsert.js
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
export function applyUpsert(schema) {
|
|
2
|
-
// Note:
|
|
3
|
-
//
|
|
4
|
-
// means however that we cannot always return a query here
|
|
5
|
-
// operations are inherently different.
|
|
2
|
+
// Note: Avoiding the findOneAndUpdate approach here as this
|
|
3
|
+
// will prevent hooks from being run on the document. This
|
|
4
|
+
// means however that we cannot always return a query here
|
|
5
|
+
// as the operations are inherently different.
|
|
6
|
+
|
|
7
|
+
schema.static('upsert', async function upsert(query, fields) {
|
|
8
|
+
fields ||= query;
|
|
9
|
+
|
|
10
|
+
let doc = await this.findOne(query);
|
|
11
|
+
|
|
12
|
+
if (doc) {
|
|
13
|
+
doc.assign(fields);
|
|
14
|
+
await doc.save();
|
|
15
|
+
} else {
|
|
16
|
+
doc = await this.create(fields);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return doc;
|
|
20
|
+
});
|
|
6
21
|
|
|
7
22
|
schema.static('findOrCreate', async function findOrCreate(query, fields) {
|
|
8
23
|
fields ||= query;
|
|
@@ -105,6 +105,6 @@ export const INCLUDE_FIELD_SCHEMA = yd.object({
|
|
|
105
105
|
include: yd.allow(yd.string(), yd.array(yd.string())).tag({
|
|
106
106
|
'x-schema': 'Includes',
|
|
107
107
|
'x-description':
|
|
108
|
-
'A `string` or `array` of fields to be selected or populated using [includes syntax](
|
|
108
|
+
'A `string` or `array` of fields to be selected or populated using [includes syntax](https://bit.ly/4mZwSq4).',
|
|
109
109
|
}),
|
|
110
110
|
});
|
package/types/upsert.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upsert.d.ts","sourceRoot":"","sources":["../src/upsert.js"],"names":[],"mappings":"AAAA,+
|
|
1
|
+
{"version":3,"file":"upsert.d.ts","sourceRoot":"","sources":["../src/upsert.js"],"names":[],"mappings":"AAAA,+CAgCC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation-schemas.d.ts","sourceRoot":"","sources":["../src/validation-schemas.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAwFsB,CAAC;;;;;;;;;;;;;;;;;;;EAxFmC;AAE1D;;;;;;;;;;;;;;;;eAyBwB,CAAC;;;;;;;;;;;;iBAuBjB,CAAA;kBAA4B,CAAC;kBAEjC,CAAF;oBAEI,CAAC;oBAEI,CAAC;;;wBA2BC,CAAC;8BAGI,CAAC;oBAA+B,CAAC;oBAE1C,CAAC;oCAEL,CAAC;uBAAkC,CAAC;8BAAyC,CAAC;uBACzD,CAAC;iBAA4B,CAAC;;;
|
|
1
|
+
{"version":3,"file":"validation-schemas.d.ts","sourceRoot":"","sources":["../src/validation-schemas.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAwFsB,CAAC;;;;;;;;;;;;;;;;;;;EAxFmC;AAE1D;;;;;;;;;;;;;;;;eAyBwB,CAAC;;;;;;;;;;;;iBAuBjB,CAAA;kBAA4B,CAAC;kBAEjC,CAAF;oBAEI,CAAC;oBAEI,CAAC;;;wBA2BC,CAAC;8BAGI,CAAC;oBAA+B,CAAC;oBAE1C,CAAC;oCAEL,CAAC;uBAAkC,CAAC;8BAAyC,CAAC;uBACzD,CAAC;iBAA4B,CAAC;;;mBAW0D,CAAC;yBAAoC,CAAC;0BAAqC,CAAC;yBAAoC,CAAC;sBAAiC,CAAC;yBAAoC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAdpR,CAAC;;;;;;;;;;;;;;;;;;;EA9ElB;AAEL;;;;;;;;;;;;kBA0Fmb,CAAC;oBAA+B,CAAC;qBAAgC,CAAC;sBAAiC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAdjgB,CAAC;;;;;;;;;;;;;;;;;EAlElB;AAEL;;;;;;;;;;;;kBA8Emb,CAAC;oBAA+B,CAAC;qBAAgC,CAAC;sBAAiC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAdjgB,CAAC;;;;;;;;;;;;;;;;;EAtDlB;AAEL;;;;;;;;;;;;kBAkEmb,CAAC;oBAA+B,CAAC;qBAAgC,CAAC;sBAAiC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAdjgB,CAAC;;;;;;;;;;;;;;;;;EAlBlB;AAEL,8EAqBK;AAEL;;;;;;;;;;;;kBAOmb,CAAC;oBAA+B,CAAC;qBAAgC,CAAC;sBAAiC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAdjgB,CAAC;;;;;;;;;;;;;;;;;EAapB"}
|