├── .editorconfig
├── .eslintignore
├── .eslintrc.json
├── .github
└── workflows
│ └── test.yml
├── .gitignore
├── .idea
├── .gitignore
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── dictionaries
│ └── saibotsivad.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── jsLibraryMappings.xml
├── jsLinters
│ └── eslint.xml
├── markdown.xml
├── modules.xml
├── mongodb.iml
└── vcs.xml
├── .nvmrc
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── demo
├── .eslintrc.json
├── README.md
├── demo.js
└── fetch-shim.js
├── index.d.ts
├── package-lock.json
├── package.json
└── src
├── .eslintrc.json
└── index.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = tab
6 | indent_size = 4
7 |
8 | [*.js]
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = true
14 |
15 | [*.{yml,yaml}]
16 | indent_style = space
17 | indent_size = 2
18 |
19 | [package.json]
20 | indent_style = space
21 | indent_size = 2
22 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # the usual suspects
2 | /node_modules
3 | .DS_Store
4 |
5 | # personal local files
6 | /configuration.js
7 | /configuration.sh
8 | /fiddle.js
9 |
10 | # globbed things
11 | globbed-*.js
12 |
13 | *.ts
14 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "es6": true
4 | },
5 | "extends": [
6 | "eslint:recommended"
7 | ],
8 | "parserOptions": {
9 | "ecmaVersion": "latest",
10 | "sourceType": "module"
11 | },
12 | "rules": {
13 | "array-bracket-spacing": [
14 | "error",
15 | "always",
16 | {
17 | "objectsInArrays": true,
18 | "arraysInArrays": true
19 | }
20 | ],
21 | "block-spacing": [
22 | "error",
23 | "always"
24 | ],
25 | "brace-style": [
26 | "error",
27 | "1tbs",
28 | {
29 | "allowSingleLine": true
30 | }
31 | ],
32 | "comma-dangle": [
33 | "error",
34 | "always-multiline"
35 | ],
36 | "comma-spacing": [
37 | "error",
38 | {
39 | "before": false,
40 | "after": true
41 | }
42 | ],
43 | "eol-last": [
44 | "error",
45 | "always"
46 | ],
47 | "eqeqeq": [
48 | "error",
49 | "always"
50 | ],
51 | "indent": [
52 | "error",
53 | "tab"
54 | ],
55 | "keyword-spacing": [
56 | "error",
57 | {
58 | "before": true
59 | }
60 | ],
61 | "linebreak-style": [
62 | "error",
63 | "unix"
64 | ],
65 | "no-eval": "error",
66 | "no-implied-eval": "error",
67 | "no-irregular-whitespace": [
68 | "error",
69 | {
70 | "skipStrings": false
71 | }
72 | ],
73 | "no-new": "error",
74 | "no-return-await": "error",
75 | "no-unexpected-multiline": "error",
76 | "no-useless-rename": "error",
77 | "no-var": [
78 | "error"
79 | ],
80 | "object-curly-spacing": [
81 | "error",
82 | "always"
83 | ],
84 | "quotes": [
85 | "error",
86 | "single",
87 | {
88 | "avoidEscape": true
89 | }
90 | ],
91 | "semi": [
92 | "error",
93 | "never"
94 | ],
95 | "space-before-blocks": [
96 | "error",
97 | "always"
98 | ],
99 | "space-before-function-paren": [
100 | "error",
101 | {
102 | "anonymous": "always",
103 | "asyncArrow": "always",
104 | "named": "never"
105 | }
106 | ],
107 | "space-in-parens": [
108 | "error",
109 | "never"
110 | ],
111 | "valid-jsdoc": [
112 | "error",
113 | {
114 | "requireReturn": false
115 | }
116 | ]
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | #
2 | # This workflow will run all the normal static tests (linting, unit, etc.), will
3 | # make sure the build completes successfully, and will connect to a MongoDB Data API
4 | # if merged to the main branch.
5 | #
6 |
7 | name: test
8 |
9 | on:
10 | push:
11 | branches: [ '*' ]
12 |
13 | jobs:
14 | build:
15 | environment: test
16 | runs-on: ubuntu-latest
17 | strategy:
18 | matrix:
19 | node-version: [ 16.x, 18.x, 20.x ]
20 | steps:
21 | - uses: actions/checkout@v4
22 | - name: Use Node.js ${{ matrix.node-version }}
23 | uses: actions/setup-node@v4
24 | with:
25 | node-version: ${{ matrix.node-version }}
26 | - run: npm ci
27 | - run: npm run lint
28 | - run: npm run build
29 | - run: npm run demo
30 | env:
31 | MONGODB_API_URL: ${{secrets.MONGODB_API_URL}}
32 | MONGODB_API_KEY: ${{secrets.MONGODB_API_KEY}}
33 | MONGODB_DATABASE_NAME: ${{secrets.MONGODB_DATABASE_NAME}}
34 | MONGODB_CLUSTER_NAME: ${{secrets.MONGODB_CLUSTER_NAME}}
35 | MONGODB_COLLECTION_NAME: ${{secrets.MONGODB_COLLECTION_NAME}}
36 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # the usual culprits
2 | /node_modules
3 | .DS_Store
4 |
5 | # personal local files
6 | /configuration.js
7 | /configuration.sh
8 | /fiddle.js
9 |
10 | # globbed things
11 | globbed-*.js
12 |
13 | # built things
14 | /dist
15 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/dictionaries/saibotsivad.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.idea/jsLibraryMappings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/jsLinters/eslint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/markdown.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/mongodb.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v16.10.0
2 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6 | and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7 |
8 | Change categories are:
9 |
10 | * `Added` for new features.
11 | * `Changed` for changes in existing functionality.
12 | * `Deprecated` for once-stable features removed in upcoming releases.
13 | * `Removed` for deprecated features removed in this release.
14 | * `Fixed` for any bug fixes.
15 | * `Security` to invite users to upgrade in case of vulnerabilities.
16 |
17 | ## Unreleased
18 | ### Added
19 | ### Changed
20 | ### Deprecated
21 | ### Fixed
22 | ### Removed
23 | ### Security
24 |
25 | ## [1.2.0](https://github.com/saibotsivad/mongodb/compare/v1.1.0...v1.2.0) - 2024-06-15
26 | ### Added
27 | - Support for Web API [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers),
28 | so you can use the global `fetch` as-is.
29 | - Updated tests to run against Node.js version 18 and 20 as well as 16 (original).
30 | ### Fixed
31 | - Type for option parameters had `cluster` instead of `dataSource`, which was a breaking
32 | change in `1.0.0`. Types are now fixed. Closes #3
33 |
34 | ## [1.1.0](https://github.com/saibotsivad/mongodb/compare/v1.0.0...v1.1.0) - 2022-09-30
35 | ### Added
36 | - The `interpose` method allows you to inspect and mutate requests immediately prior to
37 | sending them, for things like logging and debugging.
38 |
39 | ## [1.0.0](https://github.com/saibotsivad/mongodb/compare/v0.0.10...v1.0.0) - 2022-09-30
40 |
41 | Since MongoDB Data API is now out of beta, this library is going to v1 as well! 🎉
42 |
43 | ### Added
44 | - Full test suite (it's the demo code) that actually connects to a MongoDB Data API
45 | instance to verify that all requests are being made correctly. (Note to my future
46 | self: this is using a free version, which will likely be automatically spun down
47 | due to inactivity. I will need to go spin it back up for tests to pass.)
48 | ### Changed
49 | - BREAKING: Simplified the interface a bit, by requiring the fully qualified URL instead of region
50 | and/or app ID. Here are the [MongoDB URL docs](https://www.mongodb.com/docs/atlas/api/data-api-resources/#base-url).
51 | - BREAKING: Renamed `cluster` to `dataSource` to match their parameter names better.
52 | - Change the default-vs-overrides a bit: you don't *need* to specify the `dataSource`, `database`,
53 | or `collection` properties at initialization. If you do, you can still specify them at
54 | the request to override the defaults.
55 |
56 | ## [0.0.10](https://github.com/saibotsivad/mongodb/compare/v0.0.9...v0.0.10) - 2022-02-23
57 | ### Fixed
58 | - Documentation only: the `insertMany` examples were incorrectly written.
59 |
60 | ## [0.0.9](https://github.com/saibotsivad/mongodb/compare/v0.0.8...v0.0.9) - 2022-01-28
61 | ### Fixed
62 | - After using this for a while now, I was able to make the error handling more consistent.
63 |
64 | ## [0.0.8](https://github.com/saibotsivad/mongodb/compare/v0.0.7...v0.0.8) - 2022-01-25
65 | ### Fixed
66 | - Tidy up the response handling code a bit after experimenting with the Data API responses more thoroughly.
67 | - Several example corrections to the docs.
68 |
69 | ## [0.0.6-0.0.7](https://github.com/saibotsivad/mongodb/compare/v0.0.5...v0.0.7) - 2022-01-24
70 | ### Fixed
71 | - Creating can return a 201, and errors aren't always JSON bodies.
72 | - Parameters needs rest expansion.
73 |
74 | ## [0.0.4-0.0.5](https://github.com/saibotsivad/mongodb/compare/v0.0.3...v0.0.5) - 2022-01-14
75 | ### Added
76 | - JSDoc documentation for all the functions. I tried adding a little more to the TS definition.
77 | ### Changed
78 | - Made the function results more consistent with the MongoDB Data API, e.g. calling `deleteOne` returns `{ deletedCount: Number }` instead of `Number`. This was done to make it easier to add properties as the Data API becomes more feature complete.
79 |
80 | ## [0.0.1-0.0.3](https://github.com/saibotsivad/mongodb/compare/v0.0.0...v0.0.3) - 2022-01-12
81 | ### Fixed
82 | - Correction to paths so IDEs recognize the module correctly.
83 |
84 | ## [0.0.0](https://github.com/saibotsivad/mongodb/tree/v0.0.0) - 2022-01-12
85 | ### Added
86 | - Created the base project from [saibotsivad/init](https://github.com/saibotsivad/init).
87 | - Basic functionality and documentation in the readme.
88 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contribution Guide
2 |
3 | Considering contributing? Thank you so much!
4 |
5 | ## Pull Requests
6 |
7 | Please consider these simple guidelines when filing a pull request:
8 |
9 | * Commits follow the [Angular commit convention](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#-git-commit-guidelines)
10 | * [Tabs for indentation, spaces for alignment](https://gist.github.com/saibotsivad/06021a81865226cfc140)
11 | * Features and bug fixes should be covered by test cases
12 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Very Open License (VOL)
2 |
3 | The contributor(s) to this creative work voluntarily grant permission
4 | to any individual(s) or entities of any kind
5 |
6 | - to use the creative work in any manner,
7 | - to modify the creative work without restriction,
8 | - to sell the creative work or derivatives thereof for profit, and
9 | - to release modifications of the creative work in part or whole under any license
10 |
11 | with no requirement for compensation or recognition of any kind.
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # @saibotsivad/mongodb
2 |
3 | Simple wrapper for the [MongoDB Data API](https://docs.atlas.mongodb.com/api/data-api/).
4 |
5 | > **v1 Update!** MongoDB's "Data API" is out of beta, so this library is now v1! 🎉
6 |
7 | ## Install
8 |
9 | The usual ways:
10 |
11 | ```shell
12 | npm install @saibotsivad/mongodb
13 | ```
14 |
15 | ## Example
16 |
17 | Instantiate and issue a request:
18 |
19 | ```js
20 | import { mongodb } from '@saibotsivad/mongodb'
21 |
22 | const db = mongodb({
23 | apiKey: 'AKAIDEXAMPLEKEY',
24 | apiUrl: 'https://data.mongodb-api.com/app/data-abc123/endpoint/data/v1',
25 | dataSource: 'myCluster3',
26 | database: 'myDatabase',
27 | collection: 'vehicles',
28 | })
29 |
30 | const car = await db.findOne({ filter: { type: 'car' } })
31 | // => { _id: "61df...", type: "car", ...etc }
32 | ```
33 |
34 | ## Instantiate
35 |
36 | Import the `{ mongodb }` function and instantiate with the following properties:
37 |
38 | #### `apiKey: string` **(always required)**
39 |
40 | The programmatic API key, generated using the MongoDB Atlas interface.
41 |
42 | #### `apiUrl: string` **(always required)**
43 |
44 | The fully qualified URL, e.g. something like this:
45 |
46 | ```
47 | https://data.mongodb-api.com/app/data-abc123/endpoint/data/v1
48 | ```
49 |
50 | #### `interpose: function`
51 |
52 | Called immediately prior to making the `fetch` request, with the name of the request (e.g. `findOne`) and the body of the request. Useful for things like logging and debugging, but you can also mutate the object if needed.
53 |
54 | ```ts
55 | type interpose = (input: { name: string, body: Object }) => { body: Object }
56 | ```
57 |
58 | ## Request Requirements
59 |
60 | These are properties that are **required** for every request.
61 |
62 | You can set them when you create a `mongodb` instance, or override or provide them on the individual request:
63 |
64 | ```js
65 | const db = mongodb({
66 | apiKey: 'AKAIDEXAMPLEKEY',
67 | apiUrl: 'https://data.mongodb-api.com/app/data-abc123/endpoint/data/v1',
68 | dataSource: 'myCluster1',
69 | database: 'myDatabase',
70 | collection: 'vehicles',
71 | })
72 |
73 | // override `collection` for this one request
74 | const car = await db.findOne({ filter: { type: 'hobbit' } }, { collection: 'people' })
75 | // => { _id: "42fd...", type: "hobbit", ...etc }
76 | ```
77 |
78 | #### `dataSource: string`
79 |
80 | The name of the MongoDB cluster.
81 |
82 | #### `database: string`
83 |
84 | The name of the MongoDB database.
85 |
86 | #### `collection: string`
87 |
88 | The name of the collection.
89 |
90 | ## Environment Specific
91 |
92 | #### `fetch: function`
93 |
94 | This library was written to use the [`fetch` Web API](https://developer.mozilla.org/en-US/docs/Web/API/fetch) using `globalThis.fetch` to make requests to the MongoDB Data API.
95 |
96 | To make requests in an environment *without* `fetch`, e.g. NodeJS, you will need to provide your own fetch-like implementation.
97 |
98 | Check [the response type definition](./index.d.ts) for interface requirements, but for example you could use something like the very lightweight [`httpie`](https://github.com/lukeed/httpie/) library, like in [the demo](./demo/fetch-shim.js).
99 |
100 | ## Methods
101 |
102 | The available methods follow the [Data API Resources](https://docs.atlas.mongodb.com/api/data-api-resources/) exactly, so go read those for more details.
103 |
104 | Each one can be overridden with a second property, which is an object containing the earlier "Request Requirements" properties, e.g.:
105 |
106 | ```js
107 | await db.findOne(
108 | { filter: { type: 'car' } },
109 | {
110 | dataSource: 'AlternateCluster',
111 | database: 'AlternateDatabase',
112 | collection: 'AlternateTable',
113 | },
114 | )
115 | ```
116 |
117 | ### aggregate
118 |
119 | [Runs an aggregation pipeline](https://docs.atlas.mongodb.com/api/data-api-resources/#run-an-aggregation-pipeline) and returns the result set of the final stage of the pipeline as an array of documents.
120 |
121 | ```ts
122 | (
123 | parameters: { pipeline: MongoPipeline },
124 | overrides?: { dataSource?: string, database?: string, collection?: string },
125 | ) =>
126 | Promise<{ documents: Array