diff --git a/examples/todo-list/.dockerignore b/examples/todo-list/.dockerignore new file mode 100644 index 000000000000..7aecc7e3dda5 --- /dev/null +++ b/examples/todo-list/.dockerignore @@ -0,0 +1,5 @@ +node_modules +npm-debug.log +/dist +# Cache used by TypeScript's incremental build +*.tsbuildinfo diff --git a/examples/todo-list/Dockerfile b/examples/todo-list/Dockerfile new file mode 100644 index 000000000000..bca90e201a53 --- /dev/null +++ b/examples/todo-list/Dockerfile @@ -0,0 +1,28 @@ +# Check out https://hub.docker.com/_/node to select a new base image +FROM node:10-slim + +# Set to a non-root built-in user `node` +USER node + +# Create app directory (with user `node`) +RUN mkdir -p /home/node/app + +WORKDIR /home/node/app + +# Install app dependencies +# A wildcard is used to ensure both package.json AND package-lock.json are copied +# where available (npm@5+) +COPY --chown=node package*.json ./ + +RUN npm install + +# Bundle app source code +COPY --chown=node . . + +RUN npm run build + +# Bind to all network interfaces so that it can be mapped to the host OS +ENV HOST=0.0.0.0 PORT=3000 + +EXPOSE ${PORT} +CMD [ "node", "." ] diff --git a/examples/todo-list/src/controllers/todo.controller.ts b/examples/todo-list/src/controllers/todo.controller.ts index 8a81c7600498..517307993987 100644 --- a/examples/todo-list/src/controllers/todo.controller.ts +++ b/examples/todo-list/src/controllers/todo.controller.ts @@ -19,7 +19,9 @@ import {Todo, TodoList} from '../models'; import {TodoRepository} from '../repositories'; export class TodoController { - constructor(@repository(TodoRepository) protected todoRepo: TodoRepository) {} + constructor( + @repository(TodoRepository) protected todoRepository: TodoRepository, + ) {} @post('/todos', { responses: { @@ -39,7 +41,7 @@ export class TodoController { }) todo: Omit, ): Promise { - return this.todoRepo.create(todo); + return this.todoRepository.create(todo); } @get('/todos/{id}', { @@ -59,7 +61,7 @@ export class TodoController { @param.query.object('filter', getFilterSchemaFor(Todo)) filter?: Filter, ): Promise { - return this.todoRepo.findById(id, filter); + return this.todoRepository.findById(id, filter); } @get('/todos', { @@ -81,7 +83,7 @@ export class TodoController { @param.query.object('filter', getFilterSchemaFor(Todo)) filter?: Filter, ): Promise { - return this.todoRepo.find(filter); + return this.todoRepository.find(filter); } @put('/todos/{id}', { @@ -95,7 +97,7 @@ export class TodoController { @param.path.number('id') id: number, @requestBody() todo: Todo, ): Promise { - await this.todoRepo.replaceById(id, todo); + await this.todoRepository.replaceById(id, todo); } @patch('/todos/{id}', { @@ -116,7 +118,7 @@ export class TodoController { }) todo: Partial, ): Promise { - await this.todoRepo.updateById(id, todo); + await this.todoRepository.updateById(id, todo); } @del('/todos/{id}', { @@ -127,7 +129,7 @@ export class TodoController { }, }) async deleteTodo(@param.path.number('id') id: number): Promise { - await this.todoRepo.deleteById(id); + await this.todoRepository.deleteById(id); } @get('/todos/{id}/todo-list', { @@ -139,6 +141,6 @@ export class TodoController { }, }) async findOwningList(@param.path.number('id') id: number): Promise { - return this.todoRepo.todoList(id); + return this.todoRepository.todoList(id); } } diff --git a/examples/todo-list/src/datasources/geocoder.datasource.config.json b/examples/todo-list/src/datasources/geocoder.datasource.config.json deleted file mode 100644 index a95c67c892ea..000000000000 --- a/examples/todo-list/src/datasources/geocoder.datasource.config.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "connector": "rest", - "options": { - "headers": { - "accept": "application/json", - "content-type": "application/json" - }, - "timeout": 15000 - }, - "operations": [ - { - "template": { - "method": "GET", - "url": "https://geocoding.geo.census.gov/geocoder/locations/onelineaddress", - "query": { - "format": "{format=json}", - "benchmark": "Public_AR_Current", - "address": "{address}" - }, - "responsePath": "$.result.addressMatches[*].coordinates" - }, - "functions": { - "geocode": ["address"] - } - } - ] -} - diff --git a/examples/todo-list/src/datasources/geocoder.datasource.ts b/examples/todo-list/src/datasources/geocoder.datasource.ts deleted file mode 100644 index aadd239613cd..000000000000 --- a/examples/todo-list/src/datasources/geocoder.datasource.ts +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright IBM Corp. 2018. All Rights Reserved. -// Node module: @loopback/example-todo -// This file is licensed under the MIT License. -// License text available at https://opensource.org/licenses/MIT - -import {inject} from '@loopback/core'; -import {AnyObject, juggler} from '@loopback/repository'; -import config from './geocoder.datasource.config.json'; - -export class GeocoderDataSource extends juggler.DataSource { - static dataSourceName = 'geocoder'; - - constructor( - @inject('datasources.config.geocoder', {optional: true}) - dsConfig: AnyObject = config, - ) { - dsConfig = Object.assign({}, dsConfig, { - // A workaround for the current design flaw where inside our monorepo, - // packages/service-proxy/node_modules/loopback-datasource-juggler - // cannot see/load the connector from - // examples/todo/node_modules/loopback-connector-rest - connector: require('loopback-connector-rest'), - }); - super(dsConfig); - } -} diff --git a/examples/todo-list/src/models/todo-list-image.model.ts b/examples/todo-list/src/models/todo-list-image.model.ts index 37e9cc6e12a8..fd4d7c477b5c 100644 --- a/examples/todo-list/src/models/todo-list-image.model.ts +++ b/examples/todo-list/src/models/todo-list-image.model.ts @@ -11,6 +11,7 @@ export class TodoListImage extends Entity { @property({ type: 'number', id: true, + generated: false, }) id: number; diff --git a/examples/todo-list/src/models/todo-list.model.ts b/examples/todo-list/src/models/todo-list.model.ts index 8b23ffc2d868..8e4bebd63102 100644 --- a/examples/todo-list/src/models/todo-list.model.ts +++ b/examples/todo-list/src/models/todo-list.model.ts @@ -15,6 +15,7 @@ export class TodoList extends Entity { @property({ type: 'number', id: true, + generated: false, }) id: number; @@ -30,10 +31,10 @@ export class TodoList extends Entity { color?: string; @hasMany(() => Todo) - todos?: Todo[]; + todos: Todo[]; @hasOne(() => TodoListImage) - image?: TodoListImage; + image: TodoListImage; constructor(data?: Partial) { super(data); diff --git a/examples/todo-list/src/models/todo.model.ts b/examples/todo-list/src/models/todo.model.ts index 64ceddafa179..b06295dc3ab7 100644 --- a/examples/todo-list/src/models/todo.model.ts +++ b/examples/todo-list/src/models/todo.model.ts @@ -11,6 +11,7 @@ export class Todo extends Entity { @property({ type: 'number', id: true, + generated: false, }) id: number; diff --git a/examples/todo-list/src/services/geocoder.service.ts b/examples/todo-list/src/services/geocoder.service.ts deleted file mode 100644 index 7a86e8c76cf7..000000000000 --- a/examples/todo-list/src/services/geocoder.service.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {getService} from '@loopback/service-proxy'; -import {inject, Provider} from '@loopback/core'; -import {Error: bad inputDataSource} from '../datasources'; - -export interface Geocoder { - // this is where you define the Node.js methods that will be - // mapped to REST/SOAP/gRPC operations as stated in the datasource - // json file. -} - -export class GeocoderProvider implements Provider { - constructor( - // must match the name property in the datasource json file - @inject('datasources.') - protected dataSource: Error: bad inputDataSource = new Error: bad inputDataSource(), - ) {} - - value(): Promise { - return getService(this.dataSource); - } -} diff --git a/examples/todo-list/src/services/index.ts b/examples/todo-list/src/services/index.ts deleted file mode 100644 index 3a4a2b3916b6..000000000000 --- a/examples/todo-list/src/services/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './geocoder.service';