├── .gitignore ├── .yo-rc.json ├── LICENSE ├── generators └── app │ ├── index.js │ └── templates │ ├── .editorconfig │ ├── .gitignore │ ├── README.md │ ├── angular.json │ ├── e2e │ ├── protractor.conf.js │ ├── src │ │ ├── app.e2e-spec.ts │ │ └── app.po.ts │ └── tsconfig.e2e.json │ ├── package-lock.json │ ├── package.json │ ├── popup.js │ ├── src │ ├── app │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ ├── card │ │ │ ├── card.component.css │ │ │ ├── card.component.html │ │ │ └── card.component.ts │ │ ├── dashboard │ │ │ ├── dashboard.component.css │ │ │ ├── dashboard.component.html │ │ │ ├── dashboard.component.spec.ts │ │ │ └── dashboard.component.ts │ │ ├── login-popup │ │ │ ├── login-popup.component.css │ │ │ ├── login-popup.component.html │ │ │ └── login-popup.component.ts │ │ ├── login │ │ │ ├── login.component.css │ │ │ ├── login.component.html │ │ │ └── login.component.ts │ │ ├── models │ │ │ ├── solid-profile.model.ts │ │ │ ├── solid-provider.model.ts │ │ │ └── solid-session.model.ts │ │ ├── popup.html │ │ ├── register │ │ │ ├── register.component.css │ │ │ ├── register.component.html │ │ │ └── register.component.ts │ │ └── services │ │ │ ├── auth.guard.service.ts │ │ │ ├── rdf.service.ts │ │ │ └── solid.auth.service.ts │ ├── assets │ │ ├── .gitkeep │ │ ├── images │ │ │ ├── Generic.png │ │ │ ├── Inrupt.png │ │ │ ├── JD.svg │ │ │ ├── Solid.png │ │ │ ├── Solid_Pattern.png │ │ │ ├── jd-logo_red_hex_only.svg.png │ │ │ └── profile.png │ │ ├── js │ │ │ └── libs │ │ │ │ ├── popup.js │ │ │ │ └── rdflib.min.js │ │ └── types │ │ │ └── rdflib │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── index.d.ts │ │ │ └── package.json │ ├── browserslist │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── karma.conf.js │ ├── main.ts │ ├── polyfills.ts │ ├── styles.css │ ├── test.ts │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ └── tslint.json │ ├── tsconfig.json │ └── tslint.json ├── package-lock.json ├── package.json └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # See http://help.github.com/ignore-files/ for more about ignoring files. 3 | 4 | # compiled output 5 | /dist 6 | /tmp 7 | /out-tsc 8 | 9 | # dependencies 10 | /node_modules 11 | generators/app/templates/node_modules 12 | generators/app/templates/dist 13 | 14 | # IDEs and editors 15 | /.idea 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | *.sublime-workspace 22 | 23 | # IDE - VSCode 24 | .vscode/* 25 | !.vscode/settings.json 26 | !.vscode/tasks.json 27 | !.vscode/launch.json 28 | !.vscode/extensions.json 29 | 30 | # misc 31 | /.sass-cache 32 | /connect.lock 33 | /coverage 34 | /libpeerconnection.log 35 | npm-debug.log 36 | yarn-error.log 37 | testem.log 38 | /typings 39 | 40 | # System Files 41 | .DS_Store 42 | Thumbs.db -------------------------------------------------------------------------------- /.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-solid-angular": { 3 | "promptValues": { 4 | "name": "test" 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 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 | -------------------------------------------------------------------------------- /generators/app/index.js: -------------------------------------------------------------------------------- 1 | const Generator = require('yeoman-generator'); 2 | const chalk = require('chalk'); 3 | const yosay = require('yosay'); 4 | const figlet = require('figlet'); 5 | const path = require('path'); 6 | const mkdirp = require('mkdirp'); 7 | 8 | 9 | module.exports = class extends Generator { 10 | constructor(args, opts) { 11 | super(args, opts); 12 | } 13 | 14 | prompting() { 15 | const done = this.async(); 16 | this.log(yosay(chalk.cyan.bold('Welcome to the \n Solid Angular 6 Generator'))); 17 | 18 | return this.prompt([{ 19 | type: 'input', 20 | name: 'name', 21 | message: 'Please enter your application name :', 22 | store: true, 23 | validate: (name) => { 24 | const pass = name.match(/^[^\d\s!@£$%^&*()+=]+$/); 25 | if (pass) { 26 | return true; 27 | } 28 | return `${chalk.red('Provide a valid "App name", digits and whitespaces not allowed')}`; 29 | }, 30 | default: this.appname // Default to current folder name 31 | }]).then((answers) => { 32 | this.props = answers; 33 | done(); 34 | }); 35 | 36 | } 37 | 38 | writing() { 39 | this.log('Copying app directory...'); 40 | if (path.basename(this.destinationPath()) !== this.props.name) { 41 | this.log( 42 | `Creating folder...` 43 | ); 44 | mkdirp(this.props.name); 45 | this.destinationRoot(this.destinationPath(this.props.name)); 46 | } 47 | 48 | this.log(this.templatePath()); 49 | this.log(this.destinationPath()); 50 | /*this.fs.copyTpl( 51 | this.templatePath(), 52 | this.destinationPath(), 53 | { 54 | name: this.props.name 55 | } 56 | 57 | 58 | ); 59 | */ 60 | this.fs.copy( 61 | this.templatePath(), 62 | this.destinationRoot(), 63 | { 64 | name: this.props.name 65 | }, 66 | {}, 67 | { 68 | globOptions: { 69 | ignore: ['node_modules', 'dist'] 70 | } 71 | } 72 | ); 73 | } 74 | 75 | install() { 76 | this.log('Installing dependencies...'); 77 | /*const _this = this; 78 | if (this.props.runNpm) { 79 | this.installDependencies({ 80 | npm: true, 81 | callback: function () { 82 | _this.log(`${chalk.bold.underline.green('Dependencies installed!')}`); 83 | } 84 | }); 85 | }*/ 86 | this.npmInstall(); 87 | this.completed = true; 88 | } 89 | 90 | end() { 91 | if (this.completed) { 92 | this.log('Installation complete. Welcome to Solid'); 93 | this.log(chalk.bold.blue(figlet.textSync('- Solid -', 94 | { 95 | font: '3D-ASCII', 96 | horizontalLayout: 'full', 97 | verticalLayout: 'full' 98 | } 99 | ))); 100 | return; 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /generators/app/templates/.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 | -------------------------------------------------------------------------------- /generators/app/templates/.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 | -------------------------------------------------------------------------------- /generators/app/templates/README.md: -------------------------------------------------------------------------------- 1 | # SolidApp 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.0.8. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 28 | 29 | ## Extra steps 30 | 31 | Go to tsconfig.app.json into paths add the following data : "paths": { 32 | "zlib": ["node_modules/browserify-zlib/lib/index.js"], 33 | "http": ["node_modules/@angular/http"], 34 | "https": ["node_modules/@angular/http"], 35 | "stream": ["node_modules/jszip/dist/jszip.min.js"] 36 | } 37 | -------------------------------------------------------------------------------- /generators/app/templates/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "solid-app": { 7 | "root": "", 8 | "sourceRoot": "src", 9 | "projectType": "application", 10 | "prefix": "app", 11 | "schematics": {}, 12 | "architect": { 13 | "build": { 14 | "builder": "@angular-devkit/build-angular:browser", 15 | "options": { 16 | "outputPath": "dist/solid-app", 17 | "index": "src/index.html", 18 | "main": "src/main.ts", 19 | "polyfills": "src/polyfills.ts", 20 | "tsConfig": "src/tsconfig.app.json", 21 | "assets": [ 22 | "src/favicon.ico", 23 | "src/assets" 24 | ], 25 | "styles": [ 26 | "src/styles.css", 27 | "node_modules/@ng-select/ng-select/themes/default.theme.css", 28 | "node_modules/purecss/build/grids-core-min.css", 29 | "node_modules/purecss/build/grids-min.css", 30 | "node_modules/purecss/build/grids-responsive-min.css", 31 | "node_modules/ngx-toastr/toastr.css" 32 | ], 33 | "scripts": [ 34 | "node_modules/solid-auth-client/dist-lib/solid-auth-client.bundle.js", 35 | "src/assets/js/libs/rdflib.min.js" 36 | ] 37 | }, 38 | "configurations": { 39 | "production": { 40 | "fileReplacements": [ 41 | { 42 | "replace": "src/environments/environment.ts", 43 | "with": "src/environments/environment.prod.ts" 44 | } 45 | ], 46 | "optimization": true, 47 | "outputHashing": "all", 48 | "sourceMap": false, 49 | "extractCss": true, 50 | "namedChunks": false, 51 | "aot": true, 52 | "extractLicenses": true, 53 | "vendorChunk": false, 54 | "buildOptimizer": true 55 | } 56 | } 57 | }, 58 | "serve": { 59 | "builder": "@angular-devkit/build-angular:dev-server", 60 | "options": { 61 | "browserTarget": "solid-app:build" 62 | }, 63 | "configurations": { 64 | "production": { 65 | "browserTarget": "solid-app:build:production" 66 | } 67 | } 68 | }, 69 | "extract-i18n": { 70 | "builder": "@angular-devkit/build-angular:extract-i18n", 71 | "options": { 72 | "browserTarget": "solid-app:build" 73 | } 74 | }, 75 | "test": { 76 | "builder": "@angular-devkit/build-angular:karma", 77 | "options": { 78 | "main": "src/test.ts", 79 | "polyfills": "src/polyfills.ts", 80 | "tsConfig": "src/tsconfig.spec.json", 81 | "karmaConfig": "src/karma.conf.js", 82 | "styles": [ 83 | "src/styles.css", 84 | "node_modules/@ng-select/ng-select/themes/default.theme.css", 85 | "node_modules/ngx-toastr/toastr.css" 86 | ], 87 | "scripts": [], 88 | "assets": [ 89 | "src/favicon.ico", 90 | "src/assets" 91 | ] 92 | } 93 | }, 94 | "lint": { 95 | "builder": "@angular-devkit/build-angular:tslint", 96 | "options": { 97 | "tsConfig": [ 98 | "src/tsconfig.app.json", 99 | "src/tsconfig.spec.json" 100 | ], 101 | "exclude": [ 102 | "**/node_modules/**" 103 | ] 104 | } 105 | } 106 | } 107 | }, 108 | "solid-app-e2e": { 109 | "root": "e2e/", 110 | "projectType": "application", 111 | "architect": { 112 | "e2e": { 113 | "builder": "@angular-devkit/build-angular:protractor", 114 | "options": { 115 | "protractorConfig": "e2e/protractor.conf.js", 116 | "devServerTarget": "solid-app:serve" 117 | }, 118 | "configurations": { 119 | "production": { 120 | "devServerTarget": "solid-app:serve:production" 121 | } 122 | } 123 | }, 124 | "lint": { 125 | "builder": "@angular-devkit/build-angular:tslint", 126 | "options": { 127 | "tsConfig": "e2e/tsconfig.e2e.json", 128 | "exclude": [ 129 | "**/node_modules/**" 130 | ] 131 | } 132 | } 133 | } 134 | } 135 | }, 136 | "defaultProject": "solid-app" 137 | } 138 | -------------------------------------------------------------------------------- /generators/app/templates/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './src/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | onPrepare() { 23 | require('ts-node').register({ 24 | project: require('path').join(__dirname, './tsconfig.e2e.json') 25 | }); 26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; -------------------------------------------------------------------------------- /generators/app/templates/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('workspace-project App', () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | 10 | it('should display welcome message', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('Welcome to solid-app!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /generators/app/templates/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /generators/app/templates/e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /generators/app/templates/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "solid-app", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "test": "ng test", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e" 11 | }, 12 | "browser": { 13 | "crypto": false, 14 | "fetch": false, 15 | "window": false 16 | }, 17 | "private": true, 18 | "dependencies": { 19 | "@angular/animations": "^8.1.1", 20 | "@angular/common": "^8.1.1", 21 | "@angular/compiler": "^8.1.1", 22 | "@angular/core": "^8.1.1", 23 | "@angular/forms": "^8.1.1", 24 | "@angular/platform-browser": "^8.1.1", 25 | "@angular/platform-browser-dynamic": "^8.1.1", 26 | "@angular/router": "^8.1.1", 27 | "@ng-select/ng-select": "^2.5.1", 28 | "@types/solid-auth-client": "^2.3.0", 29 | "core-js": "^2.5.4", 30 | "crypto-js": "^3.1.9-1", 31 | "http": "^0.0.0", 32 | "isomorphic-fetch": "^2.2.1", 33 | "ngx-toastr": "^9.0.2", 34 | "node-fetch": "^2.2.0", 35 | "path": "^0.12.7", 36 | "process": "^0.11.10", 37 | "purecss": "^1.0.0", 38 | "rdflib": "^0.19.0", 39 | "rxjs": "^6.5.2", 40 | "solid-auth-client": "^2.2.3", 41 | "stdio": "^0.2.7", 42 | "text-encoding": "^0.6.4", 43 | "webcrypto": "^0.1.1", 44 | "whatwg-url": "^7.0.0", 45 | "zone.js": "^0.9.1" 46 | }, 47 | "devDependencies": { 48 | "@angular-devkit/build-angular": "^0.12.4", 49 | "@angular/cli": "^8.1.1", 50 | "@angular/compiler-cli": "^8.1.1", 51 | "@angular/http": "^7.2.15", 52 | "@angular/language-service": "^8.1.1", 53 | "@types/jasmine": "~2.8.6", 54 | "@types/jasminewd2": "~2.0.3", 55 | "@types/node": "~8.9.4", 56 | "codelyzer": "^5.1.0", 57 | "jasmine-core": "~2.99.1", 58 | "jasmine-spec-reporter": "~4.2.1", 59 | "karma": "^4.1.0", 60 | "karma-chrome-launcher": "~2.2.0", 61 | "karma-coverage-istanbul-reporter": "~2.0.0", 62 | "karma-jasmine": "~1.1.1", 63 | "karma-jasmine-html-reporter": "^0.2.2", 64 | "protractor": "^5.4.1", 65 | "ts-node": "~5.0.1", 66 | "tslint": "~5.9.1", 67 | "typescript": "~3.4.5" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/generator-solid-angular/0461c0016fb15398259a5b9b0e9b1d5d781e0be5/generators/app/templates/src/app/app.component.css -------------------------------------------------------------------------------- /generators/app/templates/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | describe('AppComponent', () => { 4 | beforeEach(async(() => { 5 | TestBed.configureTestingModule({ 6 | declarations: [ 7 | AppComponent 8 | ], 9 | }).compileComponents(); 10 | })); 11 | it('should create the app', async(() => { 12 | const fixture = TestBed.createComponent(AppComponent); 13 | const app = fixture.debugElement.componentInstance; 14 | expect(app).toBeTruthy(); 15 | })); 16 | it(`should have as title 'app'`, async(() => { 17 | const fixture = TestBed.createComponent(AppComponent); 18 | const app = fixture.debugElement.componentInstance; 19 | expect(app.title).toEqual('app'); 20 | })); 21 | it('should render title in a h1 tag', async(() => { 22 | const fixture = TestBed.createComponent(AppComponent); 23 | fixture.detectChanges(); 24 | const compiled = fixture.debugElement.nativeElement; 25 | expect(compiled.querySelector('h1').textContent).toContain('Welcome to solid-app!'); 26 | })); 27 | }); 28 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { popupLogin } from 'solid-auth-client/dist-lib/solid-auth-client.bundle.js'; 3 | 4 | 5 | @Component({ 6 | selector: 'app-root', 7 | templateUrl: './app.component.html', 8 | styleUrls: ['./app.component.css'] 9 | }) 10 | export class AppComponent { 11 | title = 'app'; 12 | } 13 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { AppComponent } from './app.component'; 6 | import {LoginPopupComponent} from './login-popup/login-popup.component'; 7 | import {LoginComponent} from './login/login.component'; 8 | import { CardComponent } from './card/card.component'; 9 | import { DashboardComponent } from './dashboard/dashboard.component'; 10 | 11 | // Services 12 | import { AuthService } from './services/solid.auth.service'; 13 | import { AuthGuard } from './services/auth.guard.service'; 14 | import { NgSelectModule } from '@ng-select/ng-select'; 15 | import { FormsModule } from '@angular/forms'; 16 | import { RegisterComponent } from './register/register.component'; 17 | import { ToastrModule } from 'ngx-toastr'; 18 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 19 | 20 | 21 | 22 | const routes: Routes = [ 23 | { 24 | path: '', 25 | component: LoginComponent 26 | }, 27 | { 28 | path: 'login', 29 | component: LoginComponent 30 | }, 31 | { 32 | path: 'login-popup', 33 | component: LoginPopupComponent 34 | }, 35 | { 36 | path: 'dashboard', 37 | component: DashboardComponent, 38 | canActivate: [AuthGuard], 39 | }, 40 | { 41 | path: 'card', 42 | component: CardComponent, 43 | canActivate: [AuthGuard], 44 | }, 45 | { 46 | path: 'register', 47 | component: RegisterComponent 48 | } 49 | ]; 50 | 51 | @NgModule({ 52 | declarations: [ 53 | AppComponent, 54 | LoginComponent, 55 | LoginPopupComponent, 56 | DashboardComponent, 57 | CardComponent, 58 | RegisterComponent 59 | ], 60 | imports: [ 61 | BrowserModule, 62 | FormsModule, 63 | RouterModule.forRoot(routes), 64 | NgSelectModule, 65 | ToastrModule.forRoot(), 66 | BrowserAnimationsModule //required for toastr 67 | ], 68 | providers: [AuthService], 69 | bootstrap: [AppComponent] 70 | }) 71 | export class AppModule { } 72 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/card/card.component.css: -------------------------------------------------------------------------------- 1 | .profile-container { 2 | font-family: 'Roboto', sans-serif; 3 | } 4 | 5 | .profile-container h1 { 6 | font-size: 24px; 7 | color: #7C55FB; 8 | font-weight: bold; 9 | line-height: 32px; 10 | letter-spacing: 1.2px; 11 | text-align: center; 12 | margin-top: 82px; 13 | text-transform: uppercase; 14 | } 15 | 16 | .profile-fields-container { 17 | max-width: 740px; 18 | min-height: 500px; 19 | margin: 0 auto; 20 | border: 1px solid #ccc; 21 | box-shadow: #ccc 1px 1px 4px; 22 | position: relative; 23 | } 24 | 25 | .profile-fields-container .profile-image-container { 26 | height: 200px; 27 | width: 100%; 28 | background-size: cover !important; 29 | background: url('/assets/images/Solid_Pattern.png'); 30 | } 31 | 32 | .profile-fields-container .profile-image-container img { 33 | height: 128px; 34 | border-radius: 50%; 35 | margin-left: auto; 36 | margin-right:auto; 37 | position: relative; 38 | top:40px; 39 | display: block; 40 | } 41 | 42 | .profile-fields-container i { 43 | font-size: 14px; 44 | color: #89969F; 45 | padding-left: 26px; 46 | padding-right: 10px; 47 | margin-top: 24px; 48 | } 49 | 50 | .profile-fields-container input[type=text].field-text { 51 | height: 12px; 52 | width: 280px; 53 | border: 1px solid #89969F; 54 | border-radius: 4px; 55 | padding: 10px; 56 | } 57 | 58 | .profile-fields-container input[type=text].field-text::placeholder { 59 | color: rgba(102,102,102,0.2); 60 | } 61 | 62 | .profile-save-button-container { 63 | display: flex; 64 | align-items: center; 65 | margin-bottom: auto; 66 | height: 100px; 67 | flex-direction: column; 68 | justify-content: flex-end; 69 | } 70 | 71 | .profile-save-button { 72 | background-color: #7C55FB; 73 | margin-left: auto; 74 | margin-right: auto; 75 | width: 280px; 76 | } 77 | 78 | .profile-save-button:disabled { 79 | background-color: #F0EEEB; 80 | border-color: #F0EEEB; 81 | cursor: not-allowed; 82 | } 83 | 84 | .topnav { 85 | position:absolute; 86 | top:0; 87 | left:0; 88 | width: 100%; 89 | background-color: #7C4DFF; 90 | height: 50px; 91 | color: #fff; 92 | } 93 | 94 | .topnav .logo { 95 | display: inline-block; 96 | font-family: 'Roboto Slab', serif; 97 | font-size: 24px; 98 | font-weight: bold; 99 | text-transform: uppercase; 100 | line-height: 32px; 101 | padding-right: 80px; 102 | position: relative; 103 | top: -8px; 104 | left: 28px; 105 | } 106 | 107 | .topnav .menu-item { 108 | display: inline-block; 109 | font-size: 10px; 110 | line-height: 13px; 111 | width: 100px; 112 | height: 100%; 113 | text-align: center; 114 | } 115 | 116 | .topnav .menu-item i { 117 | font-size: 24px; 118 | margin-top:8px; 119 | margin-bottom: 2px; 120 | } 121 | 122 | .topnav .profile-menu { 123 | float: right; 124 | display: inline-block; 125 | width: 50px; 126 | height: 50px; 127 | background-color: rgba(0,0,0,0.25); 128 | } 129 | 130 | .topnav .profile-menu img { 131 | display: block; 132 | height: 30px; 133 | width: 30px; 134 | border-radius: 50%; 135 | margin: 0 auto; 136 | margin-top:10px; 137 | cursor: pointer; 138 | } 139 | 140 | .loading-image { 141 | text-align: center; 142 | margin-top: 50px; 143 | } 144 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/card/card.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 11 | 17 | 23 | 24 |
25 | 26 |
27 |
28 |

