├── .dockerignore ├── .editorconfig ├── .github ├── FUNDING.yml └── workflows │ └── docker-image.yml ├── .gitignore ├── .travis.yml ├── Dockerfile ├── LICENSE ├── README.md ├── angular.json ├── ngsw-config.json ├── package-lock.json ├── package.json ├── projects ├── ng-sapphiredb │ ├── README.md │ ├── karma.conf.js │ ├── ng-package.json │ ├── ng-package.prod.json │ ├── package.json │ ├── src │ │ ├── lib │ │ │ ├── sapphire-db.module.ts │ │ │ └── sapphire-db.service.ts │ │ ├── public_api.ts │ │ └── test.ts │ ├── tsconfig.lib.json │ ├── tsconfig.lib.prod.json │ ├── tsconfig.spec.json │ └── tslint.json └── sapphiredb │ ├── README.md │ ├── karma.conf.js │ ├── ng-package.json │ ├── ng-package.prod.json │ ├── package.json │ ├── src │ ├── lib │ │ ├── collection │ │ │ ├── collection-base.ts │ │ │ ├── collection-data.ts │ │ │ ├── collection-manager.ts │ │ │ ├── collection-value.ts │ │ │ ├── default-collection.ts │ │ │ ├── ordered-collection.ts │ │ │ ├── prefilter │ │ │ │ ├── count-prefilter.ts │ │ │ │ ├── first-prefilter.ts │ │ │ │ ├── include-prefilter.ts │ │ │ │ ├── iprefilter.ts │ │ │ │ ├── order-by-prefilter.ts │ │ │ │ ├── select-prefilter.ts │ │ │ │ ├── skip-prefilter.ts │ │ │ │ ├── take-prefilter.ts │ │ │ │ ├── then-order-by-prefilter.ts │ │ │ │ └── where-prefilter.ts │ │ │ ├── query-collection.ts │ │ │ └── reduced-collection.ts │ │ ├── command │ │ │ ├── collection-command-base.ts │ │ │ ├── command-base.ts │ │ │ ├── connection │ │ │ │ └── connection-response.ts │ │ │ ├── create-range │ │ │ │ ├── create-range-command.ts │ │ │ │ └── create-range-response.ts │ │ │ ├── delete-range │ │ │ │ ├── delete-range-command.ts │ │ │ │ └── delete-range-response.ts │ │ │ ├── execute-commands │ │ │ │ ├── execute-commands-command.ts │ │ │ │ └── execute-commands-response.ts │ │ │ ├── execute │ │ │ │ ├── execute-command.ts │ │ │ │ └── execute-response.ts │ │ │ ├── invoke │ │ │ │ ├── invoke-command.ts │ │ │ │ └── invoke-response.ts │ │ │ ├── message │ │ │ │ ├── message-command.ts │ │ │ │ └── message-response.ts │ │ │ ├── publish │ │ │ │ └── publish-command.ts │ │ │ ├── query-connections │ │ │ │ ├── query-connections-command.ts │ │ │ │ └── query-connections-response.ts │ │ │ ├── query-query │ │ │ │ └── query-query-command.ts │ │ │ ├── query │ │ │ │ ├── query-command.ts │ │ │ │ └── query-response.ts │ │ │ ├── response-base.ts │ │ │ ├── sapphire-db-error-response.ts │ │ │ ├── stream │ │ │ │ ├── complete-stream-command.ts │ │ │ │ ├── init-stream-response.ts │ │ │ │ └── stream-command.ts │ │ │ ├── subscribe-message │ │ │ │ ├── subscribe-message-command.ts │ │ │ │ └── topic-response.ts │ │ │ ├── subscribe-query │ │ │ │ └── subscribe-query-command.ts │ │ │ ├── subscribe │ │ │ │ ├── change-response.ts │ │ │ │ └── subscribe-command.ts │ │ │ ├── unsubscribe-message │ │ │ │ └── unsubscribe-message-command.ts │ │ │ ├── unsubscribe │ │ │ │ └── unsubscribe-command.ts │ │ │ ├── update-range │ │ │ │ ├── update-range-command.ts │ │ │ │ └── update-range-response.ts │ │ │ └── validated-response-base.ts │ │ ├── connection │ │ │ ├── connection-base.ts │ │ │ ├── connection-manager.ts │ │ │ ├── poll-connection.ts │ │ │ ├── sse-connection.ts │ │ │ └── websocket-connection.ts │ │ ├── helper │ │ │ ├── action-helper.ts │ │ │ ├── array-helper.ts │ │ │ ├── auth-token-helper.ts │ │ │ ├── collection-helper.ts │ │ │ ├── condition-types.ts │ │ │ ├── decorator-helper.ts │ │ │ ├── decorators │ │ │ │ └── primary-key.ts │ │ │ ├── filter-functions.ts │ │ │ ├── guid-helper.ts │ │ │ ├── rxjs-helper.ts │ │ │ ├── sapphire-class-transformer.ts │ │ │ └── sapphire-storage.ts │ │ ├── models │ │ │ ├── command-references.ts │ │ │ ├── sapphire-db-options.ts │ │ │ ├── subscribe-command-info.ts │ │ │ └── types.ts │ │ ├── modules │ │ │ ├── action │ │ │ │ ├── action-result.ts │ │ │ │ └── action-sender.ts │ │ │ ├── messaging │ │ │ │ └── messaging.ts │ │ │ └── offline │ │ │ │ ├── offline-helper.ts │ │ │ │ ├── offline-manager.ts │ │ │ │ ├── offline-response.ts │ │ │ │ └── sapphire-offline-entity.ts │ │ └── sapphire-db.ts │ ├── public-api.ts │ └── test.ts │ ├── tsconfig.lib.json │ ├── tsconfig.lib.prod.json │ ├── tsconfig.spec.json │ └── tslint.json ├── server.ts ├── src ├── app │ ├── actions │ │ ├── actions-routing.module.ts │ │ ├── actions.module.ts │ │ └── main │ │ │ ├── main.component.html │ │ │ ├── main.component.less │ │ │ ├── main.component.spec.ts │ │ │ └── main.component.ts │ ├── app-routing.module.ts │ ├── app.component.html │ ├── app.component.less │ ├── app.component.spec.ts │ ├── app.component.ts │ ├── app.module.ts │ ├── app.server.module.ts │ ├── configuration │ │ ├── configuration-routing.module.ts │ │ ├── configuration.module.ts │ │ ├── connection-types │ │ │ ├── connection-types.component.html │ │ │ ├── connection-types.component.less │ │ │ ├── connection-types.component.spec.ts │ │ │ └── connection-types.component.ts │ │ ├── fluent │ │ │ ├── fluent.component.html │ │ │ ├── fluent.component.less │ │ │ ├── fluent.component.spec.ts │ │ │ └── fluent.component.ts │ │ ├── main │ │ │ ├── main.component.html │ │ │ ├── main.component.less │ │ │ ├── main.component.spec.ts │ │ │ └── main.component.ts │ │ └── sync │ │ │ ├── sync.component.html │ │ │ ├── sync.component.less │ │ │ ├── sync.component.spec.ts │ │ │ └── sync.component.ts │ ├── data │ │ ├── changes │ │ │ ├── changes.component.html │ │ │ ├── changes.component.less │ │ │ ├── changes.component.spec.ts │ │ │ └── changes.component.ts │ │ ├── class-transformer │ │ │ ├── class-transformer.component.html │ │ │ ├── class-transformer.component.less │ │ │ ├── class-transformer.component.spec.ts │ │ │ └── class-transformer.component.ts │ │ ├── conflict-handling │ │ │ ├── conflict-handling.component.html │ │ │ ├── conflict-handling.component.less │ │ │ ├── conflict-handling.component.spec.ts │ │ │ └── conflict-handling.component.ts │ │ ├── count │ │ │ ├── count.component.html │ │ │ ├── count.component.less │ │ │ ├── count.component.spec.ts │ │ │ └── count.component.ts │ │ ├── data-routing.module.ts │ │ ├── data.module.ts │ │ ├── events │ │ │ ├── events.component.html │ │ │ ├── events.component.less │ │ │ ├── events.component.spec.ts │ │ │ └── events.component.ts │ │ ├── include │ │ │ ├── include.component.html │ │ │ ├── include.component.less │ │ │ ├── include.component.spec.ts │ │ │ └── include.component.ts │ │ ├── limit │ │ │ ├── limit.component.html │ │ │ ├── limit.component.less │ │ │ ├── limit.component.spec.ts │ │ │ └── limit.component.ts │ │ ├── manage │ │ │ ├── manage.component.html │ │ │ ├── manage.component.less │ │ │ ├── manage.component.spec.ts │ │ │ └── manage.component.ts │ │ ├── model-definition │ │ │ ├── model-definition.component.html │ │ │ ├── model-definition.component.less │ │ │ ├── model-definition.component.spec.ts │ │ │ └── model-definition.component.ts │ │ ├── model-validation │ │ │ ├── model-validation.component.html │ │ │ ├── model-validation.component.less │ │ │ ├── model-validation.component.spec.ts │ │ │ └── model-validation.component.ts │ │ ├── offline │ │ │ ├── offline.component.html │ │ │ ├── offline.component.less │ │ │ ├── offline.component.spec.ts │ │ │ └── offline.component.ts │ │ ├── order │ │ │ ├── order.component.html │ │ │ ├── order.component.less │ │ │ ├── order.component.spec.ts │ │ │ └── order.component.ts │ │ ├── prefilter │ │ │ ├── prefilter.component.html │ │ │ ├── prefilter.component.less │ │ │ ├── prefilter.component.spec.ts │ │ │ └── prefilter.component.ts │ │ ├── query │ │ │ ├── query.component.html │ │ │ ├── query.component.less │ │ │ ├── query.component.spec.ts │ │ │ └── query.component.ts │ │ ├── select │ │ │ ├── select.component.html │ │ │ ├── select.component.less │ │ │ ├── select.component.spec.ts │ │ │ └── select.component.ts │ │ ├── server-side-query │ │ │ ├── server-side-query.component.html │ │ │ ├── server-side-query.component.less │ │ │ ├── server-side-query.component.spec.ts │ │ │ └── server-side-query.component.ts │ │ └── where │ │ │ ├── where.component.html │ │ │ ├── where.component.less │ │ │ ├── where.component.spec.ts │ │ │ └── where.component.ts │ ├── demos │ │ ├── chat │ │ │ ├── chat.component.html │ │ │ ├── chat.component.less │ │ │ ├── chat.component.spec.ts │ │ │ └── chat.component.ts │ │ ├── demos-routing.module.ts │ │ ├── demos.module.ts │ │ ├── editor │ │ │ ├── editor.component.html │ │ │ ├── editor.component.less │ │ │ ├── editor.component.spec.ts │ │ │ └── editor.component.ts │ │ ├── examples │ │ │ ├── examples.component.html │ │ │ ├── examples.component.less │ │ │ ├── examples.component.spec.ts │ │ │ └── examples.component.ts │ │ └── pixels │ │ │ ├── pixels.component.html │ │ │ ├── pixels.component.less │ │ │ ├── pixels.component.spec.ts │ │ │ └── pixels.component.ts │ ├── messaging │ │ ├── main │ │ │ ├── main.component.html │ │ │ ├── main.component.less │ │ │ ├── main.component.spec.ts │ │ │ └── main.component.ts │ │ ├── messaging-routing.module.ts │ │ └── messaging.module.ts │ ├── security │ │ ├── create-auth │ │ │ ├── create-auth.component.html │ │ │ ├── create-auth.component.less │ │ │ ├── create-auth.component.spec.ts │ │ │ └── create-auth.component.ts │ │ ├── current-user │ │ │ ├── current-user.component.html │ │ │ ├── current-user.component.less │ │ │ ├── current-user.component.spec.ts │ │ │ └── current-user.component.ts │ │ ├── execute │ │ │ ├── execute.component.html │ │ │ ├── execute.component.less │ │ │ ├── execute.component.spec.ts │ │ │ └── execute.component.ts │ │ ├── general │ │ │ ├── general.component.html │ │ │ ├── general.component.less │ │ │ ├── general.component.spec.ts │ │ │ └── general.component.ts │ │ ├── net-core │ │ │ ├── net-core.component.html │ │ │ ├── net-core.component.less │ │ │ ├── net-core.component.spec.ts │ │ │ └── net-core.component.ts │ │ ├── query-auth │ │ │ ├── query-auth.component.html │ │ │ ├── query-auth.component.less │ │ │ ├── query-auth.component.spec.ts │ │ │ └── query-auth.component.ts │ │ ├── remove-auth │ │ │ ├── remove-auth.component.html │ │ │ ├── remove-auth.component.less │ │ │ ├── remove-auth.component.spec.ts │ │ │ └── remove-auth.component.ts │ │ ├── security-routing.module.ts │ │ ├── security.module.ts │ │ ├── update-auth │ │ │ ├── update-auth.component.html │ │ │ ├── update-auth.component.less │ │ │ ├── update-auth.component.spec.ts │ │ │ └── update-auth.component.ts │ │ ├── user-state.service.spec.ts │ │ └── user-state.service.ts │ ├── shared.module.ts │ ├── shared │ │ ├── doc │ │ │ ├── doc.component.html │ │ │ ├── doc.component.less │ │ │ ├── doc.component.spec.ts │ │ │ └── doc.component.ts │ │ ├── legal-disclosure │ │ │ ├── legal-disclosure.component.html │ │ │ ├── legal-disclosure.component.less │ │ │ ├── legal-disclosure.component.spec.ts │ │ │ └── legal-disclosure.component.ts │ │ ├── pipes │ │ │ ├── sanitize-html.pipe.spec.ts │ │ │ └── sanitize-html.pipe.ts │ │ ├── platform.service.ts │ │ └── privacy │ │ │ ├── privacy.component.html │ │ │ ├── privacy.component.less │ │ │ ├── privacy.component.spec.ts │ │ │ └── privacy.component.ts │ └── start │ │ ├── angular │ │ ├── angular.component.html │ │ ├── angular.component.less │ │ ├── angular.component.spec.ts │ │ └── angular.component.ts │ │ ├── changelog │ │ ├── changelog.component.html │ │ ├── changelog.component.less │ │ ├── changelog.component.spec.ts │ │ └── changelog.component.ts │ │ ├── contribution │ │ ├── contribution.component.html │ │ ├── contribution.component.less │ │ ├── contribution.component.spec.ts │ │ └── contribution.component.ts │ │ ├── implementations │ │ ├── implementations.component.html │ │ ├── implementations.component.less │ │ ├── implementations.component.spec.ts │ │ └── implementations.component.ts │ │ ├── js │ │ ├── js.component.html │ │ ├── js.component.less │ │ ├── js.component.spec.ts │ │ └── js.component.ts │ │ ├── main │ │ ├── main.component.html │ │ ├── main.component.less │ │ ├── main.component.spec.ts │ │ └── main.component.ts │ │ ├── net-core │ │ ├── net-core.component.html │ │ ├── net-core.component.less │ │ ├── net-core.component.spec.ts │ │ └── net-core.component.ts │ │ ├── sponsors │ │ ├── sponsors.component.html │ │ ├── sponsors.component.less │ │ ├── sponsors.component.spec.ts │ │ └── sponsors.component.ts │ │ ├── start-routing.module.ts │ │ ├── start.module.ts │ │ └── todo │ │ ├── todo.component.html │ │ ├── todo.component.less │ │ ├── todo.component.spec.ts │ │ └── todo.component.ts ├── assets │ ├── .gitkeep │ ├── angular-environment.js │ ├── angular-environment.template.js │ ├── banner │ │ ├── SapphireDB Banner.png │ │ └── SapphireDB Banner.svg │ └── icon │ │ ├── android-icon-144x144.png │ │ ├── android-icon-192x192.png │ │ ├── android-icon-36x36.png │ │ ├── android-icon-48x48.png │ │ ├── android-icon-72x72.png │ │ ├── android-icon-96x96.png │ │ ├── apple-icon-114x114.png │ │ ├── apple-icon-120x120.png │ │ ├── apple-icon-144x144.png │ │ ├── apple-icon-152x152.png │ │ ├── apple-icon-180x180.png │ │ ├── apple-icon-57x57.png │ │ ├── apple-icon-60x60.png │ │ ├── apple-icon-72x72.png │ │ ├── apple-icon-76x76.png │ │ ├── apple-icon-precomposed.png │ │ ├── apple-icon.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── favicon.ico │ │ ├── logo.png │ │ ├── logo.svg │ │ ├── ms-icon-144x144.png │ │ ├── ms-icon-150x150.png │ │ ├── ms-icon-310x310.png │ │ └── ms-icon-70x70.png ├── browserslist ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── favicon.ico ├── hmr.ts ├── index.html ├── karma.conf.js ├── main.server.ts ├── main.ts ├── manifest.json ├── polyfills.ts ├── robots.txt ├── sitemap.xml ├── styles.less ├── test.ts ├── tsconfig.app.json ├── tsconfig.spec.json └── tslint.json ├── ssr-polyfills.ts ├── tsconfig.json ├── tsconfig.server.json └── tslint.json /.dockerignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: morrisjdev 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Build and push docker image 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*.*.*' 7 | 8 | jobs: 9 | main: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - 13 | name: Checkout 14 | uses: actions/checkout@v2 15 | - 16 | name: Set up QEMU 17 | uses: docker/setup-qemu-action@v1 18 | - 19 | name: Set up Docker Buildx 20 | uses: docker/setup-buildx-action@v1 21 | - 22 | name: Login to GitHub Container Registry 23 | uses: docker/login-action@v1 24 | with: 25 | registry: ${{ secrets.DOCKER_REGISTRY_URL }} 26 | username: ${{ secrets.DOCKER_REGISTRY_USER }} 27 | password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }} 28 | - 29 | name: Get tag version 30 | id: get_version 31 | run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//} 32 | - 33 | name: Build and push 34 | uses: docker/build-push-action@v2 35 | with: 36 | context: . 37 | file: ./Dockerfile 38 | push: true 39 | tags: | 40 | ${{ secrets.DOCKER_REGISTRY_URL }}/sapphiredb.docs.client:${{ steps.get_version.outputs.VERSION }} 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | /node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # misc 28 | /.sass-cache 29 | /connect.lock 30 | /coverage 31 | /libpeerconnection.log 32 | npm-debug.log 33 | yarn-error.log 34 | testem.log 35 | /typings 36 | 37 | # System Files 38 | .DS_Store 39 | Thumbs.db 40 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "node" 4 | before_script: 5 | - npm install -g @angular/cli 6 | script: 7 | - ng build sapphiredb 8 | - ng build ng-sapphiredb 9 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine AS build 2 | 3 | WORKDIR /app 4 | 5 | COPY . . 6 | 7 | RUN npm install 8 | RUN npm run publish 9 | 10 | FROM node:alpine 11 | 12 | WORKDIR /usr/src/app 13 | 14 | COPY --from=build /app/dist/docs-client ./ 15 | 16 | RUN apk add --no-cache gettext 17 | 18 | CMD ["/bin/sh", "-c", "envsubst < ./browser/assets/angular-environment.template.js > ./browser/assets/angular-environment.js && exec node main.js"] 19 | 20 | EXPOSE 80 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018-2020 Morris Janatzek 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ngsw-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/service-worker/config/schema.json", 3 | "index": "/index.html", 4 | "assetGroups": [ 5 | { 6 | "name": "app", 7 | "installMode": "prefetch", 8 | "resources": { 9 | "files": [ 10 | "/favicon.ico", 11 | "/index.html", 12 | "/manifest.json", 13 | "/*.css", 14 | "/*.js", 15 | "/metro*", 16 | "/assets/icon/logo.svg" 17 | ], 18 | "urls": [ 19 | "https://upload.wikimedia.org/wikipedia/commons/**/*.svg", 20 | "https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" 21 | ] 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /projects/ng-sapphiredb/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../../coverage'), 20 | reports: ['html', 'lcovonly'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false 30 | }); 31 | }; 32 | -------------------------------------------------------------------------------- /projects/ng-sapphiredb/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/ng-sapphiredb", 4 | "lib": { 5 | "entryFile": "src/public_api.ts" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /projects/ng-sapphiredb/ng-package.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/ng-sapphiredb", 4 | "lib": { 5 | "entryFile": "src/public_api.ts" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /projects/ng-sapphiredb/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng-sapphiredb", 3 | "version": "3.1.8", 4 | "description": "Angular client implementation for SapphireDb", 5 | "peerDependencies": { 6 | "@angular/common": "~9.0.7", 7 | "@angular/core": "~9.0.7", 8 | "rxjs": "^6.5.4", 9 | "axios": "^0.19.1", 10 | "sapphiredb": "^3.1.8" 11 | }, 12 | "keywords": [ 13 | "realtime", 14 | "database", 15 | "asp.net core", 16 | "entity framework", 17 | "websocket", 18 | "angular", 19 | "rxjs", 20 | "sse", 21 | "self-hosted", 22 | "firebase", 23 | "signalr" 24 | ], 25 | "author": { 26 | "name": "Morris Janatzek" 27 | }, 28 | "license": "MIT", 29 | "bugs": { 30 | "url": "https://github.com/morrisjdev/ng-sapphiredb/issues" 31 | }, 32 | "homepage": "https://sapphire-db.com/", 33 | "repository": { 34 | "type": "git", 35 | "url": "https://github.com/morrisjdev/ng-sapphiredb.git" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /projects/ng-sapphiredb/src/lib/sapphire-db.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {SAPPHIRE_DB_OPTIONS, SapphireDbService} from './sapphire-db.service'; 3 | 4 | @NgModule({ 5 | imports: [], 6 | declarations: [], 7 | providers: [ 8 | SapphireDbService, 9 | { provide: SAPPHIRE_DB_OPTIONS, useValue: null }, 10 | ] 11 | }) 12 | export class SapphireDbModule {} 13 | -------------------------------------------------------------------------------- /projects/ng-sapphiredb/src/lib/sapphire-db.service.ts: -------------------------------------------------------------------------------- 1 | import {Inject, Injectable, InjectionToken, NgZone, Optional} from '@angular/core'; 2 | import {SapphireDbOptions, SapphireDb, SapphireClassTransformer, SapphireStorage} from 'sapphiredb'; 3 | 4 | export const SAPPHIRE_DB_OPTIONS = new InjectionToken('sapphire-db.options'); 5 | export const SAPPHIRE_DB_STARTUP_TOKEN = new InjectionToken('sapphire-db.startup-token'); 6 | 7 | @Injectable() 8 | export class SapphireDbService extends SapphireDb { 9 | constructor(@Inject(SAPPHIRE_DB_OPTIONS) options: SapphireDbOptions, 10 | @Optional() storage: SapphireStorage, 11 | @Optional() classTransformer: SapphireClassTransformer, 12 | private ngZone: NgZone, 13 | @Optional() @Inject(SAPPHIRE_DB_STARTUP_TOKEN) startupToken: string) { 14 | super(options, storage, classTransformer, (executeCode: () => void) => { 15 | this.ngZone.run(executeCode); 16 | }, startupToken); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /projects/ng-sapphiredb/src/public_api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Public API Surface of ng-sapphiredb 3 | */ 4 | 5 | export * from './lib/sapphire-db.service'; 6 | export * from './lib/sapphire-db.module'; 7 | -------------------------------------------------------------------------------- /projects/ng-sapphiredb/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'core-js/es7/reflect'; 4 | import 'zone.js/dist/zone'; 5 | import 'zone.js/dist/zone-testing'; 6 | import { getTestBed } from '@angular/core/testing'; 7 | import { 8 | BrowserDynamicTestingModule, 9 | platformBrowserDynamicTesting 10 | } from '@angular/platform-browser-dynamic/testing'; 11 | 12 | declare const require: any; 13 | 14 | // First, initialize the Angular testing environment. 15 | getTestBed().initTestEnvironment( 16 | BrowserDynamicTestingModule, 17 | platformBrowserDynamicTesting() 18 | ); 19 | // Then we find all the tests. 20 | const context = require.context('./', true, /\.spec\.ts$/); 21 | // And load the modules. 22 | context.keys().map(context); 23 | -------------------------------------------------------------------------------- /projects/ng-sapphiredb/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/lib", 5 | "target": "es2015", 6 | "module": "es2015", 7 | "moduleResolution": "node", 8 | "declaration": true, 9 | "sourceMap": true, 10 | "inlineSources": true, 11 | "emitDecoratorMetadata": true, 12 | "experimentalDecorators": true, 13 | "importHelpers": true, 14 | "types": [], 15 | "lib": [ 16 | "dom", 17 | "es2015" 18 | ] 19 | }, 20 | "angularCompilerOptions": { 21 | "skipTemplateCodegen": true, 22 | "strictMetadataEmit": true, 23 | "fullTemplateTypeCheck": true, 24 | "strictInjectionParameters": true, 25 | "flatModuleId": "AUTOGENERATED", 26 | "flatModuleOutFile": "AUTOGENERATED", 27 | "enableResourceInlining": true 28 | }, 29 | "exclude": [ 30 | "src/test.ts", 31 | "**/*.spec.ts" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /projects/ng-sapphiredb/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.json", 3 | "angularCompilerOptions": { 4 | "enableIvy": false 5 | } 6 | } -------------------------------------------------------------------------------- /projects/ng-sapphiredb/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts" 12 | ], 13 | "include": [ 14 | "**/*.spec.ts", 15 | "**/*.d.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /projects/ng-sapphiredb/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "lib", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "lib", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /projects/sapphiredb/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../../coverage/sapphiredb'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /projects/sapphiredb/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/sapphiredb", 4 | "lib": { 5 | "entryFile": "src/public-api.ts" 6 | } 7 | } -------------------------------------------------------------------------------- /projects/sapphiredb/ng-package.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/sapphiredb", 4 | "lib": { 5 | "entryFile": "src/public-api.ts" 6 | } 7 | } -------------------------------------------------------------------------------- /projects/sapphiredb/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sapphiredb", 3 | "version": "3.1.8", 4 | "description": "Javascript client implementation for SapphireDb", 5 | "peerDependencies": { 6 | "rxjs": "^6.5.4", 7 | "axios": "^0.19.1" 8 | }, 9 | "keywords": [ 10 | "realtime", 11 | "database", 12 | "asp.net core", 13 | "entity framework", 14 | "websocket", 15 | "rxjs", 16 | "sse", 17 | "self-hosted", 18 | "firebase", 19 | "signalr" 20 | ], 21 | "author": { 22 | "name": "Morris Janatzek" 23 | }, 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/morrisjdev/ng-sapphiredb/issues" 27 | }, 28 | "homepage": "https://sapphire-db.com/", 29 | "repository": { 30 | "type": "git", 31 | "url": "https://github.com/morrisjdev/ng-sapphiredb.git" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/collection/collection-data.ts: -------------------------------------------------------------------------------- 1 | import {IPrefilter} from './prefilter/iprefilter'; 2 | import {Observable} from 'rxjs'; 3 | 4 | export interface CollectionData { 5 | prefilters: IPrefilter[]; 6 | data$: Observable; 7 | referenceId?: string; 8 | } 9 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/collection/collection-value.ts: -------------------------------------------------------------------------------- 1 | import {ReplaySubject, Subscription} from 'rxjs'; 2 | 3 | export interface CollectionValueContainer { 4 | connectionId: string; 5 | values: T[]; 6 | } 7 | 8 | export class CollectionValue { 9 | referenceId: string; 10 | subject: ReplaySubject>; 11 | socketSubscription: Subscription; 12 | 13 | constructor(referenceId: string) { 14 | this.referenceId = referenceId; 15 | this.subject = new ReplaySubject>(1); 16 | } 17 | 18 | public setSubscription(socketSubscription: Subscription) { 19 | this.socketSubscription = socketSubscription; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/collection/ordered-collection.ts: -------------------------------------------------------------------------------- 1 | import {ThenOrderByPrefilter} from './prefilter/then-order-by-prefilter'; 2 | import {CollectionManager} from './collection-manager'; 3 | import {DefaultCollection} from './default-collection'; 4 | import {ConnectionManager} from '../connection/connection-manager'; 5 | import {ClassType, SortDirection} from '../models/types'; 6 | import {SapphireClassTransformer} from '../helper/sapphire-class-transformer'; 7 | import {OfflineManager} from '../modules/offline/offline-manager'; 8 | 9 | export class OrderedCollection extends DefaultCollection { 10 | constructor(collectionName: string, 11 | connectionManagerService: ConnectionManager, 12 | collectionManagerService: CollectionManager, 13 | classType: ClassType, 14 | classTransformer: SapphireClassTransformer, 15 | offlineManager: OfflineManager, 16 | enableLocalChangePreview: boolean) { 17 | super(collectionName, connectionManagerService, collectionManagerService, classType, classTransformer, offlineManager, 18 | enableLocalChangePreview); 19 | } 20 | 21 | /** 22 | * Apply additional ordering to the collection without effecting previous order 23 | * @param property The name of the property to order by 24 | * @param direction The direction of ordering 25 | */ 26 | public thenOrderBy(property: keyof T, direction: SortDirection = SortDirection.ascending): OrderedCollection { 27 | return this.collectionManagerService.getCollection(this.collectionName, this.prefilters, new ThenOrderByPrefilter(property, direction)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/collection/prefilter/count-prefilter.ts: -------------------------------------------------------------------------------- 1 | import {IPrefilter} from './iprefilter'; 2 | 3 | export class CountPrefilter implements IPrefilter { 4 | prefilterType = 'CountPrefilter'; 5 | 6 | execute(values: T[]) { 7 | return values.length; 8 | } 9 | 10 | public hash() { 11 | return `${this.prefilterType}`; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/collection/prefilter/first-prefilter.ts: -------------------------------------------------------------------------------- 1 | import {IPrefilter} from './iprefilter'; 2 | 3 | export class FirstPrefilter implements IPrefilter { 4 | prefilterType = 'FirstPrefilter'; 5 | 6 | execute(values: T[]) { 7 | return values.slice(0, 1); 8 | } 9 | 10 | public hash() { 11 | return `${this.prefilterType}`; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/collection/prefilter/include-prefilter.ts: -------------------------------------------------------------------------------- 1 | import {IPrefilter} from './iprefilter'; 2 | 3 | export class IncludePrefilter implements IPrefilter { 4 | prefilterType = 'IncludePrefilter'; 5 | include: string; 6 | 7 | constructor(include: string) { 8 | this.include = include; 9 | } 10 | 11 | public execute(values: T[]): T[] { 12 | return values; 13 | } 14 | 15 | public hash() { 16 | return `${this.prefilterType},${this.include}`; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/collection/prefilter/iprefilter.ts: -------------------------------------------------------------------------------- 1 | export interface IPrefilter { 2 | prefilterType: string; 3 | execute(values: T[]): Y; 4 | hash(): string; 5 | } 6 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/collection/prefilter/order-by-prefilter.ts: -------------------------------------------------------------------------------- 1 | import {IPrefilter} from './iprefilter'; 2 | import {ArrayHelper} from '../../helper/array-helper'; 3 | import {SortDirection} from '../../models/types'; 4 | 5 | export class OrderByPrefilter implements IPrefilter { 6 | prefilterType = 'OrderByPrefilter'; 7 | property: keyof T; 8 | descending: boolean; 9 | 10 | constructor(property: keyof T, direction: SortDirection = SortDirection.ascending) { 11 | this.property = property; 12 | this.descending = direction === SortDirection.descending; 13 | } 14 | 15 | public execute(values: T[]) { 16 | return ArrayHelper.orderBy(values, x => x[this.property], this.descending); 17 | } 18 | 19 | public hash() { 20 | return `${this.prefilterType},${this.property},${this.descending}}`; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/collection/prefilter/select-prefilter.ts: -------------------------------------------------------------------------------- 1 | import {IPrefilter} from './iprefilter'; 2 | 3 | export class SelectPrefilter implements IPrefilter { 4 | prefilterType = 'SelectPrefilter'; 5 | properties: (keyof T)[]; 6 | 7 | constructor(properties: (keyof T)[]) { 8 | this.properties = properties; 9 | } 10 | 11 | public execute(values: T[]) { 12 | return values; 13 | } 14 | 15 | public hash() { 16 | return `${this.prefilterType},${JSON.stringify(this.properties)}`; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/collection/prefilter/skip-prefilter.ts: -------------------------------------------------------------------------------- 1 | import {TakePrefilter} from './take-prefilter'; 2 | 3 | export class SkipPrefilter extends TakePrefilter { 4 | prefilterType = 'SkipPrefilter'; 5 | 6 | constructor(number: number) { 7 | super(number); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/collection/prefilter/take-prefilter.ts: -------------------------------------------------------------------------------- 1 | import {IPrefilter} from './iprefilter'; 2 | 3 | export class TakePrefilter implements IPrefilter { 4 | prefilterType = 'TakePrefilter'; 5 | number: number; 6 | 7 | constructor(number: number) { 8 | this.number = number; 9 | } 10 | 11 | execute(values: T[]) { 12 | return values; 13 | } 14 | 15 | public hash() { 16 | return `${this.prefilterType},${this.number}`; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/collection/prefilter/then-order-by-prefilter.ts: -------------------------------------------------------------------------------- 1 | import {ArrayHelper} from '../../helper/array-helper'; 2 | import {OrderByPrefilter} from './order-by-prefilter'; 3 | import {SortDirection} from '../../models/types'; 4 | 5 | export class ThenOrderByPrefilter extends OrderByPrefilter { 6 | prefilterType = 'ThenOrderByPrefilter'; 7 | 8 | constructor(property: keyof T, direction: SortDirection = SortDirection.ascending) { 9 | super(property, direction); 10 | } 11 | 12 | public execute(values: T[]) { 13 | return ArrayHelper.thenOrderBy(values, x => x[this.property], this.descending); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/collection/prefilter/where-prefilter.ts: -------------------------------------------------------------------------------- 1 | import {IPrefilter} from './iprefilter'; 2 | import {ConditionType} from '../../helper/condition-types'; 3 | import {FilterFunctions} from '../../helper/filter-functions'; 4 | 5 | export class WherePrefilter implements IPrefilter { 6 | prefilterType = 'WherePrefilter'; 7 | conditions: ConditionType; 8 | 9 | private conditionFunction: (value: T) => boolean; 10 | 11 | constructor(conditions: ConditionType) { 12 | this.conditions = conditions; 13 | this.conditionFunction = FilterFunctions.convertConditionParts(this.conditions); 14 | } 15 | 16 | public execute(values: T[]) { 17 | return values.filter(this.conditionFunction); 18 | } 19 | 20 | public hash() { 21 | return `${this.prefilterType},${JSON.stringify(this.conditions)}`; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/collection/query-collection.ts: -------------------------------------------------------------------------------- 1 | import {CollectionBase} from './collection-base'; 2 | import {ConnectionManager} from '../connection/connection-manager'; 3 | import {CollectionManager} from './collection-manager'; 4 | import {ClassType} from '../models/types'; 5 | import {SapphireClassTransformer} from '../helper/sapphire-class-transformer'; 6 | import {OfflineManager} from '../modules/offline/offline-manager'; 7 | import {SubscribeQueryCommand} from '../command/subscribe-query/subscribe-query-command'; 8 | import {QueryQueryCommand} from '../command/query-query/query-query-command'; 9 | 10 | export class QueryCollection extends CollectionBase { 11 | constructor(queryName: string, 12 | parameters: any[], 13 | connectionManagerService: ConnectionManager, 14 | collectionManagerService: CollectionManager, 15 | classType: ClassType, 16 | classTransformer: SapphireClassTransformer, 17 | offlineManager: OfflineManager, 18 | enableLocalChangePreview: boolean) { 19 | super(queryName, connectionManagerService, collectionManagerService, classType, classTransformer, offlineManager, 20 | enableLocalChangePreview, 21 | () => new SubscribeQueryCommand(queryName, parameters), 22 | () => new QueryQueryCommand(queryName, parameters)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/collection/reduced-collection.ts: -------------------------------------------------------------------------------- 1 | import {CollectionBase} from './collection-base'; 2 | import {CollectionManager} from './collection-manager'; 3 | import {ConnectionManager} from '../connection/connection-manager'; 4 | import {OfflineManager} from '../modules/offline/offline-manager'; 5 | 6 | export class ReducedCollection extends CollectionBase { 7 | constructor(collectionName: string, 8 | connectionManagerService: ConnectionManager, 9 | collectionManagerService: CollectionManager, 10 | offlineManager: OfflineManager, 11 | enableLocalChangePreview: boolean) { 12 | super(collectionName, connectionManagerService, collectionManagerService, null, null, offlineManager, 13 | enableLocalChangePreview); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/collection-command-base.ts: -------------------------------------------------------------------------------- 1 | import {CommandBase} from './command-base'; 2 | 3 | export class CollectionCommandBase extends CommandBase { 4 | collectionName: string; 5 | 6 | constructor(commandType: string, collectionName: string) { 7 | super(commandType); 8 | this.collectionName = collectionName; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/command-base.ts: -------------------------------------------------------------------------------- 1 | import {GuidHelper} from '../helper/guid-helper'; 2 | 3 | export class CommandBase { 4 | commandType: string; 5 | referenceId: string; 6 | timestamp: Date; 7 | 8 | constructor(commandType: string) { 9 | this.commandType = commandType; 10 | this.referenceId = GuidHelper.generateGuid(); 11 | this.timestamp = new Date(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/connection/connection-response.ts: -------------------------------------------------------------------------------- 1 | import {ResponseBase} from '../response-base'; 2 | 3 | export interface ConnectionResponse extends ResponseBase { 4 | connectionId: string; 5 | authTokenValid: boolean; 6 | } 7 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/create-range/create-range-command.ts: -------------------------------------------------------------------------------- 1 | import {CollectionCommandBase} from '../collection-command-base'; 2 | 3 | export class CreateRangeCommand extends CollectionCommandBase { 4 | values: any[]; 5 | 6 | constructor(collectionName: string, values: any[]) { 7 | super('CreateRangeCommand', collectionName); 8 | this.values = values; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/create-range/create-range-response.ts: -------------------------------------------------------------------------------- 1 | import {ResponseBase} from '../response-base'; 2 | import {ValidatedResponseBase} from '../validated-response-base'; 3 | 4 | export interface CreateRangeResponse extends ResponseBase { 5 | results: ValidatedResponseBase[]; 6 | } 7 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/delete-range/delete-range-command.ts: -------------------------------------------------------------------------------- 1 | import {CollectionCommandBase} from '../collection-command-base'; 2 | 3 | export class DeleteRangeCommand extends CollectionCommandBase { 4 | values: { [propertyName: string]: any }[]; 5 | 6 | constructor(collectionName: string, primaryKeyList: { [propertyName: string]: any }[]) { 7 | super('DeleteRangeCommand', collectionName); 8 | this.values = primaryKeyList; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/delete-range/delete-range-response.ts: -------------------------------------------------------------------------------- 1 | import {ResponseBase} from '../response-base'; 2 | import {ValidatedResponseBase} from '../validated-response-base'; 3 | 4 | export interface DeleteRangeResponse extends ResponseBase { 5 | results: ValidatedResponseBase[]; 6 | } 7 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/execute-commands/execute-commands-command.ts: -------------------------------------------------------------------------------- 1 | import {CommandBase} from '../command-base'; 2 | 3 | export class ExecuteCommandsCommand extends CommandBase { 4 | commands: CommandBase[]; 5 | 6 | constructor(commands: CommandBase[]) { 7 | super('ExecuteCommandsCommand'); 8 | this.commands = commands; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/execute-commands/execute-commands-response.ts: -------------------------------------------------------------------------------- 1 | import {ResponseBase} from '../response-base'; 2 | import {CommandBase} from '../command-base'; 3 | 4 | export interface ExecuteCommandsResponse extends ResponseBase { 5 | results: ExecuteCommandsResultResponse[]; 6 | } 7 | 8 | export interface ExecuteCommandsResultResponse extends ResponseBase { 9 | command: CommandBase; 10 | response: ResponseBase; 11 | } 12 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/execute/execute-command.ts: -------------------------------------------------------------------------------- 1 | import {CommandBase} from '../command-base'; 2 | 3 | export class ExecuteCommand extends CommandBase { 4 | action: string; 5 | parameters: any[]; 6 | 7 | constructor(action: string, parameters: any[]) { 8 | super('ExecuteCommand'); 9 | this.action = action; 10 | this.parameters = parameters; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/execute/execute-response.ts: -------------------------------------------------------------------------------- 1 | import {ResponseBase} from '../response-base'; 2 | 3 | export interface ExecuteResponse extends ResponseBase { 4 | result: any; 5 | type: ExecuteResponseType; 6 | } 7 | 8 | export enum ExecuteResponseType { 9 | End, Notify, Async 10 | } 11 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/invoke/invoke-command.ts: -------------------------------------------------------------------------------- 1 | import {CollectionCommandBase} from '../collection-command-base'; 2 | 3 | export class InvokeCommand extends CollectionCommandBase { 4 | primaryKeys: { [propertyName: string]: any }; 5 | action: string; 6 | 7 | parameters: any[]; 8 | 9 | constructor(collectionName: string, action: string, primaryKeys: { [propertyName: string]: any }, parameters: any[]) { 10 | super('InvokeCommand', collectionName); 11 | this.action = action; 12 | this.primaryKeys = primaryKeys; 13 | this.parameters = parameters; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/invoke/invoke-response.ts: -------------------------------------------------------------------------------- 1 | import {ResponseBase} from '../response-base'; 2 | 3 | export interface InvokeResponse extends ResponseBase { 4 | result: any; 5 | } 6 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/message/message-command.ts: -------------------------------------------------------------------------------- 1 | import {CommandBase} from '../command-base'; 2 | 3 | export class MessageCommand extends CommandBase { 4 | data: any; 5 | filter: string; 6 | filterParameters: any[]; 7 | 8 | constructor(data: any, filter?: string, filterParamters?: any[]) { 9 | super('MessageCommand'); 10 | this.data = data; 11 | this.filter = filter; 12 | this.filterParameters = filterParamters; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/message/message-response.ts: -------------------------------------------------------------------------------- 1 | import {ResponseBase} from '../response-base'; 2 | 3 | export interface MessageResponse extends ResponseBase { 4 | data: any; 5 | } 6 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/publish/publish-command.ts: -------------------------------------------------------------------------------- 1 | import {CommandBase} from '../command-base'; 2 | 3 | export class PublishCommand extends CommandBase { 4 | topic: string; 5 | data: any; 6 | retain: boolean; 7 | 8 | constructor(topic: string, data: any, retain: boolean) { 9 | super('PublishCommand'); 10 | this.topic = topic; 11 | this.data = data; 12 | this.retain = retain; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/query-connections/query-connections-command.ts: -------------------------------------------------------------------------------- 1 | import {CommandBase} from '../command-base'; 2 | 3 | export class QueryConnectionsCommand extends CommandBase { 4 | constructor() { 5 | super('QueryConnectionsCommand'); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/query-connections/query-connections-response.ts: -------------------------------------------------------------------------------- 1 | import {ResponseBase} from '../response-base'; 2 | 3 | export interface QueryConnectionsResponse extends ResponseBase { 4 | connections: RealtimeConnection[]; 5 | } 6 | 7 | export interface RealtimeConnection { 8 | id: string; 9 | information: HttpInformation; 10 | type: 'Websocket'|'SSE'|'Poll'; 11 | } 12 | 13 | export interface HttpInformation { 14 | remotePort: number; 15 | localPort: number; 16 | userId?: string; 17 | userAgent?: string; 18 | apiName: string; 19 | } 20 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/query-query/query-query-command.ts: -------------------------------------------------------------------------------- 1 | import {CommandBase} from '../command-base'; 2 | 3 | export class QueryQueryCommand extends CommandBase { 4 | queryName: string; 5 | parameters: any[]; 6 | 7 | constructor(queryName: string, parameters: any[]) { 8 | super('QueryQueryCommand'); 9 | this.queryName = queryName; 10 | this.parameters = parameters; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/query/query-command.ts: -------------------------------------------------------------------------------- 1 | import {CollectionCommandBase} from '../collection-command-base'; 2 | import {IPrefilter} from '../../collection/prefilter/iprefilter'; 3 | 4 | export class QueryCommand extends CollectionCommandBase { 5 | prefilters: IPrefilter[]; 6 | 7 | constructor(collectionName: string, prefilters: IPrefilter[]) { 8 | super('QueryCommand', collectionName); 9 | this.prefilters = prefilters; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/query/query-response.ts: -------------------------------------------------------------------------------- 1 | import {ResponseBase} from '../response-base'; 2 | 3 | export interface QueryResponse extends ResponseBase { 4 | result: any; 5 | } 6 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/response-base.ts: -------------------------------------------------------------------------------- 1 | import {SapphireDbErrorResponse} from './sapphire-db-error-response'; 2 | 3 | export interface ResponseBase { 4 | responseType: string; 5 | referenceId: string; 6 | error?: SapphireDbErrorResponse; 7 | timestamp: Date; 8 | } 9 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/sapphire-db-error-response.ts: -------------------------------------------------------------------------------- 1 | export interface SapphireDbErrorResponse { 2 | type: string; 3 | message: string; 4 | id: string; 5 | data: { [key: string]: any }; 6 | } 7 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/stream/complete-stream-command.ts: -------------------------------------------------------------------------------- 1 | import {CommandBase} from '../command-base'; 2 | 3 | export class CompleteStreamCommand extends CommandBase { 4 | private streamId: string; 5 | private index: number; 6 | private error: boolean; 7 | 8 | constructor(streamId: string, index: number, error: boolean = false) { 9 | super('CompleteStreamCommand'); 10 | this.streamId = streamId; 11 | this.index = index; 12 | this.error = error; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/stream/init-stream-response.ts: -------------------------------------------------------------------------------- 1 | import {ResponseBase} from '../response-base'; 2 | 3 | export interface InitStreamResponse extends ResponseBase { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/stream/stream-command.ts: -------------------------------------------------------------------------------- 1 | import {CommandBase} from '../command-base'; 2 | 3 | export class StreamCommand extends CommandBase { 4 | streamId: string; 5 | frameData: any; 6 | index: number; 7 | 8 | constructor(streamId: string, frameData: any, index: number) { 9 | super('StreamCommand'); 10 | this.streamId = streamId; 11 | this.frameData = frameData; 12 | this.index = index; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/subscribe-message/subscribe-message-command.ts: -------------------------------------------------------------------------------- 1 | import {CommandBase} from '../command-base'; 2 | 3 | export class SubscribeMessageCommand extends CommandBase { 4 | topic: string; 5 | 6 | constructor(topic: string) { 7 | super('SubscribeMessageCommand'); 8 | this.topic = topic; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/subscribe-message/topic-response.ts: -------------------------------------------------------------------------------- 1 | import {ResponseBase} from '../response-base'; 2 | 3 | export interface TopicResponse extends ResponseBase { 4 | message: any; 5 | topic: string; 6 | } 7 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/subscribe-query/subscribe-query-command.ts: -------------------------------------------------------------------------------- 1 | import {QueryQueryCommand} from '../query-query/query-query-command'; 2 | 3 | export class SubscribeQueryCommand extends QueryQueryCommand { 4 | queryName: string; 5 | parameters: any[]; 6 | 7 | constructor(queryName: string, parameters: any[]) { 8 | super(queryName, parameters); 9 | this.commandType = 'SubscribeQueryCommand'; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/subscribe/change-response.ts: -------------------------------------------------------------------------------- 1 | import {ResponseBase} from '../response-base'; 2 | 3 | export interface ChangeResponse extends ResponseBase { 4 | state: ChangeState; 5 | value: any; 6 | changes?: any; 7 | } 8 | 9 | export interface ChangesResponse extends ResponseBase { 10 | changes: ChangeResponse[]; 11 | } 12 | 13 | export enum ChangeState { 14 | Added, Deleted, Modified 15 | } 16 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/subscribe/subscribe-command.ts: -------------------------------------------------------------------------------- 1 | import {IPrefilter} from '../../collection/prefilter/iprefilter'; 2 | import {QueryCommand} from '../query/query-command'; 3 | 4 | export class SubscribeCommand extends QueryCommand { 5 | constructor(collectionName: string, prefilters: IPrefilter[]) { 6 | super(collectionName, prefilters); 7 | this.commandType = 'SubscribeCommand'; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/unsubscribe-message/unsubscribe-message-command.ts: -------------------------------------------------------------------------------- 1 | import {CommandBase} from '../command-base'; 2 | 3 | export class UnsubscribeMessageCommand extends CommandBase { 4 | constructor(referenceId: string) { 5 | super('UnsubscribeMessageCommand'); 6 | this.referenceId = referenceId; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/unsubscribe/unsubscribe-command.ts: -------------------------------------------------------------------------------- 1 | import {CommandBase} from '../command-base'; 2 | 3 | export class UnsubscribeCommand extends CommandBase { 4 | constructor(referenceId: string) { 5 | super('UnsubscribeCommand'); 6 | this.referenceId = referenceId; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/update-range/update-range-command.ts: -------------------------------------------------------------------------------- 1 | import {CollectionCommandBase} from '../collection-command-base'; 2 | 3 | export class UpdateRangeCommand extends CollectionCommandBase { 4 | entries: UpdateEntry[]; 5 | 6 | constructor(collectionName: string, updateEntries: UpdateEntry[]) { 7 | super('UpdateRangeCommand', collectionName); 8 | this.entries = updateEntries; 9 | } 10 | } 11 | 12 | export class UpdateEntry { 13 | value: any; 14 | updatedProperties: any; 15 | 16 | constructor(value: any, updatedProperties: any, ) { 17 | this.value = value; 18 | this.updatedProperties = updatedProperties; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/update-range/update-range-response.ts: -------------------------------------------------------------------------------- 1 | import {ResponseBase} from '../response-base'; 2 | import {ValidatedResponseBase} from '../validated-response-base'; 3 | 4 | export interface UpdateRangeResponse extends ResponseBase { 5 | results: (UpdateResponse|ValidatedResponseBase)[]; 6 | } 7 | 8 | export interface UpdateResponse extends ValidatedResponseBase { 9 | updatedProperties: any; 10 | } 11 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/command/validated-response-base.ts: -------------------------------------------------------------------------------- 1 | import {ResponseBase} from './response-base'; 2 | 3 | export interface ValidatedResponseBase extends ResponseBase { 4 | validationResults: { [propertyName: string]: string[] }; 5 | value: any; 6 | } 7 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/connection/connection-base.ts: -------------------------------------------------------------------------------- 1 | import {SapphireDbOptions} from '../models/sapphire-db-options'; 2 | import {ResponseBase} from '../command/response-base'; 3 | import {CommandBase} from '../command/command-base'; 4 | import {BehaviorSubject, Observable, Subscription} from 'rxjs'; 5 | import {AuthTokenState, ConnectionInformation, ConnectionState} from '../models/types'; 6 | 7 | export abstract class ConnectionBase { 8 | public messageHandler: (message: ResponseBase) => void; 9 | 10 | public connectionInformation$ = new BehaviorSubject({ 11 | connectionId: null, 12 | readyState: ConnectionState.disconnected 13 | }); 14 | 15 | public checkAuthToken: () => Observable; 16 | 17 | public abstract send(object: CommandBase, storedCommand: boolean): Subscription; 18 | public abstract setData(options: SapphireDbOptions, authToken?: string): void; 19 | 20 | public updateConnectionInformation(readyState: ConnectionState, connectionId?: string) { 21 | const connectionInformation = this.connectionInformation$.value; 22 | connectionInformation.readyState = readyState; 23 | connectionInformation.connectionId = connectionId; 24 | this.connectionInformation$.next(connectionInformation); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/helper/action-helper.ts: -------------------------------------------------------------------------------- 1 | import {ActionResult} from '../modules/action/action-result'; 2 | import {ExecuteResponseType} from '../command/execute/execute-response'; 3 | 4 | // @dynamic 5 | export class ActionHelper { 6 | public static result(completeFn?: (result: ResultType) => void, asyncFn?: (result: ResultType) => void, notifyFn?: (notification: NotificationType) => void) { 7 | return (result: ActionResult) => { 8 | if (result.type === ExecuteResponseType.End) { 9 | if (completeFn) { 10 | completeFn(result.result); 11 | } 12 | } else if (result.type === ExecuteResponseType.Async) { 13 | if (asyncFn) { 14 | asyncFn(result.result); 15 | } 16 | } else if (result.type === ExecuteResponseType.Notify) { 17 | if (notifyFn) { 18 | notifyFn(result.notification); 19 | } 20 | } 21 | }; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/helper/auth-token-helper.ts: -------------------------------------------------------------------------------- 1 | import {from, Observable, of} from 'rxjs'; 2 | import {AuthTokenState} from '../models/types'; 3 | import {AxiosResponse, default as axios} from 'axios'; 4 | import {catchError, map} from 'rxjs/operators'; 5 | import {SapphireDbOptions} from '../models/sapphire-db-options'; 6 | 7 | export class AuthTokenHelper { 8 | public static validateAuthToken$(authToken: string, options: SapphireDbOptions): Observable { 9 | const checkAuthTokenUrl = `${options.useSsl ? 'https' : 'http'}://${options.serverBaseUrl}/sapphire/authToken`; 10 | 11 | return from(axios.post(checkAuthTokenUrl, null, { 12 | headers: { 13 | Authorization: `Bearer ${authToken}` 14 | } 15 | })).pipe( 16 | map((response: AxiosResponse) => response.data), 17 | map((authTokenValid: boolean) => authTokenValid ? AuthTokenState.valid : AuthTokenState.invalid), 18 | catchError(error => { 19 | if (error?.response?.status === 401) { 20 | return of(AuthTokenState.invalid); 21 | } 22 | 23 | return of(AuthTokenState.error); 24 | }) 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/helper/condition-types.ts: -------------------------------------------------------------------------------- 1 | export type CompareOperationType = 2 | '==' 3 | | '!=' 4 | | '<' 5 | | '>' 6 | | '<=' 7 | | '>=' 8 | | 'Contains' 9 | | 'ContainsCaseInsensitive' 10 | | 'StartsWith' 11 | | 'StartsWithCaseInsensitive' 12 | | 'EndsWith' 13 | | 'EndsWithCaseInsensitive' 14 | | 'InArray' 15 | | 'ArrayContains' 16 | | 'NotEqualIgnoreCase' 17 | | 'EqualIgnoreCase'; 18 | 19 | export type BaseConditionType = [keyof T, CompareOperationType, any]; 20 | export type CombineType = 'and' | 'or'; 21 | export type CompoundConditionType = BaseConditionType | CombineType; 22 | export type ConditionType = (CompoundConditionType[] | CompoundConditionType)[] | BaseConditionType; 23 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/helper/decorator-helper.ts: -------------------------------------------------------------------------------- 1 | import {ClassType, PrimaryKeyEntry} from '../models/types'; 2 | 3 | // @dynamic 4 | export class DecoratorHelper { 5 | private static primaryKeys: PrimaryKeyEntry[] = []; 6 | 7 | public static addPrimaryKey(type: ClassType, property: string): void { 8 | const classType: Function = type.constructor; 9 | 10 | const entryIndex = this.primaryKeys.findIndex(pk => pk.type === classType); 11 | 12 | if (entryIndex !== -1) { 13 | const previousPrimaryKeys = this.primaryKeys[entryIndex].primaryKeys; 14 | this.primaryKeys[entryIndex].primaryKeys = [ ...previousPrimaryKeys, property ]; 15 | } else { 16 | if ((classType).prototype.__proto__.constructor !== Object) { 17 | this.primaryKeys.push({ 18 | type: classType, 19 | primaryKeys: [ property, ...this.getPrimaryKeys((classType).prototype.__proto__.constructor) ] 20 | }); 21 | } else { 22 | this.primaryKeys.push({ 23 | type: classType, 24 | primaryKeys: [ property ] 25 | }); 26 | } 27 | } 28 | } 29 | 30 | public static getPrimaryKeys(type: Function): string[] { 31 | const entryIndex = this.primaryKeys.findIndex(pk => pk.type === type); 32 | 33 | if (entryIndex === -1) { 34 | if ((type).prototype.__proto__.constructor !== Object) { 35 | return this.getPrimaryKeys((type).prototype.__proto__.constructor); 36 | } 37 | 38 | return []; 39 | } 40 | 41 | return this.primaryKeys[entryIndex].primaryKeys; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/helper/decorators/primary-key.ts: -------------------------------------------------------------------------------- 1 | import {DecoratorHelper} from '../decorator-helper'; 2 | 3 | // @dynamic 4 | export function PrimaryKey() { 5 | return function(target: any, property: string): void { 6 | DecoratorHelper.addPrimaryKey(target, property); 7 | }; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/helper/guid-helper.ts: -------------------------------------------------------------------------------- 1 | export class GuidHelper { 2 | static generateGuid(): string { 3 | const template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'; 4 | 5 | return template.replace(/[xy]/g, (c) => { 6 | const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8); 7 | return v.toString(16); 8 | }); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/helper/rxjs-helper.ts: -------------------------------------------------------------------------------- 1 | import {concat, Observable, OperatorFunction} from 'rxjs'; 2 | 3 | // @dynamic 4 | export class RxjsHelper { 5 | static startWithObservable(startWith: Observable): OperatorFunction { 6 | return ((source: Observable) => concat(startWith, source)); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/helper/sapphire-class-transformer.ts: -------------------------------------------------------------------------------- 1 | import {ClassType} from '../models/types'; 2 | 3 | export abstract class SapphireClassTransformer { 4 | abstract plainToClass(value: any, classType: ClassType): T|T[]; 5 | 6 | abstract classToPlain(value: T|T[]): any; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/helper/sapphire-storage.ts: -------------------------------------------------------------------------------- 1 | import {Observable, of} from 'rxjs'; 2 | 3 | export abstract class SapphireStorage { 4 | abstract get(key: string): Observable; 5 | abstract set(key: string, value: string): void; 6 | } 7 | 8 | export class SapphireNoopStorage extends SapphireStorage { 9 | get(key: string): Observable { 10 | return of(null); 11 | } 12 | 13 | set(key: string, value: string): void { } 14 | } 15 | 16 | export class SapphireLocalStorage extends SapphireStorage { 17 | get(key: string): Observable { 18 | return of(localStorage.getItem(key)); 19 | } 20 | 21 | set(key: string, value: string) { 22 | localStorage.setItem(key, value); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/models/command-references.ts: -------------------------------------------------------------------------------- 1 | import {Subject} from 'rxjs'; 2 | import {ResponseBase} from '../command/response-base'; 3 | 4 | export interface CommandReferences { 5 | [reference: string]: { 6 | subject$: Subject; 7 | keep?: boolean; 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/models/sapphire-db-options.ts: -------------------------------------------------------------------------------- 1 | export interface SapphireDbOptions { 2 | /** 3 | * The connection to use. If left empty the best suiting connection type is automatically selected 4 | */ 5 | connectionType?: 'websocket' | 'sse' | 'poll'; 6 | 7 | /** 8 | * The base url of the server. If left empty the hostname and port of the current application is used. 9 | */ 10 | serverBaseUrl?: string; 11 | 12 | /** 13 | * Use ssl to connect to server. If left empty the current ssl-settings are used. 14 | */ 15 | useSsl?: boolean; 16 | 17 | /** 18 | * Api key to be used when connecting. 19 | */ 20 | apiKey?: string; 21 | 22 | /** 23 | * Secret to be used when connecting. 24 | */ 25 | apiSecret?: string; 26 | 27 | /** 28 | * Enable offline support and try to store collection data and changes locally when not connected to server. 29 | */ 30 | offlineSupport?: boolean; 31 | 32 | /** 33 | * Enables local handling and preview of operations before server execution for faster result displaying 34 | */ 35 | enableLocalChangePreview?: boolean; 36 | } 37 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/models/subscribe-command-info.ts: -------------------------------------------------------------------------------- 1 | import {CommandBase} from '../command/command-base'; 2 | 3 | export interface SubscribeCommandInfo { 4 | sendWithAuthToken: boolean; 5 | command: CommandBase; 6 | } 7 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/models/types.ts: -------------------------------------------------------------------------------- 1 | export enum ConnectionState { 2 | disconnected, connecting, connected 3 | } 4 | 5 | export enum AuthTokenState { 6 | valid, error, invalid, not_set, validating 7 | } 8 | 9 | export interface ConnectionInformation { 10 | readyState: ConnectionState; 11 | connectionId: string; 12 | } 13 | 14 | export enum SortDirection { 15 | ascending, descending 16 | } 17 | 18 | export type ClassType = new (...args: any[]) => T; 19 | 20 | export interface PrimaryKeyEntry { 21 | type: Function; 22 | primaryKeys: string[]; 23 | } 24 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/modules/action/action-result.ts: -------------------------------------------------------------------------------- 1 | import {ExecuteResponse, ExecuteResponseType} from '../../command/execute/execute-response'; 2 | 3 | export class ActionResult { 4 | type: ExecuteResponseType; 5 | result: X; 6 | notification: Y; 7 | 8 | constructor (response: ExecuteResponse) { 9 | this.type = response.type; 10 | 11 | if (response.type === ExecuteResponseType.End || response.type === ExecuteResponseType.Async) { 12 | this.result = response.result; 13 | } else if (response.type === ExecuteResponseType.Notify) { 14 | this.notification = response.result; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/modules/offline/offline-response.ts: -------------------------------------------------------------------------------- 1 | import {ValidatedResponseBase} from '../../command/validated-response-base'; 2 | 3 | export interface OfflineResponse { 4 | results: ValidatedResponseBase[]; 5 | } 6 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/lib/modules/offline/sapphire-offline-entity.ts: -------------------------------------------------------------------------------- 1 | import {GuidHelper} from '../../helper/guid-helper'; 2 | import {PrimaryKey} from '../../helper/decorators/primary-key'; 3 | 4 | export class SapphireOfflineEntity { 5 | @PrimaryKey() 6 | public id: string; 7 | protected modifiedOn?: Date; 8 | 9 | constructor() { 10 | this.id = GuidHelper.generateGuid(); 11 | this.modifiedOn = undefined; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/public-api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Public API Surface of sapphiredb 3 | */ 4 | 5 | export * from './lib/models/sapphire-db-options'; 6 | export * from './lib/sapphire-db'; 7 | 8 | export * from './lib/helper/action-helper'; 9 | export * from './lib/helper/condition-types'; 10 | export * from './lib/helper/sapphire-class-transformer'; 11 | export * from './lib/helper/sapphire-storage'; 12 | export * from './lib/helper/decorators/primary-key'; 13 | 14 | export * from './lib/collection/default-collection'; 15 | export * from './lib/collection/ordered-collection'; 16 | export * from './lib/collection/reduced-collection'; 17 | export * from './lib/collection/query-collection'; 18 | 19 | export * from './lib/modules/messaging/messaging'; 20 | export * from './lib/modules/action/action-result'; 21 | export * from './lib/modules/offline/offline-response'; 22 | 23 | export * from './lib/models/types'; 24 | export * from './lib/modules/offline/sapphire-offline-entity'; 25 | 26 | export * from './lib/command/connection/connection-response'; 27 | 28 | export * from './lib/command/execute/execute-response'; 29 | export * from './lib/command/query-connections/query-connections-response'; 30 | export * from './lib/command/create-range/create-range-response'; 31 | export * from './lib/command/update-range/update-range-response'; 32 | export * from './lib/command/delete-range/delete-range-response'; 33 | export * from './lib/command/subscribe/change-response'; 34 | 35 | export * from './lib/command/query/query-response'; 36 | -------------------------------------------------------------------------------- /projects/sapphiredb/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone'; 4 | import 'zone.js/dist/zone-testing'; 5 | import { getTestBed } from '@angular/core/testing'; 6 | import { 7 | BrowserDynamicTestingModule, 8 | platformBrowserDynamicTesting 9 | } from '@angular/platform-browser-dynamic/testing'; 10 | 11 | declare const require: any; 12 | 13 | // First, initialize the Angular testing environment. 14 | getTestBed().initTestEnvironment( 15 | BrowserDynamicTestingModule, 16 | platformBrowserDynamicTesting() 17 | ); 18 | // Then we find all the tests. 19 | const context = require.context('./', true, /\.spec\.ts$/); 20 | // And load the modules. 21 | context.keys().map(context); 22 | -------------------------------------------------------------------------------- /projects/sapphiredb/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/lib", 5 | "target": "es2015", 6 | "declaration": true, 7 | "inlineSources": true, 8 | "types": [], 9 | "lib": [ 10 | "dom", 11 | "es2018" 12 | ] 13 | }, 14 | "angularCompilerOptions": { 15 | "skipTemplateCodegen": true, 16 | "strictMetadataEmit": true, 17 | "fullTemplateTypeCheck": true, 18 | "strictInjectionParameters": true, 19 | "enableResourceInlining": true 20 | }, 21 | "exclude": [ 22 | "src/test.ts", 23 | "**/*.spec.ts" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /projects/sapphiredb/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.json", 3 | "angularCompilerOptions": { 4 | "enableIvy": false 5 | } 6 | } -------------------------------------------------------------------------------- /projects/sapphiredb/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts" 12 | ], 13 | "include": [ 14 | "**/*.spec.ts", 15 | "**/*.d.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /projects/sapphiredb/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "lib", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "lib", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/app/actions/actions-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import {MainComponent} from './main/main.component'; 4 | 5 | 6 | const routes: Routes = [ 7 | { path: 'main', component: MainComponent }, 8 | { path: '', pathMatch: 'full', redirectTo: 'main' } 9 | ]; 10 | 11 | @NgModule({ 12 | imports: [RouterModule.forChild(routes)], 13 | exports: [RouterModule] 14 | }) 15 | export class ActionsRoutingModule { } 16 | -------------------------------------------------------------------------------- /src/app/actions/actions.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | 3 | import {ActionsRoutingModule} from './actions-routing.module'; 4 | import {MainComponent} from './main/main.component'; 5 | import {SharedModule} from '../shared.module'; 6 | 7 | 8 | @NgModule({ 9 | declarations: [MainComponent], 10 | imports: [ 11 | SharedModule, 12 | ActionsRoutingModule 13 | ] 14 | }) 15 | export class ActionsModule { } 16 | -------------------------------------------------------------------------------- /src/app/actions/main/main.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/actions/main/main.component.less -------------------------------------------------------------------------------- /src/app/actions/main/main.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { MainComponent } from './main.component'; 4 | 5 | describe('MainComponent', () => { 6 | let component: MainComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ MainComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(MainComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {RouterModule, Routes} from '@angular/router'; 3 | import {LegalDisclosureComponent} from './shared/legal-disclosure/legal-disclosure.component'; 4 | import {PrivacyComponent} from './shared/privacy/privacy.component'; 5 | 6 | const routes: Routes = [ 7 | { path: 'start', loadChildren: () => import('./start/start.module').then(m => m.StartModule) }, 8 | { path: 'data', loadChildren: () => import('./data/data.module').then(m => m.DataModule) }, 9 | { path: 'security', loadChildren: () => import('./security/security.module').then(m => m.SecurityModule) }, 10 | { path: 'actions', loadChildren: () => import('./actions/actions.module').then(m => m.ActionsModule) }, 11 | { path: 'messaging', loadChildren: () => import('./messaging/messaging.module').then(m => m.MessagingModule) }, 12 | { path: 'configuration', loadChildren: () => import('./configuration/configuration.module').then(m => m.ConfigurationModule) }, 13 | { path: 'demos', loadChildren: () => import('./demos/demos.module').then(m => m.DemosModule) }, 14 | 15 | { path: 'legal-details', component: LegalDisclosureComponent }, 16 | { path: 'privacy', component: PrivacyComponent }, 17 | 18 | { path: '**', redirectTo: 'start', pathMatch: 'full' } 19 | ]; 20 | 21 | @NgModule({ 22 | imports: [RouterModule.forRoot(routes, { 23 | initialNavigation: 'enabled' 24 | })], 25 | exports: [RouterModule] 26 | }) 27 | export class AppRoutingModule { } 28 | -------------------------------------------------------------------------------- /src/app/app.component.less: -------------------------------------------------------------------------------- 1 | .page-container { 2 | position: relative; 3 | min-height: 100vh; 4 | } 5 | 6 | .page-content { 7 | padding-top: 64px; 8 | padding-bottom: 220px; 9 | } 10 | 11 | .footer-position { 12 | position: absolute; 13 | bottom: 0; 14 | width: 100%; 15 | } 16 | -------------------------------------------------------------------------------- /src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { RouterTestingModule } from '@angular/router/testing'; 3 | import { AppComponent } from './app.component'; 4 | describe('AppComponent', () => { 5 | beforeEach(async(() => { 6 | TestBed.configureTestingModule({ 7 | imports: [ 8 | RouterTestingModule 9 | ], 10 | declarations: [ 11 | AppComponent 12 | ], 13 | }).compileComponents(); 14 | })); 15 | it('should create the app', async(() => { 16 | const fixture = TestBed.createComponent(AppComponent); 17 | const app = fixture.debugElement.componentInstance; 18 | expect(app).toBeTruthy(); 19 | })); 20 | it(`should have as title 'app'`, async(() => { 21 | const fixture = TestBed.createComponent(AppComponent); 22 | const app = fixture.debugElement.componentInstance; 23 | expect(app.title).toEqual('app'); 24 | })); 25 | it('should render title in a h1 tag', async(() => { 26 | const fixture = TestBed.createComponent(AppComponent); 27 | fixture.detectChanges(); 28 | const compiled = fixture.debugElement.nativeElement; 29 | expect(compiled.querySelector('h1').textContent).toContain('Welcome to DemoClient!'); 30 | })); 31 | }); 32 | -------------------------------------------------------------------------------- /src/app/app.server.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { ServerModule } from '@angular/platform-server'; 3 | 4 | import { AppModule } from './app.module'; 5 | import { AppComponent } from './app.component'; 6 | 7 | @NgModule({ 8 | imports: [ 9 | AppModule, 10 | ServerModule 11 | ], 12 | providers: [ 13 | // Add universal-only providers here 14 | ], 15 | bootstrap: [ AppComponent ], 16 | }) 17 | export class AppServerModule {} 18 | -------------------------------------------------------------------------------- /src/app/configuration/configuration-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import {MainComponent} from './main/main.component'; 4 | import {SyncComponent} from './sync/sync.component'; 5 | import {ConnectionTypesComponent} from './connection-types/connection-types.component'; 6 | import {FluentComponent} from './fluent/fluent.component'; 7 | 8 | const routes: Routes = [ 9 | { path: 'main', component: MainComponent }, 10 | { path: 'sync', component: SyncComponent }, 11 | { path: 'connection-types', component: ConnectionTypesComponent }, 12 | { path: 'fluent', component: FluentComponent }, 13 | { path: '', pathMatch: 'full', redirectTo: 'main' } 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [RouterModule.forChild(routes)], 18 | exports: [RouterModule] 19 | }) 20 | export class ConfigurationRoutingModule { } 21 | -------------------------------------------------------------------------------- /src/app/configuration/configuration.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | 3 | import {ConfigurationRoutingModule} from './configuration-routing.module'; 4 | import {MainComponent} from './main/main.component'; 5 | import {SharedModule} from '../shared.module'; 6 | import {FormsModule} from '@angular/forms'; 7 | import {SyncComponent} from './sync/sync.component'; 8 | import {ConnectionTypesComponent} from './connection-types/connection-types.component'; 9 | import { FluentComponent } from './fluent/fluent.component'; 10 | 11 | 12 | @NgModule({ 13 | declarations: [MainComponent, SyncComponent, ConnectionTypesComponent, FluentComponent], 14 | imports: [ 15 | SharedModule, 16 | FormsModule, 17 | ConfigurationRoutingModule 18 | ] 19 | }) 20 | export class ConfigurationModule { } 21 | -------------------------------------------------------------------------------- /src/app/configuration/connection-types/connection-types.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/configuration/connection-types/connection-types.component.less -------------------------------------------------------------------------------- /src/app/configuration/connection-types/connection-types.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ConnectionTypesComponent } from './connection-types.component'; 4 | 5 | describe('ConnectionTypesComponent', () => { 6 | let component: ConnectionTypesComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ConnectionTypesComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ConnectionTypesComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/configuration/connection-types/connection-types.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-connection-types', 5 | templateUrl: './connection-types.component.html', 6 | styleUrls: ['./connection-types.component.less'] 7 | }) 8 | export class ConnectionTypesComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | setConnectionType(type: string) { 16 | localStorage.setItem('connectionType', type); 17 | location.reload(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/app/configuration/fluent/fluent.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/configuration/fluent/fluent.component.less -------------------------------------------------------------------------------- /src/app/configuration/fluent/fluent.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FluentComponent } from './fluent.component'; 4 | 5 | describe('FluentComponent', () => { 6 | let component: FluentComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ FluentComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(FluentComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/configuration/fluent/fluent.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-fluent', 5 | templateUrl: './fluent.component.html', 6 | styleUrls: ['./fluent.component.less'] 7 | }) 8 | export class FluentComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/configuration/main/main.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/configuration/main/main.component.less -------------------------------------------------------------------------------- /src/app/configuration/main/main.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { MainComponent } from './main.component'; 4 | 5 | describe('MainComponent', () => { 6 | let component: MainComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ MainComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(MainComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/configuration/main/main.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {SapphireDbService} from 'ng-sapphiredb'; 3 | import {Observable, of, Subject} from 'rxjs'; 4 | import {debounce, debounceTime, filter, map, switchMap} from 'rxjs/operators'; 5 | 6 | @Component({ 7 | selector: 'app-main', 8 | templateUrl: './main.component.html', 9 | styleUrls: ['./main.component.less'] 10 | }) 11 | export class MainComponent implements OnInit { 12 | 13 | input$ = new Subject(); 14 | hash$: Observable; 15 | 16 | constructor(private db: SapphireDbService) { } 17 | 18 | ngOnInit() { 19 | this.hash$ = this.input$.pipe( 20 | debounceTime(200), 21 | filter(v => !!v), 22 | switchMap((v) => { 23 | return this.db.execute('Example.CreateHash', v).pipe( 24 | map(r => r.result) 25 | ); 26 | }) 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/app/configuration/sync/sync.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/configuration/sync/sync.component.less -------------------------------------------------------------------------------- /src/app/configuration/sync/sync.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SyncComponent } from './sync.component'; 4 | 5 | describe('NlbComponent', () => { 6 | let component: SyncComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ SyncComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(SyncComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/configuration/sync/sync.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-sync', 5 | templateUrl: './sync.component.html', 6 | styleUrls: ['./sync.component.less'] 7 | }) 8 | export class SyncComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/data/changes/changes.component.html: -------------------------------------------------------------------------------- 1 |

Changes

2 | 3 |

You can observe the changes of a collection by calling the method .changes()

4 | 5 | 6 |

Changes

7 |

8 | 9 | Created: {{ change.value | json }} 10 | 11 | 12 | Removed: {{ change.value | json }} 13 | 14 | 15 | Updated: {{ change.value | json }} 16 | 17 |

18 | 19 |

Values

20 | {{ values$ | async | json }}
21 | 22 |
23 | ;\n\n 27 | 28 | \tconstructor(private db: SapphireDbService) { }\n\n 29 | 30 | \tngOnInit() {\n 31 | \t\tthis.changes$ = this.db.collection('demo.entries').changes().pipe(\n 32 | \t\t\tfilter(v => v.responseType !== 'QueryResponse'),\n 33 | \t\t\tscan((arr, v) => [...arr, v], [])\n 34 | \t\t);\n 35 | \t}\n 36 | } 37 | ]]> 38 |
39 |
40 | -------------------------------------------------------------------------------- /src/app/data/changes/changes.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/changes/changes.component.less -------------------------------------------------------------------------------- /src/app/data/changes/changes.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ChangesComponent } from './changes.component'; 4 | 5 | describe('ChangesComponent', () => { 6 | let component: ChangesComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ChangesComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ChangesComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/changes/changes.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import { SapphireDbService } from 'ng-sapphiredb'; 3 | import {Observable} from 'rxjs'; 4 | import {DialogService} from 'ng-metro4'; 5 | import {filter, map, scan, shareReplay} from 'rxjs/operators'; 6 | import {ChangesResponse} from 'sapphiredb'; 7 | 8 | @Component({ 9 | selector: 'app-changes', 10 | templateUrl: './changes.component.html', 11 | styleUrls: ['./changes.component.less'] 12 | }) 13 | export class ChangesComponent implements OnInit { 14 | 15 | changes$: Observable; 16 | values$: Observable; 17 | 18 | constructor(private db: SapphireDbService, private dialogService: DialogService) { } 19 | 20 | ngOnInit() { 21 | this.values$ = this.db.collection('demo.entries').values(); 22 | 23 | this.changes$ = this.db.collection('demo.entries').changes().pipe( 24 | filter(v => v.responseType !== 'QueryResponse'), 25 | map((r: ChangesResponse) => r.changes), 26 | scan((arr, v) => [...arr, ...v].Reverse().Take(10).Reverse(), []) 27 | ); 28 | } 29 | 30 | addValue() { 31 | this.dialogService.prompt('Content', 'Please enter a new content').subscribe((v) => { 32 | this.db.collection('demo.entries').add({ 33 | content: v 34 | }); 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/app/data/class-transformer/class-transformer.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/class-transformer/class-transformer.component.less -------------------------------------------------------------------------------- /src/app/data/class-transformer/class-transformer.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ClassTransformerComponent } from './class-transformer.component'; 4 | 5 | describe('ClassTransformerComponent', () => { 6 | let component: ClassTransformerComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ClassTransformerComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ClassTransformerComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/class-transformer/class-transformer.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {DefaultCollection, PrimaryKey} from 'sapphiredb'; 3 | import {SapphireDbService} from 'ng-sapphiredb'; 4 | import {Observable} from 'rxjs'; 5 | import {Transform} from 'class-transformer'; 6 | 7 | class ExampleEntry { 8 | @PrimaryKey() 9 | id?: string; 10 | 11 | @Transform((v: string) => parseInt(v, null), { toClassOnly: true }) 12 | @Transform((v: number) => `123${v}`, { toPlainOnly: true }) 13 | content: number; 14 | 15 | constructor() { 16 | this.content = 126; 17 | } 18 | } 19 | 20 | @Component({ 21 | selector: 'app-class-transformer', 22 | templateUrl: './class-transformer.component.html', 23 | styleUrls: ['./class-transformer.component.less'] 24 | }) 25 | export class ClassTransformerComponent implements OnInit { 26 | 27 | collection: DefaultCollection; 28 | values$: Observable; 29 | 30 | constructor(private db: SapphireDbService) { } 31 | 32 | ngOnInit() { 33 | this.collection = this.db.collection('demo.entries', ExampleEntry); 34 | this.values$ = this.collection.values(); 35 | } 36 | 37 | add() { 38 | this.collection.add(new ExampleEntry()); 39 | } 40 | 41 | update(value: ExampleEntry) { 42 | this.collection.update([value, { content: 34 }]); 43 | } 44 | 45 | remove(value: ExampleEntry) { 46 | this.collection.remove(value); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/app/data/conflict-handling/conflict-handling.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/conflict-handling/conflict-handling.component.less -------------------------------------------------------------------------------- /src/app/data/conflict-handling/conflict-handling.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ConflictHandlingComponent } from './conflict-handling.component'; 4 | 5 | describe('ConflictHandlingComponent', () => { 6 | let component: ConflictHandlingComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ConflictHandlingComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ConflictHandlingComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/conflict-handling/conflict-handling.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-conflict-handling', 5 | templateUrl: './conflict-handling.component.html', 6 | styleUrls: ['./conflict-handling.component.less'] 7 | }) 8 | export class ConflictHandlingComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit(): void { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/data/count/count.component.html: -------------------------------------------------------------------------------- 1 |

Count data

2 | 3 |

4 | You can use the count prefilter to count the values of your collection. 5 |

6 | 7 |
8 | Note that the usage of the prefilter types Take, Skip, Select, Count and First 9 | will require the collection data to always get queried from the database on every change. Keep that in mind when creating performance critical tasks. 10 |
11 | 12 | 13 | {{ values$ | async | json }}
14 | 15 |
16 | ;\n 20 | 21 | \tconstructor(private db: SapphireDbService) { }\n\n 22 | 23 | \tngOnInit() {\n 24 | \t\tthis.values$ = this.db.collection('entries')\n 25 | \t\t\t.count()\n 26 | \t\t\t.values();\n 27 | \t}\n 28 | } 29 | ]]> 30 |
31 |
32 | 33 | -------------------------------------------------------------------------------- /src/app/data/count/count.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/count/count.component.less -------------------------------------------------------------------------------- /src/app/data/count/count.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { CountComponent } from './count.component'; 4 | 5 | describe('CountComponent', () => { 6 | let component: CountComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ CountComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(CountComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/count/count.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {Observable} from 'rxjs'; 3 | import {DialogService} from 'ng-metro4'; 4 | import { SapphireDbService } from 'ng-sapphiredb'; 5 | 6 | @Component({ 7 | selector: 'app-count', 8 | templateUrl: './count.component.html', 9 | styleUrls: ['./count.component.less'] 10 | }) 11 | export class CountComponent implements OnInit { 12 | 13 | 14 | values$: Observable; 15 | 16 | constructor(private db: SapphireDbService, private dialogService: DialogService) { } 17 | 18 | ngOnInit() { 19 | this.values$ = this.db.collection('demo.entries') 20 | .count() 21 | .values(); 22 | } 23 | 24 | addValue() { 25 | this.dialogService.prompt('Content', 'Please enter a new content').subscribe((v) => { 26 | this.db.collection('demo.entries').add({ 27 | content: v 28 | }); 29 | }); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/app/data/data.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | 3 | import {DataRoutingModule} from './data-routing.module'; 4 | import {SharedModule} from '../shared.module'; 5 | import {QueryComponent} from './query/query.component'; 6 | import {ManageComponent} from './manage/manage.component'; 7 | import {PrefilterComponent} from './prefilter/prefilter.component'; 8 | import {WhereComponent} from './where/where.component'; 9 | import {OrderComponent} from './order/order.component'; 10 | import {LimitComponent} from './limit/limit.component'; 11 | import {SelectComponent} from './select/select.component'; 12 | import {CountComponent} from './count/count.component'; 13 | import {EventsComponent} from './events/events.component'; 14 | import {ChangesComponent} from './changes/changes.component'; 15 | import {IncludeComponent} from './include/include.component'; 16 | import { ClassTransformerComponent } from './class-transformer/class-transformer.component'; 17 | import { ModelValidationComponent } from './model-validation/model-validation.component'; 18 | import { OfflineComponent } from './offline/offline.component'; 19 | import { ConflictHandlingComponent } from './conflict-handling/conflict-handling.component'; 20 | import { ModelDefinitionComponent } from './model-definition/model-definition.component'; 21 | import { ServerSideQueryComponent } from './server-side-query/server-side-query.component'; 22 | 23 | 24 | @NgModule({ 25 | declarations: [QueryComponent, ManageComponent, PrefilterComponent, WhereComponent, OrderComponent, LimitComponent, SelectComponent, CountComponent, EventsComponent, ChangesComponent, IncludeComponent, ClassTransformerComponent, ModelValidationComponent, OfflineComponent, ConflictHandlingComponent, ModelDefinitionComponent, ServerSideQueryComponent], 26 | imports: [ 27 | SharedModule, 28 | DataRoutingModule 29 | ] 30 | }) 31 | export class DataModule { } 32 | -------------------------------------------------------------------------------- /src/app/data/events/events.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/events/events.component.less -------------------------------------------------------------------------------- /src/app/data/events/events.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { EventsComponent } from './events.component'; 4 | 5 | describe('EventsComponent', () => { 6 | let component: EventsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ EventsComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(EventsComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/events/events.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {DefaultCollection} from 'sapphiredb'; 3 | import { SapphireDbService } from 'ng-sapphiredb'; 4 | import {Observable} from 'rxjs'; 5 | 6 | @Component({ 7 | selector: 'app-events', 8 | templateUrl: './events.component.html', 9 | styleUrls: ['./events.component.less'] 10 | }) 11 | export class EventsComponent implements OnInit { 12 | 13 | collection: DefaultCollection; 14 | values$: Observable; 15 | logs$: Observable; 16 | 17 | constructor(private db: SapphireDbService) { } 18 | 19 | ngOnInit() { 20 | this.collection = this.db.collection('demo.eventDemos'); 21 | this.values$ = this.collection.values(); 22 | this.logs$ = this.db.collection('demo.logs').values(); 23 | } 24 | 25 | create() { 26 | this.collection.add({ 27 | content: 'Test 123' 28 | }); 29 | } 30 | 31 | update(value: any) { 32 | this.collection.update([value, { 33 | content: 'Updated content' 34 | }]); 35 | } 36 | 37 | remove(value: any) { 38 | this.collection.remove(value); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/app/data/include/include.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/include/include.component.less -------------------------------------------------------------------------------- /src/app/data/include/include.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { IncludeComponent } from './include.component'; 4 | 5 | describe('IncludeComponent', () => { 6 | let component: IncludeComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ IncludeComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(IncludeComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/limit/limit.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/limit/limit.component.less -------------------------------------------------------------------------------- /src/app/data/limit/limit.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { LimitComponent } from './limit.component'; 4 | 5 | describe('LimitComponent', () => { 6 | let component: LimitComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ LimitComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(LimitComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/limit/limit.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {Observable} from 'rxjs'; 3 | import {DialogService} from 'ng-metro4'; 4 | import { SapphireDbService } from 'ng-sapphiredb'; 5 | 6 | @Component({ 7 | selector: 'app-limit', 8 | templateUrl: './limit.component.html', 9 | styleUrls: ['./limit.component.less'] 10 | }) 11 | export class LimitComponent implements OnInit { 12 | 13 | values$: Observable; 14 | values2$: Observable; 15 | valueFirst$: Observable; 16 | 17 | constructor(private db: SapphireDbService, private dialogService: DialogService) { } 18 | 19 | ngOnInit() { 20 | this.values$ = this.db.collection('demo.entries') 21 | .take(5) 22 | .values(); 23 | 24 | this.values2$ = this.db.collection('demo.entries') 25 | .skip(5) 26 | .values(); 27 | 28 | this.valueFirst$ = this.db.collection('demo.entries') 29 | .first() 30 | .values(); 31 | } 32 | 33 | addValue() { 34 | this.dialogService.prompt('Content', 'Please enter a new content').subscribe((v) => { 35 | this.db.collection('demo.entries').add({ 36 | content: v 37 | }); 38 | }); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/app/data/manage/manage.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/manage/manage.component.less -------------------------------------------------------------------------------- /src/app/data/manage/manage.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ManageComponent } from './manage.component'; 4 | 5 | describe('ManageComponent', () => { 6 | let component: ManageComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ManageComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ManageComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/model-definition/model-definition.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/model-definition/model-definition.component.less -------------------------------------------------------------------------------- /src/app/data/model-definition/model-definition.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ModelDefinitionComponent } from './model-definition.component'; 4 | 5 | describe('ModelDefinitionComponent', () => { 6 | let component: ModelDefinitionComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ModelDefinitionComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ModelDefinitionComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/model-definition/model-definition.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-model-definition', 5 | templateUrl: './model-definition.component.html', 6 | styleUrls: ['./model-definition.component.less'] 7 | }) 8 | export class ModelDefinitionComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit(): void { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/data/model-validation/model-validation.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/model-validation/model-validation.component.less -------------------------------------------------------------------------------- /src/app/data/model-validation/model-validation.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ModelValidationComponent } from './model-validation.component'; 4 | 5 | describe('ModelValidationComponent', () => { 6 | let component: ModelValidationComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ModelValidationComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ModelValidationComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/offline/offline.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/offline/offline.component.less -------------------------------------------------------------------------------- /src/app/data/offline/offline.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { OfflineComponent } from './offline.component'; 4 | 5 | describe('OfflineComponent', () => { 6 | let component: OfflineComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ OfflineComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OfflineComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/offline/offline.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-offline', 5 | templateUrl: './offline.component.html', 6 | styleUrls: ['./offline.component.less'] 7 | }) 8 | export class OfflineComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/data/order/order.component.html: -------------------------------------------------------------------------------- 1 |

Order data - OrderBy/ThenOrderBy prefilter

2 | 3 |

4 | You can use the orderBy-prefilter to change the ordering of the data the server returns.
5 | Pass the property name you want to sort by. 6 |

7 | 8 |

9 | In this example the values are sorted by content. The first example is in ascending order, the second in descending order. 10 |

11 | 12 | 13 | {{ values$ | async | json }}

14 | {{ values2$ | async | json }}
15 | 16 |
17 | ;\n 21 | \tvalues2$: Observable;\n\n 22 | 23 | \tconstructor(private db: SapphireDbService) { }\n\n 24 | 25 | \tngOnInit() {\n 26 | \t\tthis.values$ = this.db.collection('entries')\n 27 | \t\t\t.orderBy('content', SortDirection.ascending)\n 28 | \t\t\t.values();\n\n 29 | 30 | \t\tthis.values2$ = this.db.collection('entries')\n 31 | \t\t\t.orderBy('content', SortDirection.descending)\n 32 | \t\t\t.values();\n 33 | \t}\n 34 | } 35 | ]]> 36 |
37 |
38 | 39 |
40 | The second parameter of the method is used to define the direction of sorting. If false the values are sorted in ascending order, if true in descending order. 41 |
42 | 43 |
44 | If you want to sort by more than one object use thenOrderBy for following sorting statements. 45 |
46 | 47 | Continue with limit prefilters 48 | -------------------------------------------------------------------------------- /src/app/data/order/order.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/order/order.component.less -------------------------------------------------------------------------------- /src/app/data/order/order.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { OrderComponent } from './order.component'; 4 | 5 | describe('OrderComponent', () => { 6 | let component: OrderComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ OrderComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OrderComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/order/order.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {Observable} from 'rxjs'; 3 | import {DialogService} from 'ng-metro4'; 4 | import { SortDirection} from 'sapphiredb'; 5 | import { SapphireDbService } from 'ng-sapphiredb'; 6 | 7 | @Component({ 8 | selector: 'app-order', 9 | templateUrl: './order.component.html', 10 | styleUrls: ['./order.component.less'] 11 | }) 12 | export class OrderComponent implements OnInit { 13 | 14 | values$: Observable; 15 | values2$: Observable; 16 | 17 | constructor(private db: SapphireDbService, private dialogService: DialogService) { } 18 | 19 | ngOnInit() { 20 | this.values$ = this.db.collection('demo.entries') 21 | .orderBy('content', SortDirection.ascending) 22 | .values(); 23 | 24 | this.values2$ = this.db.collection('demo.entries') 25 | .orderBy('content', SortDirection.descending) 26 | .values(); 27 | } 28 | 29 | addValue() { 30 | this.dialogService.prompt('Content', 'Please enter a new content').subscribe((v) => { 31 | this.db.collection('demo.entries').add({ 32 | content: v 33 | }); 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/app/data/prefilter/prefilter.component.html: -------------------------------------------------------------------------------- 1 |

Prefilters

2 | 3 |

SapphireDb comes with several prefilters that are executed on server side. You can use them to filter, order or select your data.

4 | 5 |

6 | The usage is very easy. Just use the extension methods on the collection. 7 |

8 | 9 |

10 | In this small example only values that start with testValue are queried. 11 |

12 | 13 | 14 | {{ values$ | async | json }}
15 | 16 |
17 | ;\n\n 21 | 22 | \tconstructor(private db: SapphireDbService) { }\n\n 23 | 24 | \tngOnInit() {\n 25 | \t\tthis.values$ = this.db.collection('entries')}\n 26 | \t\t\t.where(['content', 'StartsWith', 'testValue'])\n 27 | \t\t\t.values();\n 28 | \t}\n 29 | } 30 | ]]> 31 |
32 |
33 | 34 | Continue with where prefilter 35 | -------------------------------------------------------------------------------- /src/app/data/prefilter/prefilter.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/prefilter/prefilter.component.less -------------------------------------------------------------------------------- /src/app/data/prefilter/prefilter.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { PrefilterComponent } from './prefilter.component'; 4 | 5 | describe('PrefilterComponent', () => { 6 | let component: PrefilterComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ PrefilterComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(PrefilterComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/prefilter/prefilter.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {Observable} from 'rxjs'; 3 | import {DialogService} from 'ng-metro4'; 4 | import { SapphireDbService } from 'ng-sapphiredb'; 5 | 6 | @Component({ 7 | selector: 'app-prefilter', 8 | templateUrl: './prefilter.component.html', 9 | styleUrls: ['./prefilter.component.less'] 10 | }) 11 | export class PrefilterComponent implements OnInit { 12 | 13 | values$: Observable; 14 | 15 | constructor(private db: SapphireDbService, private dialogService: DialogService) { } 16 | 17 | ngOnInit() { 18 | this.values$ = this.db.collection('demo.entries') 19 | .where(['content', 'StartsWith', 'testValue']) 20 | .values(); 21 | } 22 | 23 | addValue() { 24 | this.dialogService.prompt('Content', 'Please enter a new content').subscribe((v) => { 25 | this.db.collection('demo.entries').add({ 26 | content: v 27 | }); 28 | }); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/app/data/query/query.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/query/query.component.less -------------------------------------------------------------------------------- /src/app/data/query/query.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { QueryComponent } from './query.component'; 4 | 5 | describe('QueryComponent', () => { 6 | let component: QueryComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ QueryComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(QueryComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/query/query.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { SapphireDbService } from 'ng-sapphiredb'; 3 | import {Observable} from 'rxjs'; 4 | import {DialogService} from 'ng-metro4'; 5 | import {shareReplay, take} from 'rxjs/operators'; 6 | 7 | @Component({ 8 | selector: 'app-query', 9 | templateUrl: './query.component.html', 10 | styleUrls: ['./query.component.less'] 11 | }) 12 | export class QueryComponent implements OnInit { 13 | 14 | values$: Observable; 15 | valuesSnapshot$: Observable; 16 | 17 | constructor(private db: SapphireDbService, private dialogService: DialogService) { } 18 | 19 | ngOnInit() { 20 | this.values$ = this.db.collection('demo.entries').values(); 21 | this.valuesSnapshot$ = this.db.collection('demo.entries').snapshot(); 22 | } 23 | 24 | addValue() { 25 | this.dialogService.prompt('Content', 'Please enter a new content').subscribe((v) => { 26 | this.db.collection('demo.entries').add({ 27 | content: v 28 | }); 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/app/data/select/select.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/select/select.component.less -------------------------------------------------------------------------------- /src/app/data/select/select.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SelectComponent } from './select.component'; 4 | 5 | describe('SelectComponent', () => { 6 | let component: SelectComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ SelectComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(SelectComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/select/select.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {Observable} from 'rxjs'; 3 | import {DialogService} from 'ng-metro4'; 4 | import { SapphireDbService } from 'ng-sapphiredb'; 5 | 6 | @Component({ 7 | selector: 'app-select', 8 | templateUrl: './select.component.html', 9 | styleUrls: ['./select.component.less'] 10 | }) 11 | export class SelectComponent implements OnInit { 12 | 13 | values$: Observable; 14 | values2$: Observable; 15 | 16 | constructor(private db: SapphireDbService, private dialogService: DialogService) { } 17 | 18 | ngOnInit() { 19 | this.values$ = this.db.collection('demo.entries') 20 | .select('content') 21 | .values(); 22 | 23 | this.values2$ = this.db.collection('demo.entries') 24 | .select('content', 'id') 25 | .values(); 26 | } 27 | 28 | addValue() { 29 | this.dialogService.prompt('Content', 'Please enter a new content').subscribe((v) => { 30 | this.db.collection('demo.entries').add({ 31 | content: v 32 | }); 33 | }); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/app/data/server-side-query/server-side-query.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/server-side-query/server-side-query.component.less -------------------------------------------------------------------------------- /src/app/data/server-side-query/server-side-query.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ServerSideQueryComponent } from './server-side-query.component'; 4 | 5 | describe('ServerSideQueryComponent', () => { 6 | let component: ServerSideQueryComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ServerSideQueryComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ServerSideQueryComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/server-side-query/server-side-query.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {SapphireDbService} from 'ng-sapphiredb'; 3 | import {Observable} from 'rxjs'; 4 | import {QueryCollection, SapphireOfflineEntity} from 'sapphiredb'; 5 | import {DialogService} from 'ng-metro4'; 6 | 7 | @Component({ 8 | selector: 'app-server-side-query', 9 | templateUrl: './server-side-query.component.html', 10 | styleUrls: ['./server-side-query.component.less'] 11 | }) 12 | export class ServerSideQueryComponent implements OnInit { 13 | 14 | collection: QueryCollection; 15 | values$: Observable; 16 | snapshot$: Observable; 17 | 18 | defaultQueryCollection: QueryCollection; 19 | defaultQueryValues$: Observable; 20 | 21 | constructor(private db: SapphireDbService, private dialogService: DialogService) { 22 | this.collection = this.db.query('demo.entries.only_test'); 23 | this.values$ = this.collection.values(); 24 | this.snapshot$ = this.collection.snapshot(); 25 | 26 | this.defaultQueryCollection = this.db.query('demo.serverSideQueryWithDefaults.by_content'); 27 | this.defaultQueryValues$ = this.defaultQueryCollection.values(); 28 | } 29 | 30 | addValue() { 31 | this.dialogService.prompt('Content', 'Please enter a new content').subscribe((v) => { 32 | this.collection.add({ 33 | ...new SapphireOfflineEntity(), 34 | content: v, 35 | }); 36 | }); 37 | } 38 | 39 | addValueDefaultQuery() { 40 | this.dialogService.prompt('Content', 'Please enter a new content').subscribe((v) => { 41 | this.defaultQueryCollection.add({ 42 | ...new SapphireOfflineEntity(), 43 | content: v, 44 | }); 45 | }); 46 | } 47 | 48 | deleteDefaultQueryValue(entry: any) { 49 | this.defaultQueryCollection.remove(entry); 50 | } 51 | 52 | ngOnInit(): void { 53 | 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/app/data/where/where.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/data/where/where.component.less -------------------------------------------------------------------------------- /src/app/data/where/where.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { WhereComponent } from './where.component'; 4 | 5 | describe('WhereComponent', () => { 6 | let component: WhereComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ WhereComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(WhereComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/data/where/where.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {Observable, ReplaySubject} from 'rxjs'; 3 | import {DialogService} from 'ng-metro4'; 4 | import { SapphireDbService } from 'ng-sapphiredb'; 5 | import {switchMap} from 'rxjs/operators'; 6 | 7 | @Component({ 8 | selector: 'app-where', 9 | templateUrl: './where.component.html', 10 | styleUrls: ['./where.component.less'] 11 | }) 12 | export class WhereComponent implements OnInit { 13 | id: string; 14 | id$ = new ReplaySubject(); 15 | valueById$: Observable; 16 | 17 | values$: Observable; 18 | values2$: Observable; 19 | 20 | constructor(private db: SapphireDbService, private dialogService: DialogService) { } 21 | 22 | ngOnInit() { 23 | this.values$ = this.db.collection('demo.entries') 24 | .where(['content', 'StartsWith', 'testV']) 25 | .values(); 26 | 27 | this.values2$ = this.db.collection('demo.entries') 28 | .where([ 29 | [['content', 'StartsWith', 'test'], 'and', ['content', 'EndsWith', 'V']], 30 | 'or', 31 | [['content', 'StartsWith', 'var'], 'and', ['content', 'EndsWith', '2']] 32 | ]) 33 | .values(); 34 | 35 | this.valueById$ = this.id$.pipe( 36 | switchMap((id: any) => { 37 | return this.db.collection('demo.entries').where(['id', '==', id]).first().values(); 38 | }) 39 | ); 40 | } 41 | 42 | addValue() { 43 | this.dialogService.prompt('Content', 'Please enter a new content').subscribe((v) => { 44 | this.db.collection('demo.entries').add({ 45 | content: v 46 | }); 47 | }); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/app/demos/chat/chat.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/demos/chat/chat.component.less -------------------------------------------------------------------------------- /src/app/demos/chat/chat.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ChatComponent } from './chat.component'; 4 | 5 | describe('ChatComponent', () => { 6 | let component: ChatComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ChatComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ChatComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/demos/chat/chat.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {DefaultCollection} from 'sapphiredb'; 3 | import {combineLatest, Observable, of, ReplaySubject, Subject} from 'rxjs'; 4 | import {debounceTime, switchMap} from 'rxjs/operators'; 5 | import { SapphireDbService } from 'ng-sapphiredb'; 6 | 7 | interface Message { 8 | from: string; 9 | to: string; 10 | content: string; 11 | createdOn?: string; 12 | id?: string; 13 | } 14 | 15 | @Component({ 16 | selector: 'app-chat', 17 | templateUrl: './chat.component.html', 18 | styleUrls: ['./chat.component.less'] 19 | }) 20 | export class ChatComponent implements OnInit { 21 | from: string; 22 | to: string; 23 | message: string; 24 | 25 | from$ = new ReplaySubject(); 26 | to$ = new ReplaySubject(); 27 | 28 | messages$: Observable; 29 | 30 | messageCollection: DefaultCollection; 31 | 32 | constructor(private db: SapphireDbService) { } 33 | 34 | ngOnInit() { 35 | this.messageCollection = this.db.collection('demo.messages'); 36 | 37 | this.messages$ = combineLatest([this.from$, this.to$]).pipe( 38 | debounceTime(200), 39 | switchMap(([from, to]: [string, string]) => { 40 | if (!from || !to) { 41 | return of([]); 42 | } 43 | 44 | return this.messageCollection 45 | .where([[['from', '==', from], 'and', ['to', '==', to]], 'or', [['from', '==', to], 'and', ['to', '==', from]]]) 46 | .values(); 47 | }) 48 | ); 49 | } 50 | 51 | send() { 52 | if (!!this.message) { 53 | this.messageCollection.add({ 54 | from: this.from, 55 | to: this.to, 56 | content: this.message 57 | }); 58 | 59 | this.message = ''; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/app/demos/demos-routing.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {RouterModule, Routes} from '@angular/router'; 3 | import {ChatComponent} from './chat/chat.component'; 4 | import {EditorComponent} from './editor/editor.component'; 5 | import {PixelsComponent} from './pixels/pixels.component'; 6 | import {ExamplesComponent} from './examples/examples.component'; 7 | 8 | 9 | const routes: Routes = [ 10 | { path: 'chat', component: ChatComponent }, 11 | { path: 'editor', component: EditorComponent }, 12 | { path: 'pixels', component: PixelsComponent }, 13 | { path: 'examples', component: ExamplesComponent } 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [RouterModule.forChild(routes)], 18 | exports: [RouterModule] 19 | }) 20 | export class DemosRoutingModule { } 21 | -------------------------------------------------------------------------------- /src/app/demos/demos.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | 3 | import {DemosRoutingModule} from './demos-routing.module'; 4 | import {SharedModule} from '../shared.module'; 5 | import {ChatComponent} from './chat/chat.component'; 6 | import {EditorComponent} from './editor/editor.component'; 7 | import {PixelsComponent} from './pixels/pixels.component'; 8 | import {ExamplesComponent} from './examples/examples.component'; 9 | 10 | 11 | @NgModule({ 12 | declarations: [ChatComponent, EditorComponent, PixelsComponent, ExamplesComponent], 13 | imports: [ 14 | SharedModule, 15 | DemosRoutingModule 16 | ] 17 | }) 18 | export class DemosModule { } 19 | -------------------------------------------------------------------------------- /src/app/demos/editor/editor.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/demos/editor/editor.component.less -------------------------------------------------------------------------------- /src/app/demos/editor/editor.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { EditorComponent } from './editor.component'; 4 | 5 | describe('EditorComponent', () => { 6 | let component: EditorComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ EditorComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(EditorComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/demos/editor/editor.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {CreateRangeResponse, DefaultCollection, SapphireOfflineEntity} from 'sapphiredb'; 3 | import {Observable, of, ReplaySubject} from 'rxjs'; 4 | import {debounceTime, filter, map, switchMap} from 'rxjs/operators'; 5 | import {SapphireDbService} from 'ng-sapphiredb'; 6 | 7 | interface Document { 8 | id?: string; 9 | name: string; 10 | content: string; 11 | } 12 | 13 | @Component({ 14 | selector: 'app-editor', 15 | templateUrl: './editor.component.html', 16 | styleUrls: ['./editor.component.less'] 17 | }) 18 | export class EditorComponent implements OnInit { 19 | 20 | collection: DefaultCollection; 21 | 22 | name: string; 23 | name$ = new ReplaySubject(); 24 | 25 | document$: Observable; 26 | 27 | constructor(private db: SapphireDbService) { } 28 | 29 | ngOnInit() { 30 | this.collection = this.db.collection('demo.documents'); 31 | 32 | this.document$ = this.name$.pipe( 33 | debounceTime(200), 34 | filter(v => !!v), 35 | switchMap((name: string) => { 36 | const documents$: Observable = this.collection 37 | .where(['name', '==', name]) 38 | .values(); 39 | 40 | return documents$.pipe( 41 | switchMap((documents: Document[]) => { 42 | const document = documents[0]; 43 | 44 | if (!!document) { 45 | return of(document); 46 | } 47 | 48 | return this.collection.add({ 49 | name: name, 50 | content: '', 51 | id: new SapphireOfflineEntity().id 52 | }).pipe( 53 | map((result: CreateRangeResponse) => result.results[0].value) 54 | ); 55 | }) 56 | ); 57 | }) 58 | ); 59 | } 60 | 61 | updateDocument(document: Document, content: string) { 62 | this.collection.update([document, { 63 | content: content 64 | }]); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/app/demos/examples/examples.component.html: -------------------------------------------------------------------------------- 1 |

Examples

2 | 3 |

This is a list of all example repositories

4 | 5 |

Server

6 | 7 | Asp.Net Core 8 | 9 |

Client

10 | 11 | Angular
12 | NodeJs
13 | React
14 | Svelte
15 | -------------------------------------------------------------------------------- /src/app/demos/examples/examples.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/demos/examples/examples.component.less -------------------------------------------------------------------------------- /src/app/demos/examples/examples.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ExamplesComponent } from './examples.component'; 4 | 5 | describe('ExamplesComponent', () => { 6 | let component: ExamplesComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ExamplesComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ExamplesComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/demos/examples/examples.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-examples', 5 | templateUrl: './examples.component.html', 6 | styleUrls: ['./examples.component.less'] 7 | }) 8 | export class ExamplesComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/demos/pixels/pixels.component.less: -------------------------------------------------------------------------------- 1 | @width: 100%; 2 | @height: 500px; 3 | @count: 10; 4 | 5 | .pixels { 6 | position: relative; 7 | width: @width; 8 | height: @height; 9 | 10 | .pixel { 11 | width: 100% / @count; 12 | height: @height / @count; 13 | float: left; 14 | position: relative; 15 | color: #ffffff; 16 | text-align: center; 17 | line-height: @height / 10 - 2px; 18 | user-select: none; 19 | 20 | &:hover { 21 | cursor: pointer; 22 | } 23 | 24 | &::after { 25 | position: absolute; 26 | left: 0; 27 | top: 0; 28 | content: ''; 29 | width: 100%; 30 | height: 100%; 31 | border: 1px solid #ffffff; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/app/demos/pixels/pixels.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { PixelsComponent } from './pixels.component'; 4 | 5 | describe('PixelsComponent', () => { 6 | let component: PixelsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ PixelsComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(PixelsComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/demos/pixels/pixels.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {DefaultCollection} from 'sapphiredb'; 3 | import {Observable} from 'rxjs'; 4 | import {take} from 'rxjs/operators'; 5 | import {Lists} from 'ng-metro4'; 6 | import { SapphireDbService } from 'ng-sapphiredb'; 7 | 8 | interface Pixel { 9 | id?: string; 10 | color: string; 11 | x: number; 12 | y: number; 13 | } 14 | 15 | @Component({ 16 | selector: 'app-pixels', 17 | templateUrl: './pixels.component.html', 18 | styleUrls: ['./pixels.component.less'] 19 | }) 20 | export class PixelsComponent implements OnInit { 21 | 22 | size = 10; 23 | showLabels = false; 24 | 25 | private collection: DefaultCollection; 26 | public pixels$: Observable; 27 | 28 | constructor(private db: SapphireDbService) { 29 | this.collection = this.db.collection('demo.pixels').orderBy('x').thenOrderBy('y'); 30 | this.pixels$ = this.collection.values(); 31 | } 32 | 33 | changeColor(pixel: Pixel, change: number) { 34 | const allColors = Lists.colors(); 35 | let colorIndex = allColors.indexOf(pixel.color); 36 | colorIndex = (colorIndex + change) % allColors.length; 37 | 38 | if (colorIndex < 0) { 39 | colorIndex = allColors.length - 1; 40 | } 41 | 42 | this.collection.update([pixel, { 43 | color: allColors[colorIndex] 44 | }]); 45 | return false; 46 | } 47 | 48 | reset(pixels: Pixel[]) { 49 | const updateValues: [Pixel, Partial][] = pixels.map((pixel) => { 50 | return [pixel, { 51 | color: 'darkBlue' 52 | }]; 53 | }); 54 | 55 | this.collection.update(...updateValues); 56 | } 57 | 58 | ngOnInit() { 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/app/messaging/main/main.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/messaging/main/main.component.less -------------------------------------------------------------------------------- /src/app/messaging/main/main.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { MainComponent } from './main.component'; 4 | 5 | describe('MainComponent', () => { 6 | let component: MainComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ MainComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(MainComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/messaging/main/main.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnDestroy, OnInit} from '@angular/core'; 2 | import {Observable} from 'rxjs'; 3 | import {SapphireDbService} from 'ng-sapphiredb'; 4 | import {map} from 'rxjs/operators'; 5 | 6 | @Component({ 7 | selector: 'app-main', 8 | templateUrl: './main.component.html', 9 | styleUrls: ['./main.component.less'] 10 | }) 11 | export class MainComponent implements OnInit, OnDestroy { 12 | message$: Observable; 13 | topic$: Observable; 14 | 15 | message: string; 16 | 17 | subscriptions = []; 18 | 19 | constructor(private db: SapphireDbService) { } 20 | 21 | ngOnInit() { 22 | this.message$ = this.db.messaging.messages(); 23 | this.topic$ = this.db.messaging.topic('test').pipe(map(r => r.message)); 24 | } 25 | 26 | send() { 27 | this.db.messaging.send(this.message); 28 | } 29 | 30 | publish() { 31 | this.db.messaging.publish('test', this.message, true); 32 | } 33 | 34 | ngOnDestroy(): void { 35 | this.subscriptions.forEach(s => s.unsubscribe()); 36 | this.subscriptions = []; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/app/messaging/messaging-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import {MainComponent} from './main/main.component'; 4 | 5 | 6 | const routes: Routes = [ 7 | { path: 'main', component: MainComponent }, 8 | { path: '', pathMatch: 'full', redirectTo: 'main' } 9 | ]; 10 | 11 | @NgModule({ 12 | imports: [RouterModule.forChild(routes)], 13 | exports: [RouterModule] 14 | }) 15 | export class MessagingRoutingModule { } 16 | -------------------------------------------------------------------------------- /src/app/messaging/messaging.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | 3 | import {MessagingRoutingModule} from './messaging-routing.module'; 4 | import {MainComponent} from './main/main.component'; 5 | import {SharedModule} from '../shared.module'; 6 | 7 | 8 | @NgModule({ 9 | declarations: [MainComponent], 10 | imports: [ 11 | SharedModule, 12 | MessagingRoutingModule 13 | ] 14 | }) 15 | export class MessagingModule { } 16 | -------------------------------------------------------------------------------- /src/app/security/create-auth/create-auth.component.html: -------------------------------------------------------------------------------- 1 |

Create - Authentication/Authorization

2 | 3 |

You can use the [CreateAuth]-Attribute to control the permission of a user to create data in the collection.

4 | 5 |

Usage

6 | 7 |

The [CreateAuth]-Attribute can be used on the model class

8 | 9 |
10 | Every auth-attribute can be used in three ways. 11 |
    12 |
  1. Without attributes: Authentication required
  2. 13 |
  3. 14 | Policies: A comma separated string of policy-names. All policies have to succeed. Check out 15 | Policies 16 | for more details 17 |
  4. 18 |
  5. Function name: You can optionally pass the name of a function in the class that has to return a boolean. The function will get executed to check if the user is allowed for the action.
  6. 19 |
20 | 21 | Multiple attributes: You can define multiple Attributes for each model. Only one of the attributes defined condition has to succeed.
22 | Heredity: If you define AuthAttributes for a base class all sub classes will inherit this attributes until custom attributes of the same type are defined in the subclasses. 23 |
24 | 25 |

The usage equals the usage of the [QueryAuth]-Attribute. Check out the Documentation for Query

26 | -------------------------------------------------------------------------------- /src/app/security/create-auth/create-auth.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/security/create-auth/create-auth.component.less -------------------------------------------------------------------------------- /src/app/security/create-auth/create-auth.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { CreateAuthComponent } from './create-auth.component'; 4 | 5 | describe('CreateAuthComponent', () => { 6 | let component: CreateAuthComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ CreateAuthComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(CreateAuthComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/security/create-auth/create-auth.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-create-auth', 5 | templateUrl: './create-auth.component.html', 6 | styleUrls: ['./create-auth.component.less'] 7 | }) 8 | export class CreateAuthComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/security/current-user/current-user.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Use this controls to change the login state

3 | 4 |

You are currently not logged in

5 | 6 | 7 |
8 | 9 |

Current user: {{ currentUser }}

10 | 11 |
12 |
13 | -------------------------------------------------------------------------------- /src/app/security/current-user/current-user.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/security/current-user/current-user.component.less -------------------------------------------------------------------------------- /src/app/security/current-user/current-user.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { CurrentUserComponent } from './current-user.component'; 4 | 5 | describe('CurrentUserComponent', () => { 6 | let component: CurrentUserComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ CurrentUserComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(CurrentUserComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/security/current-user/current-user.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {SapphireDbService} from 'ng-sapphiredb'; 3 | import {UserStateService} from '../user-state.service'; 4 | import {Observable} from 'rxjs'; 5 | 6 | @Component({ 7 | selector: 'app-current-user', 8 | templateUrl: './current-user.component.html', 9 | styleUrls: ['./current-user.component.less'] 10 | }) 11 | export class CurrentUserComponent implements OnInit { 12 | 13 | public currentUser$: Observable; 14 | 15 | constructor(private db: SapphireDbService, private userState: UserStateService) { } 16 | 17 | ngOnInit() { 18 | this.currentUser$ = this.userState.currentUser$; 19 | } 20 | 21 | login(username: string, password: string) { 22 | this.userState.login(username, password); 23 | } 24 | 25 | logout() { 26 | this.userState.logout(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/app/security/execute/execute.component.html: -------------------------------------------------------------------------------- 1 |

Execute - Authentication/Authorization

2 | 3 |

You can use the [ActionAuth]-Attribute to control the permission of a user to execute a specific action.

4 | 5 |

Usage

6 | 7 |

The [ActionAuth]-Attribute can be used on the action handler class or a single action

8 | 9 |
10 | Every auth-attribute can be used in three ways. 11 |
    12 |
  1. Without attributes: Authentication required
  2. 13 |
  3. 14 | Policies: A comma separated string of policy-names. All policies have to succeed. Check out 15 | Policies 16 | for more details 17 |
  4. 18 |
  5. Function name: You can optionally pass the name of a function in the class that has to return a boolean. The function will get executed to check if the user is allowed for the action.
  6. 19 |
20 |
21 | 22 |

The usage equals the usage of the [QueryAuth]-Attribute. Check out the Documentation for Query

23 | -------------------------------------------------------------------------------- /src/app/security/execute/execute.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/security/execute/execute.component.less -------------------------------------------------------------------------------- /src/app/security/execute/execute.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ExecuteComponent } from './execute.component'; 4 | 5 | describe('ExecuteComponent', () => { 6 | let component: ExecuteComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ExecuteComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ExecuteComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/security/execute/execute.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-execute', 5 | templateUrl: './execute.component.html', 6 | styleUrls: ['./execute.component.less'] 7 | }) 8 | export class ExecuteComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/security/general/general.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/security/general/general.component.less -------------------------------------------------------------------------------- /src/app/security/general/general.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GeneralComponent } from './general.component'; 4 | 5 | describe('GeneralComponent', () => { 6 | let component: GeneralComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ GeneralComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(GeneralComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/security/general/general.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-general', 5 | templateUrl: './general.component.html', 6 | styleUrls: ['./general.component.less'] 7 | }) 8 | export class GeneralComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/security/net-core/net-core.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/security/net-core/net-core.component.less -------------------------------------------------------------------------------- /src/app/security/net-core/net-core.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { NetCoreComponent } from './net-core.component'; 4 | 5 | describe('NetCoreComponent', () => { 6 | let component: NetCoreComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ NetCoreComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(NetCoreComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/security/net-core/net-core.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-net-core', 5 | templateUrl: './net-core.component.html', 6 | styleUrls: ['./net-core.component.less'] 7 | }) 8 | export class NetCoreComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/security/query-auth/query-auth.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/security/query-auth/query-auth.component.less -------------------------------------------------------------------------------- /src/app/security/query-auth/query-auth.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { QueryAuthComponent } from './query-auth.component'; 4 | 5 | describe('QueryAuthComponent', () => { 6 | let component: QueryAuthComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ QueryAuthComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(QueryAuthComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/security/remove-auth/remove-auth.component.html: -------------------------------------------------------------------------------- 1 |

Remove - Authentication/Authorization

2 | 3 |

You can use the [RemoveAuth]-Attribute to control the permission of a user to remove data from the collection.

4 | 5 |

Usage

6 | 7 |

The [RemoveAuth]-Attribute can be used on the model class

8 | 9 |
10 | Every auth-attribute can be used in three ways. 11 |
    12 |
  1. Without attributes: Authentication required
  2. 13 |
  3. 14 | Policies: A comma separated string of policy-names. All policies have to succeed. Check out 15 | Policies 16 | for more details 17 |
  4. 18 |
  5. Function name: You can optionally pass the name of a function in the class that has to return a boolean. The function will get executed to check if the user is allowed for the action.
  6. 19 |
20 | 21 | Multiple attributes: You can define multiple Attributes for each model. Only one of the attributes defined condition has to succeed.
22 | Heredity: If you define AuthAttributes for a base class all sub classes will inherit this attributes until custom attributes of the same type are defined in the subclasses. 23 |
24 | 25 |

The usage equals the usage of the [QueryAuth]-Attribute. Check out the Documentation for Query

26 | -------------------------------------------------------------------------------- /src/app/security/remove-auth/remove-auth.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/security/remove-auth/remove-auth.component.less -------------------------------------------------------------------------------- /src/app/security/remove-auth/remove-auth.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { RemoveAuthComponent } from './remove-auth.component'; 4 | 5 | describe('RemoveAuthComponent', () => { 6 | let component: RemoveAuthComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ RemoveAuthComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(RemoveAuthComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/security/remove-auth/remove-auth.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-remove-auth', 5 | templateUrl: './remove-auth.component.html', 6 | styleUrls: ['./remove-auth.component.less'] 7 | }) 8 | export class RemoveAuthComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/security/security-routing.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {RouterModule, Routes} from '@angular/router'; 3 | import {NetCoreComponent} from './net-core/net-core.component'; 4 | import {GeneralComponent} from './general/general.component'; 5 | import {QueryAuthComponent} from './query-auth/query-auth.component'; 6 | import {UpdateAuthComponent} from './update-auth/update-auth.component'; 7 | import {CreateAuthComponent} from './create-auth/create-auth.component'; 8 | import {RemoveAuthComponent} from './remove-auth/remove-auth.component'; 9 | import {ExecuteComponent} from './execute/execute.component'; 10 | 11 | const routes: Routes = [ 12 | { path: 'general', component: GeneralComponent }, 13 | { path: 'net-core', component: NetCoreComponent }, 14 | { path: 'query-auth', component: QueryAuthComponent }, 15 | { path: 'update-auth', component: UpdateAuthComponent }, 16 | { path: 'create-auth', component: CreateAuthComponent }, 17 | { path: 'remove-auth', component: RemoveAuthComponent }, 18 | { path: 'action-auth', component: ExecuteComponent }, 19 | { path: '', pathMatch: 'full', redirectTo: 'general' } 20 | ]; 21 | 22 | @NgModule({ 23 | imports: [RouterModule.forChild(routes)], 24 | exports: [RouterModule] 25 | }) 26 | export class SecurityRoutingModule { } 27 | -------------------------------------------------------------------------------- /src/app/security/security.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | 3 | import {SecurityRoutingModule} from './security-routing.module'; 4 | import {SharedModule} from '../shared.module'; 5 | import { NetCoreComponent } from './net-core/net-core.component'; 6 | 7 | import { GeneralComponent } from './general/general.component'; 8 | import { QueryAuthComponent } from './query-auth/query-auth.component'; 9 | import { CurrentUserComponent } from './current-user/current-user.component'; 10 | import {UserStateService} from './user-state.service'; 11 | import { UpdateAuthComponent } from './update-auth/update-auth.component'; 12 | import { CreateAuthComponent } from './create-auth/create-auth.component'; 13 | import { RemoveAuthComponent } from './remove-auth/remove-auth.component'; 14 | import { ExecuteComponent } from './execute/execute.component'; 15 | 16 | 17 | @NgModule({ 18 | declarations: [NetCoreComponent, GeneralComponent, QueryAuthComponent, CurrentUserComponent, UpdateAuthComponent, CreateAuthComponent, RemoveAuthComponent, ExecuteComponent], 19 | imports: [ 20 | SharedModule, 21 | SecurityRoutingModule 22 | ], 23 | providers: [ 24 | UserStateService 25 | ] 26 | }) 27 | export class SecurityModule { } 28 | -------------------------------------------------------------------------------- /src/app/security/update-auth/update-auth.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/security/update-auth/update-auth.component.less -------------------------------------------------------------------------------- /src/app/security/update-auth/update-auth.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { UpdateAuthComponent } from './update-auth.component'; 4 | 5 | describe('UpdateAuthComponent', () => { 6 | let component: UpdateAuthComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ UpdateAuthComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(UpdateAuthComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/security/user-state.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { UserStateService } from './user-state.service'; 4 | 5 | describe('UserStateService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: UserStateService = TestBed.get(UserStateService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/app/security/user-state.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {AuthTokenState} from 'sapphiredb'; 3 | import {SapphireDbService} from 'ng-sapphiredb'; 4 | import {BehaviorSubject} from 'rxjs'; 5 | import {filter, take} from 'rxjs/operators'; 6 | 7 | @Injectable() 8 | export class UserStateService { 9 | public currentUser$ = new BehaviorSubject(null); 10 | 11 | constructor(private db: SapphireDbService) { } 12 | 13 | public login(username: string, password: string) { 14 | this.db.execute('user.login', username, password).subscribe(response => { 15 | this.db.setAuthToken(response.result).pipe( 16 | filter(r => r !== AuthTokenState.validating), 17 | take(1) 18 | ).subscribe((result) => { 19 | if (result === AuthTokenState.valid) { 20 | this.currentUser$.next(username); 21 | } 22 | }); 23 | }); 24 | } 25 | 26 | public logout() { 27 | this.db.setAuthToken(); 28 | this.currentUser$.next(null); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/app/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import {DocComponent} from './shared/doc/doc.component'; 4 | import {NgMetro4Module} from 'ng-metro4'; 5 | import {HighlightModule} from 'ngx-highlightjs'; 6 | import {MarkdownModule} from 'ngx-markdown'; 7 | import {SanitizeHtmlPipe} from './shared/pipes/sanitize-html.pipe'; 8 | 9 | 10 | 11 | @NgModule({ 12 | declarations: [ 13 | DocComponent, 14 | SanitizeHtmlPipe 15 | ], 16 | imports: [ 17 | CommonModule, 18 | NgMetro4Module, 19 | HighlightModule, 20 | MarkdownModule 21 | ], 22 | exports: [ 23 | DocComponent, 24 | SanitizeHtmlPipe, 25 | NgMetro4Module, 26 | HighlightModule, 27 | MarkdownModule 28 | ] 29 | }) 30 | export class SharedModule { } 31 | -------------------------------------------------------------------------------- /src/app/shared/doc/doc.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |
6 |
7 | 8 |
9 |
10 | 11 |
12 | 33 |
34 | 35 |
36 |
37 |
38 |
39 |
40 |
41 | -------------------------------------------------------------------------------- /src/app/shared/doc/doc.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/shared/doc/doc.component.less -------------------------------------------------------------------------------- /src/app/shared/doc/doc.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { DocComponent } from './doc.component'; 4 | 5 | describe('DocComponent', () => { 6 | let component: DocComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ DocComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DocComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/shared/doc/doc.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, ComponentRef, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core'; 2 | import {SapphireOfflineEntity} from 'sapphiredb'; 3 | 4 | @Component({ 5 | selector: 'app-doc', 6 | templateUrl: './doc.component.html', 7 | styleUrls: ['./doc.component.less'] 8 | }) 9 | export class DocComponent implements OnInit, OnChanges { 10 | @Input() showContent = true; 11 | 12 | id = new SapphireOfflineEntity().id; 13 | contents: { lang: string, content: string, name: string, section?: string, nameNormalized: string }[][]; 14 | @ViewChild('langElement', {static: true}) langElementRef: ElementRef; 15 | 16 | constructor() { } 17 | 18 | compileTemplate() { 19 | if (this.langElementRef.nativeElement.innerText) { 20 | this.contents = this.langElementRef.nativeElement.innerText 21 | .split('\\f:(') 22 | .filter(v => !!v.trim()) 23 | .map(v => { 24 | const languageParts = ('\\f:(' + v).match(/\\f:\((.*?)\)/)[1].split(':'); 25 | 26 | return { 27 | name: languageParts[1], 28 | lang: languageParts[0], 29 | section: languageParts[2], 30 | nameNormalized: languageParts[1].split('.').join('') + '_id' + new SapphireOfflineEntity().id, 31 | content: v.substr(v.indexOf(')') + 1).split('\\n').map(l => { 32 | return l.trim().split('\\t').map(iv => iv.trim()).join(' '); 33 | }).join('\n') 34 | }; 35 | }) 36 | .GroupBy(v => v.section); 37 | } 38 | } 39 | 40 | ngOnInit() { 41 | this.compileTemplate(); 42 | } 43 | 44 | ngOnChanges(changes: SimpleChanges): void { 45 | this.compileTemplate(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/app/shared/legal-disclosure/legal-disclosure.component.html: -------------------------------------------------------------------------------- 1 |

Legal Disclosure

2 | Information in accordance with Section 5 TMG 3 |

Stockumer Strasse 179
44225 Dortmund
4 |

Contact Information

5 | Telephone: +49 160 8743916
E-Mail: m.janatzek@freenet.de
Internet address: morrisj.net

6 |

Disclaimer

7 | Accountability for content
8 | The contents of our pages have been created with the utmost care. However, we cannot guarantee the contents' 9 | accuracy, completeness or topicality. According to statutory provisions, we are furthermore responsible for 10 | our own content on these web pages. In this matter, please note that we are not obliged to monitor 11 | the transmitted or saved information of third parties, or investigate circumstances pointing to illegal activity. 12 | Our obligations to remove or block the use of information under generally applicable laws remain unaffected by this as per 13 | §§ 8 to 10 of the Telemedia Act (TMG). 14 | 15 |

Accountability for links
16 | Responsibility for the content of 17 | external links (to web pages of third parties) lies solely with the operators of the linked pages. No violations were 18 | evident to us at the time of linking. Should any legal infringement become known to us, we will remove the respective 19 | link immediately.

Copyright
Our web pages and their contents are subject to German copyright law. Unless 20 | expressly permitted by law, every form of utilizing, reproducing or processing 21 | works subject to copyright protection on our web pages requires the prior consent of the respective owner of the rights. 22 | Individual reproductions of a work are only allowed for private use. 23 | The materials from these pages are copyrighted and any unauthorized use may violate copyright laws. 24 | 25 |

26 | Quelle: translate-24h.de

27 | -------------------------------------------------------------------------------- /src/app/shared/legal-disclosure/legal-disclosure.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/shared/legal-disclosure/legal-disclosure.component.less -------------------------------------------------------------------------------- /src/app/shared/legal-disclosure/legal-disclosure.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { LegalDisclosureComponent } from './legal-disclosure.component'; 4 | 5 | describe('LegalDisclosureComponent', () => { 6 | let component: LegalDisclosureComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ LegalDisclosureComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(LegalDisclosureComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/shared/legal-disclosure/legal-disclosure.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-legal-disclosure', 5 | templateUrl: './legal-disclosure.component.html', 6 | styleUrls: ['./legal-disclosure.component.less'] 7 | }) 8 | export class LegalDisclosureComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/shared/pipes/sanitize-html.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import { SanitizeHtmlPipe } from './sanitize-html.pipe'; 2 | 3 | describe('SanitizeHtmlPipe', () => { 4 | it('create an instance', () => { 5 | const pipe = new SanitizeHtmlPipe(null); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/shared/pipes/sanitize-html.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | import {DomSanitizer, SafeHtml} from '@angular/platform-browser'; 3 | 4 | @Pipe({ 5 | name: 'sanitizeHtml' 6 | }) 7 | export class SanitizeHtmlPipe implements PipeTransform { 8 | 9 | constructor(private sanitizer: DomSanitizer) { 10 | 11 | } 12 | 13 | transform(value: string): SafeHtml { 14 | return this.sanitizer.bypassSecurityTrustHtml(value); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/app/shared/platform.service.ts: -------------------------------------------------------------------------------- 1 | import {Inject, Injectable, PLATFORM_ID} from '@angular/core'; 2 | import {isPlatformBrowser, isPlatformServer} from '@angular/common'; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | export class PlatformService { 8 | public isBrowser: boolean; 9 | public isServer: boolean; 10 | 11 | constructor(@Inject(PLATFORM_ID) platformId: string) { 12 | this.isBrowser = isPlatformBrowser(platformId); 13 | this.isServer = isPlatformServer(platformId); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/app/shared/privacy/privacy.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/shared/privacy/privacy.component.less -------------------------------------------------------------------------------- /src/app/shared/privacy/privacy.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { PrivacyComponent } from './privacy.component'; 4 | 5 | describe('PrivacyComponent', () => { 6 | let component: PrivacyComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ PrivacyComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(PrivacyComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/shared/privacy/privacy.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-privacy', 5 | templateUrl: './privacy.component.html', 6 | styleUrls: ['./privacy.component.less'] 7 | }) 8 | export class PrivacyComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/start/angular/angular.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/start/angular/angular.component.less -------------------------------------------------------------------------------- /src/app/start/angular/angular.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { AngularComponent } from './angular.component'; 4 | 5 | describe('AngularComponent', () => { 6 | let component: AngularComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ AngularComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AngularComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/start/angular/angular.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, Inject, OnInit} from '@angular/core'; 2 | import {PlatformService} from '../../shared/platform.service'; 3 | 4 | @Component({ 5 | selector: 'app-angular', 6 | templateUrl: './angular.component.html', 7 | styleUrls: ['./angular.component.less'] 8 | }) 9 | export class AngularComponent implements OnInit { 10 | constructor(public platform: PlatformService) { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/start/changelog/changelog.component.html: -------------------------------------------------------------------------------- 1 |

Changelog

2 | 3 |
    4 |
  • 5 |
    {{ release.tag_name }}
    6 |

    {{ release.published_at | date }}

    7 |

    8 |
  • 9 |
10 | -------------------------------------------------------------------------------- /src/app/start/changelog/changelog.component.less: -------------------------------------------------------------------------------- 1 | ul { 2 | margin-left: 80px; 3 | 4 | li { 5 | &::before { 6 | display: none; 7 | } 8 | 9 | div { 10 | position: absolute; 11 | font-size: 2rem; 12 | color: #e4e4e4; 13 | left: 0; 14 | top: 0.3125rem; 15 | margin-left: -100px; 16 | width: 80px; 17 | text-align: right; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/app/start/changelog/changelog.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ChangelogComponent } from './changelog.component'; 4 | 5 | describe('ChangelogComponent', () => { 6 | let component: ChangelogComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ChangelogComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ChangelogComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/start/changelog/changelog.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {HttpClient} from '@angular/common/http'; 3 | import {Observable, of} from 'rxjs'; 4 | import {catchError, shareReplay} from 'rxjs/operators'; 5 | 6 | interface ReleaseEntry { 7 | tag_name: string; 8 | published_at: Date; 9 | body: string; 10 | } 11 | 12 | @Component({ 13 | selector: 'app-changelog', 14 | templateUrl: './changelog.component.html', 15 | styleUrls: ['./changelog.component.less'] 16 | }) 17 | export class ChangelogComponent implements OnInit { 18 | 19 | releases$: Observable; 20 | 21 | constructor(private httpClient: HttpClient) { 22 | this.releases$ = this.httpClient.get('https://api.github.com/repos/SapphireDb/SapphireDb/releases').pipe( 23 | catchError(() => of([])), 24 | shareReplay() 25 | ); 26 | } 27 | 28 | ngOnInit(): void { 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/app/start/contribution/contribution.component.html: -------------------------------------------------------------------------------- 1 |

Contribution

2 | 3 |

4 | This section is made for all people who are interested in the people and future of the project.
5 | If you are interested in contributing to the project check out the todo section to find a suiting task. 6 |

7 | 8 |

Todo

9 | 10 |

11 | If you are interested to help bringing the project forward check out the list of open tasks. 12 |

13 | 14 | Todo 15 | 16 |

Contributors

17 | 18 |

19 | I want to thank all contributors of the project for the great work.
20 | I also want to thank the developers of used third party libraries for their work. 21 |

22 | 23 |
24 |
25 |
26 |
27 |
28 | 29 |
30 |
Morris Janatzek
31 |
morrisjdev
32 |
33 |
34 | 35 |
36 | 41 |
42 |
43 |
44 | 45 | -------------------------------------------------------------------------------- /src/app/start/contribution/contribution.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/start/contribution/contribution.component.less -------------------------------------------------------------------------------- /src/app/start/contribution/contribution.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ContributionComponent } from './contribution.component'; 4 | 5 | describe('ContributionComponent', () => { 6 | let component: ContributionComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ContributionComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ContributionComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/start/contribution/contribution.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-contribution', 5 | templateUrl: './contribution.component.html', 6 | styleUrls: ['./contribution.component.less'] 7 | }) 8 | export class ContributionComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/start/implementations/implementations.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/start/implementations/implementations.component.less -------------------------------------------------------------------------------- /src/app/start/implementations/implementations.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ImplementationsComponent } from './implementations.component'; 4 | 5 | describe('ImplementationsComponent', () => { 6 | let component: ImplementationsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ImplementationsComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ImplementationsComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/start/implementations/implementations.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-implementations', 5 | templateUrl: './implementations.component.html', 6 | styleUrls: ['./implementations.component.less'] 7 | }) 8 | export class ImplementationsComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/start/js/js.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/start/js/js.component.less -------------------------------------------------------------------------------- /src/app/start/js/js.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { JsComponent } from './js.component'; 4 | 5 | describe('JsComponent', () => { 6 | let component: JsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ JsComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(JsComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/start/js/js.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {PlatformService} from '../../shared/platform.service'; 3 | 4 | @Component({ 5 | selector: 'app-js', 6 | templateUrl: './js.component.html', 7 | styleUrls: ['./js.component.less'] 8 | }) 9 | export class JsComponent implements OnInit { 10 | 11 | constructor(public platform: PlatformService) { } 12 | 13 | ngOnInit() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/app/start/main/main.component.less: -------------------------------------------------------------------------------- 1 | .container-fluid.page-content { 2 | padding: 52px 0 220px 0; 3 | 4 | & > .row > .cell-12 { 5 | padding: 0; 6 | } 7 | } 8 | 9 | .hero .logo { 10 | width: 20%; 11 | } 12 | -------------------------------------------------------------------------------- /src/app/start/main/main.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { MainComponent } from './main.component'; 4 | 5 | describe('MainComponent', () => { 6 | let component: MainComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ MainComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(MainComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/start/main/main.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit, ViewEncapsulation} from '@angular/core'; 2 | import {SapphireDbService} from 'ng-sapphiredb'; 3 | import {Observable} from 'rxjs'; 4 | import {DefaultCollection} from 'sapphiredb'; 5 | 6 | @Component({ 7 | selector: 'app-main', 8 | templateUrl: './main.component.html', 9 | styleUrls: ['./main.component.less'], 10 | encapsulation: ViewEncapsulation.None 11 | }) 12 | export class MainComponent implements OnInit { 13 | 14 | collection: DefaultCollection; 15 | values$: Observable; 16 | 17 | constructor(private db: SapphireDbService) { 18 | this.collection = this.db.collection('demo.entries'); 19 | this.values$ = this.collection.take(4).values(); 20 | } 21 | 22 | ngOnInit() { 23 | } 24 | 25 | add() { 26 | this.collection.add({ 27 | content: 'This is an example text' 28 | }); 29 | } 30 | 31 | remove(item: any) { 32 | this.collection.remove(item); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/app/start/net-core/net-core.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/start/net-core/net-core.component.less -------------------------------------------------------------------------------- /src/app/start/net-core/net-core.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { NetCoreComponent } from './net-core.component'; 4 | 5 | describe('NetCoreComponent', () => { 6 | let component: NetCoreComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ NetCoreComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(NetCoreComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/start/net-core/net-core.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {PlatformService} from '../../shared/platform.service'; 3 | 4 | @Component({ 5 | selector: 'app-net-core', 6 | templateUrl: './net-core.component.html', 7 | styleUrls: ['./net-core.component.less'] 8 | }) 9 | export class NetCoreComponent implements OnInit { 10 | 11 | constructor(public platform: PlatformService) { } 12 | 13 | ngOnInit() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/app/start/sponsors/sponsors.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/start/sponsors/sponsors.component.less -------------------------------------------------------------------------------- /src/app/start/sponsors/sponsors.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SponsorsComponent } from './sponsors.component'; 4 | 5 | describe('SponsorsComponent', () => { 6 | let component: SponsorsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ SponsorsComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(SponsorsComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/start/sponsors/sponsors.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-sponsors', 5 | templateUrl: './sponsors.component.html', 6 | styleUrls: ['./sponsors.component.less'] 7 | }) 8 | export class SponsorsComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/start/start-routing.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {RouterModule, Routes} from '@angular/router'; 3 | import {MainComponent} from './main/main.component'; 4 | import {NetCoreComponent} from './net-core/net-core.component'; 5 | import {AngularComponent} from './angular/angular.component'; 6 | import {ImplementationsComponent} from './implementations/implementations.component'; 7 | import {ContributionComponent} from './contribution/contribution.component'; 8 | import {SponsorsComponent} from './sponsors/sponsors.component'; 9 | import {JsComponent} from './js/js.component'; 10 | import {ChangelogComponent} from './changelog/changelog.component'; 11 | import {TodoComponent} from './todo/todo.component'; 12 | 13 | 14 | const routes: Routes = [ 15 | { path: 'main', component: MainComponent }, 16 | { path: 'net-core', component: NetCoreComponent }, 17 | { path: 'angular', component: AngularComponent }, 18 | { path: 'js', component: JsComponent }, 19 | { path: 'implementations', component: ImplementationsComponent }, 20 | { path: 'contribution', component: ContributionComponent }, 21 | { path: 'sponsors', component: SponsorsComponent }, 22 | { path: 'changelog', component: ChangelogComponent }, 23 | { path: 'todo', component: TodoComponent }, 24 | { path: '', pathMatch: 'full', redirectTo: 'main' } 25 | ]; 26 | 27 | @NgModule({ 28 | imports: [RouterModule.forChild(routes)], 29 | exports: [RouterModule] 30 | }) 31 | export class StartRoutingModule { } 32 | -------------------------------------------------------------------------------- /src/app/start/start.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | 3 | import {StartRoutingModule} from './start-routing.module'; 4 | import {MainComponent} from './main/main.component'; 5 | import {NetCoreComponent} from './net-core/net-core.component'; 6 | import {AngularComponent} from './angular/angular.component'; 7 | import {SharedModule} from '../shared.module'; 8 | import {ImplementationsComponent} from './implementations/implementations.component'; 9 | import {ContributionComponent} from './contribution/contribution.component'; 10 | import {SponsorsComponent} from './sponsors/sponsors.component'; 11 | import {JsComponent} from './js/js.component'; 12 | import {ChangelogComponent} from './changelog/changelog.component'; 13 | import { TodoComponent } from './todo/todo.component'; 14 | 15 | @NgModule({ 16 | declarations: [MainComponent, NetCoreComponent, AngularComponent, ImplementationsComponent, ContributionComponent, SponsorsComponent, JsComponent, ChangelogComponent, TodoComponent], 17 | imports: [ 18 | SharedModule, 19 | StartRoutingModule 20 | ] 21 | }) 22 | export class StartModule { } 23 | -------------------------------------------------------------------------------- /src/app/start/todo/todo.component.html: -------------------------------------------------------------------------------- 1 |

Todo

2 | 3 | 10 | -------------------------------------------------------------------------------- /src/app/start/todo/todo.component.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/app/start/todo/todo.component.less -------------------------------------------------------------------------------- /src/app/start/todo/todo.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { TodoComponent } from './todo.component'; 4 | 5 | describe('TodoComponent', () => { 6 | let component: TodoComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ TodoComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(TodoComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/start/todo/todo.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {HttpClient} from '@angular/common/http'; 3 | import {Observable, of} from 'rxjs'; 4 | import {catchError, map, shareReplay, switchMap} from 'rxjs/operators'; 5 | 6 | interface Milestone { 7 | todos?: Todo[]; 8 | title: string; 9 | id?: number; 10 | } 11 | 12 | interface Todo { 13 | milestone?: Milestone; 14 | id?: number; 15 | title: string; 16 | html_url?: string; 17 | state: 'open'|'closed'; 18 | } 19 | 20 | @Component({ 21 | selector: 'app-todo', 22 | templateUrl: './todo.component.html', 23 | styleUrls: ['./todo.component.less'] 24 | }) 25 | export class TodoComponent implements OnInit { 26 | 27 | milestones$: Observable; 28 | 29 | constructor(private httpClient: HttpClient) { 30 | this.milestones$ = this.httpClient.get('https://api.github.com/repos/SapphireDb/SapphireDb/milestones').pipe( 31 | catchError(() => of([])), 32 | switchMap((milestones: Milestone[]) => { 33 | return this.httpClient.get('https://api.github.com/repos/SapphireDb/SapphireDb/issues?labels=todo').pipe( 34 | catchError(() => of([])), 35 | map((todos: Todo[]) => { 36 | return milestones.map(milestone => ({ 37 | id: milestone.id, 38 | title: milestone.title, 39 | todos: todos.filter(t => t.milestone.id === milestone.id).map(t => ({ 40 | id: t.id, 41 | title: t.title, 42 | html_url: t.html_url, 43 | state: t.state 44 | } as Todo)) 45 | } as Milestone)); 46 | }) 47 | ); 48 | }), 49 | shareReplay() 50 | ); 51 | } 52 | 53 | ngOnInit(): void { 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/.gitkeep -------------------------------------------------------------------------------- /src/assets/angular-environment.js: -------------------------------------------------------------------------------- 1 | (function (window) { 2 | window.angularEnvironment = window.angularEnvironment || {}; 3 | })(this); 4 | -------------------------------------------------------------------------------- /src/assets/angular-environment.template.js: -------------------------------------------------------------------------------- 1 | (function (window) { 2 | const env = window.angularEnvironment || {}; 3 | 4 | env.serverBaseUrl = '${BACKEND_URL}'; 5 | env.useSsl = '${USE_SSL}'; 6 | 7 | window.angularEnvironment = env; 8 | })(this); 9 | -------------------------------------------------------------------------------- /src/assets/banner/SapphireDB Banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/banner/SapphireDB Banner.png -------------------------------------------------------------------------------- /src/assets/icon/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/android-icon-144x144.png -------------------------------------------------------------------------------- /src/assets/icon/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/android-icon-192x192.png -------------------------------------------------------------------------------- /src/assets/icon/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/android-icon-36x36.png -------------------------------------------------------------------------------- /src/assets/icon/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/android-icon-48x48.png -------------------------------------------------------------------------------- /src/assets/icon/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/android-icon-72x72.png -------------------------------------------------------------------------------- /src/assets/icon/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/android-icon-96x96.png -------------------------------------------------------------------------------- /src/assets/icon/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/apple-icon-114x114.png -------------------------------------------------------------------------------- /src/assets/icon/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/apple-icon-120x120.png -------------------------------------------------------------------------------- /src/assets/icon/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/apple-icon-144x144.png -------------------------------------------------------------------------------- /src/assets/icon/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/apple-icon-152x152.png -------------------------------------------------------------------------------- /src/assets/icon/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/apple-icon-180x180.png -------------------------------------------------------------------------------- /src/assets/icon/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/apple-icon-57x57.png -------------------------------------------------------------------------------- /src/assets/icon/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/apple-icon-60x60.png -------------------------------------------------------------------------------- /src/assets/icon/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/apple-icon-72x72.png -------------------------------------------------------------------------------- /src/assets/icon/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/apple-icon-76x76.png -------------------------------------------------------------------------------- /src/assets/icon/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/apple-icon-precomposed.png -------------------------------------------------------------------------------- /src/assets/icon/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/apple-icon.png -------------------------------------------------------------------------------- /src/assets/icon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/favicon-16x16.png -------------------------------------------------------------------------------- /src/assets/icon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/favicon-32x32.png -------------------------------------------------------------------------------- /src/assets/icon/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/favicon-96x96.png -------------------------------------------------------------------------------- /src/assets/icon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/favicon.ico -------------------------------------------------------------------------------- /src/assets/icon/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/logo.png -------------------------------------------------------------------------------- /src/assets/icon/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/ms-icon-144x144.png -------------------------------------------------------------------------------- /src/assets/icon/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/ms-icon-150x150.png -------------------------------------------------------------------------------- /src/assets/icon/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/ms-icon-310x310.png -------------------------------------------------------------------------------- /src/assets/icon/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/assets/icon/ms-icon-70x70.png -------------------------------------------------------------------------------- /src/browserslist: -------------------------------------------------------------------------------- 1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | # For IE 9-11 support, please uncomment the last line of the file and adjust as needed 5 | > 0.5% 6 | last 2 versions 7 | Firefox ESR 8 | not dead 9 | # IE 9-11 -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | ...(window as any).angularEnvironment 4 | }; 5 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false, 7 | serverBaseUrl: 'localhost:5000', 8 | useSsl: false 9 | }; 10 | 11 | /* 12 | * In development mode, to ignore zone related error stack frames such as 13 | * `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can 14 | * import the following file, but please comment it out in production mode 15 | * because it will have performance impact when throw error 16 | */ 17 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 18 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SapphireDb/sapphiredb-js/f37608c681d2d8c3551e63ada22d1da8373defce/src/favicon.ico -------------------------------------------------------------------------------- /src/hmr.ts: -------------------------------------------------------------------------------- 1 | import { NgModuleRef, ApplicationRef } from '@angular/core'; 2 | import { createNewHosts } from '@angularclass/hmr'; 3 | 4 | export const hmrBootstrap = (module: any, bootstrap: () => Promise>) => { 5 | let ngModule: NgModuleRef; 6 | module.hot.accept(); 7 | bootstrap().then(mod => ngModule = mod).catch((err) => console.error(err)); 8 | module.hot.dispose(() => { 9 | const appRef: ApplicationRef = ngModule.injector.get(ApplicationRef); 10 | const elements = appRef.components.map(c => c.location.nativeElement); 11 | const makeVisible = createNewHosts(elements); 12 | ngModule.destroy(); 13 | makeVisible(); 14 | }); 15 | }; 16 | -------------------------------------------------------------------------------- /src/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../coverage'), 20 | reports: ['html', 'lcovonly'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false 30 | }); 31 | }; -------------------------------------------------------------------------------- /src/main.server.ts: -------------------------------------------------------------------------------- 1 | import {enableProdMode} from '@angular/core'; 2 | import 'linq4js'; 3 | 4 | enableProdMode(); 5 | 6 | export { AppServerModule } from './app/app.server.module'; 7 | 8 | export { renderModule, renderModuleFactory } from '@angular/platform-server'; 9 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import 'linq4js'; 3 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 4 | 5 | import { AppModule } from './app/app.module'; 6 | import { environment } from './environments/environment'; 7 | 8 | import { hmrBootstrap } from './hmr'; 9 | 10 | declare const module: any; 11 | 12 | if (environment.production) { 13 | enableProdMode(); 14 | } 15 | 16 | const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule); 17 | 18 | if (module.hot) { 19 | hmrBootstrap(module, bootstrap); 20 | } else { 21 | bootstrap(); 22 | } 23 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SapphireDb - A self hosted realtime database", 3 | "short_name": "SapphireDb - A self hosted realtime database", 4 | "theme_color": "#0077a3", 5 | "background_color": "#fafafa", 6 | "display": "standalone", 7 | "scope": "/", 8 | "start_url": "/", 9 | "icons": [ 10 | { 11 | "src": "./assets/icon/android-icon-36x36.png", 12 | "sizes": "36x36", 13 | "type": "image/png", 14 | "density": "0.75" 15 | }, 16 | { 17 | "src": "./assets/icon/android-icon-48x48.png", 18 | "sizes": "48x48", 19 | "type": "image/png", 20 | "density": "1.0" 21 | }, 22 | { 23 | "src": "./assets/icon/android-icon-72x72.png", 24 | "sizes": "72x72", 25 | "type": "image/png", 26 | "density": "1.5" 27 | }, 28 | { 29 | "src": "./assets/icon/android-icon-96x96.png", 30 | "sizes": "96x96", 31 | "type": "image/png", 32 | "density": "2.0" 33 | }, 34 | { 35 | "src": "./assets/icon/android-icon-144x144.png", 36 | "sizes": "144x144", 37 | "type": "image/png", 38 | "density": "3.0" 39 | }, 40 | { 41 | "src": "./assets/icon/android-icon-192x192.png", 42 | "sizes": "192x192", 43 | "type": "image/png", 44 | "density": "4.0" 45 | } 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /src/robots.txt: -------------------------------------------------------------------------------- 1 | User-Agent: * 2 | Allow: / 3 | 4 | Sitemap: https://sapphire-db.com/sitemap.xml 5 | -------------------------------------------------------------------------------- /src/styles.less: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | @import '~metro4/build/css/metro-all.min.css'; 3 | 4 | @import '~highlight.js/styles/vs.css'; 5 | 6 | code { 7 | background-color: #fcfcfc !important; 8 | } 9 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "main.ts", 9 | "polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "test.ts", 12 | "polyfills.ts" 13 | ], 14 | "include": [ 15 | "**/*.spec.ts", 16 | "**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /src/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "app", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "app", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "downlevelIteration": true, 6 | "outDir": "./dist/out-tsc", 7 | "sourceMap": true, 8 | "declaration": false, 9 | "module": "esnext", 10 | "moduleResolution": "node", 11 | "emitDecoratorMetadata": true, 12 | "experimentalDecorators": true, 13 | "target": "es2015", 14 | "typeRoots": [ 15 | "node_modules/@types" 16 | ], 17 | "lib": [ 18 | "es2018", 19 | "dom" 20 | ], 21 | "paths": { 22 | "ng-sapphiredb": [ 23 | "dist/ng-sapphiredb" 24 | ], 25 | "ng-sapphiredb/*": [ 26 | "dist/ng-sapphiredb/*" 27 | ], 28 | "sapphiredb": [ 29 | "dist/sapphiredb" 30 | ], 31 | "sapphiredb/*": [ 32 | "dist/sapphiredb/*" 33 | ] 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /tsconfig.server.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "types": [ 8 | "node" 9 | ] 10 | }, 11 | "angularCompilerOptions": { 12 | "entryModule": "src/app/app.server.module#AppServerModule" 13 | }, 14 | "files": [ 15 | "src/main.server.ts", 16 | "server.ts" 17 | ] 18 | } 19 | --------------------------------------------------------------------------------