diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/README.md b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/README.md new file mode 100644 index 0000000000..b2becbd610 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/README.md @@ -0,0 +1,450 @@ +# Cascading Option Loading with Extensions System in ABP Angular + +In this article we'll see how to loading cascading options with extensions system in ABP Angular. For this example we'll simulate renting a book process. Beside our default form properties we'll contribute `Name` property to our `Rent Form Modal` in Books module. This property will be loaded after `Genre` selected. + +> Before starting this article, I suggest you to read the [ABP Angular Dynamic Form Extensions](https://docs.abp.io/en/abp/latest/UI/Angular/Dynamic-Form-Extensions) + +### Environment + +- **ABP Framework Version:** ~7.3.0 (`~` means that use the latest patch version of the specified release) +- **DB Provider:** MongoDB +- **Angular Version:** ~16.0.0 + +### Project structure + +Books module is not a library, for this demo it'll placed in application itself + +![Folder structure](./assets/img/folder-structure.png) + +- **books folder:** Contains default form properties, tokens, models, etc. It's smilar abp module structure. +- Also I've used **standalone** and **signals** feature in this demo. +- **books-extended folder:** Contains only `Name` property for the contribute `Rent Form Modal` inside Books module. +- **For more readibility, I've used TS path aliases in this demo. Don't forget to export files in `index.ts` file 🙂** + +![tsconfig.json file](./assets/img/ts-config-file.png) + +### First look at the demo + +![Cascading Loading Demo](assets/gif/cascading-loading-demo.gif) + +### What is extensions system? + +![Extensions System Document](./assets/img/extensions-system-document.png) + +# Reviewing the code step by step + +**1.Create default form properties for `Rent Form` in the `Books` module** + +- `getInjected` function is the key point of the cascading loading +- We can reach and track any value from `Service` or `Component` +- In that way we can load options according to the selected value + +```ts +// ~/books/defaults/default-books-form.props.ts + +import { Validators } from "@angular/forms"; +import { map, of } from "rxjs"; +import { ePropType, FormProp } from "@abp/ng.theme.shared/extensions"; +import { BookDto, AuthorService, BooksService } from "../proxy"; +import { RentBookComponent } from "../components"; +import { DefaultOption } from "../utils"; + +const { required } = Validators; + +export const DEFAULT_RENT_FORM_PROPS = FormProp.createMany([ + { + type: ePropType.String, + id: "authorId", + name: "authorId", + displayName: "BookStore::Author", + defaultValue: null, + validators: () => [required], + options: (data) => { + const { authors } = data.getInjected(AuthorService); + + return of([ + DefaultOption, + ...authors().map((author) => ({ value: author.id, key: author.name })), + ]); + }, + }, + { + type: ePropType.String, + id: "genreId", + name: "genreId", + displayName: "BookStore::Genre", + defaultValue: null, + validators: () => [required], + options: (data) => { + const rentBookComponent = data.getInjected(RentBookComponent); + const { genres } = data.getInjected(BooksService); + + const genreOptions = genres().map(({ id, name }) => ({ + value: id, + key: name, + })); + + return rentBookComponent.form.controls.authorId.valueChanges.pipe( + map((value: string | undefined) => + value ? [DefaultOption, ...genreOptions] : [DefaultOption] + ) + ); + }, + }, + { + type: ePropType.Date, + id: "returnDate", + name: "returnDate", + displayName: "BookStore::ReturnDate", + defaultValue: null, + validators: () => [required], + }, +]); +``` + +**2.Configure tokens and config options** + +This steps explained in documentation, that's why I won't explain it again. If document or samples not enough please let me know 🙂 + +**Extensions Token** + +```ts +// ~/books/tokens/extensions.token.ts + +import { CreateFormPropContributorCallback } from "@abp/ng.theme.shared/extensions"; +import { InjectionToken } from "@angular/core"; +import { BookDto } from "../proxy"; +import { eBooksComponents } from "../enums"; +import { DEFAULT_RENT_FORM_PROPS } from "../defaults"; + +export const DEFAULT_BOOK_STORE_CREATE_FORM_PROPS = { + [eBooksComponents.RentBook]: DEFAULT_RENT_FORM_PROPS, +}; + +export const BOOK_STORE_RENT_FORM_PROP_CONTRIBUTORS = + new InjectionToken( + "BOOK_STORE_RENT_FORM_PROP_CONTRIBUTORS" + ); + +type CreateFormPropContributors = Partial<{ + [eBooksComponents.RentBook]: CreateFormPropContributorCallback[]; + /** + * Other creation form prop contributors... + */ + // [eBooksComponents.CreateBook]: CreateFormPropContributorCallback[]; +}>; +``` + +**Extensions Config Option** + +```ts +// ~/books/models/config-options.ts + +import { CreateFormPropContributorCallback } from "@abp/ng.theme.shared/extensions"; +import { BookDto } from "../proxy"; +import { eBooksComponents } from "../enums"; + +export type BookStoreRentFormPropContributors = Partial<{ + [eBooksComponents.RentBook]: CreateFormPropContributorCallback[]; +}>; + +export interface BooksConfigOptions { + rentFormPropContributors?: BookStoreRentFormPropContributors; +} +``` + +**3.Extensions Guard** + +It'll to collect all contributors from [ExtensionsService](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/theme-shared/extensions/src/lib/services/extensions.service.ts) + +```ts +// ~/books/guards/extensions.guard.ts + +import { Injectable, inject } from "@angular/core"; +import { Observable, map, tap } from "rxjs"; +import { ConfigStateService, IAbpGuard } from "@abp/ng.core"; +import { + ExtensionsService, + getObjectExtensionEntitiesFromStore, + mapEntitiesToContributors, + mergeWithDefaultProps, +} from "@abp/ng.theme.shared/extensions"; +import { + BOOK_STORE_RENT_FORM_PROP_CONTRIBUTORS, + DEFAULT_BOOK_STORE_CREATE_FORM_PROPS, +} from "../tokens"; + +@Injectable() +export class BooksExtensionsGuard implements IAbpGuard { + protected readonly configState = inject(ConfigStateService); + protected readonly extensions = inject(ExtensionsService); + + canActivate(): Observable { + const createFormContributors = + inject(BOOK_STORE_RENT_FORM_PROP_CONTRIBUTORS, { optional: true }) || {}; + + return getObjectExtensionEntitiesFromStore( + this.configState, + "BookStore" + ).pipe( + mapEntitiesToContributors(this.configState, "BookStore"), + tap((objectExtensionContributors) => { + mergeWithDefaultProps( + this.extensions.createFormProps, + DEFAULT_BOOK_STORE_CREATE_FORM_PROPS, + objectExtensionContributors.createForm, + createFormContributors + ); + }), + map(() => true) + ); + } +} +``` + +Yes I'm still using class based guard 🙂 much flexible... + +**4.RentBookComponent** + +- Our trackable variable defined here `(form:FormGroup)`, which means We'll track this variable in `options` property at defaults || contributors files. +- Providing `AuthorService`, also `EXTENSIONS_IDENTIFIER` for the reach dynamic properties + +```ts +import { + ChangeDetectionStrategy, + Component, + EventEmitter, + Injector, + Output, + inject, +} from "@angular/core"; +import { FormGroup } from "@angular/forms"; +import { CoreModule, uuid } from "@abp/ng.core"; +import { ThemeSharedModule } from "@abp/ng.theme.shared"; +import { + EXTENSIONS_IDENTIFIER, + FormPropData, + UiExtensionsModule, + generateFormFromProps, +} from "@abp/ng.theme.shared/extensions"; +import { AuthorService, BookDto, BooksService } from "../../proxy"; +import { eBooksComponents } from "../../enums"; + +@Component({ + standalone: true, + selector: "app-rent-book", + templateUrl: "./rent-book.component.html", + imports: [CoreModule, UiExtensionsModule, ThemeSharedModule], + providers: [ + { + provide: EXTENSIONS_IDENTIFIER, + useValue: eBooksComponents.RentBook, + }, + AuthorService, + ], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class RentBookComponent { + protected readonly injector = inject(Injector); + protected readonly authorService = inject(AuthorService); + protected readonly booksService = inject(BooksService); + + //#region Just for demo + readonly #authors = this.authorService.authors(); + readonly #genres = this.booksService.genres(); + readonly #books = this.booksService.books(); + //#endregion + + protected modalVisible = true; + @Output() modalVisibleChange = new EventEmitter(); + + selected: BookDto; + form: FormGroup; + modalBusy = false; + + protected buildForm(): void { + const data = new FormPropData(this.injector, this.selected); + this.form = generateFormFromProps(data); + } + + constructor() { + this.buildForm(); + } + + save(): void { + if (this.form.invalid) { + return; + } + + this.modalBusy = true; + + const { authorId, genreId, bookId, returnDate } = this.form.value; + + //#region Just for demo + const authorName = this.#authors.find(({ id }) => id === authorId).name; + const genreName = this.#genres.find(({ id }) => id === genreId).name; + const bookName = this.#books.find(({ id }) => id === bookId).name; + //#endregion + + this.booksService.rentedBooks.update((books) => [ + { + id: uuid(), + name: bookName, + author: authorName, + genre: genreName, + returnDate, + }, + ...books, + ]); + + this.modalBusy = false; + this.modalVisible = false; + } +} +``` + +```html + + +

{{ 'BookStore::RentABook' | abpLocalization }}

+
+ + + +
+ +
+
+ +
+ +
+
+ + + + + {{ 'AbpIdentity::Save' | abpLocalization }} + + +
+``` + +Up to the present we constructed our module's default form properties. + +- As you can see there is no book names we'll add it via contributors + +![Rent Form Without Contribution](./assets/img/rent-form-without-contribution.png) + +## Next, add new property dynamically (book name list as dropdown) + +- Created new folder ./src/app/books-extended +- Create contributors/form-prop.contributors.ts + +```ts +// ~/books-extened/contributors/form-prop.contributors.ts + +import { Validators } from "@angular/forms"; +import { map } from "rxjs"; +import { + ePropType, + FormProp, + FormPropList, +} from "@abp/ng.theme.shared/extensions"; +import { + BookDto, + BookStoreRentFormPropContributors, + BooksService, + DefaultOption, + RentBookComponent, + eBooksComponents, +} from "@book-store/books"; + +const { required, maxLength } = Validators; + +const bookIdProp = new FormProp({ + type: ePropType.String, + id: "bookId", + name: "bookId", + displayName: "BookStore::Name", + options: (data) => { + const rentBook = data.getInjected(RentBookComponent); + const { books } = data.getInjected(BooksService); + const bookOptions = books().map(({ id, name }) => ({ + value: id, + key: name, + })); + + return rentBook.form.controls.genreId.valueChanges.pipe( + map((value: string | undefined) => + value ? [DefaultOption, ...bookOptions] : [DefaultOption] + ) + ); + }, + validators: () => [required, maxLength(255)], +}); + +export function bookIdPropContributor(propList: FormPropList) { + propList.addByIndex(bookIdProp, 2); +} + +export const bookStoreRentFormPropContributors: BookStoreRentFormPropContributors = + { + [eBooksComponents.RentBook]: [bookIdPropContributor], + }; +``` + +- Load new contribution via routing & forLazy method + +```ts +// ~/app-routing.module.ts +import { bookStoreRentFormPropContributors } from "./books-extended/contributors/form-prop.contributors"; + +const routes: Routes = [ + // other routes... + { + path: "books", + loadChildren: () => + import("@book-store/books").then((m) => + m.BooksModule.forLazy({ + rentFormPropContributors: bookStoreRentFormPropContributors, + }) + ), + }, +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes, {})], + exports: [RouterModule], +}) +export class AppRoutingModule {} +``` + +Finally.. We've added new property to our module, and it'll be loaded after `Genre` selected. + +## Conclusion + +![Cascading Loading Demo](assets/gif/cascading-loading-demo.gif) + +- In ABP Angular, we can create form properties and load dropdown options dynamically via Extensions System +- We can reach and track any value from `Service` or `Component` +- We can create our custom library or module and contribute it to any module in application + +Thanks for reading, I hope it was helpful. If you have any questions, please let me know in the comments section. 👋👋 + +> You can find the source code of this article on [Github]() diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/.editorconfig b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/.editorconfig new file mode 100644 index 0000000000..59d9a3a3e7 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/.eslintrc.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/.eslintrc.json new file mode 100644 index 0000000000..47c17dd9dd --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/.eslintrc.json @@ -0,0 +1,50 @@ +{ + "root": true, + "ignorePatterns": [ + "projects/**/*" + ], + "overrides": [ + { + "files": [ + "*.ts" + ], + "parserOptions": { + "project": [ + "tsconfig.json" + ], + "createDefaultProgram": true + }, + "extends": [ + "plugin:@angular-eslint/recommended", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": [ + "*.html" + ], + "extends": [ + "plugin:@angular-eslint/template/recommended" + ], + "rules": {} + } + ] +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/.gitignore b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/.gitignore new file mode 100644 index 0000000000..b4042df1b4 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/.gitignore @@ -0,0 +1,50 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/tmp +/out-tsc +# Only exists if Bazel was run +/bazel-out + +# dependencies +/node_modules + +# profiling files +chrome-profiler-events*.json + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# misc +/.angular/cache +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +.DS_Store +Thumbs.db + +# Lock Files +*.lock +*lock.json \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/.prettierrc b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/.prettierrc new file mode 100644 index 0000000000..d0293174f3 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/.prettierrc @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "printWidth": 100, + "arrowParens": "avoid" +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/README.md b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/README.md new file mode 100644 index 0000000000..f6e01703e8 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/README.md @@ -0,0 +1,27 @@ +# BookStore + +This is a startup project based on the ABP framework. For more information, visit abp.io + +## Development server + +Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. + +## Code scaffolding + +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. + +## Build + +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. + +## Running unit tests + +Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Running end-to-end tests + +Run `ng e2e` to execute the end-to-end tests via a platform of your choice. + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/angular.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/angular.json new file mode 100644 index 0000000000..0087ff9925 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/angular.json @@ -0,0 +1,186 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "cli": { + "analytics": false, + "schematicCollections": ["@angular-eslint/schematics"] + }, + "version": 1, + "newProjectRoot": "projects", + "projects": { + "BookStore": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/BookStore", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "allowedCommonJsDependencies": ["chart.js", "js-sha256"], + "assets": ["src/favicon.ico", "src/assets"], + "styles": [ + { + "input": "node_modules/@fortawesome/fontawesome-free/css/all.min.css", + "inject": true, + "bundleName": "fontawesome-all.min" + }, + { + "input": "node_modules/@fortawesome/fontawesome-free/css/v4-shims.min.css", + "inject": true, + "bundleName": "fontawesome-v4-shims.min" + }, + { + "input": "node_modules/@swimlane/ngx-datatable/index.css", + "inject": true, + "bundleName": "ngx-datatable-index" + }, + { + "input": "node_modules/@swimlane/ngx-datatable/assets/icons.css", + "inject": true, + "bundleName": "ngx-datatable-icons" + }, + { + "input": "node_modules/@swimlane/ngx-datatable/themes/material.css", + "inject": true, + "bundleName": "ngx-datatable-material" + }, + { + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/bootstrap-dim.css", + "inject": false, + "bundleName": "bootstrap-dim" + }, + { + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/ng-bundle.css", + "inject": false, + "bundleName": "ng-bundle" + }, + { + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/side-menu/layout-bundle.css", + "inject": false, + "bundleName": "layout-bundle" + }, + { + "input": "node_modules/@abp/ng.theme.lepton-x/assets/css/abp-bundle.css", + "inject": false, + "bundleName": "abp-bundle" + }, + { + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/bootstrap-dim.rtl.css", + "inject": false, + "bundleName": "bootstrap-dim.rtl" + }, + { + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/font-bundle.css", + "inject": false, + "bundleName": "font-bundle" + }, + { + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/font-bundle.rtl.css", + "inject": false, + "bundleName": "font-bundle.rtl" + }, + { + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/ng-bundle.rtl.css", + "inject": false, + "bundleName": "ng-bundle.rtl" + }, + { + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/side-menu/layout-bundle.rtl.css", + "inject": false, + "bundleName": "layout-bundle.rtl" + }, + { + "input": "node_modules/@abp/ng.theme.lepton-x/assets/css/abp-bundle.rtl.css", + "inject": false, + "bundleName": "abp-bundle.rtl" + }, + "node_modules/bootstrap-icons/font/bootstrap-icons.css", + "src/styles.scss" + ], + "scripts": ["node_modules/bootstrap/dist/js/bootstrap.min.js"] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "2.5mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "browserTarget": "BookStore:build:production" + }, + "development": { + "browserTarget": "BookStore:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "BookStore:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.spec.json", + "karmaConfig": "karma.conf.js", + "inlineStyleLanguage": "scss", + "assets": ["src/favicon.ico", "src/assets"], + "styles": ["src/styles.scss"], + "scripts": [] + } + }, + "lint": { + "builder": "@angular-eslint/builder:lint", + "options": { + "lintFilePatterns": ["src/**/*.ts", "src/**/*.html"] + } + } + } + } + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/karma.conf.js b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/karma.conf.js new file mode 100644 index 0000000000..b7ce6cf81d --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/karma.conf.js @@ -0,0 +1,44 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + jasmine: { + // you can add configuration options for Jasmine here + // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html + // for example, you can disable the random execution with `random: false` + // or set a specific seed with `seed: 4321` + }, + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + jasmineHtmlReporter: { + suppressAll: true // removes the duplicated traces + }, + coverageReporter: { + dir: require('path').join(__dirname, './coverage/BookStore'), + subdir: '.', + reporters: [ + { type: 'html' }, + { type: 'text-summary' } + ] + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false, + restartOnFileChange: true + }); +}; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/package.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/package.json new file mode 100644 index 0000000000..2210861df0 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/package.json @@ -0,0 +1,62 @@ +{ + "name": "BookStore", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "build:prod": "ng build --configuration production", + "watch": "ng build --watch --configuration development", + "test": "ng test", + "lint": "ng lint" + }, + "private": true, + "dependencies": { + "@abp/ng.account": "~7.3.2", + "@abp/ng.components": "~7.3.2", + "@abp/ng.core": "~7.3.2", + "@abp/ng.oauth": "~7.3.2", + "@abp/ng.identity": "~7.3.2", + "@abp/ng.setting-management": "~7.3.2", + "@abp/ng.tenant-management": "~7.3.2", + "@abp/ng.theme.shared": "~7.3.2", + "@abp/ng.theme.lepton-x": "~2.3.1", + "@angular/animations": "~16.0.0", + "@angular/common": "~16.0.0", + "@angular/compiler": "~16.0.0", + "@angular/core": "~16.0.0", + "@angular/forms": "~16.0.0", + "@angular/localize": "~16.0.0", + "@angular/platform-browser": "~16.0.0", + "@angular/platform-browser-dynamic": "~16.0.0", + "@angular/router": "~16.0.0", + "bootstrap-icons": "~1.8.3", + "rxjs": "7.8.1", + "tslib": "^2.1.0", + "zone.js": "~0.13.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "~16.0.0", + "@angular-eslint/builder": "~16.0.0", + "@angular-eslint/eslint-plugin": "~16.0.0", + "@angular-eslint/eslint-plugin-template": "~16.0.0", + "@angular-eslint/schematics": "~16.0.0", + "@angular-eslint/template-parser": "~16.0.0", + "@abp/ng.schematics": "~7.3.2", + "@angular/cli": "~16.0.0", + "@angular/compiler-cli": "~16.0.0", + "@angular/language-service": "~16.0.0", + "@types/jasmine": "~3.6.0", + "@types/node": "^12.11.1", + "@typescript-eslint/eslint-plugin": "^5.36.2", + "@typescript-eslint/parser": "^5.36.2", + "eslint": "^8.23.0", + "jasmine-core": "~4.0.0", + "karma": "~6.3.0", + "karma-chrome-launcher": "~3.1.0", + "karma-coverage": "~2.1.0", + "karma-jasmine": "~4.0.0", + "karma-jasmine-html-reporter": "^1.7.0", + "typescript": "~5.0.4" + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/app-routing.module.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/app-routing.module.ts new file mode 100644 index 0000000000..d62e3fe196 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/app-routing.module.ts @@ -0,0 +1,44 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { bookStoreRentFormPropContributors } from './books-extended'; + +const routes: Routes = [ + { + path: '', + pathMatch: 'full', + loadChildren: () => import('./home/home.module').then(m => m.HomeModule), + }, + { + path: 'account', + loadChildren: () => import('@abp/ng.account').then(m => m.AccountModule.forLazy()), + }, + { + path: 'identity', + loadChildren: () => import('@abp/ng.identity').then(m => m.IdentityModule.forLazy()), + }, + { + path: 'tenant-management', + loadChildren: () => + import('@abp/ng.tenant-management').then(m => m.TenantManagementModule.forLazy()), + }, + { + path: 'setting-management', + loadChildren: () => + import('@abp/ng.setting-management').then(m => m.SettingManagementModule.forLazy()), + }, + { + path: 'books', + loadChildren: () => + import('@book-store/books').then(m => + m.BooksModule.forLazy({ + rentFormPropContributors: bookStoreRentFormPropContributors, + }) + ), + }, +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes, {})], + exports: [RouterModule], +}) +export class AppRoutingModule {} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/app.component.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/app.component.ts new file mode 100644 index 0000000000..a26e745334 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/app.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + template: ` + + + `, +}) +export class AppComponent {} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/app.module.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/app.module.ts new file mode 100644 index 0000000000..687cc5d799 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/app.module.ts @@ -0,0 +1,57 @@ +import { AccountConfigModule } from '@abp/ng.account/config'; +import { CoreModule } from '@abp/ng.core'; +import { registerLocale } from '@abp/ng.core/locale'; +import { IdentityConfigModule } from '@abp/ng.identity/config'; +import { SettingManagementConfigModule } from '@abp/ng.setting-management/config'; +import { TenantManagementConfigModule } from '@abp/ng.tenant-management/config'; +import { ThemeLeptonXModule } from '@abp/ng.theme.lepton-x'; +import { SideMenuLayoutModule } from '@abp/ng.theme.lepton-x/layouts'; +import { ThemeSharedModule } from '@abp/ng.theme.shared'; +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { environment } from '../environments/environment'; +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; +import { APP_ROUTE_PROVIDER } from './route.provider'; +import { FeatureManagementModule } from '@abp/ng.feature-management'; +import { AbpOAuthModule } from '@abp/ng.oauth'; +import { BOOK_ROUTE_PROVIDER } from '@book-store/books'; + +@NgModule({ + imports: [ + BrowserModule, + BrowserAnimationsModule, + AppRoutingModule, + CoreModule.forRoot({ + environment, + registerLocaleFn: registerLocale(), + localizations: [ + { + culture: 'en', + resources: [ + { + resourceName: 'BookStore', + texts: { + 'Menu:Books': 'Books', + }, + }, + ], + }, + ], + }), + AbpOAuthModule.forRoot(), + ThemeSharedModule.forRoot(), + AccountConfigModule.forRoot(), + IdentityConfigModule.forRoot(), + TenantManagementConfigModule.forRoot(), + SettingManagementConfigModule.forRoot(), + ThemeLeptonXModule.forRoot(), + SideMenuLayoutModule.forRoot(), + FeatureManagementModule.forRoot(), + ], + declarations: [AppComponent], + providers: [APP_ROUTE_PROVIDER, BOOK_ROUTE_PROVIDER], + bootstrap: [AppComponent], +}) +export class AppModule {} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books-extended/contributors/form-prop.contributors.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books-extended/contributors/form-prop.contributors.ts new file mode 100644 index 0000000000..7741597c82 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books-extended/contributors/form-prop.contributors.ts @@ -0,0 +1,40 @@ +import { Validators } from '@angular/forms'; +import { map } from 'rxjs'; +import { ePropType, FormProp, FormPropList } from '@abp/ng.theme.shared/extensions'; +import { + BookDto, + BookStoreRentFormPropContributors, + BooksService, + DefaultOption, + RentBookComponent, + eBooksComponents, +} from '@book-store/books'; + +const { required, maxLength } = Validators; + +const bookIdProp = new FormProp({ + type: ePropType.String, + id: 'bookId', + name: 'bookId', + displayName: 'BookStore::Name', + options: data => { + const rentBook = data.getInjected(RentBookComponent); + const { books } = data.getInjected(BooksService); + const bookOptions = books().map(({ id, name }) => ({ value: id, key: name })); + + return rentBook.form.controls.genreId.valueChanges.pipe( + map((value: string | undefined) => + value ? [DefaultOption, ...bookOptions] : [DefaultOption] + ) + ); + }, + validators: () => [required, maxLength(255)], +}); + +export function bookIdPropContributor(propList: FormPropList) { + propList.addByIndex(bookIdProp, 2); +} + +export const bookStoreRentFormPropContributors: BookStoreRentFormPropContributors = { + [eBooksComponents.RentBook]: [bookIdPropContributor], +}; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books-extended/contributors/index.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books-extended/contributors/index.ts new file mode 100644 index 0000000000..ac323a3331 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books-extended/contributors/index.ts @@ -0,0 +1 @@ +export * from './form-prop.contributors'; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books-extended/index.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books-extended/index.ts new file mode 100644 index 0000000000..81db06c73c --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books-extended/index.ts @@ -0,0 +1 @@ +export * from './contributors'; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/books-routing.module.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/books-routing.module.ts new file mode 100644 index 0000000000..9cb3fe2b4c --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/books-routing.module.ts @@ -0,0 +1,36 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes, mapToCanActivate } from '@angular/router'; +import { + ReplaceableComponents, + ReplaceableRouteContainerComponent, + RouterOutletComponent, +} from '@abp/ng.core'; +import { eBooksComponents } from './enums'; +import { BooksExtensionsGuard } from './guards'; +import BooksComponent from './books.component'; + +const routes: Routes = [ + { + path: '', + component: RouterOutletComponent, + canActivate: mapToCanActivate([BooksExtensionsGuard]), + children: [ + { + path: '', + component: ReplaceableRouteContainerComponent, + data: { + replaceableComponent: { + key: eBooksComponents.Books, + defaultComponent: BooksComponent, + } as ReplaceableComponents.RouteData, + }, + }, + ], + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class BooksRoutingModule {} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/books.component.html b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/books.component.html new file mode 100644 index 0000000000..8acc577c96 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/books.component.html @@ -0,0 +1,34 @@ +
+
+
+

