@nestjs/azure-database
Advanced tools
Comparing version 1.0.0 to 2.0.0
@@ -189,3 +189,3 @@ # Contributing to Nest | ||
``` | ||
bugfix(@nestjs/core) need to depend on latest rxjs and zone.js | ||
fix(@nestjs/core) need to depend on latest rxjs and zone.js | ||
@@ -202,6 +202,7 @@ The version in our package.json gets copied to the one we publish, and users need the latest of these. | ||
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm) | ||
* **chore**: Updating tasks etc; no production code change | ||
* **ci**: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs) | ||
* **docs**: Documentation only changes | ||
* **feature**: A new feature | ||
* **bugfix**: A bug fix | ||
* **feat**: A new feature | ||
* **fix**: A bug fix | ||
* **perf**: A code change that improves performance | ||
@@ -208,0 +209,0 @@ * **refactor**: A code change that neither fixes a bug nor adds a feature |
module.exports = { | ||
preset: 'ts-jest', | ||
testEnvironment: 'node', | ||
}; | ||
testPathIgnorePatterns: ['<rootDir>/sample/'], | ||
}; |
{ | ||
"name": "@nestjs/azure-database", | ||
"version": "1.0.0", | ||
"version": "2.0.0", | ||
"description": "The Azure Table Storage module for Nest framework (node.js)", | ||
@@ -21,3 +21,5 @@ "author": { | ||
"build": "rimraf dist && npm run build:lib && npm test", | ||
"lint": "eslint '{lib,tests}/**/*.ts' --fix", | ||
"build:lib": "tsc -p tsconfig.json", | ||
"prepare": "npm run build", | ||
"prepublish:npm": "npm run build", | ||
@@ -29,31 +31,37 @@ "publish:npm": "npm publish --access public", | ||
"peerDependencies": { | ||
"@nestjs/common": "^6.0.0", | ||
"@nestjs/core": "^6.0.0" | ||
"@nestjs/common": "^7.0.0", | ||
"@nestjs/core": "^7.0.0" | ||
}, | ||
"dependencies": { | ||
"@azure/cosmos": "^3.4.2", | ||
"@azure/ms-rest-js": "^2.0.4", | ||
"@nestjs/common": "^6.0.0", | ||
"@nestjs/core": "^6.0.0", | ||
"@nestjs/common": "^7.0.0", | ||
"@nestjs/core": "^7.0.0", | ||
"azure-storage": "^2.10.3" | ||
}, | ||
"devDependencies": { | ||
"@nestjs/testing": "6.7.1", | ||
"@types/jest": "24.0.18", | ||
"@types/node": "11.13.21", | ||
"@commitlint/cli": "12.0.1", | ||
"@commitlint/config-angular": "12.0.1", | ||
"@nestjs/testing": "7.6.14", | ||
"@types/jest": "26.0.20", | ||
"@types/node": "11.15.49", | ||
"@typescript-eslint/eslint-plugin": "4.18.0", | ||
"@typescript-eslint/parser": "4.18.0", | ||
"dotenv": "^8.1.0", | ||
"husky": "3.0.5", | ||
"jest": "24.9.0", | ||
"lint-staged": "9.4.0", | ||
"prettier": "1.18.2", | ||
"eslint": "7.22.0", | ||
"eslint-config-prettier": "8.1.0", | ||
"eslint-plugin-import": "2.22.1", | ||
"husky": "5.1.3", | ||
"jest": "26.6.3", | ||
"lint-staged": "10.5.4", | ||
"prettier": "2.2.1", | ||
"reflect-metadata": "^0.1.13", | ||
"rimraf": "^3.0.0", | ||
"supertest": "4.0.2", | ||
"ts-jest": "24.1.0", | ||
"tslint": "5.20.0", | ||
"typescript": "3.6.3" | ||
"supertest": "6.1.3", | ||
"ts-jest": "26.5.3", | ||
"typescript": "4.2.3" | ||
}, | ||
"lint-staged": { | ||
"*.ts": [ | ||
"prettier --write", | ||
"git add" | ||
"prettier --write" | ||
] | ||
@@ -63,5 +71,6 @@ }, | ||
"hooks": { | ||
"pre-commit": "lint-staged" | ||
"pre-commit": "lint-staged", | ||
"commit-msg": "commitlint -c .commitlintrc.json -E HUSKY_GIT_PARAMS" | ||
} | ||
} | ||
} |
261
README.md
@@ -10,3 +10,3 @@ <p align="center"> | ||
<p align="center">A progressive <a href="http://nodejs.org" target="blank">Node.js</a> framework for building efficient and scalable server-side applications, heavily inspired by <a href="https://angular.io" target="blank">Angular</a>.</p> | ||
<p align="center">A progressive <a href="http://nodejs.org" target="blank">Node.js</a> framework for building efficient and scalable server-side applications.</p> | ||
<p align="center"> | ||
@@ -19,3 +19,3 @@ <a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a> | ||
<a href="https://coveralls.io/github/nestjs/nest?branch=master"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#5" alt="Coverage" /></a> | ||
<a href="https://gitter.im/nestjs/nestjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge"><img src="https://badges.gitter.im/nestjs/nestjs.svg" alt="Gitter" /></a> | ||
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a> | ||
<a href="https://opencollective.com/nest#backer"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a> | ||
@@ -31,3 +31,3 @@ <a href="https://opencollective.com/nest#sponsor"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a> | ||
Azure Database ([Table Storage](http://bit.ly/nest_azure-storage-table) and more) module for [Nest](https://github.com/nestjs/nest) framework (node.js) | ||
Azure Database ([Table Storage](http://bit.ly/nest_azure-storage-table), [Cosmos DB](https://azure.microsoft.com/en-us/services/cosmos-db/) and more) module for [Nest](https://github.com/nestjs/nest) framework (node.js) | ||
@@ -38,5 +38,6 @@ ## Tutorial | ||
## Before Installation | ||
For Table Storage | ||
1. Create a Storage account and resource ([read more](http://bit.ly/nest_new-azure-storage-account)) | ||
@@ -46,2 +47,8 @@ 1. For [Table Storage](http://bit.ly/nest_azure-storage-table), In the [Azure Portal](https://portal.azure.com), go to **Dashboard > Storage > _your-storage-account_**. | ||
For Cosmos DB | ||
1. Create a Cosmos DB account and resource ([read more](https://azure.microsoft.com/en-us/services/cosmos-db/)) | ||
1. For [Cosmos DB](http://bit.ly/nest_azure-storage-table), In the [Azure Portal](https://portal.azure.com), go to **Dashboard > Azure Cosmos DB > _your-cosmos-db-account_**. | ||
1. Note down the "URI" and "Primary Key" obtained at **Keys** under **Settings** tab. | ||
## Installation | ||
@@ -63,7 +70,7 @@ | ||
2. **IMPORTANT: Make sure to add your `.env` file to your .gitignore! The `.env` file MUST NOT be versionned on Git.** | ||
2. **IMPORTANT: Make sure to add your `.env` file to your .gitignore! The `.env` file MUST NOT be versioned on Git.** | ||
3. Make sure to include the following call to your main file: | ||
``` | ||
```typescript | ||
if (process.env.NODE_ENV !== 'production') require('dotenv').config(); | ||
@@ -84,3 +91,3 @@ ``` | ||
1. Create a Data Transfert Object (DTO) inside a file named `contact.dto.ts`: | ||
1. Create a Data Transfer Object (DTO) inside a file named `contact.dto.ts`: | ||
@@ -106,3 +113,3 @@ ```typescript | ||
- `@EntityBoolean(value?: string)`: For `true` or `false`values. | ||
- `@EntityBoolean(value?: string)`: For `true` or `false` values. | ||
@@ -158,3 +165,3 @@ - `@EntityString(value?: string)`: For character data. | ||
You can optionnaly pass in the following arguments: | ||
You can optionally pass in the following arguments: | ||
@@ -165,11 +172,10 @@ ```typescript | ||
createTableIfNotExists: true, | ||
}) | ||
}); | ||
``` | ||
- `table: string`: The name of the table. If not provided, the name of the `Contact` entity will be used as a table name | ||
- `createTableIfNotExists: boolean`: Whether to automatically create the table if it doesn't exists or not: | ||
- `createTableIfNotExists: boolean`: Whether to automatically create the table if it doesn't exists or not: | ||
- If `true` the table will be created during the startup of the app. | ||
- If `false` the table will not be created. **You will have to create the table by yoursel before querying it!** | ||
- If `false` the table will not be created. **You will have to create the table by yourself before querying it!** | ||
#### CRUD operations | ||
@@ -194,3 +200,4 @@ | ||
@InjectRepository(Contact) | ||
private readonly contactRepository: Repository<Contact>) {} | ||
private readonly contactRepository: Repository<Contact>, | ||
) {} | ||
} | ||
@@ -209,6 +216,5 @@ ``` | ||
async create(contact: Contact, rowKeyValue: string): Promise<Contact> { | ||
//if rowKeyValue is null, rowKeyValue will generate a UUID | ||
return this.contactRepository.create(contact, rowKeyValue) | ||
} | ||
//if rowKeyValue is null, rowKeyValue will generate a UUID | ||
return this.contactRepository.create(contact, rowKeyValue) | ||
} | ||
``` | ||
@@ -224,3 +230,3 @@ | ||
try { | ||
return await this.contactService.find(rowKey, new Contact()); | ||
return await this.contactRepository.find(rowKey, new Contact()); | ||
} catch (error) { | ||
@@ -238,3 +244,3 @@ // Entity not found | ||
async getAllContacts() { | ||
return await this.contactService.findAll(); | ||
return await this.contactRepository.findAll(); | ||
} | ||
@@ -255,3 +261,3 @@ ``` | ||
return await this.contactService.update(rowKey, contactEntity); | ||
return await this.contactRepository.update(rowKey, contactEntity); | ||
} catch (error) { | ||
@@ -268,3 +274,3 @@ throw new UnprocessableEntityException(error); | ||
return await this.contactService.update(rowKey, contactEntity); | ||
return await this.contactRepository.update(rowKey, contactEntity); | ||
} catch (error) { | ||
@@ -285,3 +291,3 @@ throw new UnprocessableEntityException(error); | ||
try { | ||
const response = await this.contactService.delete(rowKey, new Contact()); | ||
const response = await this.contactRepository.delete(rowKey, new Contact()); | ||
@@ -299,2 +305,211 @@ if (response.statusCode === 204) { | ||
### For Azure Cosmos DB support | ||
1. Create or update your existing `.env` file with the following content: | ||
``` | ||
AZURE_COSMOS_DB_NAME= | ||
AZURE_COSMOS_DB_ENDPOINT= | ||
AZURE_COSMOS_DB_KEY= | ||
``` | ||
2. **IMPORTANT: Make sure to add your `.env` file to your .gitignore! The `.env` file MUST NOT be versioned on Git.** | ||
3. Make sure to include the following call to your main file: | ||
```typescript | ||
if (process.env.NODE_ENV !== 'production') require('dotenv').config(); | ||
``` | ||
> This line must be added before any other imports! | ||
### Example | ||
> Note: Check out the CosmosDB example project included in the [sample folder](https://github.com/nestjs/azure-database/tree/master/sample/cosmos-db) | ||
#### Prepare your entity | ||
0. Create a new feature module, eg. with the nest CLI: | ||
```shell | ||
$ nest generate module event | ||
``` | ||
1. Create a Data Transfer Object (DTO) inside a file named `event.dto.ts`: | ||
```typescript | ||
export class EventDTO { | ||
name: string; | ||
type: string; | ||
date: Date; | ||
location: Point; | ||
} | ||
``` | ||
2. Create a file called `event.entity.ts` and describe the entity model using the provided decorators: | ||
- `@CosmosPartitionKey(value: string)`: Represents the `PartitionKey` of the entity (**required**). | ||
- `@CosmosDateTime(value?: string)`: For DateTime values. | ||
For instance, the shape of the following entity: | ||
```typescript | ||
import { CosmosPartitionKey, CosmosDateTime, Point } from '@nestjs/azure-database'; | ||
@CosmosPartitionKey('type') | ||
export class Event { | ||
id?: string; | ||
type: string; | ||
@CosmosDateTime() createdAt: Date; | ||
location: Point; | ||
} | ||
``` | ||
Will be automatically converted to: | ||
```json | ||
{ | ||
"type": "Meetup", | ||
"createdAt": "2019-11-15T17:05:25.427Z", | ||
"position": { | ||
"type": "Point", | ||
"coordinates": [2.3522, 48.8566] | ||
} | ||
} | ||
``` | ||
3. Import the `AzureCosmosDbModule` inside your Nest feature module `event.module.ts`: | ||
```typescript | ||
import { Module } from '@nestjs/common'; | ||
import { AzureCosmosDbModule } from '@nestjs/azure-database'; | ||
import { EventController } from './event.controller'; | ||
import { EventService } from './event.service'; | ||
import { Event } from './event.entity'; | ||
@Module({ | ||
imports: [ | ||
AzureCosmosDbModule.forRoot({ | ||
dbName: process.env.AZURE_COSMOS_DB_NAME, | ||
endpoint: process.env.AZURE_COSMOS_DB_ENDPOINT, | ||
key: process.env.AZURE_COSMOS_DB_KEY, | ||
}), | ||
AzureCosmosDbModule.forFeature([{ dto: Event }]), | ||
], | ||
providers: [EventService], | ||
controllers: [EventController], | ||
}) | ||
export class EventModule {} | ||
``` | ||
#### CRUD operations | ||
0. Create a service that will abstract the CRUD operations: | ||
```shell | ||
$ nest generate service event | ||
``` | ||
1. Use the `@InjectModel(Event)` to get an instance of the Azure Cosmos DB [Container](https://docs.microsoft.com/en-us/javascript/api/@azure/cosmos/container) for the entity definition created earlier: | ||
```typescript | ||
import { Injectable } from '@nestjs/common'; | ||
import { InjectModel } from '@nestjs/azure-database'; | ||
import { Event } from './event.entity'; | ||
@Injectable() | ||
export class EventService { | ||
constructor( | ||
@InjectModel(Event) | ||
private readonly eventContainer, | ||
) {} | ||
} | ||
``` | ||
The Azure Cosmos DB `Container` provides a couple of public APIs and Interfaces for managing various CRUD operations: | ||
##### CREATE | ||
`create(entity: T): Promise<T>`: creates a new entity. | ||
```typescript | ||
@Post() | ||
async create(event: Event): Promise<Event> { | ||
return this.eventContainer.items.create(event) | ||
} | ||
``` | ||
##### READ | ||
`query<T>(query: string | SqlQuerySpec, options?: FeedOptions): QueryIterator<T>`: run a SQL Query to find a document. | ||
```typescript | ||
@Get(':id') | ||
async getContact(@Param('id') id) { | ||
try { | ||
const querySpec = { | ||
query: "SELECT * FROM root r WHERE r.id=@id", | ||
parameters: [ | ||
{ | ||
name: "@id", | ||
value: id | ||
} | ||
] | ||
}; | ||
const { resources } = await this.eventContainer.items.query<Event>(querySpec).fetchAll() | ||
return resources | ||
} catch (error) { | ||
// Entity not found | ||
throw new UnprocessableEntityException(error); | ||
} | ||
} | ||
``` | ||
##### UPDATE | ||
`read<T>(options?: RequestOptions): Promise<ItemResponse<T>>`: Get a document. | ||
`replace<T>(body: T, options?: RequestOptions): Promise<ItemResponse<T>>`: Updates a document. | ||
```typescript | ||
@Put(':id') | ||
async saveEvent(@Param('id') id, @Body() eventData: EventDTO) { | ||
try { | ||
const { resource: item } = await this.eventContainer.item<Event>(id, 'type').read() | ||
// Disclaimer: Assign only the properties you are expecting! | ||
Object.assign(item, eventData); | ||
const { resource: replaced } = await this.eventContainer | ||
.item(id, 'type') | ||
.replace<Event>(item) | ||
return replaced | ||
} catch (error) { | ||
throw new UnprocessableEntityException(error); | ||
} | ||
} | ||
``` | ||
##### DELETE | ||
`delete<T>(options?: RequestOptions): Promise<ItemResponse<T>>`: Removes an entity from the database. | ||
```typescript | ||
@Delete(':id') | ||
async deleteEvent(@Param('id') id) { | ||
try { | ||
const { resource: deleted } = await this.eventContainer | ||
.item(id, 'type') | ||
.delete<Event>() | ||
return deleted; | ||
} catch (error) { | ||
throw new UnprocessableEntityException(error); | ||
} | ||
} | ||
``` | ||
## Support | ||
@@ -301,0 +516,0 @@ |
@@ -5,3 +5,8 @@ { | ||
], | ||
"semanticCommits": true, | ||
"packageRules": [{ | ||
"depTypeList": ["devDependencies"], | ||
"automerge": true | ||
}], | ||
"rangeStrategy": "replace" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
71417
59
819
512
7
20
1
+ Added@azure/cosmos@^3.4.2
+ Added@azure/abort-controller@1.1.0(transitive)
+ Added@azure/core-rest-pipeline@1.17.0(transitive)
+ Added@azure/core-tracing@1.2.0(transitive)
+ Added@azure/cosmos@3.17.3(transitive)
+ Added@azure/logger@1.1.4(transitive)
+ Added@nestjs/common@7.6.18(transitive)
+ Added@nestjs/core@7.6.18(transitive)
+ Added@nuxtjs/opencollective@0.3.2(transitive)
+ Addedagent-base@7.1.1(transitive)
+ Addedansi-styles@4.3.0(transitive)
+ Addedaxios@0.21.1(transitive)
+ Addedchalk@4.1.2(transitive)
+ Addedcolor-convert@2.0.1(transitive)
+ Addedcolor-name@1.1.4(transitive)
+ Addeddebug@4.3.7(transitive)
+ Addedfollow-redirects@1.15.9(transitive)
+ Addedhas-flag@4.0.0(transitive)
+ Addedhttp-proxy-agent@7.0.2(transitive)
+ Addedhttps-proxy-agent@7.0.5(transitive)
+ Addediterare@1.2.1(transitive)
+ Addedjsbi@3.2.5(transitive)
+ Addedms@2.1.3(transitive)
+ Addednode-abort-controller@3.1.1(transitive)
+ Addedobject-hash@2.1.1(transitive)
+ Addedpriorityqueuejs@1.0.0(transitive)
+ Addedpsl@1.10.0(transitive)
+ Addedsemaphore@1.1.0(transitive)
+ Addedsupports-color@7.2.0(transitive)
+ Addedtslib@2.2.0(transitive)
+ Addeduniversal-user-agent@6.0.1(transitive)
- Removed@nestjs/common@6.11.11(transitive)
- Removed@nestjs/core@6.11.11(transitive)
- Removed@nuxtjs/opencollective@0.2.2(transitive)
- Removedansi-regex@2.1.1(transitive)
- Removedansi-styles@3.2.1(transitive)
- Removedaxios@0.19.2(transitive)
- Removedchalk@2.4.2(transitive)
- Removedcli-color@2.0.0(transitive)
- Removedcolor-convert@1.9.3(transitive)
- Removedcolor-name@1.1.3(transitive)
- Removedd@1.0.2(transitive)
- Removedes5-ext@0.10.64(transitive)
- Removedes6-iterator@2.0.3(transitive)
- Removedes6-symbol@3.1.4(transitive)
- Removedes6-weak-map@2.0.3(transitive)
- Removedescape-string-regexp@1.0.5(transitive)
- Removedesniff@2.0.1(transitive)
- Removedevent-emitter@0.3.5(transitive)
- Removedext@1.7.0(transitive)
- Removedfollow-redirects@1.5.10(transitive)
- Removedhas-flag@3.0.0(transitive)
- Removedis-promise@2.2.2(transitive)
- Removediterare@1.2.0(transitive)
- Removedlru-queue@0.1.0(transitive)
- Removedmemoizee@0.4.17(transitive)
- Removednext-tick@1.1.0(transitive)
- Removedobject-hash@2.0.3(transitive)
- Removedpsl@1.9.0(transitive)
- Removedsupports-color@5.5.0(transitive)
- Removedtimers-ext@0.1.8(transitive)
- Removedtslib@1.11.1(transitive)
- Removedtype@2.7.3(transitive)
- Removeduuid@7.0.1(transitive)
Updated@nestjs/common@^7.0.0
Updated@nestjs/core@^7.0.0