diff --git a/ANGULAR2-DOCS.md b/ANGULAR2-DOCS.md deleted file mode 100644 index 7a37ba98..00000000 --- a/ANGULAR2-DOCS.md +++ /dev/null @@ -1,293 +0,0 @@ -LoopBack SDK Buider 2.0.0 (Angular 2 Docs) -================== - -The LoopBack SDK Builder provides you with a set of tools, services and declaration files; making beyond easy to integrate our LoopBack API with any Angular 2 Application (web or mobile). - -## Setup - -You need to install and configure the `loopback-sdk-builder` as stated in the [README](https://www.npmjs.com/package/loopback-sdk-builder) File in order to generate the SDK Barrel. - -#### Client Requirements -Once you have the `SDK Barrel` generated, the following package needs to be installed in your client application. - -````sh -$ npm install --save @angular/http -```` - -##### Optional Requirements -If you are working in a real-time application, you are using the [loopback-component-pubsub](https://www.npmjs.com/package/loopback-component-pubsub) and you want to have built in support within your generated sdk; then one of the following packages needs to be installed in your client application. - -**When using the SDK for Web(View)** -````sh -$ npm install --save socket.io-client -```` - -**When using the SDK for NativeScript** -````sh -$ npm install --save nativescript-socket.io -```` - -## Configure Angular 2 Application - -Once you have everything installed, you need to configure your `Angular 2 Application`. - -`angular-web/app/main.ts` -````js -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { AppComponent } from './app.component'; -import { API_PROVIDERS, LoggerConfig } from './shared'; -LoggerConfig.enabled = true; -bootstrap(AppComponent, [...API_PROVIDERS]); -```` - -### or - -`native-script/app/main.ts` -````js -import { nativeScriptBootstrap } from "nativescript-angular/application"; -import { AppComponent } from "./app.component"; -import { API_PROVIDERS, LoggerConfig } from "./shared"; -LoggerConfig.enabled = true; -nativeScriptBootstrap(AppComponent, [ ...API_PROVIDERS ]); -```` - -Basically the only difference is the bootstrap component that is different between these platforms. - -## First Steps - -The very first thing you need to do after everything is installed within your Angular 2 Application, is to import and configure the sdk in the components you will be using it. - -````js -import { LoopBackConfig } from './shared'; -@Component(...) -export class AppComponent { - constructor() { - LoopBackConfig.setBaseURL('http://127.0.0.1:3000'); - LoopBackConfig.setApiVersion('api'); - } -} -```` - -This basic configuration needs to be done in every componente that will be implementing the SDK provided services. - -I know some of you may be asking your self; *Why do I need to configure this in every single component?* And the answer is because we want to decouple our components as possible, so each of these will have their own configuration, therefore you will be able to point your components to different API instances and versions. - -For instance, having a SSO will require you to point `+signin/up` component to a different API than the rest of the components. - -Also, it will be easier to move components between api versions. - -If none of these are your case, then you may want to create a base.url.ts file inside the `./shared` directory with the following content: - -````js -export const BASE_URL = 'http://127.0.0.1:3000'; -export const API_VERSION = 'api'; -```` - -And then just update your configuration as follows: - -````js -import { LoopBackConfig, BASE_URL, API_VERSION } from './shared'; -@Component(...) -export class AppComponent { - constructor() { - LoopBackConfig.setBaseURL(BASE_URL); - LoopBackConfig.setApiVersion(API_VERSION); - } -} -```` - -**IMPORTANT:** If you don't understand what barrels and the shared directory stands for, please read the [following link](https://angular.io/styleguide#-a-id-04-10-a-create-and-import-barrels) - -## Services, Interfaces and Models (SIM) -When generating your SDK; The LoopBack SDK Builder will create a SIM set for each Model you have defined in your LoopBack Application. - -#### Services -Services are regular Angular 2 `@Injectable()` Services that allows you to interact with your API either through standard RESTful communication or over WebSockets. - -#### Interfaces -Will declare all of the model properties defined in your LoopBack Application, it will even set these as optional or required according your model configuration. - -#### Models -Models are regular classes that will implement the model Interface and a constructor that allows to extend models to provide custom functionality. - -Models and Interfaces are a set of [TypeScript Declaration Files](https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html). - -## Naming Convention -While generating your SDK; the LoopBack SDK Builder will create each of these components for each Model you have defined in your LoopBack Application. - -- Services.- Adds an `Api` postfix to the Model name. -- Interfaces.- Adds an `Interface` postfix to the Model name. -- Model.- Is just the Model name. - -## Basic Example -In order to show you what the provided *SIMs* can do for you; let me put an example code as easy as pie. - -````js -import { Component } from '@angular/core'; -// Basically everything you need is provided by the SDK Barrel -import { - Account, - AccountApi, - TokenInterface, - BASE_URL, - API_VERSION, - LoopBackConfig -} from '../shared'; - -@Component(...) - -export class SignComponent { - - // Create model instances and set the right type effortless - private account: Account = new Account(); - - // Configure LoopBack Once or Individualy by Component - constructor(private accountApi: AccountApi) { - LoopBackConfig.setBaseURL(BASE_URL); - LoopBackConfig.setApiVersion(API_VERSION); - } - - // Start making API calls right away - private signup(): void { - this.accountApi.create(this.account).subscribe((account: Account) => this.signin()); - } - - // Built-in LoopBack Authentication and Typings like Account and TokenInterface - private signin(): void { - this.accountApi.login(this.account).subscribe((token: TokenInterface) => alert('Fake Redirect')); - } -} -```` - -As you can see, using the LoopBack SDK for Angular 2 is nice and easy... Now lets make an example of how to subscribe to published events by the server. - -## Real-Time Application Example - -````js -import { Component } from '@angular/core'; -import { RouteParams } from '@angular/router-deprecated'; - -import { - Room, - RoomApi, - AccountApi, - Message, - BASE_URL, - API_VERSION, - LoopBackConfig, -} from '../../shared'; - -@Component(...) - -export class RoomComponent { - // All the types you need already there - private room : Room = new Room(); - private message : Message = new Message(); - // All the services you need already there - constructor( - private accountApi: AccountApi, - private roomApi : RoomApi, - private params : RouteParams - ) { - LoopBackConfig.setBaseURL(BASE_URL); - LoopBackConfig.setApiVersion(API_VERSION); - this.getRoom(this.params.get('id')); - } - // Built in support for the LoopBack Query Language (Include, Where, Order, Limit, Offset, Etc...) - // Built in support for the LoopBack Component Pubsub (roomApi.onCreateMessages(id: RoomId)) - getRoom(id: any): void { - this.roomApi.findById(id, { - include: [ - { - relation: 'messages', - scope: { order: 'id DESC' } - } - ] - }).subscribe((room: Room) => { - this.room = room; - this.roomApi.onCreateMessages(this.room.id) - .subscribe((message: Message) => this.room['messages'].push(message)) - }); - } - - // Built in logged account functionality - sendMessage(): void { - this.message.accountId = this.accountApi.getCurrentId(); - this.roomApi.createMessages(this.room.id, this.message) - .subscribe(() => this.message = new Message()); - } -} -```` - -## Extending Models - -One of the new great features of the LoopBack SDK Builder it that allows you to extend models in order to add new functionality within models. - -In order to avoid working directly on models and lose information when re-generating the sdk, you will need to created a new `extended` folder within `shared` at the same level of `sdk` and create a model.extended.ts file: - -````js -import { Model } from '../../'; - -export class ModelExtended extends Model { - - constructor(json: Model) { super(json); } - - customFunction() { - return `${this.name}: ${this.description}`; - } -} -```` - -And then I implemented in the component as follows: - -````js -import { Model, ModelApi, ModelExtended , LoopBackConfig } from './shared'; - -... - - constructor(private modelApi: ModelApi) { - LoopBackConfig.setBaseURL('http://localhost:3000'); - LoopBackConfig.setApiVersion('api'); - modelApi - .create({ - name: 'My Model', - description: 'This is my super description' - }) - .map((model: Model) => new ModelExtended(model)) - .subscribe((model: ModelExtended) => { - console.log(modelExtended.customFunction()); - }); - } -```` - - -## Logger Service - -The LoggerService is a tool that wraps the `console` methods (log, info, warn, error, count, group, profile, etc.) but allowing you to disable/enable your logs for development/production mode. - -````js -import { LoggerService } from './shared'; -... -class MyComponent { - constructor(private loggerService: LoggerService) { - this.loggerServicer.info('Component is Loaded'); - } -} -```` - -**How to disable the LoggerService** - -`main.ts` -````js -import { LoggerConfig } from './shared'; -LoggerConfig.enabled = false; -```` - -## Tutorials - -- [The Ultimate Guide for Building Real Time Applications](http://mean.expert/2016/06/09/angular-2-ultimate-real-time/) -- [The Ultimate Guide for Building Native Applications](https://t.co/7YobnH5Iil) - -## Contact - -Discuss features and ask questions on [Twitter](https://twitter.com/johncasarrubias). diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e7cc211..b2938a0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,35 @@ This file is created to keep history of the LoopBack SDK Builder, it does not consider or keeps any history of its parent module `loopback-sdk-angular`. +## Release 2.0.0-stable + + +[LINK TO WIKI DOCUMENTATION](https://github.com/mean-expert-official/loopback-sdk-builder/wiki) + +- Support for Angular 2 (Final API w/ NgModules & Backwards compatibility < RC5). +- Support for TypeScript (Fully Typed). +- Built in Interfaces and Models. +- Extendable Models for custom logic. +- Enables Support for Real-Time Applications [loopback-component-pubsub](https://www.npmjs.com/package/loopback-component-pubsub) +- Built in LoopBack Authentication. +- Built in Support for LoopBack Query Language [Querying Data](https://docs.strongloop.com/display/public/LB/Querying+data) +- Built in API Servics. +- Built in Platform Specific Drivers (Angular2 for web, NativeScript2, ~~Angular Universal~~). +- Built in CLI Tool for builder. +- Built in Logger Service. +- Blacklist mechanism to select which models or methods generate. +- Ability to point models to different url domains (not global baseUrl) +- IO Heartbeating to avoid disconnections. +- Small foot print 100k per generated SDK (Will increase depending on number of models). + +- Fix: https://github.com/jonathan-casarrubias/loopback-sdk-builder/issues/92 +- Fix: https://github.com/jonathan-casarrubias/loopback-sdk-builder/issues/91 +- Fix: https://github.com/jonathan-casarrubias/loopback-sdk-builder/issues/87 +- Fix: https://github.com/jonathan-casarrubias/loopback-sdk-builder/issues/86 +- Fix: https://github.com/jonathan-casarrubias/loopback-sdk-builder/issues/45 +- Fix: https://github.com/jonathan-casarrubias/loopback-sdk-builder/issues/38 + + ## Release 2.0.0-rc.9.1 - Fix: https://github.com/jonathan-casarrubias/loopback-sdk-builder/issues/90 diff --git a/REACT-DOCS.md b/REACT-DOCS.md deleted file mode 100644 index 6484953e..00000000 --- a/REACT-DOCS.md +++ /dev/null @@ -1,4 +0,0 @@ -LoopBack SDK Buider 2.0.0 (ReactJS Docs) -================== - -TODO \ No newline at end of file diff --git a/README.md b/README.md index 7789e180..bf23a3fe 100644 --- a/README.md +++ b/README.md @@ -1,211 +1,43 @@ -[![NPM](https://nodei.co/npm/loopback-sdk-builder.png?stars&downloads)](https://nodei.co/npm/loopback-sdk-builder/) [![NPM](https://nodei.co/npm-dl/loopback-sdk-builder.png)](https://nodei.co/npm/loopback-sdk-builder/) - +[![NPM](https://nodei.co/npm/loopback-sdk-builder.png?stars&downloads)](https://nodei.co/npm/loopback-sdk-builder/) LoopBack SDK Builder ================== -The LoopBack SDK Builder is a community driven module forked from the official `loopback-sdk-angular` and maintained by [@johncasarrubias](http://twitter.com/johncasarrubias). - -# Fork Reasons - -Since the launch of [Angular 2 - Beta (now RC)](http://angular.io) the community has been requesting support for this version of the framework with a really slow response from the `StrongLoop Team` with many doubts if they will continue supporting the generator. - -[Read Here The GitHub Thread](https://github.com/strongloop/loopback-sdk-angular/issues/188) - -Also, the official proposed solution does not seems to be fully compatible with todays needs. For instance, the "same" Angular 2 SDK won't work the same depending on the environment you are running (NativeScript, Web, AngularUniversal). +The [loopback-sdk-builder](https://www.npmjs.com/package/loopback-sdk-builder) is a community driven module forked from the official `loopback-sdk-angular` and refactored to support [Angular 2](http://angular.io). -Since Angular 2 does not rely on a browser DOM, the SDK implementations may be different according the environment. +The [LoopBack SDK Builder](https://www.npmjs.com/package/loopback-sdk-builder) will explore your [LoopBack Application](http://loopback.io) and will automatically build everything you need to start writing your [Angular 2 Applications](http://angular.io) right away. From Interfaces and Models to API Services and Real-time communications. -[Read about the New Angular 2 Ecosystem](https://t.co/DrV18TztdR) - -# Disclaimer - -I really don't have any plan to support Angular 1, I'm not trying to compete with the official module. - -If you want to build a SDK for Angular 1 please use the official. +# Installation -[loopback-sdk-angular](https://www.npmjs.org/loopback-sdk-angular) +````sh +$ cd to/loopback/project +$ npm install --save-dev @mean-expert/loopback-sdk-builder +```` -# Coincidences +# Documentation -The client is dynamic, in other words it automatically includes all the -LoopBack models and methods you've defined on your server. -You don't have to manually write any static code. +[LINK TO WIKI DOCUMENTATION](https://github.com/mean-expert-official/loopback-sdk-builder/wiki) # Features +- Support for Angular 2 (Final API w/ NgModules & Backwards compatibility < RC5). +- Support for TypeScript (Fully Typed). +- Built in Interfaces and Models. +- Extendable Models for custom logic. +- Enables Support for Real-Time Applications [loopback-component-pubsub](https://www.npmjs.com/package/loopback-component-pubsub) - Built in LoopBack Authentication. - Built in Support for LoopBack Query Language [Querying Data](https://docs.strongloop.com/display/public/LB/Querying+data) -- Built in Interfaces and Models. -- Built in API Calls. -- Built in PubSub support for the [loopback-component-pubsub](https://www.npmjs.com/package/loopback-component-pubsub). +- Built in API Servics. - Built in Platform Specific Drivers (Angular2 for web, NativeScript2, ~~Angular Universal~~). - Built in CLI Tool for builder. - Built in Logger Service. -- Ability to select which models or methods to generate. +- Blacklist mechanism to select which models or methods generate. - Ability to point models to different url domains (not global baseUrl) - IO Heartbeating to avoid disconnections. -- Fully Typed (TypeScript). -- Extendable Models for custom logic. - Small foot print 100k per generated SDK (Will increase depending on number of models). -# Installation - -````sh -$ cd to/api/project -$ npm install --save-dev loopback-sdk-builder@2.0.0-rc.9.1 -```` - -# LoopBack SDK CLI Options - -````text -Options: - -l, --library Client's library (angular2, react , ...) [default: "angular2"] - -d, --driver Platform specific drivers (ng4web, nativescript2, ng2universal ) [default: "ng4web"] - -i, --io Enable PubSub functionality for loopback-component-pubsub [default: "disabled"] -```` - -#### Client Requirements -The following package needs to be installed in your client application. - -- [@angular/http](npmjs.com/package/@angular/http) - -#### Generate Angular 2 SDK for Web - -The default options will create an Angular 2 SDK for Web. - -```sh -$ ./node_modules/.bin/lb-sdk server/server.js /path/to/client/sdk -``` - -Is equivalent to - -```sh -$ ./node_modules/.bin/lb-sdk server/server.js /path/to/client/sdk -l angular2 -d ng4web -i disabled -``` - -#### Generate NativeScript 2 SDK - -```sh -$ ./node_modules/.bin/lb-sdk server/server.js /path/to/client/sdk -d nativescript2 -``` - -Is equivalent to - -```sh -$ ./node_modules/.bin/lb-sdk server/server.js /path/to/client/sdk -l angular2 -d nativescript2 -i disabled -``` - - -## Enable Real Time Communication - -The Angular2 and NativeScript generators currently implement socket connectivity when using [loopback-component-pubsub](https://www.npmjs.com/package/loopback-component-pubsub). - -**This version of the SDK Builder works with LoopBack Component PubSub Version 1.0.17 or above.** - -#### Requirements -The following package needs to be installed in your client application. - -- [nativescript-socket.io](npmjs.com/package/nativescript-socket.io) when using the NativeScript2 version -- [socket.io-client](https://www.npmjs.com/package/socket.io-client) when using the Angular 2 for Web version - -To enable you will need to add the `--io enabled` or `-i enabled` flag. - -#### Angular 2 for Web - -```sh -$ ./node_modules/.bin/lb-sdk server/server.js /path/to/client/sdk -d ng4web -i enabled -``` - -#### NativeScript 2 - -```sh -$ ./node_modules/.bin/lb-sdk server/server.js /path/to/client/sdk -d nativescript2 -i enabled -``` - -# Recomended Use - -Add a script within package.json - -```json -{ - "scripts": { - "build:sdk": "./node_modules/.bin/lb-sdk server/server path/to/ng2-app/src/app/shared/sdk -d [ng4web | nativescript2] -i [enabled | disabled]" - } -} -``` - -#### then: - -```sh -$ cd to/api/project -$ npm run build:sdk -``` - -Awesome you now can build SDK for different platforms!!! - - -# Disable Models or Methods - -In order to disable a full model add the following configuration - -````js -{ - "name": "Message", - "plural": "messages", - "base": "PersistedModel", - "sdk": { - "enabled": false // default is true - } -} -```` - -If you want to disable specific methods only - -````js -{ - "name": "Message", - "plural": "messages", - "base": "PersistedModel", - "sdk": { - "enabled": true, - "blacklist": { - "findOne": true // won't generate the findOne method - } - } -} -```` - -# Next Steps - -Now that you have built your SDK, you need to understand how to use it within your Angular 2 Applications - -[Angular 2 SDK Documentation](https://github.com/jonathan-casarrubias/loopback-sdk-builder/blob/master/ANGULAR2-DOCS.md) - -# Known Issues - -- The [nativescript-socket.io](npmjs.com/package/nativescript-socket.io) package may create issues on IOS when enabling IO for NativeScript. - -# TODO - -- Redux and ngrx support -- React Support - -# Tutorials - -- [The Ultimate Guide for Building Real Time Applications](http://mean.expert/2016/06/09/angular-2-ultimate-real-time/) -- [The Ultimate Guide for Building Native Apps](https://t.co/7YobnH5Iil) - # Contact -Discuss features and ask questions on [Twitter](https://twitter.com/johncasarrubias). - -# Donations -I haven't asked for donations before, but amazingly -and I'm thankful for it- some of you directly contacted me to provide a way to donate thanks to the value the set of modules that I publish and maintain are creating within your own projects. - -So, If you feel this project is super awesome and you want to support and make it grow and live longer; you are always free to donate any amount of you wish. - -**Of course this project will always remain open source and free of charge according the MTI License.** - +Discuss features and ask questions on [@johncasarrubias at Twitter](https://twitter.com/johncasarrubias). -[![DONATIONS](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ZPQVKZJTUJ3KW) \ No newline at end of file +[![NPM](https://nodei.co/npm-dl/loopback-sdk-builder.png)](https://nodei.co/npm/loopback-sdk-builder/) \ No newline at end of file diff --git a/bin/lb-ng b/bin/lb-ng deleted file mode 100644 index 81d5f8a0..00000000 --- a/bin/lb-ng +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env node - -console.error('ERROR: lb-ng command is deprecated in version 2, use the provided lb-sdk cli tool instead.') \ No newline at end of file diff --git a/bin/lb-sdk b/bin/lb-sdk index 002beae6..4f83745a 100755 --- a/bin/lb-sdk +++ b/bin/lb-sdk @@ -17,10 +17,10 @@ var generator = require('../index'); * CLI Options Description */ var argv = optimist - .usage('\n******************************************* LoopBack SDK Builder 2.0.0 *******************************************\n' + + .usage('\n******************************************* LoopBack SDK Builder 2.0 *******************************************\n' + '\nGenerate Client SDK for your LoopBack Application.' + '\nUsage:' + - '\n $0 [options] server/app.js [client/js/lb-services.js]') + '\n ./node_modules/.bin/lb-sdk server/server path/to/sdk -d [ng4web | nativescript2] -i [enabled | disabled]') .describe('l', 'Client\'s library (angular2, react , ...)') .describe('d', 'Platform specific drivers (ng4web, nativescript2, ng2universal )') .describe('i', 'Enable PubSub functionality for loopback-component-pubsub') diff --git a/lib/angular2/index.js b/lib/angular2/index.js index 82c7c5fc..ec7dde2d 100644 --- a/lib/angular2/index.js +++ b/lib/angular2/index.js @@ -53,6 +53,14 @@ module.exports = function generate(ctx) { models: ctx.models } }, + { + template: './shared/sdk.module.ejs', + output: '/sdk.module.ts', + params: { + isIo: ctx.isIo, + models: ctx.models + } + }, { template: './shared/models/index.ejs', output: '/models/index.ts', @@ -277,10 +285,12 @@ module.exports = function generate(ctx) { // It is imperative to check first for through models, else we may miss some // Through Models. This is because multiple relationships to the same model may have // different Through models, in the next validation we avoid duplicating models, which - // can lead to miss some through models. + // can lead to miss some through models. + // Finally we will be adding through models only if these are Public if ( model.sharedClass.ctor.relations[relationName].modelThrough && - model.sharedClass.ctor.relations[relationName].modelThrough.sharedClass.name !== 'Model' + model.sharedClass.ctor.relations[relationName].modelThrough.sharedClass.name !== 'Model' && + ctx.models[model.sharedClass.ctor.relations[relationName].modelThrough.sharedClass.name] ) { let through = capitalize(model.sharedClass.ctor.relations[relationName].modelThrough.sharedClass.name); if (!loaded[through]) { @@ -317,13 +327,21 @@ module.exports = function generate(ctx) { if (methodName === 'logout') return ''; let output = new Array(); let relations = getModelRelations(model); - //if (model.name === 'Account') console.log(relations); let availableClasses = relations.map((relationName, index) => model.sharedClass.ctor.relations[relationName].targetClass ); relations.forEach(relationName => { - if (model.sharedClass.ctor.relations[relationName].modelThrough) - availableClasses.push(capitalize(model.sharedClass.ctor.relations[relationName].modelThrough.sharedClass.name)); + if (model.sharedClass.ctor.relations[relationName].modelThrough) { + let throughName = capitalize( + model.sharedClass.ctor.relations[relationName].modelThrough.sharedClass.name + ); + // Only add through models when they are Public + if (ctx.models[throughName]) { + availableClasses.push(capitalize( + model.sharedClass.ctor.relations[relationName].modelThrough.sharedClass.name + )); + } + } } ); if (isIo) params = params.filter(param => !param.arg.match(/(fk|data|options)/)); @@ -439,4 +457,4 @@ function getModelRelations(model) { model.sharedClass.ctor.relations[relationName].targetClass && model.sharedClass.ctor.relations[relationName].targetClass !== model.name ); -} \ No newline at end of file +} diff --git a/lib/angular2/shared/index.ejs b/lib/angular2/shared/index.ejs index 4aacb3c7..04eddbc0 100644 --- a/lib/angular2/shared/index.ejs +++ b/lib/angular2/shared/index.ejs @@ -1,4 +1,25 @@ -/* tslint:disable */ +/** +* @module SDK Index +* @author Jonathan Casarrubias +* @license MTI 2016 Jonathan Casarrubias +* @description +* The SDK Index is automatically built by the LoopBack SDK Builder. +* +* The SDK Index will temporally keep providing access to everything in the SDK +* including services. This is because will maintain backwards compatibility for those +* Applications below Angular 2 RC 5 version that does not support NgModule just yet. +* +* IMPORTANT NOTE: +* +* If your application is equal or above RC 5 It is recommended to import the SDK +* Module located in ./sdk.module.ts and follow the instructions. +* +* Also, It is recommended for you to start upgrading your application in order to +* support NgModules before backwards support is also dropped by Angular. +* +* READ: https://angular.io/docs/ts/latest/cookbook/rc4-to-rc5.html#!#5-cleanup +**/ + import { HTTP_PROVIDERS } from '@angular/http'; import { LoopBackAuth, @@ -10,12 +31,12 @@ Object.keys(models).forEach(function(modelName, i, arr) { %> <%- modelName %>Api<%= i < arr.length -1 ? ',' : '' %><% });%> -} from './services/index' +} from './services/index'; export const API_PROVIDERS: any[] = [ - HTTP_PROVIDERS, - LoopBackAuth, - ErrorHandler, - LoggerService, + HTTP_PROVIDERS, + LoopBackAuth, + ErrorHandler, + LoggerService, JSONSearchParams,<% Object.keys(models).forEach(function(modelName, i, arr) { modelName = modelName[0].toUpperCase() + modelName.slice(1); diff --git a/lib/angular2/shared/sdk.module.ejs b/lib/angular2/shared/sdk.module.ejs new file mode 100644 index 00000000..29bc9677 --- /dev/null +++ b/lib/angular2/shared/sdk.module.ejs @@ -0,0 +1,78 @@ +/** +* @module SDKModule +* @author Jonathan Casarrubias +* @license MTI 2016 Jonathan Casarrubias +* @description +* The SDKModule is a generated Software Development Kit automatically built by +* the LoopBack SDK Builder open source module. +* +* The SDKModule provides Angular 2 >= RC.5 support, which means that NgModules +* can import this Software Development Kit as follows: +* +* +* APP Route Module Context +* ============================================================================ +* import { NgModule } from '@angular/core'; +* import { BrowserModule } from '@angular/platform-browser'; +* // App Root +* import { AppComponent } from './app.component'; +* // Feature Modules +* import { SDKModule } from './shared/sdk/sdk.module'; +* // Import Routing +* import { routing } from './app.routing'; +* @NgModule({ +* imports: [ +* BrowserModule, +* routing, +* SDKModule.forRoot() +* ], +* declarations: [ AppComponent ], +* bootstrap: [ AppComponent ] +* }) +* export class AppModule { } +* +**/ + +import { HttpModule } from '@angular/http'; +import { CommonModule } from '@angular/common'; +import { + NgModule, + ModuleWithProviders +} from '@angular/core'; +import { + LoopBackAuth, + ErrorHandler, + LoggerService, + JSONSearchParams,<% +Object.keys(models).forEach(function(modelName, i, arr) { + modelName = modelName[0].toUpperCase() + modelName.slice(1); +%> + <%- modelName %>Api<%= i < arr.length -1 ? ',' : '' %><% +});%> +} from './services/index'; + +@NgModule({ + imports: [ CommonModule, HttpModule ], + declarations: [ ], + exports: [ ], + providers: [ ] +}) + +export class SDKModule { + static forRoot(): ModuleWithProviders { + return { + ngModule: SDKModule, + providers: [ + LoopBackAuth, + ErrorHandler, + LoggerService, + JSONSearchParams,<% + Object.keys(models).forEach(function(modelName, i, arr) { + modelName = modelName[0].toUpperCase() + modelName.slice(1); + %> + <%- modelName %>Api<%= i < arr.length -1 ? ',' : '' %><% + });%> + ] + }; + } +} diff --git a/lib/angular2/shared/services/core/base.ejs b/lib/angular2/shared/services/core/base.ejs index deb43172..e50d477b 100644 --- a/lib/angular2/shared/services/core/base.ejs +++ b/lib/angular2/shared/services/core/base.ejs @@ -26,14 +26,7 @@ export abstract class BaseLoopBackApi { @Inject(LoopBackAuth) protected auth: LoopBackAuth, @Inject(JSONSearchParams) protected searchParams: JSONSearchParams, @Optional() @Inject(ErrorHandler) protected errorHandler: ErrorHandler - ) { - if (!auth) { - this.auth = new LoopBackAuth(); - } - if (!errorHandler) { - this.errorHandler = new ErrorHandler(); - } - } + ) {} /** * Process request diff --git a/package.json b/package.json index fe9fc383..c494b62e 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,8 @@ { - "name": "loopback-sdk-builder", - "version": "2.0.0-rc.9.1", + "name": "@mean-expert/loopback-sdk-builder", + "version": "2.0.0-stable", "description": "Tool for auto-generating Software Development Kits (SDKs) for LoopBack", "bin": { - "lb-ng": "bin/lb-ng", "lb-sdk": "bin/lb-sdk" }, "main": "index.js", @@ -15,7 +14,7 @@ }, "repository": { "type": "git", - "url": "git://github.com/jonathan-casarrubias/loopback-sdk-builder.git" + "url": "git://github.com/mean-expert-official/loopback-sdk-builder.git" }, "keywords": [ "loopback", @@ -49,7 +48,7 @@ ], "license": "MIT", "bugs": { - "url": "https://github.com/jonathan-casarrubias/loopback-sdk-builder/issues" + "url": "https://github.com/mean-expert-official/loopback-sdk-builder/issues" }, "dependencies": { "ejs": "^1.0", diff --git a/tests/angular2/.clang-format b/tests/angular2/.clang-format deleted file mode 100644 index 8d1c3c31..00000000 --- a/tests/angular2/.clang-format +++ /dev/null @@ -1,3 +0,0 @@ -Language: JavaScript -BasedOnStyle: Google -ColumnLimit: 100 diff --git a/tests/angular2/.editorconfig b/tests/angular2/.editorconfig index 3ee22e5d..f3526162 100644 --- a/tests/angular2/.editorconfig +++ b/tests/angular2/.editorconfig @@ -1,13 +1,14 @@ -# EditorConfig helps developers define and maintain consistent -# coding styles between different editors and IDEs -# http://editorconfig.org - +# Editor configuration, see http://editorconfig.org root = true [*] +charset = utf-8 indent_style = space indent_size = 2 end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = 0 +trim_trailing_whitespace = false diff --git a/tests/angular2/.gitignore b/tests/angular2/.gitignore new file mode 100644 index 00000000..fccc4d9f --- /dev/null +++ b/tests/angular2/.gitignore @@ -0,0 +1,33 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/tmp + +# dependencies +/node_modules +/bower_components + +# IDEs and editors +/.idea +.project +.classpath +*.launch +.settings/ + +# misc +/.sass-cache +/connect.lock +/coverage/* +/libpeerconnection.log +npm-debug.log +testem.log +/typings + +# e2e +/e2e/*.js +/e2e/*.map + +#System Files +.DS_Store +Thumbs.db diff --git a/tests/angular2/.jshintignore b/tests/angular2/.jshintignore deleted file mode 100644 index ee8c771c..00000000 --- a/tests/angular2/.jshintignore +++ /dev/null @@ -1,2 +0,0 @@ -/client/ -/node_modules/ diff --git a/tests/angular2/.jshintrc b/tests/angular2/.jshintrc deleted file mode 100644 index feb09289..00000000 --- a/tests/angular2/.jshintrc +++ /dev/null @@ -1,21 +0,0 @@ -{ - "node": true, - "esnext": true, - "bitwise": true, - "camelcase": true, - "eqeqeq": true, - "eqnull": true, - "immed": true, - "indent": 2, - "latedef": "nofunc", - "newcap": true, - "nonew": true, - "noarg": true, - "quotmark": "single", - "regexp": true, - "undef": true, - "unused": false, - "trailing": true, - "sub": true, - "maxlen": 80 -} diff --git a/tests/angular2/.yo-rc.json b/tests/angular2/.yo-rc.json deleted file mode 100644 index 02f3fc17..00000000 --- a/tests/angular2/.yo-rc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "generator-loopback": {} -} \ No newline at end of file diff --git a/tests/angular2/README.md b/tests/angular2/README.md index 866baed5..69890e26 100644 --- a/tests/angular2/README.md +++ b/tests/angular2/README.md @@ -1,3 +1,31 @@ -# My Application +# Angular2 -The project is generated by [LoopBack](http://loopback.io). \ No newline at end of file +This project was generated with [angular-cli](https://github.com/angular/angular-cli) version 1.0.0-beta.11-webpack.2. + +## Development server +Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. + +## Code scaffolding + +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class`. + +## Build + +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build. + +## Running unit tests + +Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Running end-to-end tests + +Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). +Before running the tests make sure you are serving the app via `ng serve`. + +## Deploying to Github Pages + +Run `ng github-pages:deploy` to deploy to Github Pages. + +## Further help + +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). diff --git a/tests/angular2/angular-cli-build.js b/tests/angular2/angular-cli-build.js deleted file mode 100644 index f6dd7120..00000000 --- a/tests/angular2/angular-cli-build.js +++ /dev/null @@ -1,18 +0,0 @@ -/* global require, module */ - -var Angular2App = require('angular-cli/lib/broccoli/angular2-app'); - -module.exports = function(defaults) { - return new Angular2App(defaults, { - vendorNpmFiles: [ - 'systemjs/dist/system-polyfills.js', - 'systemjs/dist/system.src.js', - 'zone.js/dist/*.js', - 'es6-shim/es6-shim.js', - 'reflect-metadata/*.js', - 'rxjs/**/*.js', - '@angular/**/*.js', - 'socket.io-client/lib/*.js' - ] - }); -}; diff --git a/tests/angular2/angular-cli.json b/tests/angular2/angular-cli.json index f8b9e7cc..1d4a8785 100644 --- a/tests/angular2/angular-cli.json +++ b/tests/angular2/angular-cli.json @@ -1,10 +1,14 @@ { "project": { - "version": "0.1.0", + "version": "1.0.0-beta.11-webpack.2", "name": "angular2" }, "apps": [ - {"main": "src/main.ts", "tsconfig": "src/tsconfig.json"} + { + "main": "src/main.ts", + "tsconfig": "src/tsconfig.json", + "mobile": false + } ], "addons": [], "packages": [], @@ -20,6 +24,9 @@ }, "defaults": { "prefix": "app", - "sourceDir": "src" + "sourceDir": "src", + "styleExt": "css", + "prefixInterfaces": false, + "lazyRoutePrefix": "+" } } diff --git a/tests/angular2/common/models/account.json b/tests/angular2/common/models/account.json index 7702e936..d7d13307 100644 --- a/tests/angular2/common/models/account.json +++ b/tests/angular2/common/models/account.json @@ -16,6 +16,12 @@ "model": "Room", "foreignKey": "", "through": "RoomAccount" + }, + "administrations": { + "type": "hasMany", + "model": "Room", + "foreignKey": "administrationId", + "through": "RoomAdmin" } }, "acls": [], diff --git a/tests/angular2/common/models/room-admin.js b/tests/angular2/common/models/room-admin.js new file mode 100644 index 00000000..b786c9c3 --- /dev/null +++ b/tests/angular2/common/models/room-admin.js @@ -0,0 +1,3 @@ +module.exports = function(Roomadmin) { + +}; diff --git a/tests/angular2/common/models/room-admin.json b/tests/angular2/common/models/room-admin.json new file mode 100644 index 00000000..69a3737a --- /dev/null +++ b/tests/angular2/common/models/room-admin.json @@ -0,0 +1,25 @@ +{ + "name": "RoomAdmin", + "plural": "room-admins", + "base": "PersistedModel", + "idInjection": true, + "options": { + "validateUpsert": true + }, + "properties": {}, + "validations": [], + "relations": { + "account": { + "type": "belongsTo", + "model": "Account", + "foreignKey": "adminId" + }, + "room": { + "type": "belongsTo", + "model": "Room", + "foreignKey": "administrationId" + } + }, + "acls": [], + "methods": {} +} diff --git a/tests/angular2/common/models/room.json b/tests/angular2/common/models/room.json index 3980c688..61a80b58 100644 --- a/tests/angular2/common/models/room.json +++ b/tests/angular2/common/models/room.json @@ -37,6 +37,12 @@ "model": "Account", "foreignKey": "", "through": "RoomAccount" + }, + "admins": { + "type": "hasMany", + "model": "Account", + "foreignKey": "adminId", + "through": "RoomAdmin" } }, "acls": [], diff --git a/tests/angular2/config/environment.js b/tests/angular2/config/environment.js deleted file mode 100644 index 4fa28880..00000000 --- a/tests/angular2/config/environment.js +++ /dev/null @@ -1,10 +0,0 @@ -/* jshint node: true */ - -module.exports = function(environment) { - return { - environment: environment, - baseURL: '/', - locationType: 'auto' - }; -}; - diff --git a/tests/angular2/config/karma-test-shim.js b/tests/angular2/config/karma-test-shim.js deleted file mode 100644 index c1693a0b..00000000 --- a/tests/angular2/config/karma-test-shim.js +++ /dev/null @@ -1,51 +0,0 @@ -/*global jasmine, __karma__, window*/ -Error.stackTraceLimit = Infinity; -jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; - -__karma__.loaded = function () { -}; - -var distPath = '/base/dist/'; -var appPath = distPath + 'app/'; - -function isJsFile(path) { - return path.slice(-3) == '.js'; -} - -function isSpecFile(path) { - return path.slice(-8) == '.spec.js'; -} - -function isAppFile(path) { - return isJsFile(path) && (path.substr(0, appPath.length) == appPath); -} - -var allSpecFiles = Object.keys(window.__karma__.files) - .filter(isSpecFile) - .filter(isAppFile); - -// Load our SystemJS configuration. -System.config({ - baseURL: distPath -}); - -System.import('system-config.js').then(function() { - // Load and configure the TestComponentBuilder. - return Promise.all([ - System.import('@angular/core/testing'), - System.import('@angular/platform-browser-dynamic/testing') - ]).then(function (providers) { - var testing = providers[0]; - var testingBrowser = providers[1]; - - testing.setBaseTestProviders(testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, - testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS); - }); -}).then(function() { - // Finally, load all spec files. - // This will run the tests directly. - return Promise.all( - allSpecFiles.map(function (moduleName) { - return System.import(moduleName); - })); -}).then(__karma__.start, __karma__.error); \ No newline at end of file diff --git a/tests/angular2/config/karma.conf.js b/tests/angular2/config/karma.conf.js index e84b2cd4..b8aa26e0 100644 --- a/tests/angular2/config/karma.conf.js +++ b/tests/angular2/config/karma.conf.js @@ -1,10 +1,15 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/0.13/config/configuration-file.html + module.exports = function (config) { config.set({ - basePath: '../', - frameworks: ['jasmine'], + basePath: '..', + frameworks: ['jasmine', 'angular-cli'], plugins: [ require('karma-jasmine'), - require('karma-chrome-launcher') + require('karma-chrome-launcher'), + require('karma-remap-istanbul'), + require('angular-cli/plugins/karma') ], customLaunchers: { // chrome setup for travis CI using chromium @@ -14,24 +19,18 @@ module.exports = function (config) { } }, files: [ - { pattern: 'dist/vendor/es6-shim/es6-shim.js', included: true, watched: false }, - { pattern: 'dist/vendor/zone.js/dist/zone.js', included: true, watched: false }, - { pattern: 'dist/vendor/reflect-metadata/Reflect.js', included: true, watched: false }, - { pattern: 'dist/vendor/systemjs/dist/system-polyfills.js', included: true, watched: false }, - { pattern: 'dist/vendor/systemjs/dist/system.src.js', included: true, watched: false }, - { pattern: 'dist/vendor/zone.js/dist/async-test.js', included: true, watched: false }, - - { pattern: 'config/karma-test-shim.js', included: true, watched: true }, - - // Distribution folder. - { pattern: 'dist/**/*', included: false, watched: true } - ], - exclude: [ - // Vendor packages might include spec files. We don't want to use those. - 'dist/vendor/**/*.spec.js' + { pattern: './src/test.ts', watched: false } ], - preprocessors: {}, - reporters: ['progress'], + preprocessors: { + './src/test.ts': ['angular-cli'] + }, + remapIstanbulReporter: { + reports: { + html: 'coverage' + } + }, + angularCliConfig: './angular-cli.json', + reporters: ['progress', 'karma-remap-istanbul'], port: 9876, colors: true, logLevel: config.LOG_INFO, diff --git a/tests/angular2/config/protractor.conf.js b/tests/angular2/config/protractor.conf.js index 57f4f87d..3019efc2 100644 --- a/tests/angular2/config/protractor.conf.js +++ b/tests/angular2/config/protractor.conf.js @@ -1,10 +1,13 @@ +// Protractor configuration file, see link for more information +// https://github.com/angular/protractor/blob/master/docs/referenceConf.js + /*global jasmine */ var SpecReporter = require('jasmine-spec-reporter'); exports.config = { allScriptsTimeout: 11000, specs: [ - '../e2e/**/*.e2e.ts' + '../e2e/**/*.e2e-spec.ts' ], capabilities: { 'browserName': 'chrome' diff --git a/tests/angular2/e2e/app.e2e-spec.ts b/tests/angular2/e2e/app.e2e-spec.ts new file mode 100644 index 00000000..c9acef93 --- /dev/null +++ b/tests/angular2/e2e/app.e2e-spec.ts @@ -0,0 +1,14 @@ +import { Angular2Page } from './app.po'; + +describe('angular2 App', function() { + let page: Angular2Page; + + beforeEach(() => { + page = new Angular2Page(); + }); + + it('should display message saying app works', () => { + page.navigateTo(); + expect(page.getParagraphText()).toEqual('app works!'); + }); +}); diff --git a/tests/angular2/e2e/app.po.ts b/tests/angular2/e2e/app.po.ts new file mode 100644 index 00000000..b7bc9389 --- /dev/null +++ b/tests/angular2/e2e/app.po.ts @@ -0,0 +1,9 @@ +export class Angular2Page { + navigateTo() { + return browser.get('/'); + } + + getParagraphText() { + return element(by.css('app-root h1')).getText(); + } +} diff --git a/tests/angular2/e2e/tsconfig.json b/tests/angular2/e2e/tsconfig.json new file mode 100644 index 00000000..656bdb14 --- /dev/null +++ b/tests/angular2/e2e/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "declaration": false, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "module": "commonjs", + "moduleResolution": "node", + "outDir": "../dist/out-tsc-e2e", + "sourceMap": true, + "target": "es5", + "typeRoots": [ + "../node_modules/@types" + ] + } +} diff --git a/tests/angular2/loopback/model-config.json b/tests/angular2/loopback/model-config.json index 07ced160..292c9c9b 100644 --- a/tests/angular2/loopback/model-config.json +++ b/tests/angular2/loopback/model-config.json @@ -69,6 +69,10 @@ "dataSource": "db", "public": true }, + "RoomAdmin": { + "dataSource": "db", + "public": false + }, "Storage": { "dataSource": "storage", "public": true diff --git a/tests/angular2/package.json b/tests/angular2/package.json index 526dbeed..9515df70 100644 --- a/tests/angular2/package.json +++ b/tests/angular2/package.json @@ -4,23 +4,28 @@ "license": "MIT", "angular-cli": {}, "scripts": { - "start": "node loopback/server.js & ng server", - "postinstall": "typings install", + "start": "ng serve", "lint": "tslint \"src/**/*.ts\"", - "format": "clang-format -i -style=file --glob=src/**/*.ts", "pree2e": "webdriver-manager update", + "e2e": "protractor", "test": "npm run build:sdk && node loopback/server.js & ng test", "build:sdk": "npm install ../../ && ./node_modules/.bin/lb-sdk loopback/server.js src/app/shared/sdk" }, "private": true, "dependencies": { - "@angular/common": "2.0.0-rc.4", - "@angular/compiler": "2.0.0-rc.4", - "@angular/core": "2.0.0-rc.4", - "@angular/http": "2.0.0-rc.4", - "@angular/platform-browser": "2.0.0-rc.4", - "@angular/platform-browser-dynamic": "2.0.0-rc.4", - "@angular/router": "3.0.0-alpha.8", + "@angular/common": "2.0.0-rc.5", + "@angular/compiler": "2.0.0-rc.5", + "@angular/core": "2.0.0-rc.5", + "@angular/forms": "0.3.0", + "@angular/http": "2.0.0-rc.5", + "@angular/platform-browser": "2.0.0-rc.5", + "@angular/platform-browser-dynamic": "2.0.0-rc.5", + "@angular/router": "3.0.0-rc.1", + "core-js": "^2.4.0", + "reflect-metadata": "0.1.3", + "rxjs": "5.0.0-beta.6", + "ts-helpers": "^1.1.1", + "zone.js": "0.6.12", "compression": "^1.0.3", "config-chain": "^1.1.10", "cors": "^2.5.2", @@ -33,33 +38,22 @@ "loopback-component-pubsub": "^1.0.18", "loopback-component-storage": "^1.9.0", "loopback-datasource-juggler": "^2.39.0", - "reflect-metadata": "0.1.3", - "requirejs": "^2.2.0", - "rxjs": "5.0.0-beta.6", - "serve-favicon": "2.0.1", - "socket.io-client": "1.4.8", - "systemjs": "0.19.26", - "zone.js": "0.6.12" + "socket.io-client": "1.4.8" }, "devDependencies": { - "angular-cli": "0.0.*", - "browserify": "^13.1.0", - "clang-format": "^1.0.35", - "codelyzer": "0.0.14", - "ember-cli-inject-live-reload": "^1.4.0", - "jasmine-core": "^2.4.1", - "jasmine-spec-reporter": "^2.4.0", - "karma": "^0.13.15", - "karma-requirejs": "^1.0.0", - "karma-browserify": "^5.1.0", - "karma-chrome-launcher": "^0.2.3", - "karma-jasmine": "^0.3.8", - "protractor": "^3.3.0", - "requirejs": "^2.2.0", - "ts-node": "^0.5.5", - "tslint": "^3.6.0", - "typescript": "^1.8.10", - "typings": "^0.8.1", - "watchify": "^3.7.0" + "@types/jasmine": "^2.2.30", + "@types/protractor": "^1.5.16", + "angular-cli": "1.0.0-beta.11-webpack.2", + "codelyzer": "0.0.26", + "jasmine-core": "2.4.1", + "jasmine-spec-reporter": "2.5.0", + "karma": "0.13.22", + "karma-chrome-launcher": "0.2.3", + "karma-jasmine": "0.3.8", + "karma-remap-istanbul": "^0.2.1", + "protractor": "3.3.0", + "ts-node": "1.2.1", + "tslint": "3.13.0", + "typescript": "^2.0.0" } } diff --git a/tests/angular2/public/.npmignore b/tests/angular2/public/.npmignore new file mode 100644 index 00000000..e69de29b diff --git a/tests/angular2/src/app/angular2.component.spec.ts b/tests/angular2/src/app/angular2.component.spec.ts deleted file mode 100644 index ed0c9f1d..00000000 --- a/tests/angular2/src/app/angular2.component.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { - beforeEachProviders, - describe, - expect, - it, - inject -} from '@angular/core/testing'; -import { Angular2AppComponent } from '../app/angular2.component'; - -beforeEachProviders(() => [Angular2AppComponent]); - -describe('App: Angular2', () => { - it('should create the app', - inject([Angular2AppComponent], (app: Angular2AppComponent) => { - expect(app).toBeTruthy(); - })); - - it('should have as title \'angular2 works!\'', - inject([Angular2AppComponent], (app: Angular2AppComponent) => { - expect(app.title).toEqual('angular2 works!'); - })); -}); diff --git a/tests/angular2/src/app/angular2.component.ts b/tests/angular2/src/app/angular2.component.ts deleted file mode 100644 index eb93998f..00000000 --- a/tests/angular2/src/app/angular2.component.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Component } from '@angular/core'; -@Component({ - moduleId: module.id, - selector: 'angular2-app', - template: 'LoopBack SDK Builder Test App' -}) -export class Angular2AppComponent { - title = 'angular2 works!'; -} diff --git a/tests/angular2/src/app/app.component.css b/tests/angular2/src/app/app.component.css new file mode 100644 index 00000000..e69de29b diff --git a/tests/angular2/src/app/app.component.html b/tests/angular2/src/app/app.component.html new file mode 100644 index 00000000..b6931b53 --- /dev/null +++ b/tests/angular2/src/app/app.component.html @@ -0,0 +1,3 @@ +

