Skip to content

Commit

Permalink
Merge pull request #5 from surmon-china/fix/type
Browse files Browse the repository at this point in the history
feat: v0.2.0
  • Loading branch information
surmon-china authored Mar 21, 2022
2 parents ddac794 + e3770ae commit fdf3bc9
Show file tree
Hide file tree
Showing 13 changed files with 687 additions and 189 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
# Fork from: https://github.com/actions/starter-workflows/blob/master/ci/npm-publish.yml
# Fork from: https://github.com/actions/starter-workflows/blob/main/ci/npm-publish.yml

name: Publish

Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

All notable changes to this project will be documented in this file.

### v0.2.0 (2022-03-09)

**Feature**

- New creator function `createMongoDBDataAPI`

**Fix**

- [#3 Adjust typescript generics](https://github.com/surmon-china/mongodb-data-api/pull/3)
- [#4 Disable parameter inference](https://github.com/surmon-china/mongodb-data-api/pull/4)

### v0.1.0 (2022-01-31)

- Implements Beta API
69 changes: 47 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
 
[![Test Codecov](https://img.shields.io/codecov/c/github/surmon-china/mongodb-data-api?style=for-the-badge)](https://codecov.io/gh/surmon-china/mongodb-data-api)
 
[![GitHub license](https://img.shields.io/github/license/surmon-china/mongodb-data-api.svg?style=for-the-badge)](https://github.com/surmon-china/mongodb-data-api/blob/master/LICENSE)
[![GitHub license](https://img.shields.io/github/license/surmon-china/mongodb-data-api.svg?style=for-the-badge)](/LICENSE)

> MongoDB Atlas [Data API](https://docs.atlas.mongodb.com/api/data-api/) SDK for Node.js.
MongoDB Atlas [Data API](https://docs.atlas.mongodb.com/api/data-api/) SDK for Node.js.

---

Expand All @@ -33,22 +33,22 @@ yarn add mongodb-data-api
#### Init

```ts
import { MongoDBDataAPI, Region } from 'mongodb-data-api'
import { createMongoDBDataAPI, Region } from 'mongodb-data-api'

// init by URL Endpoint
const api = new MongoDBDataAPI({
const api = createMongoDBDataAPI({
apiKey: '<your_mongodb_api_key>',
urlEndpoint: 'https://data.mongodb-api.com/app/<your_mongodb_app_id>/endpoint/data/beta'
})

// or init by app ID
const api = new MongoDBDataAPI({
const api = createMongoDBDataAPI({
apiKey: '<your_mongodb_api_key>',
appId: '<your_mongodb_app_id>'
})

// specific region of app
const api = new MongoDBDataAPI({
const api = createMongoDBDataAPI({
apiKey: '<your_mongodb_api_key>',
appId: '<your_mongodb_app_id>',
region: Region.Virginia
Expand Down Expand Up @@ -126,27 +126,30 @@ api
#### Method chaining

```ts
// api.$cluster
// select cluster
const clusterA = api.$cluster('a')

// api.$cluster.$database
// select database
const databaseB = clusterA.$database('b')
const databaseC = clusterA.$database('c')

// api.$cluster.$database.$collection
const bItemCollection = databaseB.$collection('item')
const cItemCollection = databaseC.$collection('item')

// actions
bItemCollection.findOne({ filter: {/*...*/} })
cItemCollection.insertOne({ document: {/*...*/} })
// select collection
const collectionC = databaseB.$collection<C>('c')
// data actions
const data = await collectionC.findOne({
filter: {
/*...*/
}
})
const result = await collectionC.insertOne({
document: {
/*...*/
}
})

// -------------

// chaining is equivalent to the api call
api.$cluster('a').$database('b').$collection('c').findOne({ filter: {} })
api.$cluster('a').$database('b').$collection<C>('c').findOne({ filter: {} })
// the same as
api.findOne({
api.findOne<C>({
dataSource: 'a',
database: 'b',
collection: 'c',
Expand All @@ -167,6 +170,28 @@ api.$$action('findOne', {
})
```

#### Original Class

You can use the original Class to implement some special requirements.

```ts
import { MongoDBDataAPI } from 'mongodb-data-api'

const customerCollection = new MongoDBDataAPI<CustomerDocument>(
{
apiKey: '<your_mongodb_api_key>',
appId: '<your_mongodb_app_id>'
},
{
dataSource: '<target_cluster_name>',
database: '<target_database_name>',
collection: '<target_collection_name>'
}
)

const customer = await customerCollection.findOne({ ... })
```

### Development

```bash
Expand All @@ -185,8 +210,8 @@ yarn build

### Changelog

Detailed changes for each release are documented in the [release notes](https://github.com/surmon-china/mongodb-data-api/blob/master/CHANGELOG.md).
Detailed changes for each release are documented in the [release notes](/CHANGELOG.md).

### License

[MIT](https://github.com/surmon-china/mongodb-data-api/blob/master/LICENSE)
[MIT](/LICENSE)
9 changes: 5 additions & 4 deletions libundler.config.js → libundler.config.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/** @type {import('@surmon-china/libundler/lib/interface').LibundlerConfigObject} */
module.exports = {
import { defineConfig } from '@surmon-china/libundler'

export default defineConfig({
libName: 'MongoDBDataAPI',
outFileName: 'mongodb-data-api',
targets: ['cjs', 'esm'],
entry: './src/index.ts',
outDir: './dist',
external: ['axios', 'mongodb'],
minimize: false,
terser: false,
sourcemap: false
}
})
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mongodb-data-api",
"version": "0.1.0",
"version": "0.2.0",
"description": "MongoDB atlas data API SDK for Node.js",
"keywords": [
"MongoDB data API",
Expand All @@ -24,7 +24,9 @@
"scripts": {
"lint": "eslint --ext .ts src/**",
"format": "prettier --write --parser typescript \"src/**/*.ts\"",
"test": "jest",
"test": "npm run test:type && npm run test:unit",
"test:unit": "jest",
"test:type": "tsc -p ./tests-dts/tsconfig.json && tsc -p ./tests-dts/tsconfig.build.json",
"build": "libundler",
"rebirth": "npm run lint && npm run test && npm run build",
"release": ". ./scripts/release.sh"
Expand All @@ -34,7 +36,7 @@
"mongodb": "^4.0.0"
},
"devDependencies": {
"@surmon-china/libundler": "^1.1.1",
"@surmon-china/libundler": "^2.2.0",
"@types/jest": "^27.4.0",
"@typescript-eslint/eslint-plugin": "^5.9.1",
"@typescript-eslint/parser": "^5.9.1",
Expand Down
81 changes: 49 additions & 32 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import _axios, { AxiosInstance, AxiosRequestConfig } from 'axios'
import type { Filter, Projection, Sort, UpdateFilter, Document } from 'mongodb'
import type { Filter, FindOptions, Sort, UpdateFilter, Document } from 'mongodb'

// https://github.com/surmon-china/mongodb-data-api/pull/3/files @maxfi
type Projection = FindOptions['projection']

// https://github.com/surmon-china/mongodb-data-api/pull/4/files @maxfi
type NoInfer<A extends any> = [A][A extends any ? 0 : never]

type AnyKeys<T> = { [P in keyof T]?: T[P] | any }
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never }
Expand Down Expand Up @@ -59,7 +65,7 @@ interface PackEndpointConfig extends BaseConfig {

export type Config = XOR<UrlEndpointConfig, PackEndpointConfig>

export class MongoDBDataAPI<InnerDoc = any> {
export class MongoDBDataAPI<InnerDoc = Document> {
#config: Config
#baseParams: BaseParams
#axios: AxiosInstance
Expand All @@ -84,11 +90,11 @@ export class MongoDBDataAPI<InnerDoc = any> {
)
}

/** Select a collection. */
public $collection<Doc = InnerDoc>(collection: string) {
return this.#newAPI<Doc>({ collection }) as Omit<
MongoDBDataAPI<Doc>,
'$cluster' | '$database' | '$collection'
/** Select a cluster. */
public $cluster(clusterName: string) {
return this.#newAPI<InnerDoc>({ dataSource: clusterName }) as Omit<
MongoDBDataAPI<InnerDoc>,
'$cluster' | '$collection'
>
}

Expand All @@ -100,19 +106,19 @@ export class MongoDBDataAPI<InnerDoc = any> {
>
}

/** Select a cluster. */
public $cluster(clusterName: string) {
return this.#newAPI<InnerDoc>({ dataSource: clusterName }) as Omit<
MongoDBDataAPI<InnerDoc>,
'$cluster' | '$collection'
/** Select a collection. */
public $collection<Doc = InnerDoc>(collection: string) {
return this.#newAPI<Doc>({ collection }) as Omit<
MongoDBDataAPI<Doc>,
'$cluster' | '$database' | '$collection'
>
}

/**
* Execute a API action.
* @link https://docs.atlas.mongodb.com/api/data-api-resources/
*/
public $$action<Result = any>(
public $$action<Result = unknown>(
name: string,
params: BaseParams = {},
axiosConfig?: AxiosRequestConfig
Expand Down Expand Up @@ -156,8 +162,11 @@ export class MongoDBDataAPI<InnerDoc = any> {
* Find a Single Document.
* @link https://docs.atlas.mongodb.com/api/data-api-resources/#find-a-single-document
*/
public findOne<D = InnerDoc>(
params?: ExtendBaseParams<{ filter?: Filter<D>; projection?: Projection<D> }>
public findOne<D = InnerDoc, T = NoInfer<D>>(
params?: ExtendBaseParams<{
filter?: Filter<T>
projection?: Projection
}>
) {
return this.$$action<{ document: D | null }>('findOne', params)
}
Expand All @@ -166,10 +175,10 @@ export class MongoDBDataAPI<InnerDoc = any> {
* Find Multiple Documents.
* @link https://docs.atlas.mongodb.com/api/data-api-resources/#find-multiple-documents
*/
public find<D = InnerDoc>(
public find<D = InnerDoc, T = NoInfer<D>>(
params?: ExtendBaseParams<{
filter?: Filter<D>
projection?: Projection<D>
filter?: Filter<T>
projection?: Projection
sort?: Sort
limit?: number
skip?: number
Expand All @@ -182,8 +191,8 @@ export class MongoDBDataAPI<InnerDoc = any> {
* Insert a Single Document.
* @link https://docs.atlas.mongodb.com/api/data-api-resources/#insert-a-single-document
*/
public insertOne<D = InnerDoc>(
params: ExtendBaseParams<{ document: AnyKeys<D> | Document }>
public insertOne<D = InnerDoc, T = NoInfer<D>>(
params: ExtendBaseParams<{ document: AnyKeys<T> | Document }>
) {
return this.$$action<{ insertedId: string }>('insertOne', params)
}
Expand All @@ -192,8 +201,8 @@ export class MongoDBDataAPI<InnerDoc = any> {
* Insert Multiple Documents.
* @link https://docs.atlas.mongodb.com/api/data-api-resources/#insert-multiple-documents
*/
public insertMany<D = InnerDoc>(
params: ExtendBaseParams<{ documents: Array<AnyKeys<D> | Document> }>
public insertMany<D = InnerDoc, T = NoInfer<D>>(
params: ExtendBaseParams<{ documents: Array<AnyKeys<T> | Document> }>
) {
return this.$$action<{ insertedIds: Array<string> }>('insertMany', params)
}
Expand All @@ -202,10 +211,10 @@ export class MongoDBDataAPI<InnerDoc = any> {
* Update a Single Document.
* @link https://docs.atlas.mongodb.com/api/data-api-resources/#update-a-single-document
*/
public updateOne<D = InnerDoc>(
public updateOne<D = InnerDoc, T = NoInfer<D>>(
params: ExtendBaseParams<{
filter: Filter<D>
update: UpdateFilter<D>
filter: Filter<T>
update: UpdateFilter<T>
upsert?: boolean
}>
) {
Expand All @@ -220,10 +229,10 @@ export class MongoDBDataAPI<InnerDoc = any> {
* Update Multiple Documents.
* @link https://docs.atlas.mongodb.com/api/data-api-resources/#update-multiple-documents
*/
public updateMany<D = InnerDoc>(
public updateMany<D = InnerDoc, T = NoInfer<D>>(
params: ExtendBaseParams<{
filter: Filter<D>
update: UpdateFilter<D>
filter: Filter<T>
update: UpdateFilter<T>
upsert?: boolean
}>
) {
Expand All @@ -238,9 +247,9 @@ export class MongoDBDataAPI<InnerDoc = any> {
* Replace a Single Document.
* @link https://docs.atlas.mongodb.com/api/data-api-resources/#replace-a-single-document
*/
public replaceOne<D = InnerDoc>(
public replaceOne<D = InnerDoc, T = NoInfer<D>>(
params: ExtendBaseParams<{
filter: Filter<D>
filter: Filter<T>
replacement: any
upsert?: boolean
}>
Expand All @@ -256,15 +265,19 @@ export class MongoDBDataAPI<InnerDoc = any> {
* Delete a Single Document.
* @link https://docs.atlas.mongodb.com/api/data-api-resources/#delete-a-single-document
*/
public deleteOne<D = InnerDoc>(params: ExtendBaseParams<{ filter: Filter<D> }>) {
public deleteOne<D = InnerDoc, T = NoInfer<D>>(
params: ExtendBaseParams<{ filter: Filter<T> }>
) {
return this.$$action<{ deletedCount: number }>('deleteOne', params)
}

/**
* Delete Multiple Documents.
* @link https://docs.atlas.mongodb.com/api/data-api-resources/#delete-multiple-documents
*/
public deleteMany<D = InnerDoc>(params: ExtendBaseParams<{ filter: Filter<D> }>) {
public deleteMany<D = InnerDoc, T = NoInfer<D>>(
params: ExtendBaseParams<{ filter: Filter<T> }>
) {
return this.$$action<{ deletedCount: number }>('deleteMany', params)
}

Expand All @@ -278,3 +291,7 @@ export class MongoDBDataAPI<InnerDoc = any> {
return this.$$action<{ documents: T }>('pipeline', params)
}
}

export const createMongoDBDataAPI = (config: Config, axios?: AxiosInstance) => {
return new MongoDBDataAPI(config, void 0, axios)
}
Loading

0 comments on commit fdf3bc9

Please sign in to comment.