+ {{ 'BookStore::RentedBooks' | abpLocalization }} +

+ + +
+ + + + + + + + + + + + + + + + + + +
Book NameAuthorGenreReturn Date
{{ book.name }}{{ book.author }}{{ book.genre }}{{ book.returnDate | date }}
+
+
+ + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/books.component.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/books.component.ts new file mode 100644 index 0000000000..e7e6a07b79 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/books.component.ts @@ -0,0 +1,19 @@ +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { NgFor, NgIf } from '@angular/common'; +import { CoreModule } from '@abp/ng.core'; +import { ThemeSharedModule } from '@abp/ng.theme.shared'; +import { BooksService } from './proxy'; +import { RentBookComponent } from './components'; + +@Component({ + standalone: true, + selector: 'app-books', + templateUrl: './books.component.html', + imports: [NgIf, NgFor, CoreModule, ThemeSharedModule, RentBookComponent], + providers: [BooksService], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export default class BooksComponent { + protected readonly booksService = inject(BooksService); + protected modalVisible = false; +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/books.module.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/books.module.ts new file mode 100644 index 0000000000..9d098bd67a --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/books.module.ts @@ -0,0 +1,47 @@ +import { ModuleWithProviders, NgModule, NgModuleFactory } from '@angular/core'; +import { CoreModule, LazyModuleFactory } from '@abp/ng.core'; +import { BooksConfigOptions } from './models'; +import { BooksExtensionsGuard } from './guards'; +import { BOOK_STORE_RENT_FORM_PROP_CONTRIBUTORS } from './tokens'; +import { BooksRoutingModule } from './books-routing.module'; + +@NgModule({ + imports: [ + BooksRoutingModule, + CoreModule.forChild({ + localizations: [ + { + culture: 'en', + resources: [ + { + resourceName: 'BookStore', + texts: { + RentedBooks: 'Rented books', + RentABook: 'Rent a book', + Author: 'Author', + }, + }, + ], + }, + ], + }), + ], +}) +export class BooksModule { + static forChild(options: BooksConfigOptions = {}): ModuleWithProviders { + return { + ngModule: BooksModule, + providers: [ + { + provide: BOOK_STORE_RENT_FORM_PROP_CONTRIBUTORS, + useValue: options.rentFormPropContributors, + }, + BooksExtensionsGuard, + ], + }; + } + + static forLazy(options: BooksConfigOptions = {}): NgModuleFactory { + return new LazyModuleFactory(BooksModule.forChild(options)); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/components/index.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/components/index.ts new file mode 100644 index 0000000000..26eea83c51 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/components/index.ts @@ -0,0 +1 @@ +export * from './rent-book/rent-book.component'; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/components/rent-book/rent-book.component.html b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/components/rent-book/rent-book.component.html new file mode 100644 index 0000000000..34b66befad --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/components/rent-book/rent-book.component.html @@ -0,0 +1,30 @@ + + +

{{ 'BookStore::RentABook' | abpLocalization }}

+
+ + + +
+ +
+
+ +
+ +
+
+ + + + + {{ 'AbpIdentity::Save' | abpLocalization }} + + +
diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/components/rent-book/rent-book.component.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/components/rent-book/rent-book.component.ts new file mode 100644 index 0000000000..83ef9eac15 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/components/rent-book/rent-book.component.ts @@ -0,0 +1,91 @@ +import { + ChangeDetectionStrategy, + Component, + EventEmitter, + Injector, + Output, + inject, +} from '@angular/core'; +import { FormGroup } from '@angular/forms'; +import { CoreModule, uuid } from '@abp/ng.core'; +import { ThemeSharedModule } from '@abp/ng.theme.shared'; +import { + EXTENSIONS_IDENTIFIER, + FormPropData, + UiExtensionsModule, + generateFormFromProps, +} from '@abp/ng.theme.shared/extensions'; +import { AuthorService, BookDto, BooksService } from '../../proxy'; +import { eBooksComponents } from '../../enums'; + +@Component({ + standalone: true, + selector: 'app-rent-book', + templateUrl: './rent-book.component.html', + imports: [CoreModule, UiExtensionsModule, ThemeSharedModule], + providers: [ + { + provide: EXTENSIONS_IDENTIFIER, + useValue: eBooksComponents.RentBook, + }, + AuthorService, + ], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class RentBookComponent { + protected readonly injector = inject(Injector); + protected readonly authorService = inject(AuthorService); + protected readonly booksService = inject(BooksService); + + //#region Just for demo + readonly #authors = this.authorService.authors(); + readonly #genres = this.booksService.genres(); + readonly #books = this.booksService.books(); + //#endregion + + protected modalVisible = true; + @Output() modalVisibleChange = new EventEmitter(); + + selected: BookDto; + form: FormGroup; + modalBusy = false; + + protected buildForm(): void { + const data = new FormPropData(this.injector, this.selected); + this.form = generateFormFromProps(data); + } + + constructor() { + this.buildForm(); + } + + save(): void { + if (this.form.invalid) { + return; + } + + this.modalBusy = true; + + const { authorId, genreId, bookId, returnDate } = this.form.value; + + //#region Just for demo + const authorName = this.#authors.find(({ id }) => id === authorId).name; + const genreName = this.#genres.find(({ id }) => id === genreId).name; + const bookName = this.#books.find(({ id }) => id === bookId).name; + //#endregion + + this.booksService.rentedBooks.update(books => [ + { + id: uuid(), + name: bookName, + author: authorName, + genre: genreName, + returnDate, + }, + ...books, + ]); + + this.modalBusy = false; + this.modalVisible = false; + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/defaults/default-books-form-props.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/defaults/default-books-form-props.ts new file mode 100644 index 0000000000..52b3b40bec --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/defaults/default-books-form-props.ts @@ -0,0 +1,55 @@ +import { Validators } from '@angular/forms'; +import { map, of } from 'rxjs'; +import { ePropType, FormProp } from '@abp/ng.theme.shared/extensions'; +import { BookDto, AuthorService, BooksService } from '../proxy'; +import { RentBookComponent } from '../components'; +import { DefaultOption } from '../utils'; + +const { required } = Validators; + +export const DEFAULT_RENT_FORM_PROPS = FormProp.createMany([ + { + type: ePropType.String, + id: 'authorId', + name: 'authorId', + displayName: 'BookStore::Author', + defaultValue: null, + validators: () => [required], + options: data => { + const { authors } = data.getInjected(AuthorService); + + return of([ + DefaultOption, + ...authors().map(author => ({ value: author.id, key: author.name })), + ]); + }, + }, + { + type: ePropType.String, + id: 'genreId', + name: 'genreId', + displayName: 'BookStore::Genre', + defaultValue: null, + validators: () => [required], + options: data => { + const rentBookComponent = data.getInjected(RentBookComponent); + const { genres } = data.getInjected(BooksService); + + const genreOptions = genres().map(({ id, name }) => ({ value: id, key: name })); + + return rentBookComponent.form.controls.authorId.valueChanges.pipe( + map((value: string | undefined) => + value ? [DefaultOption, ...genreOptions] : [DefaultOption] + ) + ); + }, + }, + { + type: ePropType.Date, + id: 'returnDate', + name: 'returnDate', + displayName: 'BookStore::ReturnDate', + defaultValue: null, + validators: () => [required], + }, +]); diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/defaults/index.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/defaults/index.ts new file mode 100644 index 0000000000..03204273eb --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/defaults/index.ts @@ -0,0 +1 @@ +export * from './default-books-form-props'; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/enums/components.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/enums/components.ts new file mode 100644 index 0000000000..61353d95be --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/enums/components.ts @@ -0,0 +1,4 @@ +export enum eBooksComponents { + Books = 'Books', + RentBook = 'Books.RentBook', +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/enums/index.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/enums/index.ts new file mode 100644 index 0000000000..07635cbbc8 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/enums/index.ts @@ -0,0 +1 @@ +export * from './components'; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/guards/extensions.guard.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/guards/extensions.guard.ts new file mode 100644 index 0000000000..5d455cc4a5 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/guards/extensions.guard.ts @@ -0,0 +1,37 @@ +import { Injectable, inject } from '@angular/core'; +import { Observable, map, tap } from 'rxjs'; +import { ConfigStateService, IAbpGuard } from '@abp/ng.core'; +import { + ExtensionsService, + getObjectExtensionEntitiesFromStore, + mapEntitiesToContributors, + mergeWithDefaultProps, +} from '@abp/ng.theme.shared/extensions'; +import { + BOOK_STORE_RENT_FORM_PROP_CONTRIBUTORS, + DEFAULT_BOOK_STORE_CREATE_FORM_PROPS, +} from '../tokens'; + +@Injectable() +export class BooksExtensionsGuard implements IAbpGuard { + protected readonly configState = inject(ConfigStateService); + protected readonly extensions = inject(ExtensionsService); + + canActivate(): Observable { + const createFormContributors = + inject(BOOK_STORE_RENT_FORM_PROP_CONTRIBUTORS, { optional: true }) || {}; + + return getObjectExtensionEntitiesFromStore(this.configState, 'BookStore').pipe( + mapEntitiesToContributors(this.configState, 'BookStore'), + tap(objectExtensionContributors => { + mergeWithDefaultProps( + this.extensions.createFormProps, + DEFAULT_BOOK_STORE_CREATE_FORM_PROPS, + objectExtensionContributors.createForm, + createFormContributors + ); + }), + map(() => true) + ); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/guards/index.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/guards/index.ts new file mode 100644 index 0000000000..480f14c40b --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/guards/index.ts @@ -0,0 +1 @@ +export * from './extensions.guard'; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/index.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/index.ts new file mode 100644 index 0000000000..d66c0707ce --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/index.ts @@ -0,0 +1,10 @@ +export * from './components'; +export * from './defaults'; +export * from './enums'; +export * from './models'; +export * from './providers'; +export * from './proxy'; +export * from './tokens'; +export * from './utils'; +export * from './books.component'; +export * from './books.module'; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/models/config-options.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/models/config-options.ts new file mode 100644 index 0000000000..1c26f04571 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/models/config-options.ts @@ -0,0 +1,11 @@ +import { CreateFormPropContributorCallback } from '@abp/ng.theme.shared/extensions'; +import { BookDto } from '../proxy'; +import { eBooksComponents } from '../enums'; + +export type BookStoreRentFormPropContributors = Partial<{ + [eBooksComponents.RentBook]: CreateFormPropContributorCallback[]; +}>; + +export interface BooksConfigOptions { + rentFormPropContributors?: BookStoreRentFormPropContributors; +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/models/index.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/models/index.ts new file mode 100644 index 0000000000..d474226b19 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/models/index.ts @@ -0,0 +1 @@ +export * from './config-options'; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/providers/index.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/providers/index.ts new file mode 100644 index 0000000000..fe08efba8c --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/providers/index.ts @@ -0,0 +1 @@ +export * from './route.provider'; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/providers/route.provider.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/providers/route.provider.ts new file mode 100644 index 0000000000..c472226429 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/providers/route.provider.ts @@ -0,0 +1,22 @@ +import { RoutesService, eLayoutType } from '@abp/ng.core'; +import { APP_INITIALIZER, inject } from '@angular/core'; + +export const BOOK_ROUTE_PROVIDER = [ + { provide: APP_INITIALIZER, useFactory: provideBookStoreRoutes, multi: true }, +]; + +function provideBookStoreRoutes() { + const routesService = inject(RoutesService); + + return () => { + routesService.add([ + { + path: '/books', + name: '::Menu:Books', + iconClass: 'fas fa-book', + order: 1, + layout: eLayoutType.application, + }, + ]); + }; +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/proxy/author.service.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/proxy/author.service.ts new file mode 100644 index 0000000000..31f517cec8 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/proxy/author.service.ts @@ -0,0 +1,12 @@ +import { uuid } from '@abp/ng.core'; +import { Injectable, signal } from '@angular/core'; + +@Injectable() +export class AuthorService { + readonly authors = signal([ + { id: uuid(), name: 'J.K. Rowling' }, + { id: uuid(), name: 'George R.R. Martin' }, + { id: uuid(), name: 'Stephen King' }, + { id: uuid(), name: 'J.R.R. Tolkien' }, + ]); +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/proxy/books.service.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/proxy/books.service.ts new file mode 100644 index 0000000000..9d7846fadf --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/proxy/books.service.ts @@ -0,0 +1,41 @@ +import { uuid } from '@abp/ng.core'; +import { Injectable, signal } from '@angular/core'; + +@Injectable() +export class BooksService { + readonly genres = signal([ + { id: uuid(), name: 'Fantasy' }, + { id: uuid(), name: 'Science Fiction' }, + { id: uuid(), name: 'Romance' }, + ]); + + readonly books = signal([ + { id: uuid(), name: 'The Shining', author: 'Stephen King', genre: 'Science Fiction' }, + { id: uuid(), name: 'The Notebook', author: 'Nicholas Sparks', genre: 'Romance' }, + { id: uuid(), name: 'The Last Song', author: 'Nicholas Sparks', genre: 'Romance' }, + ]); + + readonly rentedBooks = signal([ + { + id: uuid(), + name: 'The Lord of the Rings', + author: 'J. R. R. Tolkien', + genre: 'Fantasy', + returnDate: new Date('2024-01-01'), + }, + { + id: uuid(), + name: 'The Hobbit', + author: 'J. R. R. Tolkien', + genre: 'Fantasy', + returnDate: new Date('2024-02-01'), + }, + { + id: uuid(), + name: 'The Stand', + author: 'Stephen King', + genre: 'Science Fiction', + returnDate: new Date('2024-03-01'), + }, + ]); +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/proxy/index.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/proxy/index.ts new file mode 100644 index 0000000000..004897f3f2 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/proxy/index.ts @@ -0,0 +1,3 @@ +export * from './models'; +export * from './author.service'; +export * from './books.service'; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/proxy/models.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/proxy/models.ts new file mode 100644 index 0000000000..7ddf5107a4 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/proxy/models.ts @@ -0,0 +1,11 @@ +import { ExtensibleFullAuditedEntityDto, ExtensibleObject } from '@abp/ng.core'; + +export interface BookDto extends ExtensibleFullAuditedEntityDto { + authorId: string; + name: string; +} + +export interface CreateUpdateRentBookDto extends ExtensibleObject { + authorId: string; + name: string; +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/tokens/extensions.token.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/tokens/extensions.token.ts new file mode 100644 index 0000000000..ce51b548dc --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/tokens/extensions.token.ts @@ -0,0 +1,20 @@ +import { CreateFormPropContributorCallback } from '@abp/ng.theme.shared/extensions'; +import { InjectionToken } from '@angular/core'; +import { BookDto } from '../proxy'; +import { eBooksComponents } from '../enums'; +import { DEFAULT_RENT_FORM_PROPS } from '../defaults'; + +export const DEFAULT_BOOK_STORE_CREATE_FORM_PROPS = { + [eBooksComponents.RentBook]: DEFAULT_RENT_FORM_PROPS, +}; + +export const BOOK_STORE_RENT_FORM_PROP_CONTRIBUTORS = + new InjectionToken('BOOK_STORE_RENT_FORM_PROP_CONTRIBUTORS'); + +type CreateFormPropContributors = Partial<{ + [eBooksComponents.RentBook]: CreateFormPropContributorCallback[]; + /** + * Other creation form prop contributors... + */ + // [eBooksComponents.CreateBook]: CreateFormPropContributorCallback[]; +}>; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/tokens/index.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/tokens/index.ts new file mode 100644 index 0000000000..33233400a2 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/tokens/index.ts @@ -0,0 +1 @@ +export * from './extensions.token'; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/utils/common.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/utils/common.ts new file mode 100644 index 0000000000..73ef8e8c78 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/utils/common.ts @@ -0,0 +1,6 @@ +import { ABP } from '@abp/ng.core'; + +export const DefaultOption = { + value: null, + key: '-', +} as ABP.Option; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/utils/index.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/utils/index.ts new file mode 100644 index 0000000000..d0b9323665 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/books/utils/index.ts @@ -0,0 +1 @@ +export * from './common'; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/home/home-routing.module.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/home/home-routing.module.ts new file mode 100644 index 0000000000..7089990134 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/home/home-routing.module.ts @@ -0,0 +1,11 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { HomeComponent } from './home.component'; + +const routes: Routes = [{ path: '', component: HomeComponent }]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class HomeRoutingModule {} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/home/home.component.html b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/home/home.component.html new file mode 100644 index 0000000000..7ced505dc9 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/home/home.component.html @@ -0,0 +1,380 @@ +
+
+ +

{{ '::Welcome' | abpLocalization }}

+ +

{{ '::LongWelcomeMessage' | abpLocalization }}

+ + + {{ 'AbpAccount::Login' | abpLocalization }} +
+
+
+
+
+ +
+
+
+ THE OFFICIAL GUIDE +

Mastering ABP Framework

+

+ Written by the creator of the ABP Framework, this book will help you gain a complete + understanding of the framework and modern web application development techniques. +

+ +
+
+
+
+
+
+

Let's improve your application!

+

Here are some links to help you get started:

+
+
+
+
+ + + + + +
+
+ + + +

+ + + + +

+
+ + + + +
+
+
+ +
+

Meet the ABP Commercial

+

A Complete Web Application Platform Built on the ABP Framework

+
+ +
+
+

+ ABP Commercial is a platform based + on the open source ABP framework. It provides pre-built application modules, rapid + application development tooling, professional UI themes, premium support and more. +

+ +
+ + + + + + + + + + + +
+
+
+ +
+ + +
+
+
+ + {{ context.title }} +
+

+ + {{ link.label }} +
+
+
+ + +
+
+
+ + + Details +
+
+
+
+ + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/home/home.component.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/home/home.component.ts new file mode 100644 index 0000000000..34de8338c6 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/home/home.component.ts @@ -0,0 +1,15 @@ +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { AuthService } from '@abp/ng.core'; + +@Component({ + selector: 'app-home', + templateUrl: './home.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class HomeComponent { + protected readonly authService = inject(AuthService); + + get hasLoggedIn(): boolean { + return this.authService.isAuthenticated; + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/home/home.module.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/home/home.module.ts new file mode 100644 index 0000000000..72d20ccc65 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/home/home.module.ts @@ -0,0 +1,10 @@ +import { NgModule } from '@angular/core'; +import { SharedModule } from '../shared/shared.module'; +import { HomeRoutingModule } from './home-routing.module'; +import { HomeComponent } from './home.component'; + +@NgModule({ + declarations: [HomeComponent], + imports: [SharedModule, HomeRoutingModule], +}) +export class HomeModule {} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/route.provider.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/route.provider.ts new file mode 100644 index 0000000000..73865dfd0a --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/route.provider.ts @@ -0,0 +1,20 @@ +import { RoutesService, eLayoutType } from '@abp/ng.core'; +import { APP_INITIALIZER } from '@angular/core'; + +export const APP_ROUTE_PROVIDER = [ + { provide: APP_INITIALIZER, useFactory: configureRoutes, deps: [RoutesService], multi: true }, +]; + +function configureRoutes(routesService: RoutesService) { + return () => { + routesService.add([ + { + path: '/', + name: '::Menu:Home', + iconClass: 'fas fa-home', + order: 1, + layout: eLayoutType.application, + }, + ]); + }; +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/shared/shared.module.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/shared/shared.module.ts new file mode 100644 index 0000000000..e4d2f39cda --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/app/shared/shared.module.ts @@ -0,0 +1,23 @@ +import { CoreModule } from '@abp/ng.core'; +import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; +import { NgModule } from '@angular/core'; +import { ThemeSharedModule } from '@abp/ng.theme.shared'; +import { NgxValidateCoreModule } from '@ngx-validate/core'; + +@NgModule({ + declarations: [], + imports: [ + CoreModule, + ThemeSharedModule, + NgbDropdownModule, + NgxValidateCoreModule + ], + exports: [ + CoreModule, + ThemeSharedModule, + NgbDropdownModule, + NgxValidateCoreModule + ], + providers: [] +}) +export class SharedModule {} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/assets/.gitkeep b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/assets/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/assets/images/logo/logo-light-thumbnail.png b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/assets/images/logo/logo-light-thumbnail.png new file mode 100644 index 0000000000..886c960864 Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/assets/images/logo/logo-light-thumbnail.png differ diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/assets/images/logo/logo-light.png b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/assets/images/logo/logo-light.png new file mode 100644 index 0000000000..6ebd97e2b2 Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/assets/images/logo/logo-light.png differ diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/environments/environment.prod.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/environments/environment.prod.ts new file mode 100644 index 0000000000..25037d2739 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/environments/environment.prod.ts @@ -0,0 +1,26 @@ +import { Environment } from '@abp/ng.core'; + +const baseUrl = 'http://localhost:4200'; + +export const environment = { + production: true, + application: { + baseUrl, + name: 'BookStore', + logoUrl: '', + }, + oAuthConfig: { + issuer: 'https://localhost:44315/', + redirectUri: baseUrl, + clientId: 'BookStore_App', + responseType: 'code', + scope: 'offline_access BookStore', + requireHttps: true + }, + apis: { + default: { + url: 'https://localhost:44315', + rootNamespace: 'Volo.BookStore', + }, + }, +} as Environment; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/environments/environment.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/environments/environment.ts new file mode 100644 index 0000000000..d56190de48 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/environments/environment.ts @@ -0,0 +1,26 @@ +import { Environment } from '@abp/ng.core'; + +const baseUrl = 'http://localhost:4200'; + +export const environment = { + production: false, + application: { + baseUrl, + name: 'BookStore', + logoUrl: '', + }, + oAuthConfig: { + issuer: 'https://localhost:44315/', + redirectUri: baseUrl, + clientId: 'BookStore_App', + responseType: 'code', + scope: 'offline_access BookStore', + requireHttps: true, + }, + apis: { + default: { + url: 'https://localhost:44315', + rootNamespace: 'Volo.BookStore', + }, + }, +} as Environment; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/favicon.ico b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/favicon.ico new file mode 100644 index 0000000000..39695854d2 Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/favicon.ico differ diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/index.html b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/index.html new file mode 100644 index 0000000000..4d9b591645 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/index.html @@ -0,0 +1,16 @@ + + + + + BookStore + + + + + + + +
+
+ + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/main.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/main.ts new file mode 100644 index 0000000000..fa4e0aef33 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/main.ts @@ -0,0 +1,13 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch(err => console.error(err)); diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/polyfills.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/polyfills.ts new file mode 100644 index 0000000000..ce7c990a67 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/polyfills.ts @@ -0,0 +1,54 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/guide/browser-support + */ +/*************************************************************************************************** + * BROWSER POLYFILLS + */ +/** + * By default, zone.js will patch all possible macroTask and DomEvents + * user can disable parts of macroTask/DomEvents patch by setting following flags + * because those flags need to be set before `zone.js` being loaded, and webpack + * will put import in the top of bundle, so user need to create a separate file + * in this directory (for example: zone-flags.ts), and put the following flags + * into that file, and then add the following code before importing zone.js. + * import './zone-flags'; + * + * The flags allowed in zone-flags.ts are listed here. + * + * The following flags will work for all browsers. + * + * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame + * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick + * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames + * + * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js + * with the following flag, it will bypass `zone.js` patch for IE/Edge + * + * (window as any).__Zone_enable_cross_context_check = true; + * + */ +/*************************************************************************************************** + * Zone JS is required by default for Angular itself. + */ +import 'zone.js'; // Included with Angular CLI. + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ + +/****************************************************************** + * Load `$localize` - used if i18n tags appear in Angular templates. + */ +import '@angular/localize/init'; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/styles.scss b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/styles.scss new file mode 100644 index 0000000000..a4be82ce1e --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/styles.scss @@ -0,0 +1,30 @@ +/* You can add global styles to this file, and also import other style files */ + +@keyframes donut-spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} +:root { + --lpx-logo: url('/assets/images/logo/logo-light.png'); + --lpx-logo-icon: url('/assets/images/logo/logo-light-thumbnail.png'); +} +.donut { + display: inline-block; + border: 4px solid rgba(0, 0, 0, 0.1); + border-left-color: #7983ff; + border-radius: 50%; + width: 30px; + height: 30px; + animation: donut-spin 1.2s linear infinite; + + &.centered { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/test.ts b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/test.ts new file mode 100644 index 0000000000..c33c903cb4 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/src/test.ts @@ -0,0 +1,10 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files +import 'zone.js/testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting, +} from '@angular/platform-browser-dynamic/testing'; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/start.ps1 b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/start.ps1 new file mode 100644 index 0000000000..dac71a8164 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/start.ps1 @@ -0,0 +1,2 @@ +yarn +yarn start \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/tsconfig.app.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/tsconfig.app.json new file mode 100644 index 0000000000..ff396d4ce2 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/tsconfig.app.json @@ -0,0 +1,10 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"] +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/tsconfig.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/tsconfig.json new file mode 100644 index 0000000000..0216700f88 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/tsconfig.json @@ -0,0 +1,26 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "sourceMap": true, + "declaration": false, + "downlevelIteration": true, + "experimentalDecorators": true, + "moduleResolution": "node", + "importHelpers": true, + "target": "ES2022", + "module": "es2020", + "lib": ["es2018", "dom"], + "paths": { + "@proxy": ["src/app/proxy/index.ts"], + "@proxy/*": ["src/app/proxy/*"], + "@book-store/books": ["src/app/books/index.ts"] + }, + "useDefineForClassFields": false + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/tsconfig.spec.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/tsconfig.spec.json new file mode 100644 index 0000000000..669344f8d2 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/angular/tsconfig.spec.json @@ -0,0 +1,10 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": ["jasmine"] + }, + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/.gitattributes b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/.gitattributes new file mode 100644 index 0000000000..c941e52669 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/.gitattributes @@ -0,0 +1 @@ +**/wwwroot/libs/** linguist-vendored diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/.gitignore b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/.gitignore new file mode 100644 index 0000000000..1e0c791e1e --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/.gitignore @@ -0,0 +1,265 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# BookStore +src/Volo.BookStore.Web/Logs/* +src/Volo.BookStore.Web.Host/Logs/* +src/Volo.BookStore.AuthServer/Logs/* +src/Volo.BookStore.HttpApi.Host/Logs/* +src/Volo.BookStore.HttpApi.Host/Logs/* +src/Volo.BookStore.DbMigrator/Logs/* +src/Volo.BookStore.Blazor.Server/Logs/* +src/Volo.BookStore.Blazor.Server.Tiered/Logs/* + +# Use abp install-libs to restore. +**/wwwroot/libs/* diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/.prettierrc b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/.prettierrc new file mode 100644 index 0000000000..56af76bd94 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/.prettierrc @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "useTabs": false, + "tabWidth": 4 +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/NuGet.Config b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/NuGet.Config new file mode 100644 index 0000000000..bdc451971a --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/NuGet.Config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/Volo.BookStore.sln b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/Volo.BookStore.sln new file mode 100644 index 0000000000..3bc323ccea --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/Volo.BookStore.sln @@ -0,0 +1,123 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29020.237 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.BookStore.Domain", "src\Volo.BookStore.Domain\Volo.BookStore.Domain.csproj", "{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.BookStore.Application", "src\Volo.BookStore.Application\Volo.BookStore.Application.csproj", "{1A94A50E-06DC-43C1-80B5-B662820EC3EB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CA9AC87F-097E-4F15-8393-4BC07735A5B0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{04DBDB01-70F4-4E06-B468-8F87850B22BE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.BookStore.Application.Tests", "test\Volo.BookStore.Application.Tests\Volo.BookStore.Application.Tests.csproj", "{50B2631D-129C-47B3-A587-029CCD6099BC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.BookStore.MongoDB", "src\Volo.BookStore.MongoDB\Volo.BookStore.MongoDB.csproj", "{E3444355-D47E-431E-BDD0-DD3A7113B2AE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.BookStore.Domain.Shared", "src\Volo.BookStore.Domain.Shared\Volo.BookStore.Domain.Shared.csproj", "{42F719ED-8413-4895-B5B4-5AB56079BC66}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.BookStore.Application.Contracts", "src\Volo.BookStore.Application.Contracts\Volo.BookStore.Application.Contracts.csproj", "{520659C8-C734-4298-A3DA-B539DB9DFC0B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.BookStore.HttpApi", "src\Volo.BookStore.HttpApi\Volo.BookStore.HttpApi.csproj", "{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.BookStore.HttpApi.Client", "src\Volo.BookStore.HttpApi.Client\Volo.BookStore.HttpApi.Client.csproj", "{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.BookStore.TestBase", "test\Volo.BookStore.TestBase\Volo.BookStore.TestBase.csproj", "{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.BookStore.Domain.Tests", "test\Volo.BookStore.Domain.Tests\Volo.BookStore.Domain.Tests.csproj", "{E512F4D9-9375-480F-A2F6-A46509F9D824}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.BookStore.MongoDB.Tests", "test\Volo.BookStore.MongoDB.Tests\Volo.BookStore.MongoDB.Tests.csproj", "{6015D17B-104B-4EC2-A9B7-D8A40C891458}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.BookStore.HttpApi.Client.ConsoleTestApp", "test\Volo.BookStore.HttpApi.Client.ConsoleTestApp\Volo.BookStore.HttpApi.Client.ConsoleTestApp.csproj", "{EF480016-9127-4916-8735-D2466BDBC582}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.BookStore.DbMigrator", "src\Volo.BookStore.DbMigrator\Volo.BookStore.DbMigrator.csproj", "{AA94D832-1CCC-4715-95A9-A483F23A1A5D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.BookStore.HttpApi.Host", "src\Volo.BookStore.HttpApi.Host\Volo.BookStore.HttpApi.Host.csproj", "{748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.Build.0 = Release|Any CPU + {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.Build.0 = Release|Any CPU + {50B2631D-129C-47B3-A587-029CCD6099BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {50B2631D-129C-47B3-A587-029CCD6099BC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {50B2631D-129C-47B3-A587-029CCD6099BC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {50B2631D-129C-47B3-A587-029CCD6099BC}.Release|Any CPU.Build.0 = Release|Any CPU + {E3444355-D47E-431E-BDD0-DD3A7113B2AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E3444355-D47E-431E-BDD0-DD3A7113B2AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E3444355-D47E-431E-BDD0-DD3A7113B2AE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E3444355-D47E-431E-BDD0-DD3A7113B2AE}.Release|Any CPU.Build.0 = Release|Any CPU + {42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.Build.0 = Release|Any CPU + {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.Build.0 = Release|Any CPU + {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.Build.0 = Release|Any CPU + {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.Build.0 = Release|Any CPU + {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.Build.0 = Release|Any CPU + {E512F4D9-9375-480F-A2F6-A46509F9D824}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E512F4D9-9375-480F-A2F6-A46509F9D824}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E512F4D9-9375-480F-A2F6-A46509F9D824}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E512F4D9-9375-480F-A2F6-A46509F9D824}.Release|Any CPU.Build.0 = Release|Any CPU + {6015D17B-104B-4EC2-A9B7-D8A40C891458}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6015D17B-104B-4EC2-A9B7-D8A40C891458}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6015D17B-104B-4EC2-A9B7-D8A40C891458}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6015D17B-104B-4EC2-A9B7-D8A40C891458}.Release|Any CPU.Build.0 = Release|Any CPU + {EF480016-9127-4916-8735-D2466BDBC582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EF480016-9127-4916-8735-D2466BDBC582}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EF480016-9127-4916-8735-D2466BDBC582}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EF480016-9127-4916-8735-D2466BDBC582}.Release|Any CPU.Build.0 = Release|Any CPU + {AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.Build.0 = Release|Any CPU + {748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {554AD327-6DBA-4F8F-96F8-81CE7A0C863F} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {1A94A50E-06DC-43C1-80B5-B662820EC3EB} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {50B2631D-129C-47B3-A587-029CCD6099BC} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} + {E3444355-D47E-431E-BDD0-DD3A7113B2AE} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {42F719ED-8413-4895-B5B4-5AB56079BC66} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {520659C8-C734-4298-A3DA-B539DB9DFC0B} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {4164BDF7-F527-4E85-9CE6-E3C2D7426A27} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {3B5A0094-670D-4BB1-BFDD-61B88A8773DC} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {91853F21-9CD9-4132-BC29-A7D5D84FFFE7} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} + {E512F4D9-9375-480F-A2F6-A46509F9D824} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} + {6015D17B-104B-4EC2-A9B7-D8A40C891458} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} + {EF480016-9127-4916-8735-D2466BDBC582} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} + {AA94D832-1CCC-4715-95A9-A483F23A1A5D} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {748584B1-BA69-4F6A-81AA-F4BDE6BCE29D} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6AAFA1C6-603E-13FA-45E5-7910AA9F661D} + EndGlobalSection +EndGlobal diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/Volo.BookStore.sln.DotSettings b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/Volo.BookStore.sln.DotSettings new file mode 100644 index 0000000000..cb0b2c919f --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/Volo.BookStore.sln.DotSettings @@ -0,0 +1,23 @@ + + True + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + Required + Required + Required + Required + False + True + False + False + True + False + False + SQL + \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/common.props b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/common.props new file mode 100644 index 0000000000..7e89c3a06b --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/common.props @@ -0,0 +1,19 @@ + + + latest + 1.0.0 + $(NoWarn);CS1591 + app + + + + + $(NoWarn);0436 + + + + + + + + \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application.Contracts/BookStoreApplicationContractsModule.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application.Contracts/BookStoreApplicationContractsModule.cs new file mode 100644 index 0000000000..2934725914 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application.Contracts/BookStoreApplicationContractsModule.cs @@ -0,0 +1,28 @@ +using Volo.Abp.Account; +using Volo.Abp.FeatureManagement; +using Volo.Abp.Identity; +using Volo.Abp.Modularity; +using Volo.Abp.ObjectExtending; +using Volo.Abp.PermissionManagement; +using Volo.Abp.SettingManagement; +using Volo.Abp.TenantManagement; + +namespace Volo.BookStore; + +[DependsOn( + typeof(BookStoreDomainSharedModule), + typeof(AbpAccountApplicationContractsModule), + typeof(AbpFeatureManagementApplicationContractsModule), + typeof(AbpIdentityApplicationContractsModule), + typeof(AbpPermissionManagementApplicationContractsModule), + typeof(AbpSettingManagementApplicationContractsModule), + typeof(AbpTenantManagementApplicationContractsModule), + typeof(AbpObjectExtendingModule) +)] +public class BookStoreApplicationContractsModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + BookStoreDtoExtensions.Configure(); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application.Contracts/BookStoreDtoExtensions.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application.Contracts/BookStoreDtoExtensions.cs new file mode 100644 index 0000000000..9a1989048a --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application.Contracts/BookStoreDtoExtensions.cs @@ -0,0 +1,28 @@ +using Volo.Abp.Identity; +using Volo.Abp.ObjectExtending; +using Volo.Abp.Threading; + +namespace Volo.BookStore; + +public static class BookStoreDtoExtensions +{ + private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); + + public static void Configure() + { + OneTimeRunner.Run(() => + { + /* You can add extension properties to DTOs + * defined in the depended modules. + * + * Example: + * + * ObjectExtensionManager.Instance + * .AddOrUpdateProperty("Title"); + * + * See the documentation for more: + * https://docs.abp.io/en/abp/latest/Object-Extensions + */ + }); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application.Contracts/Permissions/BookStorePermissionDefinitionProvider.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application.Contracts/Permissions/BookStorePermissionDefinitionProvider.cs new file mode 100644 index 0000000000..4907095ba7 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application.Contracts/Permissions/BookStorePermissionDefinitionProvider.cs @@ -0,0 +1,20 @@ +using Volo.BookStore.Localization; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Localization; + +namespace Volo.BookStore.Permissions; + +public class BookStorePermissionDefinitionProvider : PermissionDefinitionProvider +{ + public override void Define(IPermissionDefinitionContext context) + { + var myGroup = context.AddGroup(BookStorePermissions.GroupName); + //Define your own permissions here. Example: + //myGroup.AddPermission(BookStorePermissions.MyPermission1, L("Permission:MyPermission1")); + } + + private static LocalizableString L(string name) + { + return LocalizableString.Create(name); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application.Contracts/Permissions/BookStorePermissions.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application.Contracts/Permissions/BookStorePermissions.cs new file mode 100644 index 0000000000..d81d0b9e04 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application.Contracts/Permissions/BookStorePermissions.cs @@ -0,0 +1,9 @@ +namespace Volo.BookStore.Permissions; + +public static class BookStorePermissions +{ + public const string GroupName = "BookStore"; + + //Add your own permission names. Example: + //public const string MyPermission1 = GroupName + ".MyPermission1"; +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application.Contracts/Volo.BookStore.Application.Contracts.csproj b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application.Contracts/Volo.BookStore.Application.Contracts.csproj new file mode 100644 index 0000000000..eeb49ae0b9 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application.Contracts/Volo.BookStore.Application.Contracts.csproj @@ -0,0 +1,25 @@ + + + + + + netstandard2.0;netstandard2.1;net7.0 + enable + Volo.BookStore + + + + + + + + + + + + + + + + + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application/BookStoreAppService.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application/BookStoreAppService.cs new file mode 100644 index 0000000000..0e95ac502d --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application/BookStoreAppService.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Volo.BookStore.Localization; +using Volo.Abp.Application.Services; + +namespace Volo.BookStore; + +/* Inherit your application services from this class. + */ +public abstract class BookStoreAppService : ApplicationService +{ + protected BookStoreAppService() + { + LocalizationResource = typeof(BookStoreResource); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application/BookStoreApplicationAutoMapperProfile.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application/BookStoreApplicationAutoMapperProfile.cs new file mode 100644 index 0000000000..e0ffe129db --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application/BookStoreApplicationAutoMapperProfile.cs @@ -0,0 +1,13 @@ +using AutoMapper; + +namespace Volo.BookStore; + +public class BookStoreApplicationAutoMapperProfile : Profile +{ + public BookStoreApplicationAutoMapperProfile() + { + /* You can configure your AutoMapper mapping configuration here. + * Alternatively, you can split your mapping configurations + * into multiple profile classes for a better organization. */ + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application/BookStoreApplicationModule.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application/BookStoreApplicationModule.cs new file mode 100644 index 0000000000..acaef510f0 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application/BookStoreApplicationModule.cs @@ -0,0 +1,31 @@ +using Volo.Abp.Account; +using Volo.Abp.AutoMapper; +using Volo.Abp.FeatureManagement; +using Volo.Abp.Identity; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement; +using Volo.Abp.SettingManagement; +using Volo.Abp.TenantManagement; + +namespace Volo.BookStore; + +[DependsOn( + typeof(BookStoreDomainModule), + typeof(AbpAccountApplicationModule), + typeof(BookStoreApplicationContractsModule), + typeof(AbpIdentityApplicationModule), + typeof(AbpPermissionManagementApplicationModule), + typeof(AbpTenantManagementApplicationModule), + typeof(AbpFeatureManagementApplicationModule), + typeof(AbpSettingManagementApplicationModule) + )] +public class BookStoreApplicationModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.AddMaps(); + }); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application/Properties/AssemblyInfo.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..ac61697eba --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application/Properties/AssemblyInfo.cs @@ -0,0 +1,2 @@ +using System.Runtime.CompilerServices; +[assembly:InternalsVisibleToAttribute("Volo.BookStore.Application.Tests")] diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application/Volo.BookStore.Application.csproj b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application/Volo.BookStore.Application.csproj new file mode 100644 index 0000000000..07e5f02b8f --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Application/Volo.BookStore.Application.csproj @@ -0,0 +1,25 @@ + + + + + + net7.0 + enable + Volo.BookStore + + + + + + + + + + + + + + + + + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.DbMigrator/BookStoreDbMigratorModule.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.DbMigrator/BookStoreDbMigratorModule.cs new file mode 100644 index 0000000000..5e22160e8e --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.DbMigrator/BookStoreDbMigratorModule.cs @@ -0,0 +1,14 @@ +using Volo.BookStore.MongoDB; +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; + +namespace Volo.BookStore.DbMigrator; + +[DependsOn( + typeof(AbpAutofacModule), + typeof(BookStoreMongoDbModule), + typeof(BookStoreApplicationContractsModule) + )] +public class BookStoreDbMigratorModule : AbpModule +{ +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.DbMigrator/DbMigratorHostedService.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.DbMigrator/DbMigratorHostedService.cs new file mode 100644 index 0000000000..5116dd7d40 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.DbMigrator/DbMigratorHostedService.cs @@ -0,0 +1,51 @@ +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Volo.BookStore.Data; +using Serilog; +using Volo.Abp; +using Volo.Abp.Data; + +namespace Volo.BookStore.DbMigrator; + +public class DbMigratorHostedService : IHostedService +{ + private readonly IHostApplicationLifetime _hostApplicationLifetime; + private readonly IConfiguration _configuration; + + public DbMigratorHostedService(IHostApplicationLifetime hostApplicationLifetime, IConfiguration configuration) + { + _hostApplicationLifetime = hostApplicationLifetime; + _configuration = configuration; + } + + public async Task StartAsync(CancellationToken cancellationToken) + { + using (var application = await AbpApplicationFactory.CreateAsync(options => + { + options.Services.ReplaceConfiguration(_configuration); + options.UseAutofac(); + options.Services.AddLogging(c => c.AddSerilog()); + options.AddDataMigrationEnvironment(); + })) + { + await application.InitializeAsync(); + + await application + .ServiceProvider + .GetRequiredService() + .MigrateAsync(); + + await application.ShutdownAsync(); + + _hostApplicationLifetime.StopApplication(); + } + } + + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.DbMigrator/Program.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.DbMigrator/Program.cs new file mode 100644 index 0000000000..ad7a716225 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.DbMigrator/Program.cs @@ -0,0 +1,41 @@ +using System.IO; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Serilog; +using Serilog.Events; + +namespace Volo.BookStore.DbMigrator; + +class Program +{ + static async Task Main(string[] args) + { + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Information() + .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) + .MinimumLevel.Override("Volo.Abp", LogEventLevel.Warning) +#if DEBUG + .MinimumLevel.Override("Volo.BookStore", LogEventLevel.Debug) +#else + .MinimumLevel.Override("Volo.BookStore", LogEventLevel.Information) +#endif + .Enrich.FromLogContext() + .WriteTo.Async(c => c.File("Logs/logs.txt")) + .WriteTo.Async(c => c.Console()) + .CreateLogger(); + + await CreateHostBuilder(args).RunConsoleAsync(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .AddAppSettingsSecretsJson() + .ConfigureLogging((context, logging) => logging.ClearProviders()) + .ConfigureServices((hostContext, services) => + { + services.AddHostedService(); + }); +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.DbMigrator/Volo.BookStore.DbMigrator.csproj b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.DbMigrator/Volo.BookStore.DbMigrator.csproj new file mode 100644 index 0000000000..515425a510 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.DbMigrator/Volo.BookStore.DbMigrator.csproj @@ -0,0 +1,45 @@ + + + + + + Exe + net7.0 + enable + + + + + + PreserveNewest + Always + + + + PreserveNewest + Always + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.DbMigrator/appsettings.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.DbMigrator/appsettings.json new file mode 100644 index 0000000000..ea3e6ed462 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.DbMigrator/appsettings.json @@ -0,0 +1,30 @@ +{ + "ConnectionStrings": { + "Default": "mongodb://localhost:27017/BookStore" + }, + "Redis": { + "Configuration": "127.0.0.1" + }, + "OpenIddict": { + "Applications": { + "BookStore_Web": { + "ClientId": "BookStore_Web", + "ClientSecret": "1q2w3e*", + "RootUrl": "https://localhost:44375" + }, + "BookStore_App": { + "ClientId": "BookStore_App", + "RootUrl": "http://localhost:4200" + }, + "BookStore_BlazorServerTiered": { + "ClientId": "BookStore_BlazorServerTiered", + "ClientSecret": "1q2w3e*", + "RootUrl": "https://localhost:44367" + }, + "BookStore_Swagger": { + "ClientId": "BookStore_Swagger", + "RootUrl": "https://localhost:44315" + } + } + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/BookStoreDomainErrorCodes.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/BookStoreDomainErrorCodes.cs new file mode 100644 index 0000000000..e3d6ad0a4a --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/BookStoreDomainErrorCodes.cs @@ -0,0 +1,6 @@ +namespace Volo.BookStore; + +public static class BookStoreDomainErrorCodes +{ + /* You can add your business exception error codes here, as constants */ +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/BookStoreDomainSharedModule.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/BookStoreDomainSharedModule.cs new file mode 100644 index 0000000000..448b5abed2 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/BookStoreDomainSharedModule.cs @@ -0,0 +1,58 @@ +using Volo.BookStore.Localization; +using Volo.Abp.AuditLogging; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.FeatureManagement; +using Volo.Abp.Identity; +using Volo.Abp.Localization; +using Volo.Abp.Localization.ExceptionHandling; +using Volo.Abp.Modularity; +using Volo.Abp.OpenIddict; +using Volo.Abp.PermissionManagement; +using Volo.Abp.SettingManagement; +using Volo.Abp.TenantManagement; +using Volo.Abp.Validation.Localization; +using Volo.Abp.VirtualFileSystem; + +namespace Volo.BookStore; + +[DependsOn( + typeof(AbpAuditLoggingDomainSharedModule), + typeof(AbpBackgroundJobsDomainSharedModule), + typeof(AbpFeatureManagementDomainSharedModule), + typeof(AbpIdentityDomainSharedModule), + typeof(AbpOpenIddictDomainSharedModule), + typeof(AbpPermissionManagementDomainSharedModule), + typeof(AbpSettingManagementDomainSharedModule), + typeof(AbpTenantManagementDomainSharedModule) + )] +public class BookStoreDomainSharedModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + BookStoreGlobalFeatureConfigurator.Configure(); + BookStoreModuleExtensionConfigurator.Configure(); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + + Configure(options => + { + options.Resources + .Add("en") + .AddBaseTypes(typeof(AbpValidationResource)) + .AddVirtualJson("/Localization/BookStore"); + + options.DefaultResourceType = typeof(BookStoreResource); + }); + + Configure(options => + { + options.MapCodeNamespace("BookStore", typeof(BookStoreResource)); + }); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/BookStoreGlobalFeatureConfigurator.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/BookStoreGlobalFeatureConfigurator.cs new file mode 100644 index 0000000000..e8d33f4a67 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/BookStoreGlobalFeatureConfigurator.cs @@ -0,0 +1,22 @@ +using Volo.Abp.Threading; + +namespace Volo.BookStore; + +public static class BookStoreGlobalFeatureConfigurator +{ + private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); + + public static void Configure() + { + OneTimeRunner.Run(() => + { + /* You can configure (enable/disable) global features of the used modules here. + * + * YOU CAN SAFELY DELETE THIS CLASS AND REMOVE ITS USAGES IF YOU DON'T NEED TO IT! + * + * Please refer to the documentation to lear more about the Global Features System: + * https://docs.abp.io/en/abp/latest/Global-Features + */ + }); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/BookStoreModuleExtensionConfigurator.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/BookStoreModuleExtensionConfigurator.cs new file mode 100644 index 0000000000..4a852321a8 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/BookStoreModuleExtensionConfigurator.cs @@ -0,0 +1,73 @@ +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Identity; +using Volo.Abp.ObjectExtending; +using Volo.Abp.Threading; + +namespace Volo.BookStore; + +public static class BookStoreModuleExtensionConfigurator +{ + private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); + + public static void Configure() + { + OneTimeRunner.Run(() => + { + ConfigureExistingProperties(); + ConfigureExtraProperties(); + }); + } + + private static void ConfigureExistingProperties() + { + /* You can change max lengths for properties of the + * entities defined in the modules used by your application. + * + * Example: Change user and role name max lengths + + IdentityUserConsts.MaxNameLength = 99; + IdentityRoleConsts.MaxNameLength = 99; + + * Notice: It is not suggested to change property lengths + * unless you really need it. Go with the standard values wherever possible. + * + * If you are using EF Core, you will need to run the add-migration command after your changes. + */ + } + + private static void ConfigureExtraProperties() + { + /* You can configure extra properties for the + * entities defined in the modules used by your application. + * + * This class can be used to define these extra properties + * with a high level, easy to use API. + * + * Example: Add a new property to the user entity of the identity module + + ObjectExtensionManager.Instance.Modules() + .ConfigureIdentity(identity => + { + identity.ConfigureUser(user => + { + user.AddOrUpdateProperty( //property type: string + "SocialSecurityNumber", //property name + property => + { + //validation rules + property.Attributes.Add(new RequiredAttribute()); + property.Attributes.Add(new StringLengthAttribute(64) {MinimumLength = 4}); + + property.Configuration[IdentityModuleExtensionConsts.ConfigurationNames.AllowUserToEdit] = true; + + //...other configurations for this property + } + ); + }); + }); + + * See the documentation for more: + * https://docs.abp.io/en/abp/latest/Module-Entity-Extensions + */ + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/ar.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/ar.json new file mode 100644 index 0000000000..96bbf80b40 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/ar.json @@ -0,0 +1,8 @@ +{ + "culture": "ar", + "texts": { + "Menu:Home": "الرئيسية", + "Menu:Home": "الصفحة الرئيسية", + "LongWelcomeMessage": "مرحبا بكم في التطبيق. هذا مشروع بدء تشغيل يعتمد على إطار عمل ABP. لمزيد من المعلومات ، يرجى زيارة abp.io." + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/cs.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/cs.json new file mode 100644 index 0000000000..5a0bbf613e --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/cs.json @@ -0,0 +1,8 @@ +{ + "culture": "cs", + "texts": { + "Menu:Home": "Úvod", + "Welcome": "Vítejte", + "LongWelcomeMessage": "Vítejte v aplikaci. Toto je startovací projekt založený na ABP frameworku. Pro více informací, navštivte abp.io." + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/de.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/de.json new file mode 100644 index 0000000000..831493be86 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/de.json @@ -0,0 +1,8 @@ +{ + "culture": "de", + "texts": { + "Menu:Home": "Home", + "Welcome": "Willkommen", + "LongWelcomeMessage": "Willkommen bei der Anwendung. Dies ist ein Startup-Projekt, das auf dem ABP-Framework basiert. Weitere Informationen finden Sie unter abp.io." + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/en-GB.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/en-GB.json new file mode 100644 index 0000000000..d2ca0793a3 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/en-GB.json @@ -0,0 +1,8 @@ +{ + "culture": "en-GB", + "texts": { + "Menu:Home": "Home", + "Welcome": "Welcome", + "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information, visit abp.io." + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/en.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/en.json new file mode 100644 index 0000000000..d2a6a9831e --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/en.json @@ -0,0 +1,8 @@ +{ + "culture": "en", + "texts": { + "Menu:Home": "Home", + "Welcome": "Welcome", + "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information, visit abp.io." + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/es.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/es.json new file mode 100644 index 0000000000..31b4b59e25 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/es.json @@ -0,0 +1,8 @@ +{ + "culture": "es", + "texts": { + "Menu:Home": "Inicio", + "Welcome": "Bienvenido", + "LongWelcomeMessage": "Bienvenido a la aplicación, este es un proyecto base basado en el framework ABP. Para más información, visita abp.io." + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/fi.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/fi.json new file mode 100644 index 0000000000..a318859f23 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/fi.json @@ -0,0 +1,8 @@ +{ + "culture": "fi", + "texts": { + "Menu:Home": "Koti", + "Welcome": "Tervetuloa", + "LongWelcomeMessage": "Tervetuloa sovellukseen. Tämä on ABP-kehykseen perustuva käynnistysprojekti. Lisätietoja on osoitteessa abp.io." + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/fr.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/fr.json new file mode 100644 index 0000000000..e76eac0c71 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/fr.json @@ -0,0 +1,8 @@ +{ + "culture": "fr", + "texts": { + "Menu:Home": "Accueil", + "Welcome": "Bienvenue", + "LongWelcomeMessage": "Bienvenue dans l'application. Il s'agit d'un projet de démarrage basé sur le framework ABP. Pour plus d'informations, visitez abp.io." + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/hi.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/hi.json new file mode 100644 index 0000000000..a1676bfd45 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/hi.json @@ -0,0 +1,8 @@ +{ + "culture": "hi", + "texts": { + "Menu:Home": "घर", + "Welcome": "स्वागत हे", + "LongWelcomeMessage": "आवेदन करने के लिए आपका स्वागत है। यह एबीपी ढांचे पर आधारित एक स्टार्टअप परियोजना है। अधिक जानकारी के लिए, abp.io पर जाएं।" + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/hr.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/hr.json new file mode 100644 index 0000000000..fa8efab322 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/hr.json @@ -0,0 +1,8 @@ +{ + "culture": "hr", + "texts": { + "Menu:Home": "Početna", + "Welcome": "Dobrodošli", + "LongWelcomeMessage": "Dobrodošli u aplikaciju. Ovo je startup projekt temeljen na ABP framework-u. Za više informacija posjetite abp.io." + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/hu.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/hu.json new file mode 100644 index 0000000000..c7b6a33a0f --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/hu.json @@ -0,0 +1,8 @@ +{ + "culture": "hu", + "texts": { + "Menu:Home": "Kezdőlap", + "Welcome": "Üdvözlöm", + "LongWelcomeMessage": "Üdvözöljük az alkalmazásban. Ez egy ABP keretrendszeren alapuló startup projekt. További információkért látogasson el az abp.io oldalra." + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/is.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/is.json new file mode 100644 index 0000000000..190df90373 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/is.json @@ -0,0 +1,8 @@ +{ + "culture": "is", + "texts": { + "Menu:Home": "Heim", + "Welcome": "Velkomin", + "LongWelcomeMessage": "Verið velkomin í forritið. Þetta er startup verkefni sem byggir á ABP. Nánari upplýsingar er að finna á abp.io." + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/it.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/it.json new file mode 100644 index 0000000000..82ce42b033 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/it.json @@ -0,0 +1,8 @@ +{ + "culture": "it", + "texts": { + "Menu:Home": "Home", + "Welcome": "Benvenuto", + "LongWelcomeMessage": "Benvenuto nell'applicazione. Questo è un progetto di avvio basato sul framework ABP. Per ulteriori informazioni, visita abp.io." + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/nl.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/nl.json new file mode 100644 index 0000000000..9ba8da4743 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/nl.json @@ -0,0 +1,8 @@ +{ + "culture": "nl", + "texts": { + "Menu:Home": "Home", + "Welcome": "Welkom", + "LongWelcomeMessage": "Welkom bij de applicatie. Dit is een startup-project gebaseerd op het ABP-framework. Bezoek abp.io voor meer informatie." + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/pl-PL.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/pl-PL.json new file mode 100644 index 0000000000..33412f307c --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/pl-PL.json @@ -0,0 +1,8 @@ +{ + "culture": "pl-PL", + "texts": { + "Menu:Home": "Home", + "Welcome": "Witaj", + "LongWelcomeMessage": "Witaj w aplikacji. To jest inicjalny projekt bazujący na ABP framework. Po więcej informacji odwiedź stronę abp.io." + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/pt-BR.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/pt-BR.json new file mode 100644 index 0000000000..8c818a07af --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/pt-BR.json @@ -0,0 +1,8 @@ +{ + "culture": "pt-BR", + "texts": { + "Menu:Home": "Principal", + "Welcome": "Seja bem-vindo!", + "LongWelcomeMessage": "Bem-vindo a esta aplicação. Este é um projeto inicial baseado no ABP framework. Para mais informações, visite abp.io." + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/ro-RO.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/ro-RO.json new file mode 100644 index 0000000000..1fe560196e --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/ro-RO.json @@ -0,0 +1,8 @@ +{ + "culture": "ro-RO", + "texts": { + "Menu:Home": "Acasă", + "Welcome": "Bun venit", + "LongWelcomeMessage": "Bun venit la aplicaţie. Acesta este un proiect de pornire bazat pe framework-ul ABP. Pentru mai multe informaţii, vizitaţi, visit abp.io." + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/ru.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/ru.json new file mode 100644 index 0000000000..8464e44344 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/ru.json @@ -0,0 +1,8 @@ +{ + "culture": "ru", + "texts": { + "Menu:Home": "Главная", + "Welcome": "Добро пожаловать", + "LongWelcomeMessage": "Добро пожаловать в приложение. Этот запущенный проект основан на фреймворке ABP. Для получения дополнительной информации посетите сайт abp.io." + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/sk.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/sk.json new file mode 100644 index 0000000000..4f35aaf1c3 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/sk.json @@ -0,0 +1,8 @@ +{ + "culture": "sk", + "texts": { + "Menu:Home": "Domov", + "Welcome": "Vitajte", + "LongWelcomeMessage": "Vitajte v aplikácii. Toto je štartovací projekt založený na ABP frameworku. Viac informácií nájdete na stránke abp.io." + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/sl.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/sl.json new file mode 100644 index 0000000000..a066ef26ba --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/sl.json @@ -0,0 +1,8 @@ +{ + "culture": "sl", + "texts": { + "Menu:Home": "Domov", + "Welcome": "Dobrodošli", + "LongWelcomeMessage": "Dobrodošli v aplikaciji. To je začetni projekt na osnovi okolja ABP. Za več informacij obiščite abp.io." + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/tr.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/tr.json new file mode 100644 index 0000000000..2cc911e48e --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/tr.json @@ -0,0 +1,8 @@ +{ + "culture": "tr", + "texts": { + "Menu:Home": "Ana sayfa", + "Welcome": "Hoşgeldiniz", + "LongWelcomeMessage": "Uygulamaya hoşgeldiniz. Bu, ABP framework'ü üzerine bina edilmiş bir başlangıç projesidir. Daha fazla bilgi için abp.io adresini ziyaret edebilirsiniz." + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/vi.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/vi.json new file mode 100644 index 0000000000..c115a35726 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/vi.json @@ -0,0 +1,8 @@ +{ + "culture": "vi", + "texts": { + "Menu:Home": "Trang chủ", + "Welcome": "Chào mừng bạn", + "LongWelcomeMessage": "Chào mừng bạn đến ứng dụng. Đây là một dự án khởi nghiệp dựa trên khung ABP. Để biết thêm thông tin, hãy truy cập abp.io." + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/zh-Hans.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/zh-Hans.json new file mode 100644 index 0000000000..23790bde50 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/zh-Hans.json @@ -0,0 +1,8 @@ +{ + "culture": "zh-Hans", + "texts": { + "Menu:Home": "首页", + "Welcome": "欢迎", + "LongWelcomeMessage": "欢迎来到该应用程序. 这是一个基于ABP框架的启动项目. 有关更多信息, 请访问 abp.io." + } + } \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/zh-Hant.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/zh-Hant.json new file mode 100644 index 0000000000..31e0ab5a47 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStore/zh-Hant.json @@ -0,0 +1,8 @@ +{ + "culture": "zh-Hant", + "texts": { + "Menu:Home": "首頁", + "Welcome": "歡迎", + "LongWelcomeMessage": "歡迎來到此應用程式. 這是一個基於ABP框架的起始專案. 有關更多訊息, 請瀏覽 abp.io." + } + } \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStoreResource.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStoreResource.cs new file mode 100644 index 0000000000..f31196391e --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Localization/BookStoreResource.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Localization; + +namespace Volo.BookStore.Localization; + +[LocalizationResourceName("BookStore")] +public class BookStoreResource +{ + +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/MultiTenancy/MultiTenancyConsts.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/MultiTenancy/MultiTenancyConsts.cs new file mode 100644 index 0000000000..e3f057073c --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/MultiTenancy/MultiTenancyConsts.cs @@ -0,0 +1,10 @@ +namespace Volo.BookStore.MultiTenancy; + +public static class MultiTenancyConsts +{ + /* Enable/disable multi-tenancy easily in a single point. + * If you will never need to multi-tenancy, you can remove + * related modules and code parts, including this file. + */ + public const bool IsEnabled = true; +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Volo.BookStore.Domain.Shared.csproj b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Volo.BookStore.Domain.Shared.csproj new file mode 100644 index 0000000000..8938c4c83c --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain.Shared/Volo.BookStore.Domain.Shared.csproj @@ -0,0 +1,32 @@ + + + + + + netstandard2.0;netstandard2.1;net7.0 + enable + Volo.BookStore + true + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/BookStoreConsts.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/BookStoreConsts.cs new file mode 100644 index 0000000000..cadd7103bd --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/BookStoreConsts.cs @@ -0,0 +1,8 @@ +namespace Volo.BookStore; + +public static class BookStoreConsts +{ + public const string DbTablePrefix = "App"; + + public const string DbSchema = null; +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/BookStoreDomainModule.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/BookStoreDomainModule.cs new file mode 100644 index 0000000000..1427b60b3e --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/BookStoreDomainModule.cs @@ -0,0 +1,68 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Volo.BookStore.MultiTenancy; +using Volo.Abp.AuditLogging; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.Emailing; +using Volo.Abp.FeatureManagement; +using Volo.Abp.Identity; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.MultiTenancy; +using Volo.Abp.OpenIddict; +using Volo.Abp.PermissionManagement.Identity; +using Volo.Abp.PermissionManagement.OpenIddict; +using Volo.Abp.SettingManagement; +using Volo.Abp.TenantManagement; + +namespace Volo.BookStore; + +[DependsOn( + typeof(BookStoreDomainSharedModule), + typeof(AbpAuditLoggingDomainModule), + typeof(AbpBackgroundJobsDomainModule), + typeof(AbpFeatureManagementDomainModule), + typeof(AbpIdentityDomainModule), + typeof(AbpOpenIddictDomainModule), + typeof(AbpPermissionManagementDomainOpenIddictModule), + typeof(AbpPermissionManagementDomainIdentityModule), + typeof(AbpSettingManagementDomainModule), + typeof(AbpTenantManagementDomainModule), + typeof(AbpEmailingModule) +)] +public class BookStoreDomainModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Languages.Add(new LanguageInfo("ar", "ar", "العربية", "ae")); + options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština")); + options.Languages.Add(new LanguageInfo("en", "en", "English", "gb")); + options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)")); + options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); + options.Languages.Add(new LanguageInfo("hr", "hr", "Croatian")); + options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish", "fi")); + options.Languages.Add(new LanguageInfo("fr", "fr", "Français", "fr")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it")); + options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); + options.Languages.Add(new LanguageInfo("ru", "ru", "Русский", "ru")); + options.Languages.Add(new LanguageInfo("sk", "sk", "Slovak", "sk")); + options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe", "tr")); + options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); + options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文")); + options.Languages.Add(new LanguageInfo("de-DE", "de-DE", "Deutsch", "de")); + options.Languages.Add(new LanguageInfo("es", "es", "Español")); + }); + + Configure(options => + { + options.IsEnabled = MultiTenancyConsts.IsEnabled; + }); + +#if DEBUG + context.Services.Replace(ServiceDescriptor.Singleton()); +#endif + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Data/BookStoreDbMigrationService.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Data/BookStoreDbMigrationService.cs new file mode 100644 index 0000000000..191cd3325d --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Data/BookStoreDbMigrationService.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Identity; +using Volo.Abp.MultiTenancy; +using Volo.Abp.TenantManagement; + +namespace Volo.BookStore.Data; + +public class BookStoreDbMigrationService : ITransientDependency +{ + public ILogger Logger { get; set; } + + private readonly IDataSeeder _dataSeeder; + private readonly IEnumerable _dbSchemaMigrators; + private readonly ITenantRepository _tenantRepository; + private readonly ICurrentTenant _currentTenant; + + public BookStoreDbMigrationService( + IDataSeeder dataSeeder, + IEnumerable dbSchemaMigrators, + ITenantRepository tenantRepository, + ICurrentTenant currentTenant) + { + _dataSeeder = dataSeeder; + _dbSchemaMigrators = dbSchemaMigrators; + _tenantRepository = tenantRepository; + _currentTenant = currentTenant; + + Logger = NullLogger.Instance; + } + + public async Task MigrateAsync() + { + + Logger.LogInformation("Started database migrations..."); + + await MigrateDatabaseSchemaAsync(); + await SeedDataAsync(); + + Logger.LogInformation($"Successfully completed host database migrations."); + + var tenants = await _tenantRepository.GetListAsync(includeDetails: true); + + var migratedDatabaseSchemas = new HashSet(); + foreach (var tenant in tenants) + { + using (_currentTenant.Change(tenant.Id)) + { + if (tenant.ConnectionStrings.Any()) + { + var tenantConnectionStrings = tenant.ConnectionStrings + .Select(x => x.Value) + .ToList(); + + if (!migratedDatabaseSchemas.IsSupersetOf(tenantConnectionStrings)) + { + await MigrateDatabaseSchemaAsync(tenant); + + migratedDatabaseSchemas.AddIfNotContains(tenantConnectionStrings); + } + } + + await SeedDataAsync(tenant); + } + + Logger.LogInformation($"Successfully completed {tenant.Name} tenant database migrations."); + } + + Logger.LogInformation("Successfully completed all database migrations."); + Logger.LogInformation("You can safely end this process..."); + } + + private async Task MigrateDatabaseSchemaAsync(Tenant? tenant = null) + { + Logger.LogInformation( + $"Migrating schema for {(tenant == null ? "host" : tenant.Name + " tenant")} database..."); + + foreach (var migrator in _dbSchemaMigrators) + { + await migrator.MigrateAsync(); + } + } + + private async Task SeedDataAsync(Tenant? tenant = null) + { + Logger.LogInformation($"Executing {(tenant == null ? "host" : tenant.Name + " tenant")} database seed..."); + + await _dataSeeder.SeedAsync(new DataSeedContext(tenant?.Id) + .WithProperty(IdentityDataSeedContributor.AdminEmailPropertyName, IdentityDataSeedContributor.AdminEmailDefaultValue) + .WithProperty(IdentityDataSeedContributor.AdminPasswordPropertyName, IdentityDataSeedContributor.AdminPasswordDefaultValue) + ); + } + +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Data/IBookStoreDbSchemaMigrator.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Data/IBookStoreDbSchemaMigrator.cs new file mode 100644 index 0000000000..6543f4b142 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Data/IBookStoreDbSchemaMigrator.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace Volo.BookStore.Data; + +public interface IBookStoreDbSchemaMigrator +{ + Task MigrateAsync(); +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Data/NullBookStoreDbSchemaMigrator.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Data/NullBookStoreDbSchemaMigrator.cs new file mode 100644 index 0000000000..4935647b7e --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Data/NullBookStoreDbSchemaMigrator.cs @@ -0,0 +1,15 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.BookStore.Data; + +/* This is used if database provider does't define + * IBookStoreDbSchemaMigrator implementation. + */ +public class NullBookStoreDbSchemaMigrator : IBookStoreDbSchemaMigrator, ITransientDependency +{ + public Task MigrateAsync() + { + return Task.CompletedTask; + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/OpenIddict/OpenIddictDataSeedContributor.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/OpenIddict/OpenIddictDataSeedContributor.cs new file mode 100644 index 0000000000..dfa294a922 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/OpenIddict/OpenIddictDataSeedContributor.cs @@ -0,0 +1,415 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Localization; +using OpenIddict.Abstractions; +using Volo.Abp; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.OpenIddict.Applications; +using Volo.Abp.OpenIddict.Scopes; +using Volo.Abp.PermissionManagement; +using Volo.Abp.Uow; + +namespace Volo.BookStore.OpenIddict; + +/* Creates initial data that is needed to property run the application + * and make client-to-server communication possible. + */ +public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDependency +{ + private readonly IConfiguration _configuration; + private readonly IOpenIddictApplicationRepository _openIddictApplicationRepository; + private readonly IAbpApplicationManager _applicationManager; + private readonly IOpenIddictScopeRepository _openIddictScopeRepository; + private readonly IOpenIddictScopeManager _scopeManager; + private readonly IPermissionDataSeeder _permissionDataSeeder; + private readonly IStringLocalizer L; + + public OpenIddictDataSeedContributor( + IConfiguration configuration, + IOpenIddictApplicationRepository openIddictApplicationRepository, + IAbpApplicationManager applicationManager, + IOpenIddictScopeRepository openIddictScopeRepository, + IOpenIddictScopeManager scopeManager, + IPermissionDataSeeder permissionDataSeeder, + IStringLocalizer l ) + { + _configuration = configuration; + _openIddictApplicationRepository = openIddictApplicationRepository; + _applicationManager = applicationManager; + _openIddictScopeRepository = openIddictScopeRepository; + _scopeManager = scopeManager; + _permissionDataSeeder = permissionDataSeeder; + L = l; + } + + [UnitOfWork] + public virtual async Task SeedAsync(DataSeedContext context) + { + await CreateScopesAsync(); + await CreateApplicationsAsync(); + } + + private async Task CreateScopesAsync() + { + if (await _openIddictScopeRepository.FindByNameAsync("BookStore") == null) + { + await _scopeManager.CreateAsync(new OpenIddictScopeDescriptor { + Name = "BookStore", DisplayName = "BookStore API", Resources = { "BookStore" } + }); + } + } + + private async Task CreateApplicationsAsync() + { + var commonScopes = new List { + OpenIddictConstants.Permissions.Scopes.Address, + OpenIddictConstants.Permissions.Scopes.Email, + OpenIddictConstants.Permissions.Scopes.Phone, + OpenIddictConstants.Permissions.Scopes.Profile, + OpenIddictConstants.Permissions.Scopes.Roles, + "BookStore" + }; + + var configurationSection = _configuration.GetSection("OpenIddict:Applications"); + + //Web Client + var webClientId = configurationSection["BookStore_Web:ClientId"]; + if (!webClientId.IsNullOrWhiteSpace()) + { + var webClientRootUrl = configurationSection["BookStore_Web:RootUrl"].EnsureEndsWith('/'); + + /* BookStore_Web client is only needed if you created a tiered + * solution. Otherwise, you can delete this client. */ + await CreateApplicationAsync( + name: webClientId!, + type: OpenIddictConstants.ClientTypes.Confidential, + consentType: OpenIddictConstants.ConsentTypes.Implicit, + displayName: "Web Application", + secret: configurationSection["BookStore_Web:ClientSecret"] ?? "1q2w3e*", + grantTypes: new List //Hybrid flow + { + OpenIddictConstants.GrantTypes.AuthorizationCode, OpenIddictConstants.GrantTypes.Implicit + }, + scopes: commonScopes, + redirectUri: $"{webClientRootUrl}signin-oidc", + clientUri: webClientRootUrl, + postLogoutRedirectUri: $"{webClientRootUrl}signout-callback-oidc" + ); + } + + //Console Test / Angular Client + var consoleAndAngularClientId = configurationSection["BookStore_App:ClientId"]; + if (!consoleAndAngularClientId.IsNullOrWhiteSpace()) + { + var consoleAndAngularClientRootUrl = configurationSection["BookStore_App:RootUrl"]?.TrimEnd('/'); + await CreateApplicationAsync( + name: consoleAndAngularClientId!, + type: OpenIddictConstants.ClientTypes.Public, + consentType: OpenIddictConstants.ConsentTypes.Implicit, + displayName: "Console Test / Angular Application", + secret: null, + grantTypes: new List { + OpenIddictConstants.GrantTypes.AuthorizationCode, + OpenIddictConstants.GrantTypes.Password, + OpenIddictConstants.GrantTypes.ClientCredentials, + OpenIddictConstants.GrantTypes.RefreshToken + }, + scopes: commonScopes, + redirectUri: consoleAndAngularClientRootUrl, + clientUri: consoleAndAngularClientRootUrl, + postLogoutRedirectUri: consoleAndAngularClientRootUrl + ); + } + + // Blazor Client + var blazorClientId = configurationSection["BookStore_Blazor:ClientId"]; + if (!blazorClientId.IsNullOrWhiteSpace()) + { + var blazorRootUrl = configurationSection["BookStore_Blazor:RootUrl"]?.TrimEnd('/'); + + await CreateApplicationAsync( + name: blazorClientId!, + type: OpenIddictConstants.ClientTypes.Public, + consentType: OpenIddictConstants.ConsentTypes.Implicit, + displayName: "Blazor Application", + secret: null, + grantTypes: new List { OpenIddictConstants.GrantTypes.AuthorizationCode, }, + scopes: commonScopes, + redirectUri: $"{blazorRootUrl}/authentication/login-callback", + clientUri: blazorRootUrl, + postLogoutRedirectUri: $"{blazorRootUrl}/authentication/logout-callback" + ); + } + + // Blazor Server Tiered Client + var blazorServerTieredClientId = configurationSection["BookStore_BlazorServerTiered:ClientId"]; + if (!blazorServerTieredClientId.IsNullOrWhiteSpace()) + { + var blazorServerTieredRootUrl = + configurationSection["BookStore_BlazorServerTiered:RootUrl"].EnsureEndsWith('/'); + + await CreateApplicationAsync( + name: blazorServerTieredClientId!, + type: OpenIddictConstants.ClientTypes.Confidential, + consentType: OpenIddictConstants.ConsentTypes.Implicit, + displayName: "Blazor Server Application", + secret: configurationSection["BookStore_BlazorServerTiered:ClientSecret"] ?? "1q2w3e*", + grantTypes: new List //Hybrid flow + { + OpenIddictConstants.GrantTypes.AuthorizationCode, OpenIddictConstants.GrantTypes.Implicit + }, + scopes: commonScopes, + redirectUri: $"{blazorServerTieredRootUrl}signin-oidc", + clientUri: blazorServerTieredRootUrl, + postLogoutRedirectUri: $"{blazorServerTieredRootUrl}signout-callback-oidc" + ); + } + + // Swagger Client + var swaggerClientId = configurationSection["BookStore_Swagger:ClientId"]; + if (!swaggerClientId.IsNullOrWhiteSpace()) + { + var swaggerRootUrl = configurationSection["BookStore_Swagger:RootUrl"]?.TrimEnd('/'); + + await CreateApplicationAsync( + name: swaggerClientId!, + type: OpenIddictConstants.ClientTypes.Public, + consentType: OpenIddictConstants.ConsentTypes.Implicit, + displayName: "Swagger Application", + secret: null, + grantTypes: new List { OpenIddictConstants.GrantTypes.AuthorizationCode, }, + scopes: commonScopes, + redirectUri: $"{swaggerRootUrl}/swagger/oauth2-redirect.html", + clientUri: swaggerRootUrl + ); + } + } + + private async Task CreateApplicationAsync( + [NotNull] string name, + [NotNull] string type, + [NotNull] string consentType, + string displayName, + string? secret, + List grantTypes, + List scopes, + string? clientUri = null, + string? redirectUri = null, + string? postLogoutRedirectUri = null, + List? permissions = null) + { + if (!string.IsNullOrEmpty(secret) && string.Equals(type, OpenIddictConstants.ClientTypes.Public, + StringComparison.OrdinalIgnoreCase)) + { + throw new BusinessException(L["NoClientSecretCanBeSetForPublicApplications"]); + } + + if (string.IsNullOrEmpty(secret) && string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, + StringComparison.OrdinalIgnoreCase)) + { + throw new BusinessException(L["TheClientSecretIsRequiredForConfidentialApplications"]); + } + + var client = await _openIddictApplicationRepository.FindByClientIdAsync(name); + + var application = new AbpApplicationDescriptor { + ClientId = name, + Type = type, + ClientSecret = secret, + ConsentType = consentType, + DisplayName = displayName, + ClientUri = clientUri, + }; + + Check.NotNullOrEmpty(grantTypes, nameof(grantTypes)); + Check.NotNullOrEmpty(scopes, nameof(scopes)); + + if (new[] { OpenIddictConstants.GrantTypes.AuthorizationCode, OpenIddictConstants.GrantTypes.Implicit }.All( + grantTypes.Contains)) + { + application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeIdToken); + + if (string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) + { + application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeIdTokenToken); + application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeToken); + } + } + + if (!redirectUri.IsNullOrWhiteSpace() || !postLogoutRedirectUri.IsNullOrWhiteSpace()) + { + application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Logout); + } + + var buildInGrantTypes = new[] { + OpenIddictConstants.GrantTypes.Implicit, OpenIddictConstants.GrantTypes.Password, + OpenIddictConstants.GrantTypes.AuthorizationCode, OpenIddictConstants.GrantTypes.ClientCredentials, + OpenIddictConstants.GrantTypes.DeviceCode, OpenIddictConstants.GrantTypes.RefreshToken + }; + + foreach (var grantType in grantTypes) + { + if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode) + { + application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode); + application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.Code); + } + + if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode || + grantType == OpenIddictConstants.GrantTypes.Implicit) + { + application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Authorization); + } + + if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode || + grantType == OpenIddictConstants.GrantTypes.ClientCredentials || + grantType == OpenIddictConstants.GrantTypes.Password || + grantType == OpenIddictConstants.GrantTypes.RefreshToken || + grantType == OpenIddictConstants.GrantTypes.DeviceCode) + { + application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Token); + application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Revocation); + application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Introspection); + } + + if (grantType == OpenIddictConstants.GrantTypes.ClientCredentials) + { + application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.ClientCredentials); + } + + if (grantType == OpenIddictConstants.GrantTypes.Implicit) + { + application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Implicit); + } + + if (grantType == OpenIddictConstants.GrantTypes.Password) + { + application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Password); + } + + if (grantType == OpenIddictConstants.GrantTypes.RefreshToken) + { + application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.RefreshToken); + } + + if (grantType == OpenIddictConstants.GrantTypes.DeviceCode) + { + application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.DeviceCode); + application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Device); + } + + if (grantType == OpenIddictConstants.GrantTypes.Implicit) + { + application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.IdToken); + if (string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) + { + application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.IdTokenToken); + application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.Token); + } + } + + if (!buildInGrantTypes.Contains(grantType)) + { + application.Permissions.Add(OpenIddictConstants.Permissions.Prefixes.GrantType + grantType); + } + } + + var buildInScopes = new[] { + OpenIddictConstants.Permissions.Scopes.Address, OpenIddictConstants.Permissions.Scopes.Email, + OpenIddictConstants.Permissions.Scopes.Phone, OpenIddictConstants.Permissions.Scopes.Profile, + OpenIddictConstants.Permissions.Scopes.Roles + }; + + foreach (var scope in scopes) + { + if (buildInScopes.Contains(scope)) + { + application.Permissions.Add(scope); + } + else + { + application.Permissions.Add(OpenIddictConstants.Permissions.Prefixes.Scope + scope); + } + } + + if (redirectUri != null) + { + if (!redirectUri.IsNullOrEmpty()) + { + if (!Uri.TryCreate(redirectUri, UriKind.Absolute, out var uri) || !uri.IsWellFormedOriginalString()) + { + throw new BusinessException(L["InvalidRedirectUri", redirectUri]); + } + + if (application.RedirectUris.All(x => x != uri)) + { + application.RedirectUris.Add(uri); + } + } + } + + if (postLogoutRedirectUri != null) + { + if (!postLogoutRedirectUri.IsNullOrEmpty()) + { + if (!Uri.TryCreate(postLogoutRedirectUri, UriKind.Absolute, out var uri) || + !uri.IsWellFormedOriginalString()) + { + throw new BusinessException(L["InvalidPostLogoutRedirectUri", postLogoutRedirectUri]); + } + + if (application.PostLogoutRedirectUris.All(x => x != uri)) + { + application.PostLogoutRedirectUris.Add(uri); + } + } + } + + if (permissions != null) + { + await _permissionDataSeeder.SeedAsync( + ClientPermissionValueProvider.ProviderName, + name, + permissions, + null + ); + } + + if (client == null) + { + await _applicationManager.CreateAsync(application); + return; + } + + if (!HasSameRedirectUris(client, application)) + { + client.RedirectUris = JsonSerializer.Serialize(application.RedirectUris.Select(q => q.ToString().TrimEnd('/'))); + client.PostLogoutRedirectUris = JsonSerializer.Serialize(application.PostLogoutRedirectUris.Select(q => q.ToString().TrimEnd('/'))); + + await _applicationManager.UpdateAsync(client.ToModel()); + } + + if (!HasSameScopes(client, application)) + { + client.Permissions = JsonSerializer.Serialize(application.Permissions.Select(q => q.ToString())); + await _applicationManager.UpdateAsync(client.ToModel()); + } + } + + private bool HasSameRedirectUris(OpenIddictApplication existingClient, AbpApplicationDescriptor application) + { + return existingClient.RedirectUris == JsonSerializer.Serialize(application.RedirectUris.Select(q => q.ToString().TrimEnd('/'))); + } + + private bool HasSameScopes(OpenIddictApplication existingClient, AbpApplicationDescriptor application) + { + return existingClient.Permissions == JsonSerializer.Serialize(application.Permissions.Select(q => q.ToString().TrimEnd('/'))); + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Properties/AssemblyInfo.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..bf6d15e67a --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Properties/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; +[assembly:InternalsVisibleToAttribute("Volo.BookStore.Domain.Tests")] +[assembly:InternalsVisibleToAttribute("Volo.BookStore.TestBase")] diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Settings/BookStoreSettingDefinitionProvider.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Settings/BookStoreSettingDefinitionProvider.cs new file mode 100644 index 0000000000..a2c454aa8b --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Settings/BookStoreSettingDefinitionProvider.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Settings; + +namespace Volo.BookStore.Settings; + +public class BookStoreSettingDefinitionProvider : SettingDefinitionProvider +{ + public override void Define(ISettingDefinitionContext context) + { + //Define your own settings here. Example: + //context.Add(new SettingDefinition(BookStoreSettings.MySetting1)); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Settings/BookStoreSettings.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Settings/BookStoreSettings.cs new file mode 100644 index 0000000000..944273077e --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Settings/BookStoreSettings.cs @@ -0,0 +1,9 @@ +namespace Volo.BookStore.Settings; + +public static class BookStoreSettings +{ + private const string Prefix = "BookStore"; + + //Add your own setting names here. Example: + //public const string MySetting1 = Prefix + ".MySetting1"; +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Volo.BookStore.Domain.csproj b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Volo.BookStore.Domain.csproj new file mode 100644 index 0000000000..30bb57ade3 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.Domain/Volo.BookStore.Domain.csproj @@ -0,0 +1,28 @@ + + + + + + net7.0 + enable + Volo.BookStore + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Client/BookStoreHttpApiClientModule.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Client/BookStoreHttpApiClientModule.cs new file mode 100644 index 0000000000..58ca5a4bc4 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Client/BookStoreHttpApiClientModule.cs @@ -0,0 +1,38 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Account; +using Volo.Abp.FeatureManagement; +using Volo.Abp.Identity; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement; +using Volo.Abp.TenantManagement; +using Volo.Abp.SettingManagement; +using Volo.Abp.VirtualFileSystem; + +namespace Volo.BookStore; + +[DependsOn( + typeof(BookStoreApplicationContractsModule), + typeof(AbpAccountHttpApiClientModule), + typeof(AbpIdentityHttpApiClientModule), + typeof(AbpPermissionManagementHttpApiClientModule), + typeof(AbpTenantManagementHttpApiClientModule), + typeof(AbpFeatureManagementHttpApiClientModule), + typeof(AbpSettingManagementHttpApiClientModule) +)] +public class BookStoreHttpApiClientModule : AbpModule +{ + public const string RemoteServiceName = "Default"; + + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddHttpClientProxies( + typeof(BookStoreApplicationContractsModule).Assembly, + RemoteServiceName + ); + + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Client/Volo.BookStore.HttpApi.Client.csproj b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Client/Volo.BookStore.HttpApi.Client.csproj new file mode 100644 index 0000000000..e082db71fa --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Client/Volo.BookStore.HttpApi.Client.csproj @@ -0,0 +1,29 @@ + + + + + + netstandard2.0;netstandard2.1;net7.0 + enable + Volo.BookStore + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/BookStoreBrandingProvider.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/BookStoreBrandingProvider.cs new file mode 100644 index 0000000000..9e5db01cd5 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/BookStoreBrandingProvider.cs @@ -0,0 +1,10 @@ +using Volo.Abp.DependencyInjection; +using Volo.Abp.Ui.Branding; + +namespace Volo.BookStore; + +[Dependency(ReplaceServices = true)] +public class BookStoreBrandingProvider : DefaultBrandingProvider +{ + public override string AppName => "BookStore"; +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/BookStoreHttpApiHostModule.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/BookStoreHttpApiHostModule.cs new file mode 100644 index 0000000000..fd3a17b9a1 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/BookStoreHttpApiHostModule.cs @@ -0,0 +1,219 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Cors; +using Microsoft.AspNetCore.Extensions.DependencyInjection; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Volo.BookStore.MongoDB; +using Volo.BookStore.MultiTenancy; +using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite; +using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite.Bundling; +using Microsoft.OpenApi.Models; +using OpenIddict.Validation.AspNetCore; +using Volo.Abp; +using Volo.Abp.Account; +using Volo.Abp.Account.Web; +using Volo.Abp.AspNetCore.MultiTenancy; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; +using Volo.Abp.AspNetCore.Serilog; +using Volo.Abp.Autofac; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.Swashbuckle; +using Volo.Abp.UI.Navigation.Urls; +using Volo.Abp.VirtualFileSystem; + +namespace Volo.BookStore; + +[DependsOn( + typeof(BookStoreHttpApiModule), + typeof(AbpAutofacModule), + typeof(AbpAspNetCoreMultiTenancyModule), + typeof(BookStoreApplicationModule), + typeof(BookStoreMongoDbModule), + typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule), + typeof(AbpAccountWebOpenIddictModule), + typeof(AbpAspNetCoreSerilogModule), + typeof(AbpSwashbuckleModule) +)] +public class BookStoreHttpApiHostModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(builder => + { + builder.AddValidation(options => + { + options.AddAudiences("BookStore"); + options.UseLocalServer(); + options.UseAspNetCore(); + }); + }); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + var hostingEnvironment = context.Services.GetHostingEnvironment(); + + ConfigureAuthentication(context); + ConfigureBundles(); + ConfigureUrls(configuration); + ConfigureConventionalControllers(); + ConfigureVirtualFileSystem(context); + ConfigureCors(context, configuration); + ConfigureSwaggerServices(context, configuration); + } + + private void ConfigureAuthentication(ServiceConfigurationContext context) + { + context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); + } + + private void ConfigureBundles() + { + Configure(options => + { + options.StyleBundles.Configure( + LeptonXLiteThemeBundles.Styles.Global, + bundle => + { + bundle.AddFiles("/global-styles.css"); + } + ); + }); + } + + private void ConfigureUrls(IConfiguration configuration) + { + Configure(options => + { + options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"]; + options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"]?.Split(',') ?? Array.Empty()); + + options.Applications["Angular"].RootUrl = configuration["App:ClientUrl"]; + options.Applications["Angular"].Urls[AccountUrlNames.PasswordReset] = "account/reset-password"; + }); + } + + private void ConfigureVirtualFileSystem(ServiceConfigurationContext context) + { + var hostingEnvironment = context.Services.GetHostingEnvironment(); + + if (hostingEnvironment.IsDevelopment()) + { + Configure(options => + { + options.FileSets.ReplaceEmbeddedByPhysical( + Path.Combine(hostingEnvironment.ContentRootPath, + $"..{Path.DirectorySeparatorChar}Volo.BookStore.Domain.Shared")); + options.FileSets.ReplaceEmbeddedByPhysical( + Path.Combine(hostingEnvironment.ContentRootPath, + $"..{Path.DirectorySeparatorChar}Volo.BookStore.Domain")); + options.FileSets.ReplaceEmbeddedByPhysical( + Path.Combine(hostingEnvironment.ContentRootPath, + $"..{Path.DirectorySeparatorChar}Volo.BookStore.Application.Contracts")); + options.FileSets.ReplaceEmbeddedByPhysical( + Path.Combine(hostingEnvironment.ContentRootPath, + $"..{Path.DirectorySeparatorChar}Volo.BookStore.Application")); + }); + } + } + + private void ConfigureConventionalControllers() + { + Configure(options => + { + options.ConventionalControllers.Create(typeof(BookStoreApplicationModule).Assembly); + }); + } + + private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration) + { + context.Services.AddAbpSwaggerGenWithOAuth( + configuration["AuthServer:Authority"], + new Dictionary + { + {"BookStore", "BookStore API"} + }, + options => + { + options.SwaggerDoc("v1", new OpenApiInfo { Title = "BookStore API", Version = "v1" }); + options.DocInclusionPredicate((docName, description) => true); + options.CustomSchemaIds(type => type.FullName); + }); + } + + private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration) + { + context.Services.AddCors(options => + { + options.AddDefaultPolicy(builder => + { + builder + .WithOrigins(configuration["App:CorsOrigins"]? + .Split(",", StringSplitOptions.RemoveEmptyEntries) + .Select(o => o.RemovePostFix("/")) + .ToArray() ?? Array.Empty()) + .WithAbpExposedHeaders() + .SetIsOriginAllowedToAllowWildcardSubdomains() + .AllowAnyHeader() + .AllowAnyMethod() + .AllowCredentials(); + }); + }); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + var env = context.GetEnvironment(); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseAbpRequestLocalization(); + + if (!env.IsDevelopment()) + { + app.UseErrorPage(); + } + + app.UseCorrelationId(); + app.UseStaticFiles(); + app.UseRouting(); + app.UseCors(); + app.UseAuthentication(); + app.UseAbpOpenIddictValidation(); + + if (MultiTenancyConsts.IsEnabled) + { + app.UseMultiTenancy(); + } + + app.UseUnitOfWork(); + app.UseAuthorization(); + + app.UseSwagger(); + app.UseAbpSwaggerUI(c => + { + c.SwaggerEndpoint("/swagger/v1/swagger.json", "BookStore API"); + + var configuration = context.ServiceProvider.GetRequiredService(); + c.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); + c.OAuthScopes("BookStore"); + }); + + app.UseAuditing(); + app.UseAbpSerilogEnrichers(); + app.UseConfiguredEndpoints(); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/Controllers/HomeController.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/Controllers/HomeController.cs new file mode 100644 index 0000000000..f9751a7124 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/Controllers/HomeController.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; + +namespace Volo.BookStore.Controllers; + +public class HomeController : AbpController +{ + public ActionResult Index() + { + return Redirect("~/swagger"); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/Program.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/Program.cs new file mode 100644 index 0000000000..b3e7ee2d9e --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/Program.cs @@ -0,0 +1,56 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Serilog; +using Serilog.Events; + +namespace Volo.BookStore; + +public class Program +{ + public async static Task Main(string[] args) + { + Log.Logger = new LoggerConfiguration() +#if DEBUG + .MinimumLevel.Debug() +#else + .MinimumLevel.Information() +#endif + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) + .Enrich.FromLogContext() + .WriteTo.Async(c => c.File("Logs/logs.txt")) + .WriteTo.Async(c => c.Console()) + .CreateLogger(); + + try + { + Log.Information("Starting Volo.BookStore.HttpApi.Host."); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.AddApplicationAsync(); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); + return 0; + } + catch (Exception ex) + { + if (ex is HostAbortedException) + { + throw; + } + + Log.Fatal(ex, "Host terminated unexpectedly!"); + return 1; + } + finally + { + Log.CloseAndFlush(); + } + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/Properties/launchSettings.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/Properties/launchSettings.json new file mode 100644 index 0000000000..0d9c4179db --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "https://localhost:44315", + "sslPort": 44315 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Volo.BookStore.HttpApi.Host": { + "commandName": "Project", + "launchBrowser": true, + "applicationUrl": "https://localhost:44315", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/Volo.BookStore.HttpApi.Host.csproj b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/Volo.BookStore.HttpApi.Host.csproj new file mode 100644 index 0000000000..dded9a5a07 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/Volo.BookStore.HttpApi.Host.csproj @@ -0,0 +1,40 @@ + + + + + + net7.0 + enable + Volo.BookStore + true + Volo.BookStore-4681b4fd-151f-4221-84a4-929d86723e4c + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/abp.resourcemapping.js b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/abp.resourcemapping.js new file mode 100644 index 0000000000..4a2ad45896 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/abp.resourcemapping.js @@ -0,0 +1,11 @@ +module.exports = { + aliases: { + + }, + clean: [ + + ], + mappings: { + + } +}; diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/appsettings.Development.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/appsettings.Development.json new file mode 100644 index 0000000000..2c63c08510 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/appsettings.Development.json @@ -0,0 +1,2 @@ +{ +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/appsettings.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/appsettings.json new file mode 100644 index 0000000000..43e0cda86f --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/appsettings.json @@ -0,0 +1,19 @@ +{ + "App": { + "SelfUrl": "https://localhost:44315", + "ClientUrl": "http://localhost:4200", + "CorsOrigins": "https://*.BookStore.com,http://localhost:4200", + "RedirectAllowedUrls": "http://localhost:4200" + }, + "ConnectionStrings": { + "Default": "mongodb://localhost:27017/BookStore" + }, + "AuthServer": { + "Authority": "https://localhost:44315", + "RequireHttpsMetadata": "false", + "SwaggerClientId": "BookStore_Swagger" + }, + "StringEncryption": { + "DefaultPassPhrase": "AvPA6zemcL8iyh2d" + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/package.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/package.json new file mode 100644 index 0000000000..e69486a651 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/package.json @@ -0,0 +1,8 @@ +{ + "version": "1.0.0", + "name": "my-app", + "private": true, + "dependencies": { + "@abp/aspnetcore.mvc.ui.theme.leptonxlite": "~2.3.1" + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/web.config b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/web.config new file mode 100644 index 0000000000..2f100dd06b --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/wwwroot/global-styles.css b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/wwwroot/global-styles.css new file mode 100644 index 0000000000..74db4bd54f --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/wwwroot/global-styles.css @@ -0,0 +1,6 @@ +/* Your Global Styles */ + +:root .lpx-brand-logo { + --lpx-logo: url('/images/logo/leptonx/logo-light.png'); + --lpx-logo-icon: url('/images/logo/leptonx/logo-light-thumbnail.png'); +} \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/wwwroot/images/logo/leptonx/logo-dark-thumbnail.png b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/wwwroot/images/logo/leptonx/logo-dark-thumbnail.png new file mode 100644 index 0000000000..621596bb5c Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/wwwroot/images/logo/leptonx/logo-dark-thumbnail.png differ diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/wwwroot/images/logo/leptonx/logo-dark.png b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/wwwroot/images/logo/leptonx/logo-dark.png new file mode 100644 index 0000000000..e4bfe818c8 Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/wwwroot/images/logo/leptonx/logo-dark.png differ diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/wwwroot/images/logo/leptonx/logo-light-thumbnail.png b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/wwwroot/images/logo/leptonx/logo-light-thumbnail.png new file mode 100644 index 0000000000..886c960864 Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/wwwroot/images/logo/leptonx/logo-light-thumbnail.png differ diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/wwwroot/images/logo/leptonx/logo-light.png b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/wwwroot/images/logo/leptonx/logo-light.png new file mode 100644 index 0000000000..6ebd97e2b2 Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/wwwroot/images/logo/leptonx/logo-light.png differ diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/yarn.lock b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/yarn.lock new file mode 100644 index 0000000000..2bf7d51f37 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi.Host/yarn.lock @@ -0,0 +1,2574 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@abp/aspnetcore.mvc.ui.theme.leptonxlite@~2.3.1": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.leptonxlite/-/aspnetcore.mvc.ui.theme.leptonxlite-2.3.2.tgz#1d96b59f0669a90db1689e57a1c815f54a8ca3a9" + integrity sha512-V2jj/air+M5A0r7FAfYaCPrALGKGZrT1HtMayqFOFFEJSoxqx4r/0JQ0bEdXlsvhQ3+BiVtNuKG66dTh64nAdQ== + dependencies: + "@abp/aspnetcore.mvc.ui.theme.shared" "~7.2.1" + +"@abp/aspnetcore.mvc.ui.theme.shared@~7.2.1": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-7.2.3.tgz#189dde88792497d29f76a6079dc6db34973ee98d" + integrity sha512-+G2mM/BJWqgGqZFg6GP28PaCtq+YlRmRfg7r0JQ1wkAN9pc11yKm0LRQjFnkcVBzg0A+N2hZqnFbW7wQhwXOHg== + dependencies: + "@abp/aspnetcore.mvc.ui" "~7.2.3" + "@abp/bootstrap" "~7.2.3" + "@abp/bootstrap-datepicker" "~7.2.3" + "@abp/bootstrap-daterangepicker" "~7.2.3" + "@abp/datatables.net-bs5" "~7.2.3" + "@abp/font-awesome" "~7.2.3" + "@abp/jquery-form" "~7.2.3" + "@abp/jquery-validation-unobtrusive" "~7.2.3" + "@abp/lodash" "~7.2.3" + "@abp/luxon" "~7.2.3" + "@abp/malihu-custom-scrollbar-plugin" "~7.2.3" + "@abp/moment" "~7.2.3" + "@abp/select2" "~7.2.3" + "@abp/sweetalert2" "~7.2.3" + "@abp/timeago" "~7.2.3" + "@abp/toastr" "~7.2.3" + +"@abp/aspnetcore.mvc.ui@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-7.2.3.tgz#d828561e678f6ea779a67c908705ba553ae82edc" + integrity sha512-KJCw6OxjQBgNw4QoSoDQOe32bFF9NvHdD09zMVsoCB/GgN66dcbZnk+ldidHcwjLFDPXOuHJMx+TKmno3VgUaQ== + dependencies: + ansi-colors "^4.1.1" + extend-object "^1.0.0" + glob "^7.1.6" + gulp "^4.0.2" + merge-stream "^2.0.0" + micromatch "^4.0.2" + +"@abp/bootstrap-datepicker@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-7.2.3.tgz#7610ff44a6c1ea73f0c9b4c79a31cbb9e505d66f" + integrity sha512-wiKVXftVrXcjwz0FpshD6P4WW3CNk/4cLH15aaqRjM+J0BigDeH9CczlpVc7jXdn+c8plHIRz0t5tqlUud7dIQ== + dependencies: + bootstrap-datepicker "^1.9.0" + +"@abp/bootstrap-daterangepicker@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-7.2.3.tgz#3946fb853dae52ef092db4bb23b94389577c17d3" + integrity sha512-ChdnXMzHvg+HwrUtw2z6KuqRTqHVOq8qEBai+IPW6PykJSML+tZKzer3jzDIzyHq68OIqom3n3xL0XpcniKMew== + dependencies: + bootstrap-daterangepicker "^3.1.0" + +"@abp/bootstrap@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-7.2.3.tgz#43ecd5912ac65bbc142f198ec112b0b2a15e4864" + integrity sha512-Z00q1sAwo9PvFSpfFlbbUHPMyghLOzuEuAzz/8nA6tK7WR0KQBS/0zGC0nK9hNwbyZ4FqKwPSznRVwuwrnqyhQ== + dependencies: + "@abp/core" "~7.2.3" + bootstrap "^5.1.3" + +"@abp/core@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-7.2.3.tgz#a669073989a30f600355b368c01c654714456f17" + integrity sha512-UyKBWwXbKCzKZwV2YJPgP3v2naDFsfJzV+KEHpdgLdPZyrpBhp+bQ80VNVe2HHrD/bLfhM4fu9pCXw6RYZKnvA== + dependencies: + "@abp/utils" "~7.2.3" + +"@abp/datatables.net-bs5@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-7.2.3.tgz#362f3b8ff2f3612989787e2b6ef19bad181b4206" + integrity sha512-TmXTkIX+Vb1O/fER5JeRlWIOZLoSXG4QD3F0ZbebrjgS9k7oSu9igR/VhXBs1m1lvOqcNKv7Y4LTNRAMw+Mi0A== + dependencies: + "@abp/datatables.net" "~7.2.3" + datatables.net-bs5 "^1.11.4" + +"@abp/datatables.net@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-7.2.3.tgz#36661e223d15a0f75caad607094007d974ba678b" + integrity sha512-g+LmRMg4Sk34iU/MN4RpgC/yd8NVEjhVWg/kT+nuWunsnwLHkcfK59KPGXn9ZLktL4VqQYj2WeXbDv8TEbOObg== + dependencies: + "@abp/jquery" "~7.2.3" + datatables.net "^1.11.4" + +"@abp/font-awesome@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-7.2.3.tgz#09b7c02b16ff99c9b5b62c1eefad9b1fc2879bcd" + integrity sha512-+4QRhfU08t1MYkmzTPX0B+p+SZQtOqtlDafzeDm5X6fbOlxV1hi97eRWtLtLgLjodjJWztpECWcsTUTgDhExwQ== + dependencies: + "@abp/core" "~7.2.3" + "@fortawesome/fontawesome-free" "^5.15.4" + +"@abp/jquery-form@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-7.2.3.tgz#b0b295b22ae2ba292100e64d0bb97b3e1e295307" + integrity sha512-ucdGIZ0sxefakGRei9BJvDuoN16fKsYfpOT70/udw3k7uC3gFJD0AvAlEOEZPsFZhpNoqUKexNMym4lZovqBkg== + dependencies: + "@abp/jquery" "~7.2.3" + jquery-form "^4.3.0" + +"@abp/jquery-validation-unobtrusive@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-7.2.3.tgz#1df04e286baa521c216cb949468199e6cacc34e3" + integrity sha512-Hcf1sqAFRIAYKqvN1pZGed+lazzY1nztvcmQlOOgUquiXRS3QjI3dIvxWw5nekJwUPqMpSfuC1GErQo0KpE1fw== + dependencies: + "@abp/jquery-validation" "~7.2.3" + jquery-validation-unobtrusive "^3.2.12" + +"@abp/jquery-validation@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-7.2.3.tgz#438ac052e5d71dab50cf5da8be60ea68a460a725" + integrity sha512-drpE5mXErHQPk/4KChsj3zwNCA4GqNlYquTtHNv9/t5S/NuGqFAkchPV6mRYaiQypcxCndZQNSUEqnWxbuMY0g== + dependencies: + "@abp/jquery" "~7.2.3" + jquery-validation "^1.19.3" + +"@abp/jquery@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-7.2.3.tgz#555192ff0bcde89bbabee0f734ff74bf77cce1b5" + integrity sha512-r/p3D2QlV57YvrGJsLfTuIJGwLSSi5AVFtkmgKyfpyXYOCNb+TVF9sEZOZnoZebX6cT0JRvtUfZ0dk6ZBebAzg== + dependencies: + "@abp/core" "~7.2.3" + jquery "~3.6.0" + +"@abp/lodash@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-7.2.3.tgz#99c1667f1499a7f318902e96ff81b4184b0dce86" + integrity sha512-5KuXPPpa2mkTlUYPR83bUTJUSSGoq9/kFSf9fYC0Wk2mFFeG4mRK6mXwcyHTfYshQe2qxuncxZsJ+4j5uQN9PA== + dependencies: + "@abp/core" "~7.2.3" + lodash "^4.17.21" + +"@abp/luxon@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-7.2.3.tgz#f643ed28b2d1743edd41edfec98d0e70b2f1f008" + integrity sha512-Y3IT1GbyuNSAzfpGnc5uzjz3Z/nDRUpYiZhoX0XeoQlJ+GyVT/+dytsZbuQBLgEWmQJhk9zxdcITXFT5vrWDcw== + dependencies: + "@abp/core" "~7.2.3" + luxon "^2.3.0" + +"@abp/malihu-custom-scrollbar-plugin@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-7.2.3.tgz#a29f25921b07683b02e2f5c82a3da827e3e7d552" + integrity sha512-wq9eBrw/bY3wb50v5zuL0qOcVLOT86XN2ZJQj69O/bi2+0WNdLRCqMHhY0kaafb7UIBAlKChKA/xeICwCZxn+w== + dependencies: + "@abp/core" "~7.2.3" + malihu-custom-scrollbar-plugin "^3.1.5" + +"@abp/moment@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-7.2.3.tgz#f6d2ba7b030b81239853490bdcc9e3c2bd4a39b1" + integrity sha512-pXsOzSom9RZHRGWuVaLIVzSkPayIcWMMmgSyo8T3gtZzZG/QJbpBWT+pug0X8pmV8So4d9E0LjacmODBKLM30A== + dependencies: + moment "^2.9.0" + +"@abp/select2@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-7.2.3.tgz#4cecd1cd843807583fce09ef632f472f3f7da70b" + integrity sha512-Cdzl467UftB421W+l8uikGr2NlOsHwxKDxt5yPrF03LEec1MBys5y7UPUV1TEO6l0xwAVi4mW8dXaawyIOSjUA== + dependencies: + "@abp/core" "~7.2.3" + select2 "^4.0.13" + +"@abp/sweetalert2@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-7.2.3.tgz#9e9c503bdb4d47d2b67b0d8193d82145884c90f3" + integrity sha512-KHZD1YRMN6Z4JxPfXuEwocubooux8nKq6sPNG6RKg+rWpp23Fp8nX/ZngJNywVXSRqzrdEvUAM+92JG7zMwKXw== + dependencies: + "@abp/core" "~7.2.3" + sweetalert2 "^11.3.6" + +"@abp/timeago@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-7.2.3.tgz#2ced6fa607a0471bf3385fbf5d9b1f2d902e824a" + integrity sha512-7eiibNXJWBGpQnitd/i8aWUNHOkcsuq8fAwBLJWvG8Whhh1nmBEjng0pGhheMqo0xoydefWi1K2uZDg99tKPeQ== + dependencies: + "@abp/jquery" "~7.2.3" + timeago "^1.6.7" + +"@abp/toastr@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-7.2.3.tgz#0ef7c24b232ca3d01d4ac5a7dff57800b0ebdcbf" + integrity sha512-2zNMQE6ArRULP6xl+M66/EY83ZrXfNY+sNHUkmZH4uqfGhqR/ijKIQm1quxCLDmUcAjRr1kzu8BCc98pc9tfFw== + dependencies: + "@abp/jquery" "~7.2.3" + toastr "^2.1.4" + +"@abp/utils@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-7.2.3.tgz#f384ba76b2948dbc8c49a453a343facda0825e2c" + integrity sha512-hejxDJhSI9Kor4mS9c/JHHQrW/wLXC/XMOJMUcBVkX/5IQd9GU9EW63oalNQyVA3gz3h5obnb0Qcfdv65wc5Pg== + dependencies: + just-compare "^1.3.0" + +"@fortawesome/fontawesome-free@^5.15.4": + version "5.15.4" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5" + integrity sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg== + +ansi-colors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" + integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== + dependencies: + ansi-wrap "^0.1.0" + +ansi-colors@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw== + dependencies: + ansi-wrap "0.1.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + +ansi-wrap@0.1.0, ansi-wrap@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw== + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +append-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" + integrity sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA== + dependencies: + buffer-equal "^1.0.0" + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== + +arr-filter@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/arr-filter/-/arr-filter-1.1.2.tgz#43fdddd091e8ef11aa4c45d9cdc18e2dff1711ee" + integrity sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA== + dependencies: + make-iterator "^1.0.0" + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-map@^2.0.0, arr-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/arr-map/-/arr-map-2.0.2.tgz#3a77345ffc1cf35e2a91825601f9e58f2e24cac4" + integrity sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw== + dependencies: + make-iterator "^1.0.0" + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== + +array-each@^1.0.0, array-each@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" + integrity sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA== + +array-initial@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-initial/-/array-initial-1.1.0.tgz#2fa74b26739371c3947bd7a7adc73be334b3d795" + integrity sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw== + dependencies: + array-slice "^1.0.0" + is-number "^4.0.0" + +array-last@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/array-last/-/array-last-1.3.0.tgz#7aa77073fec565ddab2493f5f88185f404a9d336" + integrity sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg== + dependencies: + is-number "^4.0.0" + +array-slice@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4" + integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w== + +array-sort@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-sort/-/array-sort-1.0.0.tgz#e4c05356453f56f53512a7d1d6123f2c54c0a88a" + integrity sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg== + dependencies: + default-compare "^1.0.0" + get-value "^2.0.6" + kind-of "^5.0.2" + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== + +async-done@^1.2.0, async-done@^1.2.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.3.2.tgz#5e15aa729962a4b07414f528a88cdf18e0b290a2" + integrity sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.2" + process-nextick-args "^2.0.0" + stream-exhaust "^1.0.1" + +async-each@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.6.tgz#52f1d9403818c179b7561e11a5d1b77eb2160e77" + integrity sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg== + +async-settle@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-settle/-/async-settle-1.0.0.tgz#1d0a914bb02575bec8a8f3a74e5080f72b2c0c6b" + integrity sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw== + dependencies: + async-done "^1.2.2" + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +bach@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880" + integrity sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg== + dependencies: + arr-filter "^1.1.1" + arr-flatten "^1.0.1" + arr-map "^2.0.0" + array-each "^1.0.0" + array-initial "^1.0.0" + array-last "^1.1.1" + async-done "^1.2.2" + async-settle "^1.0.0" + now-and-later "^2.0.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bootstrap-datepicker@^1.9.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/bootstrap-datepicker/-/bootstrap-datepicker-1.10.0.tgz#61612bbe8bf0a69a5bce32bbcdda93ebb6ccf24a" + integrity sha512-lWxtSYddAQOpbAO8UhYhHLcK6425eWoSjb5JDvZU3ePHEPF6A3eUr51WKaFy4PccU19JRxUG6wEU3KdhtKfvpg== + dependencies: + jquery ">=3.4.0 <4.0.0" + +bootstrap-daterangepicker@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bootstrap-daterangepicker/-/bootstrap-daterangepicker-3.1.0.tgz#632e6fb2de4b6360c5c0a9d5f6adb9aace051fe8" + integrity sha512-oaQZx6ZBDo/dZNyXGVi2rx5GmFXThyQLAxdtIqjtLlYVaQUfQALl5JZMJJZzyDIX7blfy4ppZPAJ10g8Ma4d/g== + dependencies: + jquery ">=1.10" + moment "^2.9.0" + +bootstrap@^5.1.3: + version "5.3.1" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.1.tgz#8ca07040ad15d7f75891d1504cf14c5dedfb1cfe" + integrity sha512-jzwza3Yagduci2x0rr9MeFSORjcHpt0lRZukZPZQJT1Dth5qzV7XcgGqYzi39KGAVYR8QEDVoO0ubFKOxzMG+g== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +buffer-equal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.1.tgz#2f7651be5b1b3f057fcd6e7ee16cf34767077d90" + integrity sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg== + +chokidar@^2.0.0: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g== + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag== + +clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== + +cloneable-readable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" + integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== + +collection-map@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c" + integrity sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA== + dependencies: + arr-map "^2.0.2" + for-own "^1.0.0" + make-iterator "^1.0.0" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +concat-stream@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +convert-source-map@^1.5.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== + +copy-props@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-2.0.5.tgz#03cf9ae328d4ebb36f8f1d804448a6af9ee3f2d2" + integrity sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw== + dependencies: + each-props "^1.3.2" + is-plain-object "^5.0.0" + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +datatables.net-bs5@^1.11.4: + version "1.13.6" + resolved "https://registry.yarnpkg.com/datatables.net-bs5/-/datatables.net-bs5-1.13.6.tgz#33bf10c0844bb08e17327d841089c1f277f796ff" + integrity sha512-lXroZoXhLhDulp8gvU7y7wBherg38SbLMGXcHwbnj+XXh4Hvy+d67zSPYbrVI3YiRwYq+aCx15G5qmMj7KjYQg== + dependencies: + datatables.net ">=1.13.4" + jquery ">=1.7" + +datatables.net@>=1.13.4, datatables.net@^1.11.4: + version "1.13.6" + resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-1.13.6.tgz#6e282adbbb2732e8df495611b8bb54e19f7a943e" + integrity sha512-rHNcnW+yEP9me82/KmRcid5eKrqPqW3+I/p1TwqCW3c/7GRYYkDyF6aJQOQ9DNS/pw+nyr4BVpjyJ3yoZXiFPg== + dependencies: + jquery ">=1.7" + +debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + +decode-uri-component@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" + integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== + +default-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f" + integrity sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ== + dependencies: + kind-of "^5.0.2" + +default-resolution@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/default-resolution/-/default-resolution-2.0.0.tgz#bcb82baa72ad79b426a76732f1a81ad6df26d684" + integrity sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ== + +define-properties@^1.1.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" + integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q== + +duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +each-props@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/each-props/-/each-props-1.3.2.tgz#ea45a414d16dd5cfa419b1a81720d5ca06892333" + integrity sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA== + dependencies: + is-plain-object "^2.0.1" + object.defaults "^1.1.0" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50: + version "0.10.62" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" + integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + +es6-iterator@^2.0.1, es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +es6-weak-map@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw== + dependencies: + homedir-polyfill "^1.0.1" + +ext@^1.1.2: + version "1.7.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== + dependencies: + type "^2.7.2" + +extend-object@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/extend-object/-/extend-object-1.0.0.tgz#42514f84015d1356caf5187969dfb2bc1bda0823" + integrity sha512-0dHDIXC7y7LDmCh/lp1oYkmv73K25AMugQI07r8eFopkW6f7Ufn1q+ETMsJjnV9Am14SlElkqy3O92r6xEaxPw== + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +fancy-log@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" + integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + parse-node-version "^1.0.0" + time-stamp "^1.0.0" + +fast-levenshtein@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz#e6a754cc8f15e58987aa9cbd27af66fd6f4e5af9" + integrity sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw== + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +findup-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" + integrity sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g== + dependencies: + detect-file "^1.0.0" + is-glob "^3.1.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +findup-sync@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" + integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== + dependencies: + detect-file "^1.0.0" + is-glob "^4.0.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +fined@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b" + integrity sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng== + dependencies: + expand-tilde "^2.0.2" + is-plain-object "^2.0.3" + object.defaults "^1.1.0" + object.pick "^1.2.0" + parse-filepath "^1.0.1" + +flagged-respawn@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41" + integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q== + +flush-write-stream@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== + +for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + integrity sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg== + dependencies: + for-in "^1.0.1" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== + dependencies: + map-cache "^0.2.2" + +fs-mkdirp-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" + integrity sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ== + dependencies: + graceful-fs "^4.1.11" + through2 "^2.0.3" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-proto "^1.0.1" + has-symbols "^1.0.3" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-stream@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" + integrity sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw== + dependencies: + extend "^3.0.0" + glob "^7.1.1" + glob-parent "^3.1.0" + is-negated-glob "^1.0.0" + ordered-read-streams "^1.0.0" + pumpify "^1.3.5" + readable-stream "^2.1.5" + remove-trailing-separator "^1.0.1" + to-absolute-glob "^2.0.0" + unique-stream "^2.0.2" + +glob-watcher@^5.0.3: + version "5.0.5" + resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-5.0.5.tgz#aa6bce648332924d9a8489be41e3e5c52d4186dc" + integrity sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw== + dependencies: + anymatch "^2.0.0" + async-done "^1.2.0" + chokidar "^2.0.0" + is-negated-glob "^1.0.0" + just-debounce "^1.0.0" + normalize-path "^3.0.0" + object.defaults "^1.1.0" + +glob@^7.1.1, glob@^7.1.6: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg== + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +glogg@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f" + integrity sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA== + dependencies: + sparkles "^1.0.0" + +graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +gulp-cli@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.3.0.tgz#ec0d380e29e52aa45e47977f0d32e18fd161122f" + integrity sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A== + dependencies: + ansi-colors "^1.0.1" + archy "^1.0.0" + array-sort "^1.0.0" + color-support "^1.1.3" + concat-stream "^1.6.0" + copy-props "^2.0.1" + fancy-log "^1.3.2" + gulplog "^1.0.0" + interpret "^1.4.0" + isobject "^3.0.1" + liftoff "^3.1.0" + matchdep "^2.0.0" + mute-stdout "^1.0.0" + pretty-hrtime "^1.0.0" + replace-homedir "^1.0.0" + semver-greatest-satisfied-range "^1.1.0" + v8flags "^3.2.0" + yargs "^7.1.0" + +gulp@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/gulp/-/gulp-4.0.2.tgz#543651070fd0f6ab0a0650c6a3e6ff5a7cb09caa" + integrity sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA== + dependencies: + glob-watcher "^5.0.3" + gulp-cli "^2.2.0" + undertaker "^1.2.1" + vinyl-fs "^3.0.0" + +gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + integrity sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw== + dependencies: + glogg "^1.0.0" + +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@^1.3.4: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +interpret@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ== + +is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q== + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== + dependencies: + number-is-nan "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-negated-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" + integrity sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug== + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + +is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== + dependencies: + is-unc-path "^1.0.0" + +is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== + dependencies: + unc-path-regex "^0.1.2" + +is-utf8@^0.2.0, is-utf8@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== + +is-valid-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" + integrity sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA== + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +jquery-form@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/jquery-form/-/jquery-form-4.3.0.tgz#7d3961c314a1f2d15298f4af1d3943f54f4149c6" + integrity sha512-q3uaVCEWdLOYUCI6dpNdwf/7cJFOsUgdpq6r0taxtGQ5NJSkOzofyWm4jpOuJ5YxdmL1FI5QR+q+HB63HHLGnQ== + dependencies: + jquery ">=1.7.2" + +jquery-mousewheel@>=3.0.6: + version "3.1.13" + resolved "https://registry.yarnpkg.com/jquery-mousewheel/-/jquery-mousewheel-3.1.13.tgz#06f0335f16e353a695e7206bf50503cb523a6ee5" + integrity sha512-GXhSjfOPyDemM005YCEHvzrEALhKDIswtxSHSR2e4K/suHVJKJxxRCGz3skPjNxjJjQa9AVSGGlYjv1M3VLIPg== + +jquery-validation-unobtrusive@^3.2.12: + version "3.2.12" + resolved "https://registry.yarnpkg.com/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.2.12.tgz#1d52841f653e516525c251e494b042e664dad8af" + integrity sha512-kPixGhVcuat7vZXngGFfSIksy4VlzZcHyRgnBIZdsfVneCU+D5sITC8T8dD/9c9K/Q+qkMlgp7ufJHz93nKSuQ== + dependencies: + jquery "^3.5.1" + jquery-validation ">=1.16" + +jquery-validation@>=1.16, jquery-validation@^1.19.3: + version "1.19.5" + resolved "https://registry.yarnpkg.com/jquery-validation/-/jquery-validation-1.19.5.tgz#557495b7cad79716897057c4447ad3cd76fda811" + integrity sha512-X2SmnPq1mRiDecVYL8edWx+yTBZDyC8ohWXFhXdtqFHgU9Wd4KHkvcbCoIZ0JaSaumzS8s2gXSkP8F7ivg/8ZQ== + +jquery@>=1.10, jquery@>=1.12.0, "jquery@>=1.5.0 <4.0", jquery@>=1.7, jquery@>=1.7.2, "jquery@>=3.4.0 <4.0.0", jquery@^3.5.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.7.1.tgz#083ef98927c9a6a74d05a6af02806566d16274de" + integrity sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg== + +jquery@~3.6.0: + version "3.6.4" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.4.tgz#ba065c188142100be4833699852bf7c24dc0252f" + integrity sha512-v28EW9DWDFpzcD9O5iyJXg3R3+q+mET5JhnjJzQUZMHOv67bpSIHq81GEYpPNZHG+XXHsfSme3nxp/hndKEcsQ== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +just-compare@^1.3.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/just-compare/-/just-compare-1.5.1.tgz#aed7e93e6bae9c3b69d79aea7805684132a0c0c5" + integrity sha512-xDEEFHNIyJNmN4uo/2RVeUcay9THtN/5ka/iw98Y/gsa8w9KXZQuyaf5eFUY6VlntA2+G+bdPmdhqqTs7T+BRw== + +just-debounce@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.1.0.tgz#2f81a3ad4121a76bc7cb45dbf704c0d76a8e5ddf" + integrity sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ== + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0, kind-of@^5.0.2: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +last-run@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/last-run/-/last-run-1.1.1.tgz#45b96942c17b1c79c772198259ba943bebf8ca5b" + integrity sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ== + dependencies: + default-resolution "^2.0.0" + es6-weak-map "^2.0.1" + +lazystream@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.1.tgz#494c831062f1f9408251ec44db1cba29242a2638" + integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw== + dependencies: + readable-stream "^2.0.5" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw== + dependencies: + invert-kv "^1.0.0" + +lead@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lead/-/lead-1.0.0.tgz#6f14f99a37be3a9dd784f5495690e5903466ee42" + integrity sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow== + dependencies: + flush-write-stream "^1.0.2" + +liftoff@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3" + integrity sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog== + dependencies: + extend "^3.0.0" + findup-sync "^3.0.0" + fined "^1.0.1" + flagged-respawn "^1.0.0" + is-plain-object "^2.0.4" + object.map "^1.0.0" + rechoir "^0.6.2" + resolve "^1.1.7" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +luxon@^2.3.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-2.5.2.tgz#17ed497f0277e72d58a4756d6a9abee4681457b6" + integrity sha512-Yg7/RDp4nedqmLgyH0LwgGRvMEKVzKbUdkBYyCosbHgJ+kaOUx0qzSiSatVc3DFygnirTPYnMM2P5dg2uH1WvA== + +make-iterator@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" + integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw== + dependencies: + kind-of "^6.0.2" + +malihu-custom-scrollbar-plugin@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.5.tgz#310cecc5e59415a1c29e9dfb5d2b6e01d66a29ef" + integrity sha512-lwW3LgI+CNDMPnP4ED2la6oYxWMkCXlnhex+s2wuOLhFDFGnGmQuTQVdRK9bvDLpxs10sGlfErVufJy9ztfgJQ== + dependencies: + jquery-mousewheel ">=3.0.6" + +map-cache@^0.2.0, map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== + dependencies: + object-visit "^1.0.0" + +matchdep@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/matchdep/-/matchdep-2.0.0.tgz#c6f34834a0d8dbc3b37c27ee8bbcb27c7775582e" + integrity sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA== + dependencies: + findup-sync "^2.0.0" + micromatch "^3.0.4" + resolve "^1.4.0" + stack-trace "0.0.10" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.2: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +moment@^2.9.0: + version "2.29.4" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" + integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +mute-stdout@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" + integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== + +nan@^2.12.1: + version "2.17.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" + integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +now-and-later@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.1.tgz#8e579c8685764a7cc02cb680380e94f43ccb1f7c" + integrity sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ== + dependencies: + once "^1.3.2" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== + dependencies: + isobject "^3.0.0" + +object.assign@^4.0.4, object.assign@^4.1.0: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.defaults@^1.0.0, object.defaults@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" + integrity sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA== + dependencies: + array-each "^1.0.1" + array-slice "^1.0.0" + for-own "^1.0.0" + isobject "^3.0.0" + +object.map@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" + integrity sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w== + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + +object.pick@^1.2.0, object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== + dependencies: + isobject "^3.0.1" + +object.reduce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.reduce/-/object.reduce-1.0.1.tgz#6fe348f2ac7fa0f95ca621226599096825bb03ad" + integrity sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw== + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + +once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +ordered-read-streams@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" + integrity sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw== + dependencies: + readable-stream "^2.0.1" + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g== + dependencies: + lcid "^1.0.0" + +parse-filepath@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" + integrity sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q== + dependencies: + is-absolute "^1.0.0" + map-cache "^0.2.0" + path-root "^0.1.1" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== + dependencies: + error-ex "^1.2.0" + +parse-node-version@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== + dependencies: + pinkie-promise "^2.0.0" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-root-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + integrity sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ== + +path-root@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + integrity sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg== + dependencies: + path-root-regex "^0.1.0" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== + +pretty-hrtime@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.5: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== + dependencies: + resolve "^1.1.6" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +remove-bom-buffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" + integrity sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ== + dependencies: + is-buffer "^1.1.5" + is-utf8 "^0.2.1" + +remove-bom-stream@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz#05f1a593f16e42e1fb90ebf59de8e569525f9523" + integrity sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA== + dependencies: + remove-bom-buffer "^3.0.0" + safe-buffer "^5.1.0" + through2 "^2.0.3" + +remove-trailing-separator@^1.0.1, remove-trailing-separator@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== + +repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== + +replace-ext@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a" + integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== + +replace-homedir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-homedir/-/replace-homedir-1.0.0.tgz#e87f6d513b928dde808260c12be7fec6ff6e798c" + integrity sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg== + dependencies: + homedir-polyfill "^1.0.1" + is-absolute "^1.0.0" + remove-trailing-separator "^1.1.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug== + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg== + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-options@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" + integrity sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A== + dependencies: + value-or-function "^3.0.0" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== + +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.4.0: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== + dependencies: + ret "~0.1.10" + +select2@^4.0.13: + version "4.0.13" + resolved "https://registry.yarnpkg.com/select2/-/select2-4.0.13.tgz#0dbe377df3f96167c4c1626033e924372d8ef44d" + integrity sha512-1JeB87s6oN/TDxQQYCvS5EFoQyvV6eYMZZ0AeA4tdFDYWN3BAGZ8npr17UBFddU0lgAt3H0yjX3X6/ekOj1yjw== + +semver-greatest-satisfied-range@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b" + integrity sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ== + dependencies: + sver-compat "^1.5.0" + +"semver@2 || 3 || 4 || 5": + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + +sparkles@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" + integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== + +spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.13" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" + integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +stack-trace@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +stream-exhaust@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d" + integrity sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw== + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== + dependencies: + ansi-regex "^2.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== + dependencies: + is-utf8 "^0.2.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +sver-compat@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8" + integrity sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg== + dependencies: + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + +sweetalert2@^11.3.6: + version "11.7.27" + resolved "https://registry.yarnpkg.com/sweetalert2/-/sweetalert2-11.7.27.tgz#de19294e1b5ae7991de27bb4ae34aff3570aaa0e" + integrity sha512-QbRXGQn1sb7HEhzA/K2xtWIwQHh/qkSbb1w6jYcTql2xy17876lTREEt1D4X6Q0x2wHtfUjKJ+Cb8IVkRoq7DQ== + +through2-filter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254" + integrity sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA== + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2@^2.0.0, through2@^2.0.3, through2@~2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw== + +timeago@^1.6.7: + version "1.6.7" + resolved "https://registry.yarnpkg.com/timeago/-/timeago-1.6.7.tgz#afd467c29a911e697fc22a81888c7c3022783cb5" + integrity sha512-FikcjN98+ij0siKH4VO4dZ358PR3oDDq4Vdl1+sN9gWz1/+JXGr3uZbUShYH/hL7bMhcTpPbplJU5Tej4b4jbQ== + dependencies: + jquery ">=1.5.0 <4.0" + +to-absolute-glob@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" + integrity sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA== + dependencies: + is-absolute "^1.0.0" + is-negated-glob "^1.0.0" + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +to-through@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-through/-/to-through-2.0.0.tgz#fc92adaba072647bc0b67d6b03664aa195093af6" + integrity sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q== + dependencies: + through2 "^2.0.3" + +toastr@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/toastr/-/toastr-2.1.4.tgz#8b43be64fb9d0c414871446f2db8e8ca4e95f181" + integrity sha512-LIy77F5n+sz4tefMmFOntcJ6HL0Fv3k1TDnNmFZ0bU/GcvIIfy6eG2v7zQmMiYgaalAiUv75ttFrPn5s0gyqlA== + dependencies: + jquery ">=1.12.0" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" + integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + +unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + integrity sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg== + +undertaker-registry@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50" + integrity sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw== + +undertaker@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/undertaker/-/undertaker-1.3.0.tgz#363a6e541f27954d5791d6fa3c1d321666f86d18" + integrity sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg== + dependencies: + arr-flatten "^1.0.1" + arr-map "^2.0.0" + bach "^1.0.0" + collection-map "^1.0.0" + es6-weak-map "^2.0.1" + fast-levenshtein "^1.0.0" + last-run "^1.1.0" + object.defaults "^1.0.0" + object.reduce "^1.0.0" + undertaker-registry "^1.0.0" + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +unique-stream@^2.0.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" + integrity sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== + dependencies: + json-stable-stringify-without-jsonify "^1.0.1" + through2-filter "^3.0.0" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +v8flags@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.2.0.tgz#b243e3b4dfd731fa774e7492128109a0fe66d656" + integrity sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg== + dependencies: + homedir-polyfill "^1.0.1" + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +value-or-function@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" + integrity sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg== + +vinyl-fs@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.3.tgz#c85849405f67428feabbbd5c5dbdd64f47d31bc7" + integrity sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng== + dependencies: + fs-mkdirp-stream "^1.0.0" + glob-stream "^6.1.0" + graceful-fs "^4.0.0" + is-valid-glob "^1.0.0" + lazystream "^1.0.0" + lead "^1.0.0" + object.assign "^4.0.4" + pumpify "^1.3.5" + readable-stream "^2.3.3" + remove-bom-buffer "^3.0.0" + remove-bom-stream "^1.2.0" + resolve-options "^1.1.0" + through2 "^2.0.0" + to-through "^2.0.0" + value-or-function "^3.0.0" + vinyl "^2.0.0" + vinyl-sourcemap "^1.1.0" + +vinyl-sourcemap@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz#92a800593a38703a8cdb11d8b300ad4be63b3e16" + integrity sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA== + dependencies: + append-buffer "^1.0.2" + convert-source-map "^1.5.0" + graceful-fs "^4.1.6" + normalize-path "^2.1.1" + now-and-later "^2.0.0" + remove-bom-buffer "^3.0.0" + vinyl "^2.0.0" + +vinyl@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.1.tgz#23cfb8bbab5ece3803aa2c0a1eb28af7cbba1974" + integrity sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ== + +which@^1.2.14: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +xtend@~4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^3.2.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== + +yargs-parser@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.1.tgz#7ede329c1d8cdbbe209bd25cdb990e9b1ebbb394" + integrity sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA== + dependencies: + camelcase "^3.0.0" + object.assign "^4.1.0" + +yargs@^7.1.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.2.tgz#63a0a5d42143879fdbb30370741374e0641d55db" + integrity sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA== + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.1" diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi/BookStoreHttpApiModule.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi/BookStoreHttpApiModule.cs new file mode 100644 index 0000000000..24f81e8754 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi/BookStoreHttpApiModule.cs @@ -0,0 +1,41 @@ +using Localization.Resources.AbpUi; +using Volo.BookStore.Localization; +using Volo.Abp.Account; +using Volo.Abp.FeatureManagement; +using Volo.Abp.Identity; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement.HttpApi; +using Volo.Abp.SettingManagement; +using Volo.Abp.TenantManagement; + +namespace Volo.BookStore; + +[DependsOn( + typeof(BookStoreApplicationContractsModule), + typeof(AbpAccountHttpApiModule), + typeof(AbpIdentityHttpApiModule), + typeof(AbpPermissionManagementHttpApiModule), + typeof(AbpTenantManagementHttpApiModule), + typeof(AbpFeatureManagementHttpApiModule), + typeof(AbpSettingManagementHttpApiModule) + )] +public class BookStoreHttpApiModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + ConfigureLocalization(); + } + + private void ConfigureLocalization() + { + Configure(options => + { + options.Resources + .Get() + .AddBaseTypes( + typeof(AbpUiResource) + ); + }); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi/Controllers/BookStoreController.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi/Controllers/BookStoreController.cs new file mode 100644 index 0000000000..2c1e706b9f --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi/Controllers/BookStoreController.cs @@ -0,0 +1,14 @@ +using Volo.BookStore.Localization; +using Volo.Abp.AspNetCore.Mvc; + +namespace Volo.BookStore.Controllers; + +/* Inherit your controllers from this class. + */ +public abstract class BookStoreController : AbpControllerBase +{ + protected BookStoreController() + { + LocalizationResource = typeof(BookStoreResource); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi/Models/Test/TestModel.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi/Models/Test/TestModel.cs new file mode 100644 index 0000000000..a523082ffe --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi/Models/Test/TestModel.cs @@ -0,0 +1,10 @@ +using System; + +namespace Volo.BookStore.Models.Test; + +public class TestModel +{ + public string Name { get; set; } + + public DateTime BirthDate { get; set; } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi/Volo.BookStore.HttpApi.csproj b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi/Volo.BookStore.HttpApi.csproj new file mode 100644 index 0000000000..c5b7c27c92 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.HttpApi/Volo.BookStore.HttpApi.csproj @@ -0,0 +1,24 @@ + + + + + + net7.0 + enable + Volo.BookStore + + + + + + + + + + + + + + + + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.MongoDB/MongoDb/BookStoreMongoDbContext.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.MongoDB/MongoDb/BookStoreMongoDbContext.cs new file mode 100644 index 0000000000..366bbc8463 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.MongoDB/MongoDb/BookStoreMongoDbContext.cs @@ -0,0 +1,22 @@ +using Volo.Abp.Data; +using Volo.Abp.MongoDB; + +namespace Volo.BookStore.MongoDB; + +[ConnectionStringName("Default")] +public class BookStoreMongoDbContext : AbpMongoDbContext +{ + /* Add mongo collections here. Example: + * public IMongoCollection Questions => Collection(); + */ + + protected override void CreateModel(IMongoModelBuilder modelBuilder) + { + base.CreateModel(modelBuilder); + + //modelBuilder.Entity(b => + //{ + // //... + //}); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.MongoDB/MongoDb/BookStoreMongoDbModule.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.MongoDB/MongoDb/BookStoreMongoDbModule.cs new file mode 100644 index 0000000000..3fed4a0832 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.MongoDB/MongoDb/BookStoreMongoDbModule.cs @@ -0,0 +1,40 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AuditLogging.MongoDB; +using Volo.Abp.BackgroundJobs.MongoDB; +using Volo.Abp.FeatureManagement.MongoDB; +using Volo.Abp.Identity.MongoDB; +using Volo.Abp.Modularity; +using Volo.Abp.OpenIddict.MongoDB; +using Volo.Abp.PermissionManagement.MongoDB; +using Volo.Abp.SettingManagement.MongoDB; +using Volo.Abp.TenantManagement.MongoDB; +using Volo.Abp.Uow; + +namespace Volo.BookStore.MongoDB; + +[DependsOn( + typeof(BookStoreDomainModule), + typeof(AbpPermissionManagementMongoDbModule), + typeof(AbpSettingManagementMongoDbModule), + typeof(AbpIdentityMongoDbModule), + typeof(AbpOpenIddictMongoDbModule), + typeof(AbpBackgroundJobsMongoDbModule), + typeof(AbpAuditLoggingMongoDbModule), + typeof(AbpTenantManagementMongoDbModule), + typeof(AbpFeatureManagementMongoDbModule) + )] +public class BookStoreMongoDbModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddMongoDbContext(options => + { + options.AddDefaultRepositories(); + }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; + }); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.MongoDB/MongoDb/MongoDbBookStoreDbSchemaMigrator.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.MongoDB/MongoDb/MongoDbBookStoreDbSchemaMigrator.cs new file mode 100644 index 0000000000..f5a5d4ed89 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.MongoDB/MongoDb/MongoDbBookStoreDbSchemaMigrator.cs @@ -0,0 +1,43 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using MongoDB.Driver; +using Volo.BookStore.Data; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MongoDB; + +namespace Volo.BookStore.MongoDB; + +public class MongoDbBookStoreDbSchemaMigrator : IBookStoreDbSchemaMigrator, ITransientDependency +{ + private readonly IServiceProvider _serviceProvider; + + public MongoDbBookStoreDbSchemaMigrator(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public async Task MigrateAsync() + { + var dbContexts = _serviceProvider.GetServices(); + var connectionStringResolver = _serviceProvider.GetRequiredService(); + + foreach (var dbContext in dbContexts) + { + var connectionString = + await connectionStringResolver.ResolveAsync( + ConnectionStringNameAttribute.GetConnStringName(dbContext.GetType())); + var mongoUrl = new MongoUrl(connectionString); + var databaseName = mongoUrl.DatabaseName; + var client = new MongoClient(mongoUrl); + + if (databaseName.IsNullOrWhiteSpace()) + { + databaseName = ConnectionStringNameAttribute.GetConnStringName(dbContext.GetType()); + } + + (dbContext as AbpMongoDbContext)?.InitializeCollections(client.GetDatabase(databaseName)); + } + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.MongoDB/Properties/AssemblyInfo.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.MongoDB/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..ff230af8be --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.MongoDB/Properties/AssemblyInfo.cs @@ -0,0 +1,2 @@ +using System.Runtime.CompilerServices; +[assembly:InternalsVisibleToAttribute("Volo.BookStore.MongoDB.Tests")] diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.MongoDB/Volo.BookStore.MongoDB.csproj b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.MongoDB/Volo.BookStore.MongoDB.csproj new file mode 100644 index 0000000000..e0b3bcf766 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/src/Volo.BookStore.MongoDB/Volo.BookStore.MongoDB.csproj @@ -0,0 +1,23 @@ + + + + + + net7.0 + enable + Volo.BookStore + + + + + + + + + + + + + + + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Application.Tests/BookStoreApplicationCollection.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Application.Tests/BookStoreApplicationCollection.cs new file mode 100644 index 0000000000..f8ef6897a3 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Application.Tests/BookStoreApplicationCollection.cs @@ -0,0 +1,10 @@ +using Volo.BookStore.MongoDB; +using Xunit; + +namespace Volo.BookStore; + +[CollectionDefinition(BookStoreTestConsts.CollectionDefinitionName)] +public class BookStoreApplicationCollection : BookStoreMongoDbCollectionFixtureBase +{ + +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Application.Tests/BookStoreApplicationTestBase.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Application.Tests/BookStoreApplicationTestBase.cs new file mode 100644 index 0000000000..0bc9a450d3 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Application.Tests/BookStoreApplicationTestBase.cs @@ -0,0 +1,6 @@ +namespace Volo.BookStore; + +public abstract class BookStoreApplicationTestBase : BookStoreTestBase +{ + +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Application.Tests/BookStoreApplicationTestModule.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Application.Tests/BookStoreApplicationTestModule.cs new file mode 100644 index 0000000000..c811ed19ce --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Application.Tests/BookStoreApplicationTestModule.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Modularity; + +namespace Volo.BookStore; + +[DependsOn( + typeof(BookStoreApplicationModule), + typeof(BookStoreDomainTestModule) + )] +public class BookStoreApplicationTestModule : AbpModule +{ + +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Application.Tests/Samples/SampleAppServiceTests.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Application.Tests/Samples/SampleAppServiceTests.cs new file mode 100644 index 0000000000..7dd5b3bfab --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Application.Tests/Samples/SampleAppServiceTests.cs @@ -0,0 +1,33 @@ +using Shouldly; +using System.Threading.Tasks; +using Volo.Abp.Identity; +using Xunit; + +namespace Volo.BookStore.Samples; + +/* This is just an example test class. + * Normally, you don't test code of the modules you are using + * (like IIdentityUserAppService here). + * Only test your own application services. + */ +[Collection(BookStoreTestConsts.CollectionDefinitionName)] +public class SampleAppServiceTests : BookStoreApplicationTestBase +{ + private readonly IIdentityUserAppService _userAppService; + + public SampleAppServiceTests() + { + _userAppService = GetRequiredService(); + } + + [Fact] + public async Task Initial_Data_Should_Contain_Admin_User() + { + //Act + var result = await _userAppService.GetListAsync(new GetIdentityUsersInput()); + + //Assert + result.TotalCount.ShouldBeGreaterThan(0); + result.Items.ShouldContain(u => u.UserName == "admin"); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Application.Tests/Volo.BookStore.Application.Tests.csproj b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Application.Tests/Volo.BookStore.Application.Tests.csproj new file mode 100644 index 0000000000..c990aa9d9b --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Application.Tests/Volo.BookStore.Application.Tests.csproj @@ -0,0 +1,20 @@ + + + + + + net7.0 + enable + Volo.BookStore + + + + + + + + + + + + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Domain.Tests/BookStoreDomainCollection.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Domain.Tests/BookStoreDomainCollection.cs new file mode 100644 index 0000000000..cf9217bbb8 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Domain.Tests/BookStoreDomainCollection.cs @@ -0,0 +1,10 @@ +using Volo.BookStore.MongoDB; +using Xunit; + +namespace Volo.BookStore; + +[CollectionDefinition(BookStoreTestConsts.CollectionDefinitionName)] +public class BookStoreDomainCollection : BookStoreMongoDbCollectionFixtureBase +{ + +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Domain.Tests/BookStoreDomainTestBase.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Domain.Tests/BookStoreDomainTestBase.cs new file mode 100644 index 0000000000..0206aff629 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Domain.Tests/BookStoreDomainTestBase.cs @@ -0,0 +1,6 @@ +namespace Volo.BookStore; + +public abstract class BookStoreDomainTestBase : BookStoreTestBase +{ + +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Domain.Tests/BookStoreDomainTestModule.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Domain.Tests/BookStoreDomainTestModule.cs new file mode 100644 index 0000000000..5cb576871a --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Domain.Tests/BookStoreDomainTestModule.cs @@ -0,0 +1,12 @@ +using Volo.BookStore.MongoDB; +using Volo.Abp.Modularity; + +namespace Volo.BookStore; + +[DependsOn( + typeof(BookStoreMongoDbTestModule) + )] +public class BookStoreDomainTestModule : AbpModule +{ + +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Domain.Tests/Samples/SampleDomainTests.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Domain.Tests/Samples/SampleDomainTests.cs new file mode 100644 index 0000000000..6290f934da --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Domain.Tests/Samples/SampleDomainTests.cs @@ -0,0 +1,45 @@ +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Identity; +using Xunit; + +namespace Volo.BookStore.Samples; + +/* This is just an example test class. + * Normally, you don't test code of the modules you are using + * (like IdentityUserManager here). + * Only test your own domain services. + */ +[Collection(BookStoreTestConsts.CollectionDefinitionName)] +public class SampleDomainTests : BookStoreDomainTestBase +{ + private readonly IIdentityUserRepository _identityUserRepository; + private readonly IdentityUserManager _identityUserManager; + + public SampleDomainTests() + { + _identityUserRepository = GetRequiredService(); + _identityUserManager = GetRequiredService(); + } + + [Fact] + public async Task Should_Set_Email_Of_A_User() + { + IdentityUser adminUser; + + /* Need to manually start Unit Of Work because + * FirstOrDefaultAsync should be executed while db connection / context is available. + */ + await WithUnitOfWorkAsync(async () => + { + adminUser = await _identityUserRepository + .FindByNormalizedUserNameAsync("ADMIN"); + + await _identityUserManager.SetEmailAsync(adminUser, "newemail@abp.io"); + await _identityUserRepository.UpdateAsync(adminUser); + }); + + adminUser = await _identityUserRepository.FindByNormalizedUserNameAsync("ADMIN"); + adminUser.Email.ShouldBe("newemail@abp.io"); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Domain.Tests/Volo.BookStore.Domain.Tests.csproj b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Domain.Tests/Volo.BookStore.Domain.Tests.csproj new file mode 100644 index 0000000000..8700370c63 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.Domain.Tests/Volo.BookStore.Domain.Tests.csproj @@ -0,0 +1,19 @@ + + + + + + net7.0 + enable + Volo.BookStore + + + + + + + + + + + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/BookStoreConsoleApiClientModule.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/BookStoreConsoleApiClientModule.cs new file mode 100644 index 0000000000..4ec0d80f72 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/BookStoreConsoleApiClientModule.cs @@ -0,0 +1,30 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Polly; +using Volo.Abp.Autofac; +using Volo.Abp.Http.Client; +using Volo.Abp.Http.Client.IdentityModel; +using Volo.Abp.Modularity; + +namespace Volo.BookStore.HttpApi.Client.ConsoleTestApp; + +[DependsOn( + typeof(AbpAutofacModule), + typeof(BookStoreHttpApiClientModule), + typeof(AbpHttpClientIdentityModelModule) + )] +public class BookStoreConsoleApiClientModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(options => + { + options.ProxyClientBuildActions.Add((remoteServiceName, clientBuilder) => + { + clientBuilder.AddTransientHttpErrorPolicy( + policyBuilder => policyBuilder.WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(Math.Pow(2, i))) + ); + }); + }); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/ClientDemoService.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/ClientDemoService.cs new file mode 100644 index 0000000000..12995f9c33 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/ClientDemoService.cs @@ -0,0 +1,25 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.Account; +using Volo.Abp.DependencyInjection; + +namespace Volo.BookStore.HttpApi.Client.ConsoleTestApp; + +public class ClientDemoService : ITransientDependency +{ + private readonly IProfileAppService _profileAppService; + + public ClientDemoService(IProfileAppService profileAppService) + { + _profileAppService = profileAppService; + } + + public async Task RunAsync() + { + var output = await _profileAppService.GetAsync(); + Console.WriteLine($"UserName : {output.UserName}"); + Console.WriteLine($"Email : {output.Email}"); + Console.WriteLine($"Name : {output.Name}"); + Console.WriteLine($"Surname : {output.Surname}"); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/ConsoleTestAppHostedService.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/ConsoleTestAppHostedService.cs new file mode 100644 index 0000000000..c4ff9e89fb --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/ConsoleTestAppHostedService.cs @@ -0,0 +1,40 @@ +using Microsoft.Extensions.Hosting; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; + +namespace Volo.BookStore.HttpApi.Client.ConsoleTestApp; + +public class ConsoleTestAppHostedService : IHostedService +{ + private readonly IConfiguration _configuration; + + public ConsoleTestAppHostedService(IConfiguration configuration) + { + _configuration = configuration; + } + + public async Task StartAsync(CancellationToken cancellationToken) + { + using (var application = await AbpApplicationFactory.CreateAsync(options => + { + options.Services.ReplaceConfiguration(_configuration); + options.UseAutofac(); + })) + { + await application.InitializeAsync(); + + var demo = application.ServiceProvider.GetRequiredService(); + await demo.RunAsync(); + + await application.ShutdownAsync(); + } + } + + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/Program.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/Program.cs new file mode 100644 index 0000000000..6e10ef599c --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/Program.cs @@ -0,0 +1,22 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace Volo.BookStore.HttpApi.Client.ConsoleTestApp; + +class Program +{ + static async Task Main(string[] args) + { + await CreateHostBuilder(args).RunConsoleAsync(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .AddAppSettingsSecretsJson() + .ConfigureServices((hostContext, services) => + { + services.AddHostedService(); + }); +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/Volo.BookStore.HttpApi.Client.ConsoleTestApp.csproj b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/Volo.BookStore.HttpApi.Client.ConsoleTestApp.csproj new file mode 100644 index 0000000000..a2d398e98f --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/Volo.BookStore.HttpApi.Client.ConsoleTestApp.csproj @@ -0,0 +1,33 @@ + + + + Exe + net7.0 + enable + + + + + + PreserveNewest + Always + + + + PreserveNewest + Always + + + + + + + + + + + + + + + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/appsettings.json b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/appsettings.json new file mode 100644 index 0000000000..34120dd8d1 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.HttpApi.Client.ConsoleTestApp/appsettings.json @@ -0,0 +1,17 @@ +{ + "RemoteServices": { + "Default": { + "BaseUrl": "https://localhost:44315" + } + }, + "IdentityClients": { + "Default": { + "GrantType": "password", + "ClientId": "BookStore_App", + "UserName": "admin", + "UserPassword": "1q2w3E*", + "Authority": "https://localhost:44315", + "Scope": "BookStore" + } + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/BookStoreMongoCollection.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/BookStoreMongoCollection.cs new file mode 100644 index 0000000000..5572b80101 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/BookStoreMongoCollection.cs @@ -0,0 +1,9 @@ +using Xunit; + +namespace Volo.BookStore.MongoDB; + +[CollectionDefinition(BookStoreTestConsts.CollectionDefinitionName)] +public class BookStoreMongoCollection : BookStoreMongoDbCollectionFixtureBase +{ + +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbCollectionFixtureBase.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbCollectionFixtureBase.cs new file mode 100644 index 0000000000..810472a3ed --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbCollectionFixtureBase.cs @@ -0,0 +1,9 @@ +using Volo.BookStore.MongoDB; +using Xunit; + +namespace Volo.BookStore.MongoDB; + +public class BookStoreMongoDbCollectionFixtureBase : ICollectionFixture +{ + +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbFixture.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbFixture.cs new file mode 100644 index 0000000000..9099fb29d3 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbFixture.cs @@ -0,0 +1,34 @@ +using System; +using EphemeralMongo; + +namespace Volo.BookStore.MongoDB; + +public class BookStoreMongoDbFixture : IDisposable +{ + public readonly static IMongoRunner MongoDbRunner; + + static BookStoreMongoDbFixture() + { + MongoDbRunner = MongoRunner.Run(new MongoRunnerOptions + { + UseSingleNodeReplicaSet = true + }); + } + + public static string GetRandomConnectionString() + { + return GetConnectionString("Db_" + Guid.NewGuid().ToString("N")); + } + + public static string GetConnectionString(string databaseName) + { + var stringArray = MongoDbRunner.ConnectionString.Split('?'); + var connectionString = stringArray[0].EnsureEndsWith('/') + databaseName + "/?" + stringArray[1]; + return connectionString; + } + + public void Dispose() + { + MongoDbRunner?.Dispose(); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbTestBase.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbTestBase.cs new file mode 100644 index 0000000000..b9233c38e5 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbTestBase.cs @@ -0,0 +1,6 @@ +namespace Volo.BookStore.MongoDB; + +public abstract class BookStoreMongoDbTestBase : BookStoreTestBase +{ + +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbTestModule.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbTestModule.cs new file mode 100644 index 0000000000..0d5f4c1453 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/BookStoreMongoDbTestModule.cs @@ -0,0 +1,20 @@ +using System; +using Volo.Abp.Data; +using Volo.Abp.Modularity; + +namespace Volo.BookStore.MongoDB; + +[DependsOn( + typeof(BookStoreTestBaseModule), + typeof(BookStoreMongoDbModule) + )] +public class BookStoreMongoDbTestModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.ConnectionStrings.Default = BookStoreMongoDbFixture.GetRandomConnectionString(); + }); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/Samples/SampleRepositoryTests.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/Samples/SampleRepositoryTests.cs new file mode 100644 index 0000000000..ba1df74ad3 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/MongoDb/Samples/SampleRepositoryTests.cs @@ -0,0 +1,42 @@ +using System; +using System.Threading.Tasks; +using MongoDB.Driver.Linq; +using Shouldly; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Identity; +using Xunit; + +namespace Volo.BookStore.MongoDB.Samples; + +/* This is just an example test class. + * Normally, you don't test ABP framework code + * (like default AppUser repository IRepository here). + * Only test your custom repository methods. + */ +[Collection(BookStoreTestConsts.CollectionDefinitionName)] +public class SampleRepositoryTests : BookStoreMongoDbTestBase +{ + private readonly IRepository _appUserRepository; + + public SampleRepositoryTests() + { + _appUserRepository = GetRequiredService>(); + } + + [Fact] + public async Task Should_Query_AppUser() + { + /* Need to manually start Unit Of Work because + * FirstOrDefaultAsync should be executed while db connection / context is available. + */ + await WithUnitOfWorkAsync(async () => + { + //Act + var adminUser = await (await _appUserRepository.GetMongoQueryableAsync()) + .FirstOrDefaultAsync(u => u.UserName == "admin"); + + //Assert + adminUser.ShouldNotBeNull(); + }); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/Volo.BookStore.MongoDB.Tests.csproj b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/Volo.BookStore.MongoDB.Tests.csproj new file mode 100644 index 0000000000..470b25cc54 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.MongoDB.Tests/Volo.BookStore.MongoDB.Tests.csproj @@ -0,0 +1,24 @@ + + + + + + net7.0 + enable + Volo.BookStore + + + + + + + + + + + + + + + + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/BookStoreTestBase.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/BookStoreTestBase.cs new file mode 100644 index 0000000000..69a0046e8a --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/BookStoreTestBase.cs @@ -0,0 +1,60 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.Modularity; +using Volo.Abp.Uow; +using Volo.Abp.Testing; + +namespace Volo.BookStore; + +/* All test classes are derived from this class, directly or indirectly. + */ +public abstract class BookStoreTestBase : AbpIntegratedTest + where TStartupModule : IAbpModule +{ + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + + protected virtual Task WithUnitOfWorkAsync(Func func) + { + return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func); + } + + protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, Func action) + { + using (var scope = ServiceProvider.CreateScope()) + { + var uowManager = scope.ServiceProvider.GetRequiredService(); + + using (var uow = uowManager.Begin(options)) + { + await action(); + + await uow.CompleteAsync(); + } + } + } + + protected virtual Task WithUnitOfWorkAsync(Func> func) + { + return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func); + } + + protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, Func> func) + { + using (var scope = ServiceProvider.CreateScope()) + { + var uowManager = scope.ServiceProvider.GetRequiredService(); + + using (var uow = uowManager.Begin(options)) + { + var result = await func(); + await uow.CompleteAsync(); + return result; + } + } + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/BookStoreTestBaseModule.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/BookStoreTestBaseModule.cs new file mode 100644 index 0000000000..96345f7667 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/BookStoreTestBaseModule.cs @@ -0,0 +1,52 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.Authorization; +using Volo.Abp.Autofac; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.Data; +using Volo.Abp.Modularity; +using Volo.Abp.Threading; + +namespace Volo.BookStore; + +[DependsOn( + typeof(AbpAutofacModule), + typeof(AbpTestBaseModule), + typeof(AbpAuthorizationModule), + typeof(BookStoreDomainModule) + )] +public class BookStoreTestBaseModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.IsJobExecutionEnabled = false; + }); + + context.Services.AddAlwaysAllowAuthorization(); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + SeedTestData(context); + } + + private static void SeedTestData(ApplicationInitializationContext context) + { + AsyncHelper.RunSync(async () => + { + using (var scope = context.ServiceProvider.CreateScope()) + { + await scope.ServiceProvider + .GetRequiredService() + .SeedAsync(); + } + }); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/BookStoreTestConsts.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/BookStoreTestConsts.cs new file mode 100644 index 0000000000..d22e331880 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/BookStoreTestConsts.cs @@ -0,0 +1,6 @@ +namespace Volo.BookStore; + +public static class BookStoreTestConsts +{ + public const string CollectionDefinitionName = "BookStore collection"; +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/BookStoreTestDataSeedContributor.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/BookStoreTestDataSeedContributor.cs new file mode 100644 index 0000000000..430e1aafe5 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/BookStoreTestDataSeedContributor.cs @@ -0,0 +1,15 @@ +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; + +namespace Volo.BookStore; + +public class BookStoreTestDataSeedContributor : IDataSeedContributor, ITransientDependency +{ + public Task SeedAsync(DataSeedContext context) + { + /* Seed additional test data... */ + + return Task.CompletedTask; + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/Security/FakeCurrentPrincipalAccessor.cs b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/Security/FakeCurrentPrincipalAccessor.cs new file mode 100644 index 0000000000..4e1ffb7a89 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/Security/FakeCurrentPrincipalAccessor.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.Security.Claims; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Security.Claims; + +namespace Volo.BookStore.Security; + +[Dependency(ReplaceServices = true)] +public class FakeCurrentPrincipalAccessor : ThreadCurrentPrincipalAccessor +{ + protected override ClaimsPrincipal GetClaimsPrincipal() + { + return GetPrincipal(); + } + + private ClaimsPrincipal GetPrincipal() + { + return new ClaimsPrincipal(new ClaimsIdentity(new List + { + new Claim(AbpClaimTypes.UserId, "2e701e62-0953-4dd3-910b-dc6cc93ccb0d"), + new Claim(AbpClaimTypes.UserName, "admin"), + new Claim(AbpClaimTypes.Email, "admin@abp.io") + })); + } +} diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/Volo.BookStore.TestBase.csproj b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/Volo.BookStore.TestBase.csproj new file mode 100644 index 0000000000..2db4fbc588 --- /dev/null +++ b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/Volo.BookStore/aspnet-core/test/Volo.BookStore.TestBase/Volo.BookStore.TestBase.csproj @@ -0,0 +1,31 @@ + + + + + + net7.0 + enable + Volo.BookStore + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/gif/cascading-loading-demo.gif b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/gif/cascading-loading-demo.gif new file mode 100644 index 0000000000..ae69070f28 Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/gif/cascading-loading-demo.gif differ diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/extensions-system-document.png b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/extensions-system-document.png new file mode 100644 index 0000000000..7f806ec42d Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/extensions-system-document.png differ diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/folder-structure.png b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/folder-structure.png new file mode 100644 index 0000000000..2d3a828773 Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/folder-structure.png differ diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/rent-form-without-contribution.png b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/rent-form-without-contribution.png new file mode 100644 index 0000000000..e29d525f7b Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/rent-form-without-contribution.png differ diff --git a/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/ts-config-file.png b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/ts-config-file.png new file mode 100644 index 0000000000..6b06e8ca90 Binary files /dev/null and b/docs/en/Community-Articles/2023-07-09-Cascading-Option-Loading-With-Extensions/assets/img/ts-config-file.png differ