+ {{title}} +

diff --git a/tests/angular2/src/app/app.component.spec.ts b/tests/angular2/src/app/app.component.spec.ts new file mode 100644 index 00000000..8f165e4e --- /dev/null +++ b/tests/angular2/src/app/app.component.spec.ts @@ -0,0 +1,19 @@ +/* tslint:disable:no-unused-variable */ +import { addProviders, async, inject } from '@angular/core/testing'; +import { AppComponent } from './app.component'; + +describe('App: Angular2', () => { + beforeEach(() => { + addProviders([AppComponent]); + }); + + it('should create the app', + inject([AppComponent], (app: AppComponent) => { + expect(app).toBeTruthy(); + })); + + it('should have as title \'app works!\'', + inject([AppComponent], (app: AppComponent) => { + expect(app.title).toEqual('app works!'); + })); +}); diff --git a/tests/angular2/src/app/app.component.ts b/tests/angular2/src/app/app.component.ts new file mode 100644 index 00000000..6bf650d6 --- /dev/null +++ b/tests/angular2/src/app/app.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + templateUrl: 'app.component.html', + styleUrls: ['app.component.css'] +}) + +export class AppComponent { + title = 'app works!'; +} diff --git a/tests/angular2/src/app/app.module.ts b/tests/angular2/src/app/app.module.ts new file mode 100644 index 00000000..f54894e4 --- /dev/null +++ b/tests/angular2/src/app/app.module.ts @@ -0,0 +1,25 @@ +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule, ApplicationRef } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { AppComponent } from './app.component'; +import { SDKModule } from './shared/sdk/sdk.module'; + +@NgModule({ + declarations: [ + AppComponent + ], + imports: [ + BrowserModule, + CommonModule, + FormsModule, + SDKModule.forRoot() + ], + providers : [ ], + entryComponents : [ AppComponent ], + bootstrap : [ AppComponent ] +}) + +export class AppModule { + +} diff --git a/tests/angular2/src/app/environment.ts b/tests/angular2/src/app/environment.ts deleted file mode 100644 index 79ee96fd..00000000 --- a/tests/angular2/src/app/environment.ts +++ /dev/null @@ -1,7 +0,0 @@ -// The file for the current environment will overwrite this one during build -// Different environments can be found in config/environment.{dev|prod}.ts -// The build system defaults to the dev environment - -export const environment = { - production: false -}; diff --git a/tests/angular2/config/environment.dev.ts b/tests/angular2/src/app/environments/environment.dev.ts similarity index 100% rename from tests/angular2/config/environment.dev.ts rename to tests/angular2/src/app/environments/environment.dev.ts diff --git a/tests/angular2/config/environment.prod.ts b/tests/angular2/src/app/environments/environment.prod.ts similarity index 100% rename from tests/angular2/config/environment.prod.ts rename to tests/angular2/src/app/environments/environment.prod.ts diff --git a/tests/angular2/src/app/environments/environment.ts b/tests/angular2/src/app/environments/environment.ts new file mode 100644 index 00000000..5c54e150 --- /dev/null +++ b/tests/angular2/src/app/environments/environment.ts @@ -0,0 +1,8 @@ +// The file for the current environment will overwrite this one during build. +// Different environments can be found in ./environment.{dev|prod}.ts, and +// you can create your own and use it with the --env flag. +// The build system defaults to the dev environment. + +export const environment = { + production: false +}; diff --git a/tests/angular2/src/app/index.ts b/tests/angular2/src/app/index.ts index 0fa7eba9..87743c9d 100644 --- a/tests/angular2/src/app/index.ts +++ b/tests/angular2/src/app/index.ts @@ -1,2 +1,3 @@ -export {environment} from './environment'; -export {Angular2AppComponent} from './angular2.component'; +export * from './environments/environment'; +export * from './app.component'; +export * from './app.module'; diff --git a/tests/angular2/src/app/room-service.service.spec.ts b/tests/angular2/src/app/room-service.service.spec.ts index 2c07e3a1..361a4c83 100644 --- a/tests/angular2/src/app/room-service.service.spec.ts +++ b/tests/angular2/src/app/room-service.service.spec.ts @@ -1,24 +1,19 @@ -import { - beforeEachProviders, - it, - describe, - expect, - inject, - async -} from '@angular/core/testing'; - +import { addProviders, async, inject } from '@angular/core/testing'; import { Room, - RoomApi, - API_PROVIDERS, - LoopBackConfig -} from './shared'; + LoopBackConfig, + API_PROVIDERS +} from './shared/sdk'; + +import { RoomApi } from './shared/sdk/services'; LoopBackConfig.setBaseURL('http://127.0.0.1:3000'); LoopBackConfig.setApiVersion('api'); describe('RoomService Tests', () => { - beforeEachProviders(() => [API_PROVIDERS]); + beforeEach(() => { + addProviders([ API_PROVIDERS ]); + }); it('should contain persisted model methods', async(inject([RoomApi], (service: RoomApi) => { diff --git a/tests/angular2/src/app/shared/index.ts b/tests/angular2/src/app/shared/index.ts index 9ba586f4..e69de29b 100644 --- a/tests/angular2/src/app/shared/index.ts +++ b/tests/angular2/src/app/shared/index.ts @@ -1 +0,0 @@ -export * from './sdk/index'; diff --git a/tests/angular2/src/app/shared/sdk/index.ts b/tests/angular2/src/app/shared/sdk/index.ts index e50ed5b6..de66afa0 100644 --- a/tests/angular2/src/app/shared/sdk/index.ts +++ b/tests/angular2/src/app/shared/sdk/index.ts @@ -1,4 +1,25 @@ -/* tslint:disable */ +/** +* @module SDK Index +* @author Jonathan Casarrubias +* @license MTI 2016 Jonathan Casarrubias +* @description +* The SDK Index is automatically built by the LoopBack SDK Builder. +* +* The SDK Index will temporally keep providing access to everything in the SDK +* including services. This is because will maintain backwards compatibility for those +* Applications below Angular 2 RC 5 version that does not support NgModule just yet. +* +* IMPORTANT NOTE: +* +* If your application is equal or above RC 5 It is recommended to import the SDK +* Module located in ./sdk.module.ts and follow the instructions. +* +* Also, It is recommended for you to start upgrading your application in order to +* support NgModules before backwards support is also dropped by Angular. +* +* READ: https://angular.io/docs/ts/latest/cookbook/rc4-to-rc5.html#!#5-cleanup +**/ + import { HTTP_PROVIDERS } from '@angular/http'; import { LoopBackAuth, @@ -15,12 +36,12 @@ import { AccountApi, RoomAccountApi, StorageApi -} from './services/index' +} from './services/index'; export const API_PROVIDERS: any[] = [ - HTTP_PROVIDERS, - LoopBackAuth, - ErrorHandler, - LoggerService, + HTTP_PROVIDERS, + LoopBackAuth, + ErrorHandler, + LoggerService, JSONSearchParams, UserApi, RoomApi, diff --git a/tests/angular2/src/app/shared/sdk/models/Account.ts b/tests/angular2/src/app/shared/sdk/models/Account.ts index 565bc53e..695159e7 100644 --- a/tests/angular2/src/app/shared/sdk/models/Account.ts +++ b/tests/angular2/src/app/shared/sdk/models/Account.ts @@ -1,6 +1,6 @@ /* tslint:disable */ import { - Room + Room, } from '../index'; export interface AccountInterface { @@ -17,6 +17,7 @@ export interface AccountInterface { id?: number; accessTokens?: Array; rooms?: Array; + administrations?: Array; } export class Account implements AccountInterface { @@ -33,6 +34,7 @@ export class Account implements AccountInterface { id: number; accessTokens: Array; rooms: Array; + administrations: Array; constructor(instance?: Account) { Object.assign(this, instance); } diff --git a/tests/angular2/src/app/shared/sdk/models/Room.ts b/tests/angular2/src/app/shared/sdk/models/Room.ts index e44b68f4..183d702c 100644 --- a/tests/angular2/src/app/shared/sdk/models/Room.ts +++ b/tests/angular2/src/app/shared/sdk/models/Room.ts @@ -2,7 +2,7 @@ import { Like, Category, - Account + Account, } from '../index'; export interface RoomInterface { @@ -12,6 +12,7 @@ export interface RoomInterface { likes?: Array; categories?: Array; accounts?: Array; + admins?: Array; } export class Room implements RoomInterface { @@ -21,6 +22,7 @@ export class Room implements RoomInterface { likes: Array; categories: Array; accounts: Array; + admins: Array; constructor(instance?: Room) { Object.assign(this, instance); } diff --git a/tests/angular2/src/app/shared/sdk/sdk.module.ts b/tests/angular2/src/app/shared/sdk/sdk.module.ts new file mode 100644 index 00000000..d0a355a3 --- /dev/null +++ b/tests/angular2/src/app/shared/sdk/sdk.module.ts @@ -0,0 +1,88 @@ +/** +* @module SDKModule +* @author Jonathan Casarrubias +* @license MTI 2016 Jonathan Casarrubias +* @description +* The SDKModule is a generated Software Development Kit automatically built by +* the LoopBack SDK Builder open source module. +* +* The SDKModule provides Angular 2 >= RC.5 support, which means that NgModules +* can import this Software Development Kit as follows: +* +* +* APP Route Module Context +* ============================================================================ +* import { NgModule } from '@angular/core'; +* import { BrowserModule } from '@angular/platform-browser'; +* // App Root +* import { AppComponent } from './app.component'; +* // Feature Modules +* import { SDKModule } from './shared/sdk/sdk.module'; +* // Import Routing +* import { routing } from './app.routing'; +* @NgModule({ +* imports: [ +* BrowserModule, +* routing, +* SDKModule.forRoot() +* ], +* declarations: [ AppComponent ], +* bootstrap: [ AppComponent ] +* }) +* export class AppModule { } +* +**/ + +import { HttpModule } from '@angular/http'; +import { CommonModule } from '@angular/common'; +import { + NgModule, + ModuleWithProviders +} from '@angular/core'; +import { + LoopBackAuth, + ErrorHandler, + LoggerService, + JSONSearchParams, + UserApi, + RoomApi, + LikeApi, + ApplicationCredentialApi, + UserCredentialApi, + UserIdentityApi, + CategoryApi, + AccountApi, + RoomAccountApi, + StorageApi +} from './services/index'; + +@NgModule({ + imports: [ CommonModule, HttpModule ], + declarations: [ ], + exports: [ ], + providers: [ ] +}) + +export class SDKModule { + static forRoot(): ModuleWithProviders { + return { + ngModule: SDKModule, + providers: [ + LoopBackAuth, + ErrorHandler, + LoggerService, + JSONSearchParams, + UserApi, + RoomApi, + LikeApi, + ApplicationCredentialApi, + UserCredentialApi, + UserIdentityApi, + CategoryApi, + AccountApi, + RoomAccountApi, + StorageApi + ] + }; + } +} diff --git a/tests/angular2/src/app/shared/sdk/services/core/base.service.ts b/tests/angular2/src/app/shared/sdk/services/core/base.service.ts index 0889754c..53e55b19 100644 --- a/tests/angular2/src/app/shared/sdk/services/core/base.service.ts +++ b/tests/angular2/src/app/shared/sdk/services/core/base.service.ts @@ -21,14 +21,7 @@ export abstract class BaseLoopBackApi { @Inject(LoopBackAuth) protected auth: LoopBackAuth, @Inject(JSONSearchParams) protected searchParams: JSONSearchParams, @Optional() @Inject(ErrorHandler) protected errorHandler: ErrorHandler - ) { - if (!auth) { - this.auth = new LoopBackAuth(); - } - if (!errorHandler) { - this.errorHandler = new ErrorHandler(); - } - } + ) {} /** * Process request diff --git a/tests/angular2/src/app/shared/sdk/services/custom/Account.ts b/tests/angular2/src/app/shared/sdk/services/custom/Account.ts index ff499caf..3ace1037 100644 --- a/tests/angular2/src/app/shared/sdk/services/custom/Account.ts +++ b/tests/angular2/src/app/shared/sdk/services/custom/Account.ts @@ -314,6 +314,192 @@ export class AccountApi extends BaseLoopBackApi { return result; } + /** + * Find a related item by id for administrations. + * + * @param any id User id + * + * @param any fk Foreign key for administrations + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * + * (The remote method definition does not provide any description. + * This usually means the response is a `Account` object.) + * + */ + public findByIdAdministrations(id: any, fk: any) { + let method: string = "GET"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/Accounts/:id/administrations/:fk"; + let routeParams: any = { + id: id, + fk: fk + }; + let postBody: any = {}; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result.map((instance: Account) => new Account(instance)); + } + + /** + * Delete a related item by id for administrations. + * + * @param any id User id + * + * @param any fk Foreign key for administrations + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * This method returns no data. + */ + public destroyByIdAdministrations(id: any, fk: any) { + let method: string = "DELETE"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/Accounts/:id/administrations/:fk"; + let routeParams: any = { + id: id, + fk: fk + }; + let postBody: any = {}; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + + /** + * Update a related item by id for administrations. + * + * @param any id User id + * + * @param any fk Foreign key for administrations + * + * @param object data Request data. + * + * This method expects a subset of model properties as request parameters. + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * + * (The remote method definition does not provide any description. + * This usually means the response is a `Account` object.) + * + */ + public updateByIdAdministrations(id: any, fk: any, data: Room = undefined) { + let method: string = "PUT"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/Accounts/:id/administrations/:fk"; + let routeParams: any = { + id: id, + fk: fk + }; + let postBody: any = { + data: data + }; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + + /** + * Add a related item by id for administrations. + * + * @param any id User id + * + * @param any fk Foreign key for administrations + * + * @param object data Request data. + * + * This method expects a subset of model properties as request parameters. + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * + * (The remote method definition does not provide any description. + * This usually means the response is a `Account` object.) + * + */ + public linkAdministrations(id: any, fk: any, data: any = undefined) { + let method: string = "PUT"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/Accounts/:id/administrations/rel/:fk"; + let routeParams: any = { + id: id, + fk: fk + }; + let postBody: any = { + data: data + }; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + + /** + * Remove the administrations relation to an item by id. + * + * @param any id User id + * + * @param any fk Foreign key for administrations + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * This method returns no data. + */ + public unlinkAdministrations(id: any, fk: any) { + let method: string = "DELETE"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/Accounts/:id/administrations/rel/:fk"; + let routeParams: any = { + id: id, + fk: fk + }; + let postBody: any = {}; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + + /** + * Check the existence of administrations relation to an item by id. + * + * @param any id User id + * + * @param any fk Foreign key for administrations + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * + * (The remote method definition does not provide any description. + * This usually means the response is a `Account` object.) + * + */ + public existsAdministrations(id: any, fk: any) { + let method: string = "HEAD"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/Accounts/:id/administrations/rel/:fk"; + let routeParams: any = { + id: id, + fk: fk + }; + let postBody: any = {}; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + /** * Queries accessTokens of Account. * @@ -546,6 +732,122 @@ export class AccountApi extends BaseLoopBackApi { return result; } + /** + * Queries administrations of Account. + * + * @param any id User id + * + * @param object filter + * + * @returns object[] An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * + * (The remote method definition does not provide any description. + * This usually means the response is a `Account` object.) + * + */ + public getAdministrations(id: any, filter: LoopBackFilter = undefined) { + let method: string = "GET"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/Accounts/:id/administrations"; + let routeParams: any = { + id: id + }; + let postBody: any = {}; + let urlParams: any = {}; + if (filter) urlParams.filter = filter; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + + /** + * Creates a new instance in administrations of this model. + * + * @param any id User id + * + * @param object data Request data. + * + * This method expects a subset of model properties as request parameters. + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * + * (The remote method definition does not provide any description. + * This usually means the response is a `Account` object.) + * + */ + public createAdministrations(id: any, data: Room = undefined) { + let method: string = "POST"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/Accounts/:id/administrations"; + let routeParams: any = { + id: id + }; + let postBody: any = { + data: data + }; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + + /** + * Deletes all administrations of this model. + * + * @param any id User id + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * This method returns no data. + */ + public deleteAdministrations(id: any) { + let method: string = "DELETE"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/Accounts/:id/administrations"; + let routeParams: any = { + id: id + }; + let postBody: any = {}; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + + /** + * Counts administrations of Account. + * + * @param any id User id + * + * @param object where Criteria to match model instances + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * Data properties: + * + * - `count` – `{number}` - + */ + public countAdministrations(id: any, where: any = undefined) { + let method: string = "GET"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/Accounts/:id/administrations/count"; + let routeParams: any = { + id: id + }; + let postBody: any = {}; + let urlParams: any = {}; + if (where) urlParams.where = where; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + /** * Create a new instance of the model and persist it into the data source. * @@ -1116,6 +1418,39 @@ export class AccountApi extends BaseLoopBackApi { return result; } + /** + * Creates a new instance in administrations of this model. + * + * @param any id User id + * + * @param object data Request data. + * + * This method expects a subset of model properties as request parameters. + * + * @returns object[] An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * + * (The remote method definition does not provide any description. + * This usually means the response is a `Account` object.) + * + */ + public createManyAdministrations(id: any, data: Room = undefined) { + let method: string = "POST"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/Accounts/:id/administrations"; + let routeParams: any = { + id: id + }; + let postBody: any = { + data: data + }; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + /** * Create a new instance of the model and persist it into the data source. * diff --git a/tests/angular2/src/app/shared/sdk/services/custom/Room.ts b/tests/angular2/src/app/shared/sdk/services/custom/Room.ts index e2d74814..1b55c4f4 100644 --- a/tests/angular2/src/app/shared/sdk/services/custom/Room.ts +++ b/tests/angular2/src/app/shared/sdk/services/custom/Room.ts @@ -595,6 +595,192 @@ export class RoomApi extends BaseLoopBackApi { return result; } + /** + * Find a related item by id for admins. + * + * @param any id PersistedModel id + * + * @param any fk Foreign key for admins + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * + * (The remote method definition does not provide any description. + * This usually means the response is a `Room` object.) + * + */ + public findByIdAdmins(id: any, fk: any) { + let method: string = "GET"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/rooms/:id/admins/:fk"; + let routeParams: any = { + id: id, + fk: fk + }; + let postBody: any = {}; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result.map((instance: Room) => new Room(instance)); + } + + /** + * Delete a related item by id for admins. + * + * @param any id PersistedModel id + * + * @param any fk Foreign key for admins + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * This method returns no data. + */ + public destroyByIdAdmins(id: any, fk: any) { + let method: string = "DELETE"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/rooms/:id/admins/:fk"; + let routeParams: any = { + id: id, + fk: fk + }; + let postBody: any = {}; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + + /** + * Update a related item by id for admins. + * + * @param any id PersistedModel id + * + * @param any fk Foreign key for admins + * + * @param object data Request data. + * + * This method expects a subset of model properties as request parameters. + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * + * (The remote method definition does not provide any description. + * This usually means the response is a `Room` object.) + * + */ + public updateByIdAdmins(id: any, fk: any, data: Account = undefined) { + let method: string = "PUT"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/rooms/:id/admins/:fk"; + let routeParams: any = { + id: id, + fk: fk + }; + let postBody: any = { + data: data + }; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + + /** + * Add a related item by id for admins. + * + * @param any id PersistedModel id + * + * @param any fk Foreign key for admins + * + * @param object data Request data. + * + * This method expects a subset of model properties as request parameters. + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * + * (The remote method definition does not provide any description. + * This usually means the response is a `Room` object.) + * + */ + public linkAdmins(id: any, fk: any, data: any = undefined) { + let method: string = "PUT"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/rooms/:id/admins/rel/:fk"; + let routeParams: any = { + id: id, + fk: fk + }; + let postBody: any = { + data: data + }; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + + /** + * Remove the admins relation to an item by id. + * + * @param any id PersistedModel id + * + * @param any fk Foreign key for admins + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * This method returns no data. + */ + public unlinkAdmins(id: any, fk: any) { + let method: string = "DELETE"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/rooms/:id/admins/rel/:fk"; + let routeParams: any = { + id: id, + fk: fk + }; + let postBody: any = {}; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + + /** + * Check the existence of admins relation to an item by id. + * + * @param any id PersistedModel id + * + * @param any fk Foreign key for admins + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * + * (The remote method definition does not provide any description. + * This usually means the response is a `Room` object.) + * + */ + public existsAdmins(id: any, fk: any) { + let method: string = "HEAD"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/rooms/:id/admins/rel/:fk"; + let routeParams: any = { + id: id, + fk: fk + }; + let postBody: any = {}; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + /** * Queries messages of Room. * @@ -1059,6 +1245,122 @@ export class RoomApi extends BaseLoopBackApi { return result; } + /** + * Queries admins of Room. + * + * @param any id PersistedModel id + * + * @param object filter + * + * @returns object[] An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * + * (The remote method definition does not provide any description. + * This usually means the response is a `Room` object.) + * + */ + public getAdmins(id: any, filter: LoopBackFilter = undefined) { + let method: string = "GET"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/rooms/:id/admins"; + let routeParams: any = { + id: id + }; + let postBody: any = {}; + let urlParams: any = {}; + if (filter) urlParams.filter = filter; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + + /** + * Creates a new instance in admins of this model. + * + * @param any id PersistedModel id + * + * @param object data Request data. + * + * This method expects a subset of model properties as request parameters. + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * + * (The remote method definition does not provide any description. + * This usually means the response is a `Room` object.) + * + */ + public createAdmins(id: any, data: Account = undefined) { + let method: string = "POST"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/rooms/:id/admins"; + let routeParams: any = { + id: id + }; + let postBody: any = { + data: data + }; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + + /** + * Deletes all admins of this model. + * + * @param any id PersistedModel id + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * This method returns no data. + */ + public deleteAdmins(id: any) { + let method: string = "DELETE"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/rooms/:id/admins"; + let routeParams: any = { + id: id + }; + let postBody: any = {}; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + + /** + * Counts admins of Room. + * + * @param any id PersistedModel id + * + * @param object where Criteria to match model instances + * + * @returns object An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * Data properties: + * + * - `count` – `{number}` - + */ + public countAdmins(id: any, where: any = undefined) { + let method: string = "GET"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/rooms/:id/admins/count"; + let routeParams: any = { + id: id + }; + let postBody: any = {}; + let urlParams: any = {}; + if (where) urlParams.where = where; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + /** * Create a new instance of the model and persist it into the data source. * @@ -1669,6 +1971,39 @@ export class RoomApi extends BaseLoopBackApi { return result; } + /** + * Creates a new instance in admins of this model. + * + * @param any id PersistedModel id + * + * @param object data Request data. + * + * This method expects a subset of model properties as request parameters. + * + * @returns object[] An empty reference that will be + * populated with the actual data once the response is returned + * from the server. + * + * + * (The remote method definition does not provide any description. + * This usually means the response is a `Room` object.) + * + */ + public createManyAdmins(id: any, data: Account = undefined) { + let method: string = "POST"; + let url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + + "/rooms/:id/admins"; + let routeParams: any = { + id: id + }; + let postBody: any = { + data: data + }; + let urlParams: any = {}; + let result = this.request(method, url, routeParams, urlParams, postBody); + return result; + } + /** * Create a new instance of the model and persist it into the data source. * diff --git a/tests/angular2/src/app/user-service.service.spec.ts b/tests/angular2/src/app/user-service.service.spec.ts index 92ed7e7c..1ae55a92 100644 --- a/tests/angular2/src/app/user-service.service.spec.ts +++ b/tests/angular2/src/app/user-service.service.spec.ts @@ -1,26 +1,20 @@ -import { - beforeEachProviders, - it, - describe, - expect, - inject, - async -} from '@angular/core/testing'; - +import { addProviders, async, inject } from '@angular/core/testing'; import { User, - UserApi, - API_PROVIDERS, LoopBackConfig, - AccessTokenInterface -} from './shared'; + AccessTokenInterface, + API_PROVIDERS +} from './shared/sdk'; + +import { UserApi } from './shared/sdk/services'; LoopBackConfig.setBaseURL('http://127.0.0.1:3000'); LoopBackConfig.setApiVersion('api'); describe('UserService Tests', () => { - beforeEachProviders(() => [API_PROVIDERS]); - + beforeEach(() => { + addProviders([ API_PROVIDERS ]); + }); it('should contain authentication methods', async(inject([UserApi], (service: UserApi) => { expect(service).toBeTruthy(); diff --git a/tests/angular2/src/index.html b/tests/angular2/src/index.html index 1c7cc81b..f376d79e 100644 --- a/tests/angular2/src/index.html +++ b/tests/angular2/src/index.html @@ -4,34 +4,12 @@ Angular2 - {{content-for 'head'}} - - - + + + - Loading... - - - - - - - + Loading... diff --git a/tests/angular2/src/main.ts b/tests/angular2/src/main.ts index cbf6b6f5..4bdf15c0 100644 --- a/tests/angular2/src/main.ts +++ b/tests/angular2/src/main.ts @@ -1,10 +1,9 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { enableProdMode } from '@angular/core'; -import { Angular2AppComponent, environment } from './app/'; -import { API_PROVIDERS } from './app/shared'; +import { AppModule, environment } from './app/'; if (environment.production) { enableProdMode(); } -bootstrap(Angular2AppComponent, [...API_PROVIDERS]); +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/tests/angular2/src/polyfills.ts b/tests/angular2/src/polyfills.ts new file mode 100644 index 00000000..8e73613f --- /dev/null +++ b/tests/angular2/src/polyfills.ts @@ -0,0 +1,18 @@ +// Prefer CoreJS over the polyfills above +import 'core-js/es6/symbol'; +import 'core-js/es6/object'; +import 'core-js/es6/function'; +import 'core-js/es6/parse-int'; +import 'core-js/es6/parse-float'; +import 'core-js/es6/number'; +import 'core-js/es6/math'; +import 'core-js/es6/string'; +import 'core-js/es6/date'; +import 'core-js/es6/array'; +import 'core-js/es6/regexp'; +import 'core-js/es6/map'; +import 'core-js/es6/set'; +import 'core-js/es6/reflect'; + +import 'core-js/es7/reflect'; +import 'zone.js/dist/zone'; diff --git a/tests/angular2/src/system-config.ts b/tests/angular2/src/system-config.ts deleted file mode 100644 index d2af1aac..00000000 --- a/tests/angular2/src/system-config.ts +++ /dev/null @@ -1,54 +0,0 @@ -/*********************************************************************************************** - * User Configuration. - **********************************************************************************************/ -/** Map relative paths to URLs. */ -const map: any = { -}; - -/** User packages configuration. */ -const packages: any = { -}; - -//////////////////////////////////////////////////////////////////////////////////////////////// -/*********************************************************************************************** - * Everything underneath this line is managed by the CLI. - **********************************************************************************************/ -const barrels: string[] = [ - // Angular specific barrels. - '@angular/core', - '@angular/common', - '@angular/compiler', - '@angular/http', - '@angular/router', - '@angular/platform-browser', - '@angular/platform-browser-dynamic', - - // Thirdparty barrels. - 'rxjs', - - // App specific barrels. - 'app', - 'app/shared', - /** @cli-barrel */ -]; - -const cliSystemConfigPackages: any = {}; -barrels.forEach((barrelName: string) => { - cliSystemConfigPackages[barrelName] = { main: 'index' }; -}); - -/** Type declaration for ambient System. */ -declare var System: any; - -// Apply the CLI SystemJS configuration. -System.config({ - map: { - '@angular': 'vendor/@angular', - 'rxjs': 'vendor/rxjs', - 'main': 'main.js' - }, - packages: cliSystemConfigPackages -}); - -// Apply the user's configuration. -System.config({ map, packages }); diff --git a/tests/angular2/src/test.ts b/tests/angular2/src/test.ts new file mode 100644 index 00000000..cef85f11 --- /dev/null +++ b/tests/angular2/src/test.ts @@ -0,0 +1,37 @@ +import 'core-js/es6'; +import 'core-js/es7/reflect'; + +// Typescript emit helpers polyfill +import 'ts-helpers'; + +import 'zone.js/dist/zone'; +import 'zone.js/dist/long-stack-trace-zone'; +import 'zone.js/dist/jasmine-patch'; +import 'zone.js/dist/async-test'; +import 'zone.js/dist/fake-async-test'; +import 'zone.js/dist/sync-test'; + +// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. +declare var __karma__: any; + +// Prevent Karma from running prematurely. +__karma__.loaded = function () {}; + + +Promise.all([ + System.import('@angular/core/testing'), + System.import('@angular/platform-browser-dynamic/testing') +]) + // First, initialize the Angular testing environment. + .then(([testing, testingBrowser]) => { + testing.setBaseTestProviders( + testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, + testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS + ); + }) + // Then we find all the tests. + .then(() => require.context('./', true, /\.spec\.ts/)) + // And load the modules. + .then(context => context.keys().map(context)) + // Finally, start Karma to run the tests. + .then(__karma__.start, __karma__.error); diff --git a/tests/angular2/src/tsconfig.json b/tests/angular2/src/tsconfig.json index 90ff5e57..03aff910 100644 --- a/tests/angular2/src/tsconfig.json +++ b/tests/angular2/src/tsconfig.json @@ -1,23 +1,20 @@ { - "compileOnSave": false, "compilerOptions": { "declaration": false, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "mapRoot": "", - "module": "commonjs", + "lib": ["es6", "dom"], + "mapRoot": "./", + "module": "es6", "moduleResolution": "node", - "noEmitOnError": true, - "noImplicitAny": false, - "outDir": "../dist/", - "rootDir": ".", + "outDir": "../dist/out-tsc", "sourceMap": true, "target": "es5", - "inlineSources": true - }, - - "files": [ - "main.ts", - "typings.d.ts" - ] + "typeRoots": [ + "../node_modules/@types" + ], + "types": [ + "jasmine" + ] + } } diff --git a/tests/angular2/src/typings.d.ts b/tests/angular2/src/typings.d.ts index ccd03c87..dc0276de 100644 --- a/tests/angular2/src/typings.d.ts +++ b/tests/angular2/src/typings.d.ts @@ -1,3 +1,8 @@ -/// -/// +// Typings reference file, see links for more information +// https://github.com/typings/typings +// https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html + +declare var System: any; declare var module: { id: string }; +declare var require: any; + diff --git a/tests/angular2/tslint.json b/tests/angular2/tslint.json index 7e941116..7b13bd17 100644 --- a/tests/angular2/tslint.json +++ b/tests/angular2/tslint.json @@ -1,40 +1,78 @@ { - "rulesDirectory": ["node_modules/codelyzer"], + "rulesDirectory": [ + "node_modules/codelyzer" + ], "rules": { - "max-line-length": [true, 100], - "no-inferrable-types": true, "class-name": true, "comment-format": [ true, "check-space" ], + "curly": true, + "eofline": true, + "forin": true, "indent": [ true, "spaces" ], - "eofline": true, - "no-duplicate-variable": true, - "no-eval": true, + "label-position": true, + "label-undefined": true, + "max-line-length": [ + true, + 140 + ], + "member-access": false, + "member-ordering": [ + true, + "static-before-instance", + "variables-before-functions" + ], "no-arg": true, - "no-internal-module": true, - "no-trailing-whitespace": true, "no-bitwise": true, + "no-console": [ + true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": true, + "no-duplicate-key": true, + "no-duplicate-variable": true, + "no-empty": false, + "no-eval": true, + "no-inferrable-types": true, "no-shadowed-variable": true, + "no-string-literal": false, + "no-switch-case-fall-through": true, + "no-trailing-whitespace": true, "no-unused-expression": true, "no-unused-variable": true, + "no-unreachable": true, + "no-use-before-declare": true, + "no-var-keyword": true, + "object-literal-sort-keys": false, "one-line": [ true, + "check-open-brace", "check-catch", "check-else", - "check-open-brace", "check-whitespace" ], "quotemark": [ true, - "single", - "avoid-escape" + "single" + ], + "radix": true, + "semicolon": [ + "always" + ], + "triple-equals": [ + true, + "allow-null-check" ], - "semicolon": [true, "always"], "typedef-whitespace": [ true, { @@ -45,13 +83,7 @@ "variable-declaration": "nospace" } ], - "curly": true, - "variable-name": [ - true, - "ban-keywords", - "check-format", - "allow-trailing-underscore" - ], + "variable-name": false, "whitespace": [ true, "check-branch", @@ -60,13 +92,19 @@ "check-separator", "check-type" ], + + "directive-selector-name": [true, "camelCase"], "component-selector-name": [true, "kebab-case"], + "directive-selector-type": [true, "attribute"], "component-selector-type": [true, "element"], - "host-parameter-decorator": true, - "input-parameter-decorator": true, - "output-parameter-decorator": true, - "attribute-parameter-decorator": true, - "input-property-directive": true, - "output-property-directive": true + "use-input-property-decorator": true, + "use-output-property-decorator": true, + "use-host-property-decorator": true, + "no-input-rename": true, + "no-output-rename": true, + "use-life-cycle-interface": true, + "use-pipe-transform-interface": true, + "component-class-suffix": true, + "directive-class-suffix": true } } diff --git a/tests/angular2/typings.json b/tests/angular2/typings.json deleted file mode 100644 index c8a8c562..00000000 --- a/tests/angular2/typings.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "ambientDevDependencies": { - "angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459", - "jasmine": "registry:dt/jasmine#2.2.0+20160412134438", - "selenium-webdriver": "registry:dt/selenium-webdriver#2.44.0+20160317120654" - }, - "ambientDependencies": { - "es6-shim": "registry:dt/es6-shim#0.31.2+20160317120654" - }, - "globalDependencies": { - "socket.io-client": "registry:dt/socket.io-client#1.4.4+20160317120654" - } -}