Profile

29 | 30 | 31 |
32 | 33 |
34 | 35 | 36 |
37 |
38 | 39 |
40 |
41 |
42 | 43 |
44 | 45 |
46 | 47 | 48 |
49 | 50 |
51 |
52 | 53 |
54 | 55 |
56 | 57 |
58 | 59 | 60 |
61 | 62 |
63 |
64 | 65 |
66 | 67 |
68 | 69 |
70 | 71 | 72 |
73 | 74 |
75 |
76 | 77 |
78 | 79 |
80 |
81 |
82 |
83 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/card/card.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewChild } from '@angular/core'; 2 | import { ActivatedRoute } from '@angular/router'; 3 | import { NgForm } from '@angular/forms'; 4 | import { SolidProfile } from '../models/solid-profile.model'; 5 | import { RdfService } from '../services/rdf.service'; 6 | import { AuthService } from '../services/solid.auth.service'; 7 | 8 | 9 | @Component({ 10 | selector: 'app-card', 11 | templateUrl: './card.component.html', 12 | styleUrls: ['./card.component.css'], 13 | }) 14 | export class CardComponent implements OnInit { 15 | 16 | profile: SolidProfile; 17 | profileImage: string; 18 | loadingProfile: Boolean; 19 | 20 | @ViewChild('f', { static: false }) cardForm: NgForm; 21 | 22 | constructor(private rdf: RdfService, 23 | private route: ActivatedRoute, private auth: AuthService) {} 24 | 25 | ngOnInit() { 26 | this.loadingProfile = true; 27 | this.loadProfile(); 28 | 29 | // Clear cached profile data 30 | // TODO: Remove this code and find a better way to get the old data 31 | localStorage.removeItem('oldProfileData'); 32 | } 33 | 34 | // Loads the profile from the rdf service and handles the response 35 | async loadProfile() { 36 | try { 37 | this.loadingProfile = true; 38 | const profile = await this.rdf.getProfile(); 39 | if (profile) { 40 | this.profile = profile; 41 | this.auth.saveOldUserData(profile); 42 | } 43 | 44 | this.loadingProfile = false; 45 | this.setupProfileData(); 46 | } catch (error) { 47 | console.log(`Error: ${error}`); 48 | } 49 | 50 | } 51 | 52 | // Submits the form, and saves the profile data using the auth/rdf service 53 | async onSubmit () { 54 | if (!this.cardForm.invalid) { 55 | try { 56 | await this.rdf.updateProfile(this.cardForm); 57 | localStorage.setItem('oldProfileData', JSON.stringify(this.profile)); 58 | } catch (err) { 59 | console.log(`Error: ${err}`); 60 | } 61 | } 62 | } 63 | 64 | // Format data coming back from server. Intended purpose is to replace profile image with default if it's missing 65 | // and potentially format the address if we need to reformat it for this UI 66 | private setupProfileData() { 67 | if (this.profile) { 68 | this.profileImage = this.profile.image ? this.profile.image : '/assets/images/profile.png'; 69 | } else { 70 | this.profileImage = '/assets/images/profile.png'; 71 | } 72 | } 73 | 74 | // Example of logout functionality. Normally wouldn't be triggered by clicking the profile picture. 75 | logout() { 76 | this.auth.solidSignOut(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/dashboard/dashboard.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/generator-solid-angular/0461c0016fb15398259a5b9b0e9b1d5d781e0be5/generators/app/templates/src/app/dashboard/dashboard.component.css -------------------------------------------------------------------------------- /generators/app/templates/src/app/dashboard/dashboard.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Your webId is {{ session.webId }}

3 | 7 |
8 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/dashboard/dashboard.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { DashboardComponent } from './dashboard.component'; 4 | 5 | describe('DashboardComponent', () => { 6 | let component: DashboardComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ DashboardComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DashboardComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/dashboard/dashboard.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { ActivatedRoute } from '@angular/router'; 3 | // import { currentSession } from 'solid-auth-client'; 4 | 5 | // Services 6 | import { AuthService } from '../services/solid.auth.service'; 7 | 8 | class Session { 9 | constructor() {} 10 | 11 | webId: string; 12 | } 13 | 14 | @Component({ 15 | selector: 'app-dashboard', 16 | templateUrl: './dashboard.component.html', 17 | styleUrls: ['./dashboard.component.css'] 18 | }) 19 | export class DashboardComponent implements OnInit { 20 | session: Session = new Session(); 21 | 22 | constructor(private auth: AuthService, private route: ActivatedRoute) {} 23 | 24 | ngOnInit() { 25 | console.log('hello'); 26 | this.loadSession(); 27 | } 28 | 29 | loadSession = async () => { 30 | // this.session = await currentSession(); 31 | } 32 | 33 | onSignOut = () => { 34 | this.auth.solidSignOut(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/login-popup/login-popup.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/generator-solid-angular/0461c0016fb15398259a5b9b0e9b1d5d781e0be5/generators/app/templates/src/app/login-popup/login-popup.component.css -------------------------------------------------------------------------------- /generators/app/templates/src/app/login-popup/login-popup.component.html: -------------------------------------------------------------------------------- 1 |
Loading...
2 | 3 | 4 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/login-popup/login-popup.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ElementRef } from '@angular/core'; 2 | declare let popup: any; 3 | 4 | @Component({ 5 | selector: 'app-login-popup', 6 | templateUrl: './login-popup.component.html', 7 | styleUrls: ['./login-popup.component.css'] 8 | }) 9 | export class LoginPopupComponent implements OnInit { 10 | 11 | constructor(private elementRef: ElementRef) {} 12 | 13 | ngOnInit() { 14 | this.runScript(); 15 | } 16 | 17 | runScript () { 18 | const s = document.createElement('script'); 19 | s.type = 'text/javascript'; 20 | s.src = '/assets/js/libs/popup.js'; 21 | this.elementRef.nativeElement.appendChild(s); 22 | // s.onload = () => this.triggerDuo(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/login/login.component.css: -------------------------------------------------------------------------------- 1 | 2 | .login-page { 3 | text-align: center; 4 | font-family: 'Roboto', sans-serif; 5 | color: #666; 6 | } 7 | 8 | .login-page h1 { 9 | font-size: 38px; 10 | text-transform: uppercase; 11 | font-weight: bold; 12 | line-height: 50px; 13 | letter-spacing: 1.9px; 14 | padding-top: 12px; 15 | margin-top: 0px; 16 | } 17 | 18 | .login-page h2 { 19 | color: #666; 20 | 21 | font-size: 16px; 22 | font-weight: 500; 23 | letter-spacing: 1px; 24 | line-height: 21px; 25 | margin-top: 48px; 26 | } 27 | 28 | .login-page .small-link { 29 | font-size: 12px; 30 | color: #666; 31 | letter-spacing: 0.75px; 32 | line-height: 16px; 33 | } 34 | 35 | .login-page .registration-link { 36 | margin-top: 38px; 37 | } 38 | 39 | .login-page .registration-link p { 40 | font-size: 16px; 41 | color: #666; 42 | letter-spacing: 1px; 43 | } 44 | 45 | .login-page .item-divider { 46 | box-sizing:border-box; 47 | height: 1px; 48 | width: 354px; 49 | border-bottom: 1px solid #E0E0E0; 50 | position: absolute; 51 | bottom:-8px; left:-9px; 52 | } 53 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/login/login.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | 6 |
7 | 8 | 9 |

10 | Profile Demo App 11 |

12 | 13 | 14 |

15 | Login with Solid Identity 16 |

17 | 18 | 19 |
20 | 40 | 46 | 47 |
48 | 49 | 50 | 54 | 55 | 56 |
57 | 58 | What is a Solid Identity? 59 | 60 |
61 | 62 |
63 | 64 | 65 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/login/login.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | // Auth Service 4 | import { AuthService } from '../services/solid.auth.service'; 5 | import { SolidProvider } from '../models/solid-provider.model'; 6 | 7 | 8 | @Component({ 9 | selector: 'app-login', 10 | templateUrl: './login.component.html', 11 | styleUrls: ['./login.component.css'] 12 | }) 13 | export class LoginComponent implements OnInit { 14 | 15 | constructor(private auth: AuthService, private router: Router) { } 16 | 17 | /** 18 | * A list of Solid Identity Providers 19 | * @type {SolidProvider[]} 20 | */ 21 | identityProviders: SolidProvider[]; 22 | selectedProviderUrl: string; 23 | customProviderUrl: string; 24 | 25 | ngOnInit() { 26 | // If we're authenticated, go to profile 27 | if (localStorage.getItem('solid-auth-client')) { 28 | this.router.navigateByUrl('/card'); 29 | } 30 | 31 | this.identityProviders = this.auth.getIdentityProviders(); 32 | } 33 | 34 | /* 35 | * Alternate login-popup function for Solid. See service for more details. 36 | */ 37 | onLoginPopup = async () => { 38 | this.auth.solidLoginPopup(); 39 | } 40 | 41 | onLogin = async () => { 42 | const idp: string = this.selectedProviderUrl ? this.selectedProviderUrl : this.customProviderUrl; 43 | 44 | if (idp) { 45 | try { 46 | this.auth.solidLogin(idp); 47 | } catch (err) { 48 | console.log('An error has occurred logging in: ' + err); 49 | } 50 | } 51 | } 52 | 53 | goToRegistration() { 54 | this.router.navigateByUrl('/register'); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/models/solid-profile.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A Solid Profile Card object 3 | * @see FOAF 4 | * @see VCARD 5 | */ 6 | export interface SolidProfile { 7 | address: { 8 | street?: string; 9 | // TODO: Add the missing address fields 10 | }; 11 | company: string; 12 | email: string; 13 | fn: string; 14 | image: string; 15 | phone: string; 16 | role: string; 17 | organization?: string; 18 | } 19 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/models/solid-provider.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents an IDP 3 | */ 4 | export interface SolidProvider { 5 | name: string; 6 | image: string; 7 | loginUrl: string; 8 | desc: string; 9 | } 10 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/models/solid-session.model.ts: -------------------------------------------------------------------------------- 1 | export interface SolidSession { 2 | accessToken: string; 3 | clientId: string; 4 | idToken: string; 5 | sessionKey: string; 6 | webId: string; 7 | } 8 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/register/register.component.css: -------------------------------------------------------------------------------- 1 | .registration { 2 | text-align: center; 3 | font-family: 'Roboto', sans-serif; 4 | } 5 | 6 | .registration .header-bar { 7 | margin: 0px; 8 | height: 44px; 9 | width: calc(100% + 16px); 10 | background-color: #3D6DEB; 11 | color: #fff; 12 | position: absolute; 13 | top: 0; 14 | left: 0; 15 | } 16 | 17 | .registration .header-bar p { 18 | text-align: center; 19 | font-family: 'Roboto', sans-serif; 20 | font-weight: bold; 21 | font-size: 14px; 22 | letter-spacing: 1px; 23 | line-height: 15px; 24 | } 25 | 26 | .registration .header-text { 27 | margin-top:92px; 28 | width: 360px; 29 | margin-left: auto; 30 | margin-right: auto; 31 | font-size: 14px; 32 | color: #666; 33 | } 34 | 35 | .registration .header-text a { 36 | color: #666; 37 | font-size: 12px; 38 | } 39 | 40 | .registration .provider-card-container { 41 | margin-top: 28px; 42 | } 43 | 44 | .registration .provider-card { 45 | height: 140px; 46 | width: 320px; 47 | border: 1px solid #DAE0E6; 48 | border-radius: 2px; 49 | background-color: #fff; 50 | margin: 10px; 51 | display: inline-block; 52 | box-shadow: #DAE0E6 1px 1px 6px; 53 | } 54 | 55 | .registration .provider-card .provider-logo { 56 | height: 44px; 57 | width: 44px; 58 | margin-left: auto; 59 | margin-right: auto; 60 | margin-top: 16px; 61 | } 62 | 63 | .registration .provider-card h2 { 64 | color: #656E75; 65 | font-size: 18px; 66 | margin-top: -2px; 67 | letter-spacing: 0.9px; 68 | line-height: 24px; 69 | } 70 | .registration .provider-card p { 71 | color: #656E75; 72 | font-size: 12px; 73 | line-height: 16px; 74 | } 75 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/register/register.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |

Select Solid Identity Provider

5 |
6 | 7 | 8 |
9 |

10 | With a Solid Identity your personal data is stored securely in a POD. You control who has access to it. 11 |

12 | 13 | Learn more about Solid IDs and PODs 14 | 15 |
16 | 17 | 18 |
19 |
20 | 21 |

{{ provider.name }}

22 |

{{ provider.desc }}

23 |
24 |
25 | 26 |
27 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/register/register.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { AuthService } from '../services/solid.auth.service'; 3 | 4 | @Component({ 5 | selector: 'app-register', 6 | templateUrl: './register.component.html', 7 | styleUrls: ['./register.component.css'] 8 | }) 9 | export class RegisterComponent implements OnInit { 10 | availableProviders: any[]; 11 | 12 | constructor(private auth: AuthService) { } 13 | 14 | ngOnInit() { 15 | this.availableProviders = this.auth.getIdentityProviders(); 16 | this.availableProviders = this.availableProviders.filter(idp => idp.providerLoginUrl !== null); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/services/auth.guard.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { 3 | CanActivate, 4 | ActivatedRouteSnapshot, 5 | RouterStateSnapshot, 6 | Router 7 | } from '@angular/router'; 8 | import { Observable } from 'rxjs'; 9 | import { map, take, tap } from 'rxjs/operators'; 10 | 11 | import { AuthService } from './solid.auth.service'; 12 | 13 | 14 | @Injectable({ 15 | providedIn: 'root', 16 | }) 17 | export class AuthGuard implements CanActivate { 18 | constructor(private auth: AuthService, private router: Router) {} 19 | 20 | canActivate( 21 | next: ActivatedRouteSnapshot, 22 | state: RouterStateSnapshot 23 | ): Observable | Promise | boolean { 24 | const isLoggedIn = localStorage.getItem('solid-auth-client') ? true : false; 25 | 26 | if (!isLoggedIn) { 27 | this.router.navigateByUrl('/login'); 28 | } 29 | 30 | return isLoggedIn; /* this.auth.session.pipe( 31 | take(1), 32 | map(session => !!session), 33 | tap(loggedIn => { 34 | if (!loggedIn) { 35 | return this.router.navigate(['/']); 36 | } 37 | }) 38 | );*/ 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/services/rdf.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { SolidSession } from '../models/solid-session.model'; 3 | declare let solid: any; 4 | declare let $rdf: any; 5 | //import * as $rdf from 'rdflib' 6 | 7 | // TODO: Remove any UI interaction from this service 8 | import { NgForm } from '@angular/forms'; 9 | import { ToastrService } from 'ngx-toastr'; 10 | 11 | const VCARD = $rdf.Namespace('http://www.w3.org/2006/vcard/ns#'); 12 | const FOAF = $rdf.Namespace('http://xmlns.com/foaf/0.1/'); 13 | 14 | /** 15 | * A service layer for RDF data manipulation using rdflib.js 16 | * @see https://solid.inrupt.com/docs/manipulating-ld-with-rdflib 17 | */ 18 | @Injectable({ 19 | providedIn: 'root', 20 | }) 21 | export class RdfService { 22 | 23 | session: SolidSession; 24 | store = $rdf.graph(); 25 | 26 | /** 27 | * A helper object that connects to the web, loads data, and saves it back. More powerful than using a simple 28 | * store object. 29 | * When you have a fetcher, then you also can ask the query engine to go fetch new linked data automatically 30 | * as your query makes its way across the web. 31 | * @see http://linkeddata.github.io/rdflib.js/doc/Fetcher.html 32 | */ 33 | fetcher = $rdf.Fetcher; 34 | 35 | /** 36 | * The UpdateManager allows you to send small changes to the server to “patch” the data as your user changes data in 37 | * real time. It also allows you to subscribe to changes other people make to the same file, keeping track of 38 | * upstream and downstream changes, and signaling any conflict between them. 39 | * @see http://linkeddata.github.io/rdflib.js/doc/UpdateManager.html 40 | */ 41 | updateManager = $rdf.UpdateManager; 42 | 43 | constructor (private toastr: ToastrService) { 44 | const fetcherOptions = {}; 45 | this.fetcher = new $rdf.Fetcher(this.store, fetcherOptions); 46 | this.updateManager = new $rdf.UpdateManager(this.store); 47 | this.getSession(); 48 | } 49 | 50 | /** 51 | * Fetches the session from Solid, and store results in localStorage 52 | */ 53 | getSession = async() => { 54 | this.session = await solid.auth.currentSession(localStorage); 55 | } 56 | 57 | /** 58 | * Gets a node that matches the specified pattern using the VCARD onthology 59 | * 60 | * any() can take a subject and a predicate to find Any one person identified by the webId 61 | * that matches against the node/predicated 62 | * 63 | * @param {string} node VCARD predicate to apply to the $rdf.any() 64 | * @param {string?} webId The webId URL (e.g. https://yourpod.solid.community/profile/card#me) 65 | * @return {string} The value of the fetched node or an emtpty string 66 | * @see https://github.com/solid/solid-tutorial-rdflib.js 67 | */ 68 | getValueFromVcard = (node: string, webId?: string): string | any => { 69 | return this.getValueFromNamespace(node, VCARD, webId); 70 | }; 71 | 72 | /** 73 | * Gets a node that matches the specified pattern using the FOAF onthology 74 | * @param {string} node FOAF predicate to apply to the $rdf.any() 75 | * @param {string?} webId The webId URL (e.g. https://yourpod.solid.community/profile/card#me) 76 | * @return {string} The value of the fetched node or an emtpty string 77 | */ 78 | getValueFromFoaf = (node: string, webId?: string) => { 79 | return this.getValueFromNamespace(node, FOAF, webId); 80 | }; 81 | 82 | transformDataForm = (form: NgForm, me: any, doc: any) => { 83 | const insertions = []; 84 | const deletions = []; 85 | const fields = Object.keys(form.value); 86 | const oldProfileData = JSON.parse(localStorage.getItem('oldProfileData')) || {}; 87 | 88 | // We need to split out into three code paths here: 89 | // 1. There is an old value and a new value. This is the update path 90 | // 2. There is no old value and a new value. This is the insert path 91 | // 3. There is an old value and no new value. Ths is the delete path 92 | // These are separate codepaths because the system needs to know what to do in each case 93 | fields.map(field => { 94 | 95 | let predicate = VCARD(this.getFieldName(field)); 96 | let subject = this.getUriForField(field, me); 97 | let why = doc; 98 | 99 | let fieldValue = this.getFieldValue(form, field); 100 | let oldFieldValue = this.getOldFieldValue(field, oldProfileData); 101 | 102 | // if there's no existing home phone number or email address, we need to add one, then add the link for hasTelephone or hasEmail 103 | if(!oldFieldValue && fieldValue && (field === 'phone' || field==='email')) { 104 | this.addNewLinkedField(field, insertions, predicate, fieldValue, why, me); 105 | } else { 106 | 107 | //Add a value to be updated 108 | if (oldProfileData[field] && form.value[field] && !form.controls[field].pristine) { 109 | deletions.push($rdf.st(subject, predicate, oldFieldValue, why)); 110 | insertions.push($rdf.st(subject, predicate, fieldValue, why)); 111 | } 112 | 113 | //Add a value to be deleted 114 | else if (oldProfileData[field] && !form.value[field] && !form.controls[field].pristine) { 115 | deletions.push($rdf.st(subject, predicate, oldFieldValue, why)); 116 | } 117 | 118 | //Add a value to be inserted 119 | else if (!oldProfileData[field] && form.value[field] && !form.controls[field].pristine) { 120 | insertions.push($rdf.st(subject, predicate, fieldValue, why)); 121 | } 122 | } 123 | }); 124 | 125 | return { 126 | insertions: insertions, 127 | deletions: deletions 128 | }; 129 | }; 130 | 131 | private addNewLinkedField(field, insertions, predicate, fieldValue, why, me: any) { 132 | //Generate a new ID. This id can be anything but needs to be unique. 133 | let newId = field + ':' + Date.now(); 134 | 135 | //Get a new subject, using the new ID 136 | let newSubject = $rdf.sym(this.session.webId.split('#')[0] + '#' + newId); 137 | 138 | //Set new predicate, based on email or phone fields 139 | let newPredicate = field === 'phone' ? $rdf.sym(VCARD('hasTelephone')) : $rdf.sym(VCARD('hasEmail')); 140 | 141 | //Add new phone or email to the pod 142 | insertions.push($rdf.st(newSubject, predicate, fieldValue, why)); 143 | 144 | //Set the type (defaults to Home/Personal for now) and insert it into the pod as well 145 | //Todo: Make this dynamic 146 | let type = field === 'phone' ? $rdf.literal('Home') : $rdf.literal('Personal'); 147 | insertions.push($rdf.st(newSubject, VCARD('type'), type, why)); 148 | 149 | //Add a link in #me to the email/phone number (by id) 150 | insertions.push($rdf.st(me, newPredicate, newSubject, why)); 151 | } 152 | 153 | private getUriForField(field, me): string { 154 | let uriString: string; 155 | let uri: any; 156 | 157 | switch(field) { 158 | case 'phone': 159 | uriString = this.getValueFromVcard('hasTelephone'); 160 | if(uriString) { 161 | uri = $rdf.sym(uriString); 162 | } 163 | break; 164 | case 'email': 165 | uriString = this.getValueFromVcard('hasEmail'); 166 | if(uriString) { 167 | uri = $rdf.sym(uriString); 168 | } 169 | break; 170 | default: 171 | uri = me; 172 | break; 173 | } 174 | 175 | return uri; 176 | } 177 | 178 | /** 179 | * Extracts the value of a field of a NgForm and converts it to a $rdf.NamedNode 180 | * @param {NgForm} form 181 | * @param {string} field The name of the field that is going to be extracted from the form 182 | * @return {RdfNamedNode} 183 | */ 184 | private getFieldValue(form: NgForm, field: string): any { 185 | let fieldValue: any; 186 | 187 | if(!form.value[field]) { 188 | return; 189 | } 190 | 191 | switch(field) { 192 | case 'phone': 193 | fieldValue = $rdf.sym('tel:+'+form.value[field]); 194 | break; 195 | case 'email': 196 | fieldValue = $rdf.sym('mailto:'+form.value[field]); 197 | break; 198 | default: 199 | fieldValue = form.value[field]; 200 | break; 201 | } 202 | 203 | return fieldValue; 204 | } 205 | 206 | private getOldFieldValue(field, oldProfile): any { 207 | let oldValue: any; 208 | 209 | if(!oldProfile || !oldProfile[field]) { 210 | return; 211 | } 212 | 213 | switch(field) { 214 | case 'phone': 215 | oldValue = $rdf.sym('tel:+'+oldProfile[field]); 216 | break; 217 | case 'email': 218 | oldValue = $rdf.sym('mailto:'+oldProfile[field]); 219 | break; 220 | default: 221 | oldValue = oldProfile[field]; 222 | break; 223 | } 224 | 225 | return oldValue; 226 | } 227 | 228 | private getFieldName(field): string { 229 | switch (field) { 230 | case 'company': 231 | return 'organization-name'; 232 | case 'phone': 233 | case 'email': 234 | return 'value'; 235 | default: 236 | return field; 237 | } 238 | } 239 | 240 | updateProfile = async (form: NgForm) => { 241 | const me = $rdf.sym(this.session.webId); 242 | const doc = $rdf.NamedNode.fromValue(this.session.webId.split('#')[0]); 243 | const data = this.transformDataForm(form, me, doc); 244 | 245 | //Update existing values 246 | if(data.insertions.length > 0 || data.deletions.length > 0) { 247 | this.updateManager.update(data.deletions, data.insertions, (response, success, message) => { 248 | if(success) { 249 | this.toastr.success('Your Solid profile has been successfully updated', 'Success!'); 250 | form.form.markAsPristine(); 251 | form.form.markAsTouched(); 252 | } else { 253 | this.toastr.error('Message: '+ message, 'An error has occurred'); 254 | } 255 | }); 256 | } 257 | }; 258 | 259 | getAddress = () => { 260 | const linkedUri = this.getValueFromVcard('hasAddress'); 261 | 262 | if (linkedUri) { 263 | return { 264 | locality: this.getValueFromVcard('locality', linkedUri), 265 | country_name: this.getValueFromVcard('country-name', linkedUri), 266 | region: this.getValueFromVcard('region', linkedUri), 267 | street: this.getValueFromVcard('street-address', linkedUri), 268 | }; 269 | } 270 | 271 | return {}; 272 | }; 273 | 274 | //Function to get email. This returns only the first email, which is temporary 275 | getEmail = () => { 276 | const linkedUri = this.getValueFromVcard('hasEmail'); 277 | 278 | if (linkedUri) { 279 | return this.getValueFromVcard('value', linkedUri).split('mailto:')[1]; 280 | } 281 | 282 | return ''; 283 | } 284 | 285 | //Function to get phone number. This returns only the first phone number, which is temporary. It also ignores the type. 286 | getPhone = () => { 287 | const linkedUri = this.getValueFromVcard('hasTelephone'); 288 | 289 | if(linkedUri) { 290 | return this.getValueFromVcard('value', linkedUri).split('tel:+')[1]; 291 | } 292 | }; 293 | 294 | getProfile = async () => { 295 | 296 | if (!this.session) { 297 | await this.getSession(); 298 | } 299 | 300 | try { 301 | await this.fetcher.load(this.session.webId); 302 | 303 | return { 304 | fn : this.getValueFromVcard('fn'), 305 | company : this.getValueFromVcard('organization-name'), 306 | phone: this.getPhone(), 307 | role: this.getValueFromVcard('role'), 308 | image: this.getValueFromVcard('hasPhoto'), 309 | address: this.getAddress(), 310 | email: this.getEmail(), 311 | }; 312 | } catch (error) { 313 | console.log(`Error fetching data: ${error}`); 314 | } 315 | }; 316 | 317 | /** 318 | * Gets any resource that matches the node, using the provided Namespace 319 | * @param {string} node The name of the predicate to be applied using the provided Namespace 320 | * @param {$rdf.namespace} namespace The RDF Namespace 321 | * @param {string?} webId The webId URL (e.g. https://yourpod.solid.community/profile/card#me) 322 | */ 323 | private getValueFromNamespace(node: string, namespace: any, webId?: string): string | any { 324 | const store = this.store.any($rdf.sym(webId || this.session.webId), namespace(node)); 325 | if (store) { 326 | return store.value; 327 | } 328 | return ''; 329 | } 330 | } 331 | -------------------------------------------------------------------------------- /generators/app/templates/src/app/services/solid.auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | import { Observable, from } from 'rxjs'; 4 | import { RdfService } from './rdf.service'; 5 | import { SolidProvider } from '../models/solid-provider.model'; 6 | declare let solid: any; 7 | 8 | interface SolidSession { 9 | accessToken: string; 10 | clientId: string; 11 | idToken: string; 12 | sessionKey: string; 13 | webId: string; 14 | } 15 | 16 | @Injectable({ 17 | providedIn: 'root', 18 | }) 19 | export class AuthService { 20 | session: Observable<{} | SolidSession>; 21 | fechInit = { 22 | method: 'PATCH', 23 | headers: { 24 | 'Content-Type': 'application/sparql-update', 25 | }, 26 | body: '', 27 | }; 28 | 29 | constructor(private router: Router, private rdf: RdfService) { 30 | this.isSessionActive(); 31 | } 32 | 33 | /* 34 | * This will check if current session is active to avoid security problems 35 | */ 36 | isSessionActive = async () => { 37 | this.session = from(solid.auth.currentSession()); 38 | } 39 | 40 | /** 41 | * Alternative login-popup function. This will open a popup that will allow you to choose an identity provider 42 | * without leaving the current page 43 | * This is recommended if you don't want to leave the current workflow. 44 | */ 45 | solidLoginPopup = async () => { 46 | try { 47 | await solid.auth.popupLogin({ popupUri: './login-popup'}); 48 | // Check if session is valid to avoid redirect issues 49 | await this.isSessionActive(); 50 | 51 | // popupLogin success redirect to profile 52 | this.router.navigate(['/card']); 53 | } catch (error) { 54 | console.log(`Error: ${error}`); 55 | } 56 | } 57 | 58 | /* 59 | * Signs out of Solid in this app, by calling the logout function and clearing the localStorage token 60 | */ 61 | solidSignOut = async () => { 62 | try { 63 | await solid.auth.logout(); 64 | // Remove localStorage 65 | localStorage.removeItem('solid-auth-client'); 66 | // Redirect to login page 67 | this.router.navigate(['/']); 68 | } catch (error) { 69 | console.log(`Error: ${error}`); 70 | } 71 | } 72 | 73 | saveOldUserData = (profile: any) => { 74 | if (!localStorage.getItem('oldProfileData')) { 75 | localStorage.setItem('oldProfileData', JSON.stringify(profile)); 76 | } 77 | } 78 | 79 | getOldUserData = () => { 80 | return JSON.parse(localStorage.getItem('oldProfileData')); 81 | } 82 | 83 | /* 84 | * Make a call to the solid auth endpoint. It requires an identity provider url, which here is coming from the dropdown, which 85 | * is populated by the getIdentityProviders() function call. It currently requires a callback url and a storage option or else 86 | * the call will fail. 87 | */ 88 | solidLogin = async (idp: string) => { 89 | await solid.auth.login(idp, { 90 | callbackUri: `${window.location.href}card`, 91 | storage: localStorage, 92 | }); 93 | } 94 | 95 | /** 96 | * Function to get providers. This is to mimic the future provider registry 97 | * 98 | * @return {SolidProvider[]} A list of SolidProviders 99 | */ 100 | getIdentityProviders(): SolidProvider[] { 101 | const inruptProvider: SolidProvider = { 102 | name: 'Inrupt', 103 | image: '/assets/images/Inrupt.png', 104 | loginUrl: 'https://inrupt.net/auth', 105 | desc: 'Inrupt Inc. provider' 106 | }; 107 | const solidCommunityProvider: SolidProvider = { 108 | name: 'Solid Community', 109 | image: '/assets/images/Solid.png', 110 | loginUrl: 'https://solid.community', 111 | desc: 'A provider maintained by the Solid Community' 112 | }; 113 | const otherProvider: SolidProvider = { 114 | name: 'Other (Enter WebID)', 115 | image: '/assets/images/Generic.png', 116 | loginUrl: null, 117 | desc: 'Generic provider' 118 | }; 119 | 120 | return [ 121 | inruptProvider, 122 | solidCommunityProvider, 123 | otherProvider 124 | ]; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /generators/app/templates/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/generator-solid-angular/0461c0016fb15398259a5b9b0e9b1d5d781e0be5/generators/app/templates/src/assets/.gitkeep -------------------------------------------------------------------------------- /generators/app/templates/src/assets/images/Generic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/generator-solid-angular/0461c0016fb15398259a5b9b0e9b1d5d781e0be5/generators/app/templates/src/assets/images/Generic.png -------------------------------------------------------------------------------- /generators/app/templates/src/assets/images/Inrupt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/generator-solid-angular/0461c0016fb15398259a5b9b0e9b1d5d781e0be5/generators/app/templates/src/assets/images/Inrupt.png -------------------------------------------------------------------------------- /generators/app/templates/src/assets/images/JD.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /generators/app/templates/src/assets/images/Solid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/generator-solid-angular/0461c0016fb15398259a5b9b0e9b1d5d781e0be5/generators/app/templates/src/assets/images/Solid.png -------------------------------------------------------------------------------- /generators/app/templates/src/assets/images/Solid_Pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/generator-solid-angular/0461c0016fb15398259a5b9b0e9b1d5d781e0be5/generators/app/templates/src/assets/images/Solid_Pattern.png -------------------------------------------------------------------------------- /generators/app/templates/src/assets/images/jd-logo_red_hex_only.svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/generator-solid-angular/0461c0016fb15398259a5b9b0e9b1d5d781e0be5/generators/app/templates/src/assets/images/jd-logo_red_hex_only.svg.png -------------------------------------------------------------------------------- /generators/app/templates/src/assets/images/profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/generator-solid-angular/0461c0016fb15398259a5b9b0e9b1d5d781e0be5/generators/app/templates/src/assets/images/profile.png -------------------------------------------------------------------------------- /generators/app/templates/src/assets/types/rdflib/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 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 | -------------------------------------------------------------------------------- /generators/app/templates/src/assets/types/rdflib/README.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | > `npm install --save @types/rdflib` 3 | 4 | # Summary 5 | This package contains type definitions for rdflib (https://github.com/linkeddata/rdflib.js). 6 | 7 | # Details 8 | Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/rdflib 9 | 10 | Additional Details 11 | * Last updated: Sat, 04 Aug 2018 00:56:31 GMT 12 | * Dependencies: none 13 | * Global values: none 14 | 15 | # Credits 16 | These definitions were written by Cénotélie . 17 | -------------------------------------------------------------------------------- /generators/app/templates/src/assets/types/rdflib/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for rdflib 0.17 2 | // Project: https://github.com/linkeddata/rdflib.js 3 | // Definitions by: Cénotélie 4 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 5 | // Acknowledgements: This work has been financed by Logilab SA, FRANCE, logilab.fr 6 | 7 | /** 8 | * Class orders 9 | */ 10 | export const ClassOrder: { 11 | [id: string]: number; 12 | }; 13 | /** 14 | * A type for values that serves as inputs 15 | */ 16 | export type ValueType = Node | Date | string | number | boolean | undefined; 17 | /** 18 | * The superclass of all RDF Statement objects, that is NamedNode, Literal, BlankNode, etc. 19 | */ 20 | export class Node { 21 | /** 22 | * The type of node 23 | */ 24 | termType: string; 25 | /** 26 | * Whether this node is a variable 27 | */ 28 | isVar: boolean; 29 | /** 30 | * The class order for this node 31 | */ 32 | classOrder: number; 33 | /** 34 | * The nod's value 35 | */ 36 | value: string; 37 | /** 38 | * Gets the substituted node for this one, according to the specified bindings 39 | * @param bindings Bindings of identifiers to nodes 40 | */ 41 | substitute(bindings: { [id: string]: Node }): Node; 42 | /** 43 | * Compares this node with another 44 | * @param term The other node 45 | */ 46 | compareTerm(term: Node): number; 47 | /** 48 | * Gets whether the two nodes are equal 49 | * @param other The other node 50 | */ 51 | equals(other: Node): boolean; 52 | /** 53 | * Gets a hash for this node 54 | */ 55 | hashString(): string; 56 | /** 57 | * Gets whether this node is the same as the other one 58 | * @param other Another node 59 | */ 60 | sameTerm(other: Node): boolean; 61 | /** 62 | * Gets the canonical string representation of this node 63 | */ 64 | toCanonical(): string; 65 | /** 66 | * Gets the n-triples string representation of this node 67 | */ 68 | toNT(): string; 69 | /** 70 | * Gets the string representation of this node 71 | */ 72 | toString(): string; 73 | /** 74 | * Gets a node for the specifed input 75 | * @param value An input value 76 | */ 77 | static fromValue(value: ValueType): Node | ValueType; 78 | /** 79 | * Gets the javascript object equivalent to a node 80 | * @param term The RDF node 81 | */ 82 | static toJS(term: Node): any; 83 | } 84 | /** 85 | * An empty node 86 | */ 87 | export class Empty extends Node { 88 | constructor(); 89 | static termType: string; 90 | } 91 | /** 92 | * A collection of other RDF nodes 93 | */ 94 | export class Collection extends Node { 95 | /** 96 | * The identifier for this collection 97 | */ 98 | id: string; 99 | /** 100 | * The nodes in this collection 101 | */ 102 | elements: Node[]; 103 | /** 104 | * Whether this collection is closed 105 | */ 106 | closed: boolean; 107 | /** 108 | * Initializes this collection 109 | * @param initial The initial elements 110 | */ 111 | constructor(initial: ReadonlyArray); 112 | /** 113 | * Appends an element to this collection 114 | * @param element The new element 115 | */ 116 | append(element: Node): number; 117 | /** 118 | * Closes this collection 119 | */ 120 | close(): boolean; 121 | /** 122 | * Removes the first element from the collection (and return it) 123 | */ 124 | shift(): Node; 125 | /** 126 | * Preprends the specified element to the colelction's front 127 | * @param element The element to preprend 128 | */ 129 | unshift(element: Node): number; 130 | static termType: string; 131 | } 132 | /** 133 | * An RDF blank node 134 | */ 135 | export class BlankNode extends Node { 136 | /** 137 | * The identifier for the blank node 138 | */ 139 | id: string; 140 | /** 141 | * Whether this is a blank node 142 | */ 143 | isBlank: boolean; 144 | /** 145 | * Initializes this node 146 | * @param id The identifier for the blank node 147 | */ 148 | constructor(id: string); 149 | /** 150 | * Gets a copy of this blank node in the specified formula 151 | * @param formula The formula 152 | */ 153 | copy(formula: Formula): BlankNode; 154 | /** 155 | * The next unique identifier for blank nodes 156 | */ 157 | static nextId: number; 158 | static termType: string; 159 | static NTAnonymousNodePrefix: string; 160 | } 161 | /** 162 | * A named (IRI) RDF node 163 | */ 164 | export class NamedNode extends Node { 165 | /** 166 | * The URI for this node 167 | */ 168 | uri: string; 169 | /** 170 | * Initializes this node 171 | * @param iri The IRI for this node 172 | */ 173 | constructor(iri: NamedNode | string); 174 | /** 175 | * Returns an RDF node for the containing directory, ending in slash. 176 | */ 177 | dir(): NamedNode; 178 | /** 179 | * Returns an named node for the whole web site, ending in slash. 180 | * Contrast with the "origin" which does NOT have a trailing slash 181 | */ 182 | site(): NamedNode; 183 | /** 184 | * Gets the named node for the document 185 | */ 186 | doc(): NamedNode; 187 | static termType: string; 188 | /** 189 | * Gets a named node from the specified input value 190 | * @param value An input value 191 | */ 192 | static fromValue(value: ValueType): NamedNode | ValueType; 193 | } 194 | /** 195 | * A RDF literal node 196 | */ 197 | export class Literal extends Node { 198 | /** 199 | * The language for the literal 200 | */ 201 | lang: string; 202 | /** 203 | * The language for the literal 204 | */ 205 | language: string; 206 | /** 207 | * The literal's datatype as a named node 208 | */ 209 | datatype: NamedNode; 210 | /** 211 | * Initializes this literal 212 | * @param value The literal's lexical value 213 | * @param language The language for the literal 214 | * @param datatype The literal's datatype as a named node 215 | */ 216 | constructor(value: string, language: string, datatype: NamedNode); 217 | /** 218 | * Gets a copy of this literal 219 | */ 220 | copy(): Literal; 221 | static termType: string; 222 | /** 223 | * Builds a literal node from a boolean value 224 | * @param value The value 225 | */ 226 | static fromBoolean(value: boolean): Literal; 227 | /** 228 | * Builds a literal node from a date value 229 | * @param value The value 230 | */ 231 | static fromDate(value: Date): Literal; 232 | /** 233 | * Builds a literal node from a number value 234 | * @param value The value 235 | */ 236 | static fromNumber(value: number): Literal; 237 | /** 238 | * Builds a literal node from an input value 239 | * @param value The input value 240 | */ 241 | static fromValue(value: ValueType): Literal | ValueType; 242 | } 243 | /** 244 | * Variables are placeholders used in patterns to be matched. 245 | * In cwm they are symbols which are the formula's list of quantified variables. 246 | * In sparql they are not visibly URIs. Here we compromise, by having 247 | * a common special base URI for variables. Their names are uris, 248 | * but the ? notation has an implicit base uri of 'varid:' 249 | */ 250 | export class Variable extends Node { 251 | /** 252 | * The base string for a variable's name 253 | */ 254 | base: string; 255 | /** 256 | * The unique identifier of this variable 257 | */ 258 | uri: string; 259 | /** 260 | * Initializes this variable 261 | * @param name The variable's name 262 | */ 263 | constructor(name: string); 264 | static termType: string; 265 | } 266 | /** 267 | * The RDF default graph 268 | */ 269 | export class DefaultGraph extends Node { 270 | /** 271 | * Initializes this graph 272 | */ 273 | constructor(); 274 | } 275 | export namespace uri { 276 | /** 277 | * Gets the document part of an URI 278 | * @param uri The URI 279 | */ 280 | function docpart(uri: string): string; 281 | /** 282 | * Gets the document part of an URI as a named node 283 | * @param x The URI 284 | */ 285 | function document(x: string): NamedNode; 286 | /** 287 | * Gets the hostname in an URI 288 | * @param u The URI 289 | */ 290 | function hostpart(u: string): string; 291 | /** 292 | * Joins an URI with a base 293 | * @param given The relative part 294 | * @param base The base URI 295 | */ 296 | function join(given: string, base: string): string; 297 | /** 298 | * Gets the protocol part of an URI 299 | * @param uri The URI 300 | */ 301 | function protocol(uri: string): string; 302 | /** 303 | * Gets a relative uri 304 | * @param base The base URI 305 | * @param uri The absolute URI 306 | */ 307 | function refTo(base: string, uri: string): string; 308 | } 309 | export namespace log { 310 | /** 311 | * Logs a debug event 312 | * @param x The event 313 | */ 314 | function debug(x: any): void; 315 | /** 316 | * Logs a warning event 317 | * @param x The event 318 | */ 319 | function warn(x: any): void; 320 | /** 321 | * Logs an information event 322 | * @param x The event 323 | */ 324 | function info(x: any): void; 325 | /** 326 | * Logs an error event 327 | * @param x The event 328 | */ 329 | function error(x: any): void; 330 | /** 331 | * Logs a success event 332 | * @param x The event 333 | */ 334 | function success(x: any): void; 335 | /** 336 | * Logs a message event 337 | * @param x The event 338 | */ 339 | function msg(x: any): void; 340 | } 341 | /** 342 | * An RDF statement (subject, predicate, object) 343 | */ 344 | export class Statement { 345 | /** 346 | * The statement's subject 347 | */ 348 | subject: Node; 349 | /** 350 | * The statement's predicate 351 | */ 352 | predicate: Node; 353 | /** 354 | * The statement's object 355 | */ 356 | object: Node; 357 | /** 358 | * The origin of this statement 359 | */ 360 | why: ValueType; 361 | /** 362 | * The graph the contains this statement 363 | */ 364 | graph: ValueType; 365 | /** 366 | * Initializes this statement 367 | * @param subject The statement's subject 368 | * @param predicate The statement's predicate 369 | * @param object The statement's object 370 | * @param graph The graph the contains this statement 371 | */ 372 | constructor( 373 | subject: ValueType, 374 | predicate: ValueType, 375 | object: ValueType, 376 | graph: ValueType 377 | ); 378 | /** 379 | * Gets whether two statements are the same 380 | * @param other The other statement 381 | */ 382 | equals(other: Statement): boolean; 383 | /** 384 | * Gets this statement with the bindings substituted 385 | * @param bindings The bindings 386 | */ 387 | substitute(bindings: { [id: string]: Node }): Statement; 388 | /** 389 | * Gets the canonical string representation of this statement 390 | */ 391 | toCanonical(): string; 392 | /** 393 | * Gets the n-triples string representation of this statement 394 | */ 395 | toNT(): string; 396 | /** 397 | * Gets the string representation of this statement 398 | */ 399 | toString(): string; 400 | } 401 | export namespace convert { 402 | /** 403 | * Converts an n3 string to JSON 404 | * @param n3String The n3 string 405 | * @param jsonCallback Callback when the operation terminated 406 | */ 407 | function convertToJson( 408 | n3String: string, 409 | jsonCallback: (err: string, jsonString: string) => void 410 | ): void; 411 | /** 412 | * Converts an n3 string to n-quads 413 | * @param n3String The n3 string 414 | * @param nquadCallback Callback when the operation terminated 415 | */ 416 | function convertToNQuads( 417 | n3String: string, 418 | nquadCallback: (err: string, nquadString: string) => void 419 | ): void; 420 | } 421 | /** 422 | * A formula, or store of RDF statements 423 | */ 424 | export class Formula extends Node { 425 | /** 426 | * The stored statements 427 | */ 428 | statements: Statement[]; 429 | /** 430 | * Initializes this formula 431 | * @param statements The initial statements in this formulat 432 | * @param constraints The additional constraints 433 | * @param initBindings The initial bindings 434 | * @param optional 435 | */ 436 | constructor( 437 | statements: ReadonlyArray, 438 | constraints: ReadonlyArray, 439 | initBindings: { 440 | [id: string]: Node; 441 | }, 442 | optional: ReadonlyArray 443 | ); 444 | /** 445 | * Adds a statement to this formula 446 | * @param s The subject 447 | * @param p The predicate 448 | * @param o The object 449 | * @param g The graph that contains the statement 450 | */ 451 | add(s: ValueType, p: ValueType, o: ValueType, g: ValueType): number; 452 | /** 453 | * Adds a statement to this formula 454 | * @param st The statement to add 455 | */ 456 | addStatement(st: Statement): number; 457 | /** 458 | * Gets a node that matches the specified pattern 459 | * @param s The subject 460 | * @param p The predicate 461 | * @param o The object 462 | * @param g The graph that contains the statement 463 | */ 464 | any(s: ValueType, p: ValueType, o?: ValueType, g?: ValueType): Node; 465 | /** 466 | * Gets a blank node 467 | * @param id The node's identifier 468 | */ 469 | bnode(id: string): BlankNode; 470 | /** 471 | * Finds the types in the list which have no *stored* subtypes 472 | * These are a set of classes which provide by themselves complete 473 | * information -- the other classes are redundant for those who 474 | * know the class DAG. 475 | * @param types A map of the types 476 | */ 477 | bottomTypeURIs(types: { 478 | [id: string]: string | NamedNode; 479 | }): { 480 | [id: string]: string | NamedNode; 481 | }; 482 | /** 483 | * Gets a new collection 484 | */ 485 | collection(): Collection; 486 | /** 487 | * Gets each node that matches the specified pattern 488 | * @param s The subject 489 | * @param p The predicate 490 | * @param o The object 491 | * @param g The graph that contains the statement 492 | */ 493 | each(s: ValueType, p: ValueType, o: ValueType, g: ValueType): Node[]; 494 | /** 495 | * Gets whether this formula is equals to the other one 496 | * @param other The other formula 497 | */ 498 | equals(other: Formula): boolean; 499 | /** 500 | * For thisClass or any subclass, anything which has it is its type 501 | * or is the object of something which has the type as its range, or subject 502 | * of something which has the type as its domain 503 | * We don't bother doing subproperty (yet?)as it doesn't seeem to be used 504 | * much. 505 | * Get all the Classes of which we can RDFS-infer the subject is a member 506 | * @param thisClass A named node 507 | */ 508 | findMembersNT( 509 | thisClass: Node 510 | ): { 511 | [uri: string]: Statement; 512 | }; 513 | /** 514 | * For thisClass or any subclass, anything which has it is its type 515 | * or is the object of something which has the type as its range, or subject 516 | * of something which has the type as its domain 517 | * We don't bother doing subproperty (yet?)as it doesn't seeem to be used 518 | * much. 519 | * Get all the Classes of which we can RDFS-infer the subject is a member 520 | * @param subject A named node 521 | */ 522 | findMemberURIs( 523 | subject: Node 524 | ): { 525 | [uri: string]: Statement; 526 | }; 527 | /** 528 | * Get all the Classes of which we can RDFS-infer the subject is a superclass 529 | * Returns a hash table where key is NT of type and value is statement why we 530 | * think so. 531 | * Does NOT return terms, returns URI strings. 532 | * We use NT representations in this version because they handle blank nodes. 533 | * @param subject A subject node 534 | */ 535 | findSubClassesNT( 536 | subject: Node 537 | ): { 538 | [uri: string]: boolean; 539 | }; 540 | /** 541 | * Get all the Classes of which we can RDFS-infer the subject is a subclass 542 | * Returns a hash table where key is NT of type and value is statement why we 543 | * think so. 544 | * Does NOT return terms, returns URI strings. 545 | * We use NT representations in this version because they handle blank nodes. 546 | * @param subject A subject node 547 | */ 548 | findSuperClassesNT( 549 | subject: Node 550 | ): { 551 | [uri: string]: boolean; 552 | }; 553 | /** 554 | * Get all the Classes of which we can RDFS-infer the subject is a member 555 | * todo: This will loop is there is a class subclass loop (Sublass loops are 556 | * not illegal) 557 | * Returns a hash table where key is NT of type and value is statement why we 558 | * think so. 559 | * Does NOT return terms, returns URI strings. 560 | * We use NT representations in this version because they handle blank nodes. 561 | * @param subject A subject node 562 | */ 563 | findTypesNT( 564 | subject: Node 565 | ): { 566 | [uri: string]: boolean; 567 | }; 568 | /** 569 | * Get all the Classes of which we can RDFS-infer the subject is a member 570 | * todo: This will loop is there is a class subclass loop (Sublass loops are 571 | * not illegal) 572 | * Returns a hash table where key is NT of type and value is statement why we 573 | * think so. 574 | * Does NOT return terms, returns URI strings. 575 | * We use NT representations in this version because they handle blank nodes. 576 | * @param subject A subject node 577 | */ 578 | findTypeURIs( 579 | subject: Node 580 | ): { 581 | [uri: string]: boolean; 582 | }; 583 | /** 584 | * Trace the statements which connect directly, or through bnodes 585 | * Returns an array of statements 586 | * doc param may be null to search all documents in store 587 | * @param subject A subject node 588 | * @param doc A document (the graph that contains statements) 589 | * @param excludePredicateURIs The predicate URIs to exclude 590 | */ 591 | connectedStatements( 592 | subject: Node, 593 | doc: ValueType, 594 | excludePredicateURIs: ReadonlyArray 595 | ): Statement[]; 596 | /** 597 | * Creates a new empty formula 598 | */ 599 | formula(): Formula; 600 | /** 601 | * Creates a new empty indexed formulat 602 | * @param features The list of features 603 | */ 604 | formula(features: ReadonlyArray): IndexedFormula; 605 | /** 606 | * Transforms an NTriples string format into a Node. 607 | * The bnode bit should not be used on program-external values; designed 608 | * for internal work such as storing a bnode id in an HTML attribute. 609 | * This will only parse the strings generated by the vaious toNT() methods. 610 | * @param str A string representation 611 | */ 612 | fromNT(str: string): Node; 613 | /** 614 | * Gets whether this formula holds the specified statement 615 | * @param s A subject 616 | * @param p A predicate 617 | * @param o An object 618 | * @param g A containing graph 619 | */ 620 | holds(s: ValueType, p: ValueType, o: ValueType, g: ValueType): boolean; 621 | /** 622 | * Gets whether this formula holds the specified statement 623 | * @param s A statement 624 | */ 625 | holds(s: Statement | ReadonlyArray): boolean; 626 | /** 627 | * Gets whether this formula holds the specified statement 628 | * @param st A statement 629 | */ 630 | holdsStatement(st: Statement): boolean; 631 | /** 632 | * Gets a collection from a list of values 633 | * @param values The values 634 | */ 635 | list(values: Iterable): Collection; 636 | /** 637 | * Gets a literal node 638 | * @param val The literal's lexical value 639 | * @param lang The language 640 | * @param dt The datatype as a named node 641 | */ 642 | literal(val: string, lang: string, dt: NamedNode): Literal; 643 | /** 644 | * Transform a collection of NTriple URIs into their URI strings 645 | * @param t some iterable colletion of NTriple URI strings 646 | * @return a collection of the URIs as strings 647 | */ 648 | NTtoURI(t: { 649 | [uri: string]: any; 650 | }): { 651 | [uri: string]: any; 652 | }; 653 | /** 654 | * Serializes this formula 655 | * @param base The base string 656 | * @param contentType The content type of the syntax to use 657 | * @param provenance The provenance URI 658 | */ 659 | serialize(base: string, contentType: string, provenance: string): string; 660 | /** 661 | * Gets a new formula with the substituting bindings applied 662 | * @param bindings The bindings to substitute 663 | */ 664 | substitute(bindings: { [id: string]: Node }): Formula; 665 | /** 666 | * Gets an named node for an URI 667 | * @param uri The URI 668 | */ 669 | sym(uri: string | NamedNode): NamedNode; 670 | /** 671 | * Gets the node matching the specified pattern 672 | * @param s The subject 673 | * @param p The predicate 674 | * @param o The object 675 | * @param g The graph that contains the statement 676 | */ 677 | the(s: ValueType, p: ValueType, o: ValueType, g: ValueType): Node; 678 | /** 679 | * RDFS Inference 680 | * These are hand-written implementations of a backward-chaining reasoner 681 | * over the RDFS axioms. 682 | * @param seeds A hash of NTs of classes to start with 683 | * @param predicate The property to trace though 684 | * @param inverse Trace inverse direction 685 | */ 686 | transitiveClosure( 687 | seeds: { 688 | [uri: string]: boolean; 689 | }, 690 | predicate: Node, 691 | inverse: Node 692 | ): { 693 | [uri: string]: boolean; 694 | }; 695 | /** 696 | * Finds the types in the list which have no *stored* supertypes 697 | * We exclude the universal class, owl:Things and rdf:Resource, as it is 698 | * information-free. 699 | * @param types The types 700 | */ 701 | topTypeURIs(types: { 702 | [id: string]: string | NamedNode; 703 | }): { 704 | [id: string]: string | NamedNode; 705 | }; 706 | /** 707 | * Gets the number of statements in this formulat that matches the specified pattern 708 | * @param s The subject 709 | * @param p The predicate 710 | * @param o The object 711 | * @param g The graph that contains the statement 712 | */ 713 | whether(s: ValueType, p: ValueType, o: ValueType, g: ValueType): number; 714 | /** 715 | * Serializes this formulat to a string 716 | */ 717 | toString(): string; 718 | /** 719 | * Gets a namespace for the specified namespace's URI 720 | * @param nsuri The URI for the namespace 721 | */ 722 | ns(nsuri: string): (ln: string) => NamedNode; 723 | /** 724 | * Gets a new variable 725 | * @param name The variable's name 726 | */ 727 | variable(name: string): Variable; 728 | static termType: string; 729 | } 730 | /** 731 | * A formula (set of triples) which indexes by predicate, subject and object. 732 | * It "smushes" (merges into a single node) things which are identical 733 | * according to owl:sameAs or an owl:InverseFunctionalProperty 734 | * or an owl:FunctionalProperty 735 | */ 736 | export class IndexedFormula extends Formula { 737 | /** 738 | * The number of statements in this formula 739 | */ 740 | length: number; 741 | /** 742 | * Creates a new formula 743 | * @param features The list of features to support 744 | */ 745 | constructor(features: ReadonlyArray); 746 | /** 747 | * Gets the URI of the default graph 748 | */ 749 | static defaultGraphURI(): string; 750 | /** 751 | * Gets the statements matching the specified pattern 752 | * @param subj The subject 753 | * @param pred The predicate 754 | * @param obj The object 755 | * @param why The graph that contains the statement 756 | * @param justOne Whether to only get one statement 757 | */ 758 | statementsMatching( 759 | subj: Node, 760 | pred: Node, 761 | obj: Node, 762 | why: Node, 763 | justOne: boolean 764 | ): Statement[]; 765 | /** 766 | * Adds all the statements to this formula 767 | * @param statements A collection of statements 768 | */ 769 | addAll(statements: Iterable): void; 770 | /** 771 | * Gets the value of a node that matches the specified pattern 772 | * @param s The subject 773 | * @param p The predicate 774 | * @param o The object 775 | * @param g The graph that contains the statement 776 | */ 777 | anyValue(s: ValueType, p: ValueType, o: ValueType, g: ValueType): string; 778 | /** 779 | * Returns the symbol with canonical URI as smushed 780 | * @param term A RDF node 781 | */ 782 | canon(term: Node): Node; 783 | /** 784 | * Checks this formula for consistency 785 | */ 786 | check(): void; 787 | /** 788 | * Checks a list of statements for consistency 789 | * @param sts The list of statements to check 790 | * @param from An index with the array ['subject', 'predicate', 'object', 'why'] 791 | */ 792 | checkStatementList(sts: ReadonlyArray, from: number): boolean; 793 | /** 794 | * Closes this formula (and return it) 795 | */ 796 | close(): IndexedFormula; 797 | /** 798 | * Simplify graph in store when we realize two identifiers are equivalent 799 | * We replace the bigger with the smaller. 800 | * @param u1 The first node 801 | * @param u2 The second node 802 | */ 803 | equate(u1: Node, u2: Node): boolean; 804 | /** 805 | * eturns any quads matching the given arguments. 806 | * Standard RDFJS Taskforce method for Source objects, implemented as an 807 | * alias to `statementsMatching()` 808 | * @param subject The subject 809 | * @param predicate The predicate 810 | * @param object The object 811 | * @param graph The graph that contains the statement 812 | */ 813 | match( 814 | subject: ValueType, 815 | predicate: ValueType, 816 | object: ValueType, 817 | graph: ValueType 818 | ): Statement[]; 819 | /** 820 | * Find out whether a given URI is used as symbol in the formula 821 | * @param uri The URI to look for 822 | */ 823 | mentionsURI(uri: string): boolean; 824 | /** 825 | * Existentials are BNodes - something exists without naming 826 | * @param uri An URI 827 | */ 828 | newExistential(uri: string): Node; 829 | /** 830 | * Creates a new universal node 831 | * Universals are Variables 832 | * @param uri An URI 833 | */ 834 | newUniversal(uri: string): Node; 835 | /** 836 | * Find an unused id for a file being edited: return a symbol 837 | * (Note: Slow iff a lot of them -- could be O(log(k)) ) 838 | * @param doc A document named node 839 | */ 840 | nextSymbol(doc: NamedNode): NamedNode; 841 | /** 842 | * Removes a statement from this formula 843 | * @param st A statement to remove 844 | */ 845 | remove(st: Statement): IndexedFormula; 846 | /** 847 | * Removes all statemnts in a doc 848 | * @param doc The document 849 | */ 850 | removeDocument(doc: NamedNode): IndexedFormula; 851 | /** 852 | * Remove all statements matching args (within limit) * 853 | * @param subj The subject 854 | * @param pred The predicate 855 | * @param obj The object 856 | * @param why The graph that contains the statement 857 | * @param limit The number of statements to remove 858 | */ 859 | removeMany( 860 | subj: Node, 861 | pred: Node, 862 | obj: Node, 863 | why: Node, 864 | limit: number 865 | ): void; 866 | /** 867 | * Remove all matching statements 868 | * @param subject The subject 869 | * @param predicate The predicate 870 | * @param object The object 871 | * @param graph The graph that contains the statement 872 | */ 873 | removeMatches( 874 | subject: ValueType, 875 | predicate: ValueType, 876 | object: ValueType, 877 | graph: ValueType 878 | ): void; 879 | /** 880 | * Removes a statement 881 | * @param st The statement to remove 882 | */ 883 | removeStatement(st: Statement): Formula; 884 | /** 885 | * Removes statements 886 | * @param sts The statements to remove 887 | */ 888 | removeStatements(sts: ReadonlyArray): Formula; 889 | /** 890 | * Return all equivalent URIs by which this is known 891 | * @param x A named node 892 | */ 893 | allAliases(x: NamedNode): NamedNode[]; 894 | /** 895 | * Compare by canonical URI as smushed 896 | * @param x A named node 897 | * @param y Another named node 898 | */ 899 | sameThings(x: NamedNode, y: NamedNode): boolean; 900 | /** 901 | * A list of all the URIs by which this thing is known 902 | * @param term 903 | */ 904 | uris(term: NamedNode): string[]; 905 | } 906 | export namespace DataFactory { 907 | /** 908 | * Creates a new blank node 909 | * @param value The blank node's identifier 910 | */ 911 | function blankNode(value: string): BlankNode; 912 | /** 913 | * Creates a new collection 914 | * @param elements The initial element 915 | */ 916 | function collection(elements: ReadonlyArray): Collection; 917 | /** 918 | * Gets the default graph 919 | */ 920 | function defaultGraph(): DefaultGraph; 921 | /** 922 | * Creates a new fetcher 923 | * @param store The store to use 924 | * @param options The options 925 | */ 926 | function fetcher(store: Formula, options: any): Fetcher; 927 | /** 928 | * Creates a new graph (store) 929 | */ 930 | function graph(): IndexedFormula; 931 | /** 932 | * Creates a new literal node 933 | * @param val The lexical value 934 | * @param lang The language 935 | * @param dt The datatype 936 | */ 937 | function lit(val: string, lang: string, dt: NamedNode): Literal; 938 | /** 939 | * Creates a new literal node 940 | * @param value The lexical value 941 | * @param languageOrDatatype Either the language or the datatype 942 | */ 943 | function literal( 944 | value: string, 945 | languageOrDatatype: string | NamedNode 946 | ): Literal; 947 | /** 948 | * Creates a new named node 949 | * @param value The new named node 950 | */ 951 | function namedNode(value: string): NamedNode; 952 | /** 953 | * Creates a new statement 954 | * @param subject The subject 955 | * @param predicate The predicate 956 | * @param object The object 957 | * @param graph The containing graph 958 | */ 959 | function quad( 960 | subject: Node, 961 | predicate: Node, 962 | object: Node, 963 | graph: Node 964 | ): Statement; 965 | /** 966 | * Creates a new statement 967 | * @param subject The subject 968 | * @param predicate The predicate 969 | * @param object The object 970 | * @param graph The containing graph 971 | */ 972 | function st( 973 | subject: Node, 974 | predicate: Node, 975 | object: Node, 976 | graph: Node 977 | ): Statement; 978 | /** 979 | * Creates a new statement 980 | * @param subject The subject 981 | * @param predicate The predicate 982 | * @param object The object 983 | */ 984 | function triple(subject: Node, predicate: Node, object: Node): Statement; 985 | /** 986 | * Creates a new variable 987 | * @param name The name for the variable 988 | */ 989 | function variable(name: string): Variable; 990 | } 991 | export namespace Util { 992 | /** 993 | * Gets a named node for a media type 994 | * @param mediaType A media type 995 | */ 996 | function mediaTypeClass(mediaType: string): NamedNode; 997 | /** 998 | * Gets a named node from the name of a relation 999 | * @param relation The name of a relation 1000 | */ 1001 | function linkRelationProperty(relation: string): NamedNode; 1002 | /** 1003 | * Loads ontologies of the data we load (this is the callback from the kb to 1004 | * the fetcher). Exports as `AJAR_handleNewTerm` 1005 | * @param kb The store 1006 | * @param p A property 1007 | * @param requestedBy 1008 | */ 1009 | function AJAR_handleNewTerm( 1010 | kb: Formula, 1011 | p: NamedNode, 1012 | requestedBy: string 1013 | ): Promise; 1014 | } 1015 | /** 1016 | * A datatype-specific handler for fetching data 1017 | */ 1018 | export interface Handler { 1019 | response: any; 1020 | dom: any; 1021 | } 1022 | /** 1023 | * Responsible for fetching RDF data 1024 | */ 1025 | export class Fetcher { 1026 | store: any; 1027 | timeout: number; 1028 | appNode: BlankNode; 1029 | requested: { 1030 | [uri: string]: any; 1031 | }; 1032 | timeouts: any; 1033 | redirectedTo: any; 1034 | constructor(store: any, options: any); 1035 | static HANDLERS: { 1036 | RDFXMLHandler: Handler; 1037 | XHTMLHandler: Handler; 1038 | XMLHandler: Handler; 1039 | HTMLHandler: Handler; 1040 | TextHandler: Handler; 1041 | N3Handler: Handler; 1042 | }; 1043 | static CONTENT_TYPE_BY_EXT: { 1044 | [ext: string]: string; 1045 | }; 1046 | /** 1047 | * Promise-based load function 1048 | * 1049 | * Loads a web resource or resources into the store. 1050 | * 1051 | * A resource may be given as NamedNode object, or as a plain URI. 1052 | * an array of resources will be given, in which they will be fetched in parallel. 1053 | * By default, the HTTP headers are also recorded, in the same store, in a separate graph. 1054 | * This allows, for example, code like editable() to test the resource. 1055 | * 1056 | * @param uri {Array|Array|NamedNode|string} 1057 | * 1058 | * @param [options={}] {Object} 1059 | * 1060 | * @param [options.fetch] {Function} 1061 | * 1062 | * @param [options.referringTerm] {NamedNode} Referring term, the resource which 1063 | * referred to this (for tracking bad links) 1064 | * 1065 | * @param [options.contentType] {string} Provided content type (for writes) 1066 | * 1067 | * @param [options.forceContentType] {string} Override the incoming header to 1068 | * force the data to be treated as this content-type (for reads) 1069 | * 1070 | * @param [options.force] {boolean} Load the data even if loaded before. 1071 | * Also sets the `Cache-Control:` header to `no-cache` 1072 | * 1073 | * @param [options.baseURI=docuri] {Node|string} Original uri to preserve 1074 | * through proxying etc (`xhr.original`). 1075 | * 1076 | * @param [options.proxyUsed] {boolean} Whether this request is a retry via 1077 | * a proxy (generally done from an error handler) 1078 | * 1079 | * @param [options.withCredentials] {boolean} flag for XHR/CORS etc 1080 | * 1081 | * @param [options.clearPreviousData] {boolean} Before we parse new data, 1082 | * clear old, but only on status 200 responses 1083 | * 1084 | * @param [options.noMeta] {boolean} Prevents the addition of various metadata 1085 | * triples (about the fetch request) to the store 1086 | * 1087 | * @param [options.noRDFa] {boolean} 1088 | * 1089 | * @returns {Promise} 1090 | */ 1091 | load (uri: Array|Array|NamedNode|string, options?: Object) 1092 | } 1093 | /** 1094 | * The update manager is a helper object for a store. 1095 | * Just as a Fetcher provides the store with the ability to read and write, 1096 | * the Update Manager provides functionality for making small patches in real time, 1097 | * and also looking out for concurrent updates from other agents 1098 | */ 1099 | export class UpdateManager { 1100 | store: IndexedFormula; 1101 | ifps: any; 1102 | fps: any; 1103 | ns: any; 1104 | /** 1105 | * @param {IndexedFormula} store - the quadstore to store data and metadata. Created if not passed.f 1106 | */ 1107 | constructor(store?: IndexedFormula); 1108 | /** 1109 | * This high-level function updates the local store if the web has been changed 1110 | * successfully. 1111 | * 1112 | * Deletions, insertions may be undefined or single statements or lists or formulae 1113 | * (may contain bnodes which can be indirectly identified by a where clause). 1114 | * The `why` property of each statement must be the same and give the web document to be updated 1115 | * 1116 | * @param deletions - Statement or statments to be deleted. 1117 | * @param insertions - Statement or statements to be inserted 1118 | * 1119 | * @param callback {Function} called as callback(uri, success, errorbody) 1120 | * 1121 | * @returns {*} 1122 | */ 1123 | update (deletions?, insertions?, callback?, secondTry?) 1124 | } 1125 | /** 1126 | * Gets a node for the specified input 1127 | * @param value An input value 1128 | */ 1129 | export function term(value: ValueType): Node | Collection | ValueType; 1130 | /** 1131 | * Gets a namespace 1132 | * @param nsuri The URI for the namespace 1133 | */ 1134 | export function Namespace(nsuri: string): (ln: string) => NamedNode; 1135 | /** 1136 | * Transforms an NTriples string format into a Node. 1137 | * The bnode bit should not be used on program-external values; designed 1138 | * for internal work such as storing a bnode id in an HTML attribute. 1139 | * This will only parse the strings generated by the vaious toNT() methods. 1140 | * @param str A string representation 1141 | */ 1142 | export function fromNT(str: string): Node; 1143 | /** 1144 | * Creates a new fetcher 1145 | * @param store The store to use 1146 | * @param options The options 1147 | */ 1148 | export function fetcher(store: Formula, options: any): Fetcher; 1149 | /** 1150 | * Creates a new graph (store) 1151 | */ 1152 | export function graph(): IndexedFormula; 1153 | /** 1154 | * Creates a new literal node 1155 | * @param val The lexical value 1156 | * @param lang The language 1157 | * @param dt The datatype 1158 | */ 1159 | export function lit(val: string, lang: string, dt: NamedNode): Literal; 1160 | /** 1161 | * Creates a new statement 1162 | * @param subject The subject 1163 | * @param predicate The predicate 1164 | * @param object The object 1165 | * @param graph The containing graph 1166 | */ 1167 | export function st( 1168 | subject: Node, 1169 | predicate: Node, 1170 | object: Node, 1171 | graph: Node 1172 | ): Statement; 1173 | /** 1174 | * Creates a new named node 1175 | * @param value The new named node 1176 | */ 1177 | export function sym(value: string): NamedNode; 1178 | /** 1179 | * Creates a new variable 1180 | * @param name The name for the variable 1181 | */ 1182 | export function variable(name: string): Variable; 1183 | /** 1184 | * Creates a new blank node 1185 | * @param value The blank node's identifier 1186 | */ 1187 | export function blankNode(value: string): BlankNode; 1188 | /** 1189 | * Gets the default graph 1190 | */ 1191 | export function defaultGraph(): DefaultGraph; 1192 | /** 1193 | * Creates a new literal node 1194 | * @param value The lexical value 1195 | * @param languageOrDatatype Either the language or the datatype 1196 | */ 1197 | export function literal( 1198 | value: string, 1199 | languageOrDatatype: string | NamedNode 1200 | ): Literal; 1201 | /** 1202 | * Creates a new named node 1203 | * @param value The new named node 1204 | */ 1205 | export function namedNode(value: string): NamedNode; 1206 | /** 1207 | * Creates a new statement 1208 | * @param subject The subject 1209 | * @param predicate The predicate 1210 | * @param object The object 1211 | * @param graph The containing graph 1212 | */ 1213 | export function quad( 1214 | subject: Node, 1215 | predicate: Node, 1216 | object: Node, 1217 | graph: Node 1218 | ): Statement; 1219 | /** 1220 | * Creates a new statement 1221 | * @param subject The subject 1222 | * @param predicate The predicate 1223 | * @param object The object 1224 | */ 1225 | export function triple(subject: Node, predicate: Node, object: Node): Statement; 1226 | /** 1227 | * Parse a string and put the result into the graph kb. 1228 | * Normal method is sync. 1229 | * Unfortunately jsdonld is currently written to need to be called async. 1230 | * Hence the mess below with executeCallback. 1231 | * @param str The input string to parse 1232 | * @param kb The store to use 1233 | * @param base The base URI to use 1234 | * @param contentType The content type for the input 1235 | * @param callback The callback to call when the data has been loaded 1236 | */ 1237 | export function parse( 1238 | str: string, 1239 | kb: Formula, 1240 | base: string, 1241 | contentType: string, 1242 | callback: (error: any, kb: Formula) => void 1243 | ): void; 1244 | /** 1245 | * Get the next available unique identifier 1246 | */ 1247 | export let NextId: number; 1248 | -------------------------------------------------------------------------------- /generators/app/templates/src/assets/types/rdflib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "@types/rdflib", 3 | "_id": "@types/rdflib@0.17.0", 4 | "_inBundle": false, 5 | "_integrity": "sha512-AoJnpg+G6pz4E8kCQlGTpJVCrFJgYDQkh12YbabOKhAxyHMOs/DMkT0el+zYmIYDze+e3kcAwwM0c2uSoZq2zw==", 6 | "_location": "/@types/rdflib", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "tag", 10 | "registry": true, 11 | "raw": "@types/rdflib", 12 | "name": "@types/rdflib", 13 | "escapedName": "@types%2frdflib", 14 | "scope": "@types", 15 | "rawSpec": "", 16 | "saveSpec": null, 17 | "fetchSpec": "latest" 18 | }, 19 | "_requiredBy": [ 20 | "#DEV:/", 21 | "#USER" 22 | ], 23 | "_resolved": "https://registry.npmjs.org/@types/rdflib/-/rdflib-0.17.0.tgz", 24 | "_shasum": "1d7aacc4dacb466b504758cca12a40bf53bb7fcd", 25 | "_spec": "@types/rdflib", 26 | "_where": "/Users/alfredo/projects/ng-solid-material", 27 | "bugs": { 28 | "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/issues" 29 | }, 30 | "bundleDependencies": [], 31 | "contributors": [ 32 | { 33 | "name": "Cénotélie", 34 | "url": "https://github.com/cenotelie" 35 | } 36 | ], 37 | "dependencies": {}, 38 | "deprecated": false, 39 | "description": "TypeScript definitions for rdflib", 40 | "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped#readme", 41 | "license": "MIT", 42 | "main": "", 43 | "name": "@types/rdflib", 44 | "repository": { 45 | "type": "git", 46 | "url": "git+https://github.com/DefinitelyTyped/DefinitelyTyped.git" 47 | }, 48 | "scripts": {}, 49 | "typeScriptVersion": "2.0", 50 | "typesPublisherContentHash": "e47de20f5f69dff9556700bb57af6d3c8a588c207749f5c6d32c79aece3146e6", 51 | "version": "0.17.0" 52 | } 53 | -------------------------------------------------------------------------------- /generators/app/templates/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 -------------------------------------------------------------------------------- /generators/app/templates/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /generators/app/templates/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 | }; 8 | 9 | /* 10 | * In development mode, to ignore zone related error stack frames such as 11 | * `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can 12 | * import the following file, but please comment it out in production mode 13 | * because it will have performance impact when throw error 14 | */ 15 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 16 | -------------------------------------------------------------------------------- /generators/app/templates/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/generator-solid-angular/0461c0016fb15398259a5b9b0e9b1d5d781e0be5/generators/app/templates/src/favicon.ico -------------------------------------------------------------------------------- /generators/app/templates/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SolidApp 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /generators/app/templates/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 | }; -------------------------------------------------------------------------------- /generators/app/templates/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.log(err)); 13 | -------------------------------------------------------------------------------- /generators/app/templates/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/weak-map'; 35 | // import 'core-js/es6/set'; 36 | 37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 38 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 39 | 40 | /** IE10 and IE11 requires the following for the Reflect API. */ 41 | // import 'core-js/es6/reflect'; 42 | 43 | 44 | /** Evergreen browsers require these. **/ 45 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. 46 | import 'core-js/es7/reflect'; 47 | 48 | 49 | /** 50 | * Web Animations `@angular/platform-browser/animations` 51 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 52 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 53 | **/ 54 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 55 | 56 | /** 57 | * By default, zone.js will patch all possible macroTask and DomEvents 58 | * user can disable parts of macroTask/DomEvents patch by setting following flags 59 | */ 60 | 61 | // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 62 | // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 63 | // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 64 | 65 | /* 66 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 67 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 68 | */ 69 | // (window as any).__Zone_enable_cross_context_check = true; 70 | 71 | /*************************************************************************************************** 72 | * Zone JS is required by default for Angular itself. 73 | */ 74 | import 'zone.js/dist/zone'; // Included with Angular CLI. 75 | 76 | 77 | 78 | /*************************************************************************************************** 79 | * APPLICATION IMPORTS 80 | */ 81 | -------------------------------------------------------------------------------- /generators/app/templates/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | button.wide-button { 3 | width: 360px; 4 | height: 40px; 5 | border-radius: 4px; 6 | background-color: #3D6DEB; 7 | font-size: 14px; 8 | color: #fff; 9 | font-family: 'Roboto', sans-serif; 10 | text-transform: uppercase; 11 | letter-spacing: 1.25px; 12 | line-height: 16px; 13 | cursor: pointer; 14 | } 15 | 16 | button.wide-button:disabled { 17 | background-color: #F0EEEB; 18 | border-color: #F0EEEB; 19 | cursor: not-allowed; 20 | } 21 | 22 | input[type=text].wide-text { 23 | width: 360px; 24 | height: 40px; 25 | border-radius: 4px; 26 | border: 1px solid #89969F; 27 | font-size: 14px; 28 | color: #666; 29 | } 30 | 31 | 32 | /* Styling custom dropdown */ 33 | 34 | /* This selector is for the whole control, not the dropdown itself */ 35 | .ng-select.login-select { 36 | 37 | } 38 | 39 | /* This selector is for the actual dropdown container (aka border, arrow, etc) */ 40 | .ng-select.login-select .ng-select-container { 41 | border: 2px solid #3D6DEB; 42 | } 43 | .ng-select.login-select.ng-select-opened>.ng-select-container { 44 | border: 2px solid #3D6DEB; 45 | border-radius: 4px; 46 | } 47 | 48 | 49 | .ng-select.login-select.ng-select-single .ng-select-container { 50 | height: 48px; 51 | } 52 | 53 | /* This selector is for the dropdown selection items container */ 54 | .ng-select.login-select .ng-dropdown-panel { 55 | margin-left: -180px; 56 | margin-top: -2px; 57 | border: 2px solid #3D6DEB; 58 | } 59 | 60 | .ng-select.login-select .ng-input input { 61 | font-family: 'Roboto', sans-serif; 62 | font-size: 16px; 63 | color: #666; 64 | margin-top: 6px; 65 | } 66 | 67 | /* This selector is for the dropdown arrow */ 68 | .ng-select.login-select .ng-arrow:after { 69 | 70 | } 71 | 72 | -------------------------------------------------------------------------------- /generators/app/templates/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 | -------------------------------------------------------------------------------- /generators/app/templates/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "es2015", 6 | "types": [], 7 | "paths": { 8 | "zlib": ["node_modules/browserify-zlib/lib/index.js"], 9 | "http": ["node_modules/@angular/http"], 10 | "https": ["node_modules/@angular/http"], 11 | "stream": ["node_modules/jszip/dist/jszip.min.js"], 12 | "TextEncoder": ["node_modules/text-encoding"], 13 | "fetch": ["node_modules/isomorphic-fetch"], 14 | "crypto": ["node_modules/@trust/webcrypto"], 15 | "path": ["node_modules/path-dirname"], 16 | "solid-auth-client": ["node_modules/solid-auth-client/dist-lib/solid-auth-client.bundle.js"], 17 | "child_process": ["node_modules/stdio"], 18 | //"RSASSA-PKCS1-v1_5": ["node_modules/@trust/webcrypto/src/algorithms/RSASSA-PKCS1-v1_5.js"], 19 | "window": ["node_modules/whatwg-url"] 20 | } 21 | }, 22 | "exclude": [ 23 | "src/test.ts", 24 | "**/*.spec.ts" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /generators/app/templates/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "module": "commonjs", 6 | "types": [ 7 | "jasmine", 8 | "node" 9 | ] 10 | }, 11 | "files": [ 12 | "test.ts", 13 | "polyfills.ts" 14 | ], 15 | "include": [ 16 | "**/*.spec.ts", 17 | "**/*.d.ts" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /generators/app/templates/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 | -------------------------------------------------------------------------------- /generators/app/templates/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "moduleResolution": "node", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es5", 12 | "typeRoots": [ 13 | "node_modules/@types", 14 | // Adding Custom Types 15 | "assets/types" 16 | ], 17 | "lib": [ 18 | "es2017", 19 | "dom" 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /generators/app/templates/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "arrow-return-shorthand": true, 7 | "callable-types": true, 8 | "class-name": true, 9 | "comment-format": [ 10 | true, 11 | "check-space" 12 | ], 13 | "curly": true, 14 | "deprecation": { 15 | "severity": "warn" 16 | }, 17 | "eofline": true, 18 | "forin": true, 19 | "import-blacklist": [ 20 | true, 21 | "rxjs/Rx" 22 | ], 23 | "import-spacing": true, 24 | "indent": [ 25 | true, 26 | "spaces" 27 | ], 28 | "interface-over-type-literal": true, 29 | "label-position": true, 30 | "max-line-length": [ 31 | true, 32 | 140 33 | ], 34 | "member-access": false, 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-arg": true, 47 | "no-bitwise": true, 48 | "no-console": [ 49 | true, 50 | "debug", 51 | "info", 52 | "time", 53 | "timeEnd", 54 | "trace" 55 | ], 56 | "no-construct": true, 57 | "no-debugger": true, 58 | "no-duplicate-super": true, 59 | "no-empty": false, 60 | "no-empty-interface": true, 61 | "no-eval": true, 62 | "no-inferrable-types": [ 63 | true, 64 | "ignore-params" 65 | ], 66 | "no-misused-new": true, 67 | "no-non-null-assertion": true, 68 | "no-shadowed-variable": true, 69 | "no-string-literal": false, 70 | "no-string-throw": true, 71 | "no-switch-case-fall-through": true, 72 | "no-trailing-whitespace": true, 73 | "no-unnecessary-initializer": true, 74 | "no-unused-expression": true, 75 | "no-use-before-declare": true, 76 | "no-var-keyword": true, 77 | "object-literal-sort-keys": false, 78 | "one-line": [ 79 | true, 80 | "check-open-brace", 81 | "check-catch", 82 | "check-else", 83 | "check-whitespace" 84 | ], 85 | "prefer-const": true, 86 | "quotemark": [ 87 | true, 88 | "single" 89 | ], 90 | "radix": true, 91 | "semicolon": [ 92 | true, 93 | "always" 94 | ], 95 | "triple-equals": [ 96 | true, 97 | "allow-null-check" 98 | ], 99 | "typedef-whitespace": [ 100 | true, 101 | { 102 | "call-signature": "nospace", 103 | "index-signature": "nospace", 104 | "parameter": "nospace", 105 | "property-declaration": "nospace", 106 | "variable-declaration": "nospace" 107 | } 108 | ], 109 | "unified-signatures": true, 110 | "variable-name": false, 111 | "whitespace": [ 112 | true, 113 | "check-branch", 114 | "check-decl", 115 | "check-operator", 116 | "check-separator", 117 | "check-type" 118 | ], 119 | "no-output-on-prefix": true, 120 | "use-input-property-decorator": true, 121 | "use-output-property-decorator": true, 122 | "use-host-property-decorator": true, 123 | "no-input-rename": true, 124 | "no-output-rename": true, 125 | "use-life-cycle-interface": true, 126 | "use-pipe-transform-interface": true, 127 | "component-class-suffix": true, 128 | "directive-class-suffix": true 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@inrupt/generator-solid-angular", 3 | "version": "0.1.8", 4 | "description": "Yeoman generator for Solid using Angular", 5 | "files": [ 6 | "generators" 7 | ], 8 | "keywords": [ 9 | "yeoman-generator" 10 | ], 11 | "dependencies": { 12 | "figlet": "^1.2.0", 13 | "yeoman-generator": "^4.0.1", 14 | "yosay": "^2.0.2" 15 | }, 16 | "main": "generators/app/index.js", 17 | "scripts": { 18 | "test": "echo \"Error: no test specified\" && exit 1" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/Inrupt-inc/generator-solid-angular.git" 23 | }, 24 | "author": "James Martin", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/Inrupt-inc/generator-solid-angular/issues" 28 | }, 29 | "homepage": "https://github.com/Inrupt-inc/generator-solid-angular#readme" 30 | } 31 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # ⛔ Archived 2 | This project is now archived and no longer maintained. 3 | We do not currently have supported components for Angular. 4 | We do however have supported components for React which can be found in this [repository](https://github.com/inrupt/solid-ui-react). 5 | Supported components will always use the latest [Solid client libraries](https://github.com/inrupt/solid-client-js) from [Inrupt](https://inrupt.com). 6 | We will continue to make components and libraries available for other frameworks and languages and you can find announcements on new releases on our [website](https://inrupt.com/blog). 7 | 8 | 9 | # ⛔ Solid Angular Yeoman Generator 10 | 11 | A yeoman generator to help you get up and running quickly using Solid and Angular. Running the generator will create a sample Angular profile editor application using Solid. 12 | 13 | ## ⛔ Getting Started 14 | 15 | The below instructions will get you up and running with a Solid app in a matter of minutes. 16 | 17 | ### ⛔ Prerequisites 18 | 19 | You will need a few things to get started. The first is npm, as you will need to install the app using npm. You will also likely need angular-cli installed globally. 20 | 21 | You can do this by running the following command 22 | 23 | ``` 24 | npm install -g @angular/cli 25 | ``` 26 | 27 | Another thing you will need to install manually is yeoman itself, if you don't already have it. You can install yeoman using the following command: 28 | ``` 29 | npm install -g yo 30 | ``` 31 | 32 | ### ⛔ Installing 33 | 34 | The easiest way to install the yeoman generator is using npm. To install, you can run the command 35 | ``` 36 | npm install -g @inrupt/generator-solid-angular 37 | ``` 38 | 39 | ## ⛔ Using the Generator 40 | 41 | Once it's installed, you can run the generator using a command line interface. First, navigate to the parent folder you wish to create the new project. Next, run the command 42 | ``` 43 | yo @inrupt/solid-angular 44 | ``` 45 | This will open a prompt with a few questions, such as the project name. Note the project name will also be your root folder name. 46 | 47 | The generator will then install the angular and solid project files, then run npm install for you. 48 | 49 | Once the generator has finished running, you can navigate into the newly created project folder and run the command 50 | ``` 51 | ng serve 52 | ``` 53 | That command is the regular angular-cli serve, and will launch the web app on your localhost, port 4200. 54 | 55 | With this running, you'll see a login page. 56 | --------------------------------------------------------------------------------