From 213ca4ae538036ba0b062974a813ee642f12e510 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Tue, 13 Dec 2016 15:15:23 +0100 Subject: [PATCH 01/10] added mock collection REST data --- src/backend/api.ts | 127 +++++++++++++++++++++++++-------------------- src/server.aot.ts | 4 +- src/server.ts | 4 +- 3 files changed, 76 insertions(+), 59 deletions(-) diff --git a/src/backend/api.ts b/src/backend/api.ts index 51dfc177c3..21ff469384 100644 --- a/src/backend/api.ts +++ b/src/backend/api.ts @@ -1,12 +1,12 @@ -var util = require('util'); -var { Router } = require('express'); +const util = require('util'); +const { Router } = require('express'); // Our API for demos only import { fakeDataBase } from './db'; import { fakeDemoRedisCache } from './cache'; // you would use cookies/token etc -var USER_ID = 'f9d98cf1-1b96-464e-8755-bcc2a5c09077'; // hardcoded as an example +const USER_ID = 'f9d98cf1-1b96-464e-8755-bcc2a5c09077'; // hardcoded as an example // Our API for demos only export function serverApi(req, res) { @@ -27,80 +27,97 @@ export function serverApi(req, res) { } -// todo API +// collection API -var COUNT = 4; -var TODOS = [ - { id: 0, value: 'finish example', created_at: new Date(), completed: false }, - { id: 1, value: 'add tests', created_at: new Date(), completed: false }, - { id: 2, value: 'include development environment', created_at: new Date(), completed: false }, - { id: 3, value: 'include production environment', created_at: new Date(), completed: false } +let COUNT = 2; +const COLLECTIONS = [ + { + "id": "9e32a2e2-6b91-4236-a361-995ccdc14c60", + "name": "Test Collection 1", + "handle": "123456789/5179", + "type": "collection", + "copyrightText": "

© 2005-2016 JOHN DOE SOME RIGHTS RESERVED

", + "introductoryText": "

An introductory text dolor sit amet, consectetur adipiscing elit. Duis laoreet lorem erat, eget auctor est ultrices quis. Nullam ac tincidunt quam. In nec nisl odio. In egestas aliquam tincidunt.

\r\n

Integer vitae diam id dolor pharetra dignissim in sed enim. Vivamus pulvinar tristique sem a iaculis. Aenean ultricies dui vel facilisis laoreet. Integer porta erat eu ultrices rhoncus. Sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum.

", + "shortDescription": "A collection for testing purposes", + "sidebarText": "

Some news sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum. Donec sed ultricies erat, nec sollicitudin mauris. Duis varius nulla quis quam vulputate, at hendrerit turpis rutrum. Integer nec facilisis sapien. Fusce fringilla malesuada lectus id pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae

", + }, + { + "id": "598ce822-c357-46f3-ab70-63724d02d6ad", + "name": "Test Collection 2", + "handle": "123456789/6547", + "type": "collection", + "copyrightText": "

© 2005-2016 JOHN DOE SOME RIGHTS RESERVED

", + "introductoryText": "

Another introductory text dolor sit amet, consectetur adipiscing elit. Duis laoreet lorem erat, eget auctor est ultrices quis. Nullam ac tincidunt quam. In nec nisl odio. In egestas aliquam tincidunt.

\r\n

Integer vitae diam id dolor pharetra dignissim in sed enim. Vivamus pulvinar tristique sem a iaculis. Aenean ultricies dui vel facilisis laoreet. Integer porta erat eu ultrices rhoncus. Sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum.

", + "shortDescription": "Another collection for testing purposes", + "sidebarText": "

Some more news sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum. Donec sed ultricies erat, nec sollicitudin mauris. Duis varius nulla quis quam vulputate, at hendrerit turpis rutrum. Integer nec facilisis sapien. Fusce fringilla malesuada lectus id pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae

", + } ]; -export function createTodoApi() { +export function createMockApi() { - var router = Router() + let router = Router(); - router.route('/todos') + router.route('/collections') .get(function(req, res) { console.log('GET'); // 70ms latency setTimeout(function() { - res.json(TODOS); + res.json(COLLECTIONS); }, 0); - }) - .post(function(req, res) { - console.log('POST', util.inspect(req.body, { colors: true })); - var todo = req.body; - if (todo) { - TODOS.push({ - value: todo.value, - created_at: new Date(), - completed: todo.completed, - id: COUNT++ - }); - return res.json(todo); - } - - return res.end(); + // }) + // .post(function(req, res) { + // console.log('POST', util.inspect(req.body, { colors: true })); + // let collection = req.body; + // if (collection) { + // COLLECTIONS.push({ + // value: collection.value, + // created_at: new Date(), + // completed: collection.completed, + // id: COUNT++ + // }); + // return res.json(collection); + // } + // + // return res.end(); }); - router.param('todo_id', function(req, res, next, todo_id) { + router.param('collection_id', function(req, res, next, collection_id) { // ensure correct prop type - var id = Number(req.params.todo_id); + let id = req.params.collection_id; try { - var todo = TODOS[id]; - req.todo_id = id; - req.todo = TODOS[id]; + req.collection_id = id; + req.collection = COLLECTIONS.find((collection) => { + return collection.id = id; + }); next(); } catch (e) { - next(new Error('failed to load todo')); + next(new Error('failed to load collection')); } }); - router.route('/todos/:todo_id') + router.route('/collections/:collection_id') .get(function(req, res) { - console.log('GET', util.inspect(req.todo, { colors: true })); + console.log('GET', util.inspect(req.collection, { colors: true })); - res.json(req.todo); - }) - .put(function(req, res) { - console.log('PUT', util.inspect(req.body, { colors: true })); - - var index = TODOS.indexOf(req.todo); - var todo = TODOS[index] = req.body; - - res.json(todo); - }) - .delete(function(req, res) { - console.log('DELETE', req.todo_id); - - var index = TODOS.indexOf(req.todo); - TODOS.splice(index, 1); - - res.json(req.todo); + res.json(req.collection); + // }) + // .put(function(req, res) { + // console.log('PUT', util.inspect(req.body, { colors: true })); + // + // let index = COLLECTIONS.indexOf(req.collection); + // let collection = COLLECTIONS[index] = req.body; + // + // res.json(collection); + // }) + // .delete(function(req, res) { + // console.log('DELETE', req.collection_id); + // + // let index = COLLECTIONS.indexOf(req.collection); + // COLLECTIONS.splice(index, 1); + // + // res.json(req.collection); }); return router; -}; +} diff --git a/src/server.aot.ts b/src/server.aot.ts index 7df96cb3b9..a649912eb3 100644 --- a/src/server.aot.ts +++ b/src/server.aot.ts @@ -73,10 +73,10 @@ app.use(cacheControl, express.static(path.join(ROOT, 'dist/client'), { index: fa ///////////////////////// // ** Example API // Notice API should be in a separate process -import { serverApi, createTodoApi } from './backend/api'; +import { serverApi, createMockApi } from './backend/api'; // Our API for demos only app.get('/data.json', serverApi); -app.use('/api', createTodoApi()); +app.use('/api', createMockApi()); function ngApp(req, res) { res.render('index', { diff --git a/src/server.ts b/src/server.ts index 5c4250c2f5..82e7fe0d8c 100644 --- a/src/server.ts +++ b/src/server.ts @@ -66,10 +66,10 @@ app.use(cacheControl, express.static(path.join(ROOT, 'dist/client'), { index: fa ///////////////////////// // ** Example API // Notice API should be in aseparate process -import { serverApi, createTodoApi } from './backend/api'; +import { serverApi, createMockApi } from './backend/api'; // Our API for demos only app.get('/data.json', serverApi); -app.use('/api', createTodoApi()); +app.use('/api', createMockApi()); function ngApp(req, res) { res.render('index', { From 9c6e729018786ed63fc959c9e47bf4aa5d2470ef Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Tue, 13 Dec 2016 16:22:07 +0100 Subject: [PATCH 02/10] added mock item data --- src/backend/api.ts | 105 +++++++++---- src/backend/collections.ts | 42 +++++ src/backend/items.ts | 312 +++++++++++++++++++++++++++++++++++++ 3 files changed, 432 insertions(+), 27 deletions(-) create mode 100644 src/backend/collections.ts create mode 100644 src/backend/items.ts diff --git a/src/backend/api.ts b/src/backend/api.ts index 21ff469384..4bdc108d27 100644 --- a/src/backend/api.ts +++ b/src/backend/api.ts @@ -4,6 +4,8 @@ const { Router } = require('express'); // Our API for demos only import { fakeDataBase } from './db'; import { fakeDemoRedisCache } from './cache'; +import { COLLECTIONS } from "./collections"; +import { ITEMS } from "./items"; // you would use cookies/token etc const USER_ID = 'f9d98cf1-1b96-464e-8755-bcc2a5c09077'; // hardcoded as an example @@ -27,31 +29,18 @@ export function serverApi(req, res) { } -// collection API +let COLLECTION_COUNT = 2; +let ITEM_COUNT = 2; -let COUNT = 2; -const COLLECTIONS = [ - { - "id": "9e32a2e2-6b91-4236-a361-995ccdc14c60", - "name": "Test Collection 1", - "handle": "123456789/5179", - "type": "collection", - "copyrightText": "

© 2005-2016 JOHN DOE SOME RIGHTS RESERVED

", - "introductoryText": "

An introductory text dolor sit amet, consectetur adipiscing elit. Duis laoreet lorem erat, eget auctor est ultrices quis. Nullam ac tincidunt quam. In nec nisl odio. In egestas aliquam tincidunt.

\r\n

Integer vitae diam id dolor pharetra dignissim in sed enim. Vivamus pulvinar tristique sem a iaculis. Aenean ultricies dui vel facilisis laoreet. Integer porta erat eu ultrices rhoncus. Sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum.

", - "shortDescription": "A collection for testing purposes", - "sidebarText": "

Some news sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum. Donec sed ultricies erat, nec sollicitudin mauris. Duis varius nulla quis quam vulputate, at hendrerit turpis rutrum. Integer nec facilisis sapien. Fusce fringilla malesuada lectus id pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae

", - }, - { - "id": "598ce822-c357-46f3-ab70-63724d02d6ad", - "name": "Test Collection 2", - "handle": "123456789/6547", - "type": "collection", - "copyrightText": "

© 2005-2016 JOHN DOE SOME RIGHTS RESERVED

", - "introductoryText": "

Another introductory text dolor sit amet, consectetur adipiscing elit. Duis laoreet lorem erat, eget auctor est ultrices quis. Nullam ac tincidunt quam. In nec nisl odio. In egestas aliquam tincidunt.

\r\n

Integer vitae diam id dolor pharetra dignissim in sed enim. Vivamus pulvinar tristique sem a iaculis. Aenean ultricies dui vel facilisis laoreet. Integer porta erat eu ultrices rhoncus. Sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum.

", - "shortDescription": "Another collection for testing purposes", - "sidebarText": "

Some more news sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum. Donec sed ultricies erat, nec sollicitudin mauris. Duis varius nulla quis quam vulputate, at hendrerit turpis rutrum. Integer nec facilisis sapien. Fusce fringilla malesuada lectus id pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae

", + +function toJSONAPIResponse(req, data) { + return { + "data": data, + "links": { + "self": req.protocol + '://' + req.get('host') + req.originalUrl + } } -]; +} export function createMockApi() { @@ -62,7 +51,7 @@ export function createMockApi() { console.log('GET'); // 70ms latency setTimeout(function() { - res.json(COLLECTIONS); + res.json(toJSONAPIResponse(req, COLLECTIONS)); }, 0); // }) @@ -74,7 +63,7 @@ export function createMockApi() { // value: collection.value, // created_at: new Date(), // completed: collection.completed, - // id: COUNT++ + // id: COLLECTION_COUNT++ // }); // return res.json(collection); // } @@ -99,8 +88,7 @@ export function createMockApi() { router.route('/collections/:collection_id') .get(function(req, res) { console.log('GET', util.inspect(req.collection, { colors: true })); - - res.json(req.collection); + res.json(toJSONAPIResponse(req, req.collection)); // }) // .put(function(req, res) { // console.log('PUT', util.inspect(req.body, { colors: true })); @@ -119,5 +107,68 @@ export function createMockApi() { // res.json(req.collection); }); + + router.route('/items') + .get(function(req, res) { + console.log('GET'); + // 70ms latency + setTimeout(function() { + res.json(toJSONAPIResponse(req, ITEMS)); + }, 0); + + // }) + // .post(function(req, res) { + // console.log('POST', util.inspect(req.body, { colors: true })); + // let item = req.body; + // if (item) { + // ITEMS.push({ + // value: item.value, + // created_at: new Date(), + // completed: item.completed, + // id: ITEM_COUNT++ + // }); + // return res.json(item); + // } + // + // return res.end(); + }); + + router.param('item_id', function(req, res, next, item_id) { + // ensure correct prop type + let id = req.params.item_id; + try { + req.item_id = id; + req.item = ITEMS.find((item) => { + return item.id = id; + }); + next(); + } catch (e) { + next(new Error('failed to load item')); + } + }); + + router.route('/items/:item_id') + .get(function(req, res) { + console.log('GET', util.inspect(req.item, { colors: true })); + + res.json(toJSONAPIResponse(req, req.item)); + // }) + // .put(function(req, res) { + // console.log('PUT', util.inspect(req.body, { colors: true })); + // + // let index = ITEMS.indexOf(req.item); + // let item = ITEMS[index] = req.body; + // + // res.json(item); + // }) + // .delete(function(req, res) { + // console.log('DELETE', req.item_id); + // + // let index = ITEMS.indexOf(req.item); + // ITEMS.splice(index, 1); + // + // res.json(req.item); + }); + return router; } diff --git a/src/backend/collections.ts b/src/backend/collections.ts new file mode 100644 index 0000000000..db42fa2f37 --- /dev/null +++ b/src/backend/collections.ts @@ -0,0 +1,42 @@ +export const COLLECTIONS = [ + { + "id": "9e32a2e2-6b91-4236-a361-995ccdc14c60", + "type": "collections", + "attributes": { + "name": "A Test Collection", + "handle": "123456789/5179", + "copyrightText": "

© 2005-2016 JOHN DOE SOME RIGHTS RESERVED

", + "introductoryText": "

An introductory text dolor sit amet, consectetur adipiscing elit. Duis laoreet lorem erat, eget auctor est ultrices quis. Nullam ac tincidunt quam. In nec nisl odio. In egestas aliquam tincidunt.

\r\n

Integer vitae diam id dolor pharetra dignissim in sed enim. Vivamus pulvinar tristique sem a iaculis. Aenean ultricies dui vel facilisis laoreet. Integer porta erat eu ultrices rhoncus. Sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum.

", + "shortDescription": "A collection for testing purposes", + "sidebarText": "

Some news sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum. Donec sed ultricies erat, nec sollicitudin mauris. Duis varius nulla quis quam vulputate, at hendrerit turpis rutrum. Integer nec facilisis sapien. Fusce fringilla malesuada lectus id pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae

" + }, + "relationships": { + "items": { + "data": [ + { "type": "items", "id": "21539b1d-9ef1-4eda-9c77-49565b5bfb78" }, + { "type": "items", "id": "be8325f7-243b-49f4-8a4b-df2b793ff3b5" } + ] + } + } + }, + { + "id": "598ce822-c357-46f3-ab70-63724d02d6ad", + "type": "collections", + "attributes": { + "name": "Another Test Collection", + "handle": "123456789/6547", + "copyrightText": "

© 2005-2016 JOHN DOE SOME RIGHTS RESERVED

", + "introductoryText": "

Another introductory text dolor sit amet, consectetur adipiscing elit. Duis laoreet lorem erat, eget auctor est ultrices quis. Nullam ac tincidunt quam. In nec nisl odio. In egestas aliquam tincidunt.

\r\n

Integer vitae diam id dolor pharetra dignissim in sed enim. Vivamus pulvinar tristique sem a iaculis. Aenean ultricies dui vel facilisis laoreet. Integer porta erat eu ultrices rhoncus. Sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum.

", + "shortDescription": "Another collection for testing purposes", + "sidebarText": "

Some more news sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum. Donec sed ultricies erat, nec sollicitudin mauris. Duis varius nulla quis quam vulputate, at hendrerit turpis rutrum. Integer nec facilisis sapien. Fusce fringilla malesuada lectus id pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae

" + }, + "relationships": { + "items": { + "data": [ + { "type": "items", "id": "21539b1d-9ef1-4eda-9c77-49565b5bfb78" }, + { "type": "items", "id": "be8325f7-243b-49f4-8a4b-df2b793ff3b5" } + ] + } + } + } +]; diff --git a/src/backend/items.ts b/src/backend/items.ts new file mode 100644 index 0000000000..f7721317c7 --- /dev/null +++ b/src/backend/items.ts @@ -0,0 +1,312 @@ +export const ITEMS = [ + { + "id": "21539b1d-9ef1-4eda-9c77-49565b5bfb78", + "type": "items", + "attributes": { + "name": "Do Open-Access Articles Have a Greater Research Impact?", + "handle": "123456789/8871", + "lastModified": "2016-10-14 10:41:12.886", + "isArchived": true, + "isWithdrawn": false + }, + "relationships": { + "collections": { + "data": [ + { "type": "collections", "id": "9e32a2e2-6b91-4236-a361-995ccdc14c60" }, + { "type": "collections", "id": "598ce822-c357-46f3-ab70-63724d02d6ad" } + ] + }, + "metadata": { + "data": [ + { + "type": "metadata", + "id": "d58a3098-b390-4cd6-8f52-b088b3daa637", + }, + { + "type": "metadata", + "id": "56660730-0e0d-47ec-864a-bda2327d5716", + }, + { + "type": "metadata", + "id": "b9d4ae74-2758-4964-a95e-eecd35b62f26", + }, + { + "type": "metadata", + "id": "311529ea-e339-4d8f-9292-813ebe515f03", + }, + { + "type": "metadata", + "id": "fa875444-3faf-482a-b099-77233bda914d", + }, + { + "type": "metadata", + "id": "ddbb161b-6e52-4a90-9096-c8eae8cec4c9", + }, + { + "type": "metadata", + "id": "ba51287d-a2c9-409b-8129-060b693a7570", + }, + { + "type": "metadata", + "id": "e5c1c9d4-b4e2-4bdc-9153-6b769742b33f", + }, + { + "type": "metadata", + "id": "4c125844-1eca-47aa-98f8-61c51a9c962f", + }, + { + "type": "metadata", + "id": "362c753c-a44d-468d-b256-486470b8c1e1", + }, + { + "type": "metadata", + "id": " 69a02355-37bb-479f-9496-c8743fcacf3c", + }, + { + "type": "metadata", + "id": "ffbd75d5-bf3a-47ff-af22-490240f6fcc6", + } + ] + } + }, + "included": [ + { + "type": "metadata", + "id": "d58a3098-b390-4cd6-8f52-b088b3daa637", + "attributes": { + "key": "dc.contributor.author", + "value": "Antelman, Kristin", + "language": "en" + } + }, + { + "type": "metadata", + "id": "56660730-0e0d-47ec-864a-bda2327d5716", + "attributes": { + "key": "dc.date.accessioned", + "value": "2016-10-14T10:41:13Z", + "language": null + } + }, + { + "type": "metadata", + "id": "b9d4ae74-2758-4964-a95e-eecd35b62f26", + "attributes": { + "key": "dc.date.available", + "value": "2016-10-14T10:41:13Z", + "language": null + } + }, + { + "type": "metadata", + "id": "311529ea-e339-4d8f-9292-813ebe515f03", + "attributes": { + "key": "dc.date.issued", + "value": "2004-09-01", + "language": "en" + } + }, + { + "type": "metadata", + "id": "fa875444-3faf-482a-b099-77233bda914d", + "attributes": { + "key": "dc.identifier.uri", + "value": "http://hdl.handle.net/123456789/8871", + "language": null + } + }, + { + "type": "metadata", + "id": "ddbb161b-6e52-4a90-9096-c8eae8cec4c9", + "attributes": { + "key": "dc.description.abstract", + "value": "Although many authors believe that their work has a greater research impact if it is freely available, studies to demonstrate that impact are few. This study looks at articles in four disciplines at varying stages of adoption of open access—philosophy, political science, electrical and electronic engineering and mathematics—to see whether they have a greater impact as measured by citations in the ISI Web of Science database when their authors make them freely available on the Internet. The finding is that, across all four disciplines, freely available articles do have a greater research impact. Shedding light on this category of open access reveals that scholars in diverse disciplines are adopting open-access practices and being rewarded for it.", + "language": "en" + } + }, + { + "type": "metadata", + "id": "ba51287d-a2c9-409b-8129-060b693a7570", + "attributes": { + "key": "dc.publisher", + "value": "College & Research Libraries News", + "language": "en" + } + }, + { + "type": "metadata", + "id": "e5c1c9d4-b4e2-4bdc-9153-6b769742b33f", + "attributes": { + "key": "dc.subject", + "value": "Publishing", + "language": "en" + } + }, + { + "type": "metadata", + "id": "4c125844-1eca-47aa-98f8-61c51a9c962f", + "attributes": { + "key": "dc.subject", + "value": "Intellectual Property", + "language": "en" + } + }, + { + "type": "metadata", + "id": "362c753c-a44d-468d-b256-486470b8c1e1", + "attributes": { + "key": "dc.subject", + "value": "Open Access", + "language": "en" + } + }, + { + "type": "metadata", + "id": " 69a02355-37bb-479f-9496-c8743fcacf3c", + "attributes": { + "key": "dc.title", + "value": "Do Open-Access Articles Have a Greater Research Impact?", + "language": "en" + } + }, + { + "type": "metadata", + "id": "ffbd75d5-bf3a-47ff-af22-490240f6fcc6", + "attributes": { + "key": "dc.type", + "value": "(not specified)", + "language": "en" + } + } + ] + }, + { + "id": "be8325f7-243b-49f4-8a4b-df2b793ff3b5", + "type": "items", + "attributes": { + "name": "Another Test Item", + "handle": "123456789/9978", + "lastModified": "2016-05-27 03:00:20.063", + "isArchived": true, + "isWithdrawn": false + }, + "relationships": { + "collections": { + "data": [ + { "type": "collections", "id": "9e32a2e2-6b91-4236-a361-995ccdc14c60" }, + { "type": "collections", "id": "598ce822-c357-46f3-ab70-63724d02d6ad" } + ] + }, + "metadata": { + "data": [ + { + "type": "metadata", + "id": "981c725e-53f3-4749-89ee-ef042f23c3c3", + }, + { + "type": "metadata", + "id": "521df61d-c541-4180-beb8-ac0a1bd1e852", + }, + { + "type": "metadata", + "id": "551a216d-5350-4b15-9398-9bc2e95e7a3d", + }, + { + "type": "metadata", + "id": " eb17dce4-3892-47fe-b014-6ff8e17a93ef", + }, + { + "type": "metadata", + "id": "3e840957-cb1b-4521-8f5d-fb5f6956f303", + }, + { + "type": "metadata", + "id": "ae0bc880-481b-4425-aa5b-354b38d24e4f", + }, + { + "type": "metadata", + "id": "8dc89ac4-d606-4f1a-8524-8f70a6b371de", + }, + { + "type": "metadata", + "id": "13185eb9-dc05-4bd7-9c2d-5322a2ac5326", + } + ] + } + }, + "included": [ + { + "type": "metadata", + "id": "981c725e-53f3-4749-89ee-ef042f23c3c3", + "attributes": { + "key": "dc.contributor.author", + "value": "John Doe", + "language": "en" + } + }, + { + "type": "metadata", + "id": "521df61d-c541-4180-beb8-ac0a1bd1e852", + "attributes": { + "key": "dc.date.accessioned", + "value": "2016-05-27T07:45:04Z", + "language": null + } + }, + { + "type": "metadata", + "id": "551a216d-5350-4b15-9398-9bc2e95e7a3d", + "attributes": { + "key": "dc.date.available", + "value": "2016-05-27T07:45:04Z", + "language": null + } + }, + { + "type": "metadata", + "id": " eb17dce4-3892-47fe-b014-6ff8e17a93ef", + "attributes": { + "key": "dc.date.issued", + "value": "2016-05-27", + "language": "en" + } + }, + { + "type": "metadata", + "id": "3e840957-cb1b-4521-8f5d-fb5f6956f303", + "attributes": { + "key": "dc.identifier.uri", + "value": "http://hdl.handle.net/123456789/9978", + "language": null + } + }, + { + "type": "metadata", + "id": "ae0bc880-481b-4425-aa5b-354b38d24e4f", + "attributes": { + "key": "dc.description.abstract", + "value": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas lacus velit, lacinia eu ultrices nec, auctor in sem. Donec interdum convallis ornare. Aliquam et tortor risus. Praesent ut feugiat eros, eu consequat nibh. Morbi id quam eu mi pellentesque consequat vel vitae sem. Praesent sed velit ullamcorper, efficitur odio non, aliquet urna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque eu placerat urna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nulla non aliquet mauris. Nulla quis posuere lorem. Pellentesque tempus maximus ipsum ac pretium. Nunc hendrerit tempus sem, vitae luctus erat consectetur vestibulum. Nulla sodales felis in dictum sagittis.\n\nNullam porta magna quis magna vulputate elementum. Pellentesque dictum lorem id nisl tincidunt condimentum. Sed est dolor, dapibus sit amet augue at, malesuada cursus quam. Pellentesque elit felis, malesuada dictum congue tristique, iaculis euismod ligula. Donec dignissim dolor eu lacus pulvinar porttitor. Sed quis semper augue, dictum sollicitudin eros. \n\nMauris congue lectus at turpis viverra scelerisque. Praesent at urna rhoncus, condimentum odio ac, sagittis libero. Nulla aliquam ornare bibendum. Duis quis ornare urna. Suspendisse semper tincidunt neque nec consequat. Sed enim diam, mollis eu neque vitae, lacinia varius risus. Fusce nec sem tempor, efficitur lectus sed, porta sem. Pellentesque sollicitudin ut dui vitae malesuada.", + "language": "en" + } + }, + { + "type": "metadata", + "id": "8dc89ac4-d606-4f1a-8524-8f70a6b371de", + "attributes": { + "key": "dc.title", + "value": "Another Test Item", + "language": "en" + } + }, + { + "type": "metadata", + "id": "13185eb9-dc05-4bd7-9c2d-5322a2ac5326", + "attributes": { + "key": "dc.type", + "value": "(not specified)", + "language": "en" + } + } + ] + } +]; From f87e81ed3dd0f70ded16cf440afc70eb9ba7baef Mon Sep 17 00:00:00 2001 From: Martin Walk Date: Thu, 15 Dec 2016 11:34:13 +0100 Subject: [PATCH 03/10] Update documentation of installation process --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0052719a67..d8264fced5 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,8 @@ Currently this contains the [Angular 2 Universal Starter](https://github.com/ang - [Node.js](https://nodejs.org/) ## Installation -- `npm install` +- `npm run global` to install global dependencies +- `npm install` to install local dependencies ## Serve - `npm start` to build your client app and start a web server From 8f2b1410760d70bcc3ec65a3233229745bd4110f Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Thu, 15 Dec 2016 16:56:55 +0100 Subject: [PATCH 04/10] fixed the depth of the included attribute --- src/backend/api.ts | 20 +++-- src/backend/metadata.ts | 182 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+), 5 deletions(-) create mode 100644 src/backend/metadata.ts diff --git a/src/backend/api.ts b/src/backend/api.ts index 4bdc108d27..eaced294cd 100644 --- a/src/backend/api.ts +++ b/src/backend/api.ts @@ -6,6 +6,7 @@ import { fakeDataBase } from './db'; import { fakeDemoRedisCache } from './cache'; import { COLLECTIONS } from "./collections"; import { ITEMS } from "./items"; +import { METADATA } from "./metadata"; // you would use cookies/token etc const USER_ID = 'f9d98cf1-1b96-464e-8755-bcc2a5c09077'; // hardcoded as an example @@ -33,13 +34,19 @@ let COLLECTION_COUNT = 2; let ITEM_COUNT = 2; -function toJSONAPIResponse(req, data) { - return { +function toJSONAPIResponse(req, data, included?) { + let result = { "data": data, "links": { "self": req.protocol + '://' + req.get('host') + req.originalUrl } + }; + if (included && Array.isArray(included) && included.length > 0) { + Object.assign(result, { + "included": included + }); } + return result; } export function createMockApi() { @@ -113,7 +120,7 @@ export function createMockApi() { console.log('GET'); // 70ms latency setTimeout(function() { - res.json(toJSONAPIResponse(req, ITEMS)); + res.json(toJSONAPIResponse(req, ITEMS, METADATA)); }, 0); // }) @@ -150,8 +157,11 @@ export function createMockApi() { router.route('/items/:item_id') .get(function(req, res) { console.log('GET', util.inspect(req.item, { colors: true })); - - res.json(toJSONAPIResponse(req, req.item)); + const metadataIds: string[] = req.item.relationships.metadata.map(obj => obj.id); + const itemMetadata: any[] = METADATA.filter((metadatum) => { + return metadataIds.indexOf(metadatum.id) >= 0 + }); + res.json(toJSONAPIResponse(req, req.item, itemMetadata)); // }) // .put(function(req, res) { // console.log('PUT', util.inspect(req.body, { colors: true })); diff --git a/src/backend/metadata.ts b/src/backend/metadata.ts new file mode 100644 index 0000000000..68f2ac9f5e --- /dev/null +++ b/src/backend/metadata.ts @@ -0,0 +1,182 @@ +export const METADATA = [ + { + "type": "metadata", + "id": "d58a3098-b390-4cd6-8f52-b088b3daa637", + "attributes": { + "key": "dc.contributor.author", + "value": "Antelman, Kristin", + "language": "en" + } + }, + { + "type": "metadata", + "id": "56660730-0e0d-47ec-864a-bda2327d5716", + "attributes": { + "key": "dc.date.accessioned", + "value": "2016-10-14T10:41:13Z", + "language": null + } + }, + { + "type": "metadata", + "id": "b9d4ae74-2758-4964-a95e-eecd35b62f26", + "attributes": { + "key": "dc.date.available", + "value": "2016-10-14T10:41:13Z", + "language": null + } + }, + { + "type": "metadata", + "id": "311529ea-e339-4d8f-9292-813ebe515f03", + "attributes": { + "key": "dc.date.issued", + "value": "2004-09-01", + "language": "en" + } + }, + { + "type": "metadata", + "id": "fa875444-3faf-482a-b099-77233bda914d", + "attributes": { + "key": "dc.identifier.uri", + "value": "http://hdl.handle.net/123456789/8871", + "language": null + } + }, + { + "type": "metadata", + "id": "ddbb161b-6e52-4a90-9096-c8eae8cec4c9", + "attributes": { + "key": "dc.description.abstract", + "value": "Although many authors believe that their work has a greater research impact if it is freely available, studies to demonstrate that impact are few. This study looks at articles in four disciplines at varying stages of adoption of open access—philosophy, political science, electrical and electronic engineering and mathematics—to see whether they have a greater impact as measured by citations in the ISI Web of Science database when their authors make them freely available on the Internet. The finding is that, across all four disciplines, freely available articles do have a greater research impact. Shedding light on this category of open access reveals that scholars in diverse disciplines are adopting open-access practices and being rewarded for it.", + "language": "en" + } + }, + { + "type": "metadata", + "id": "ba51287d-a2c9-409b-8129-060b693a7570", + "attributes": { + "key": "dc.publisher", + "value": "College & Research Libraries News", + "language": "en" + } + }, + { + "type": "metadata", + "id": "e5c1c9d4-b4e2-4bdc-9153-6b769742b33f", + "attributes": { + "key": "dc.subject", + "value": "Publishing", + "language": "en" + } + }, + { + "type": "metadata", + "id": "4c125844-1eca-47aa-98f8-61c51a9c962f", + "attributes": { + "key": "dc.subject", + "value": "Intellectual Property", + "language": "en" + } + }, + { + "type": "metadata", + "id": "362c753c-a44d-468d-b256-486470b8c1e1", + "attributes": { + "key": "dc.subject", + "value": "Open Access", + "language": "en" + } + }, + { + "type": "metadata", + "id": " 69a02355-37bb-479f-9496-c8743fcacf3c", + "attributes": { + "key": "dc.title", + "value": "Do Open-Access Articles Have a Greater Research Impact?", + "language": "en" + } + }, + { + "type": "metadata", + "id": "ffbd75d5-bf3a-47ff-af22-490240f6fcc6", + "attributes": { + "key": "dc.type", + "value": "(not specified)", + "language": "en" + } + }, + { + "type": "metadata", + "id": "981c725e-53f3-4749-89ee-ef042f23c3c3", + "attributes": { + "key": "dc.contributor.author", + "value": "John Doe", + "language": "en" + } + }, + { + "type": "metadata", + "id": "521df61d-c541-4180-beb8-ac0a1bd1e852", + "attributes": { + "key": "dc.date.accessioned", + "value": "2016-05-27T07:45:04Z", + "language": null + } + }, + { + "type": "metadata", + "id": "551a216d-5350-4b15-9398-9bc2e95e7a3d", + "attributes": { + "key": "dc.date.available", + "value": "2016-05-27T07:45:04Z", + "language": null + } + }, + { + "type": "metadata", + "id": " eb17dce4-3892-47fe-b014-6ff8e17a93ef", + "attributes": { + "key": "dc.date.issued", + "value": "2016-05-27", + "language": "en" + } + }, + { + "type": "metadata", + "id": "3e840957-cb1b-4521-8f5d-fb5f6956f303", + "attributes": { + "key": "dc.identifier.uri", + "value": "http://hdl.handle.net/123456789/9978", + "language": null + } + }, + { + "type": "metadata", + "id": "ae0bc880-481b-4425-aa5b-354b38d24e4f", + "attributes": { + "key": "dc.description.abstract", + "value": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas lacus velit, lacinia eu ultrices nec, auctor in sem. Donec interdum convallis ornare. Aliquam et tortor risus. Praesent ut feugiat eros, eu consequat nibh. Morbi id quam eu mi pellentesque consequat vel vitae sem. Praesent sed velit ullamcorper, efficitur odio non, aliquet urna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque eu placerat urna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nulla non aliquet mauris. Nulla quis posuere lorem. Pellentesque tempus maximus ipsum ac pretium. Nunc hendrerit tempus sem, vitae luctus erat consectetur vestibulum. Nulla sodales felis in dictum sagittis.\n\nNullam porta magna quis magna vulputate elementum. Pellentesque dictum lorem id nisl tincidunt condimentum. Sed est dolor, dapibus sit amet augue at, malesuada cursus quam. Pellentesque elit felis, malesuada dictum congue tristique, iaculis euismod ligula. Donec dignissim dolor eu lacus pulvinar porttitor. Sed quis semper augue, dictum sollicitudin eros. \n\nMauris congue lectus at turpis viverra scelerisque. Praesent at urna rhoncus, condimentum odio ac, sagittis libero. Nulla aliquam ornare bibendum. Duis quis ornare urna. Suspendisse semper tincidunt neque nec consequat. Sed enim diam, mollis eu neque vitae, lacinia varius risus. Fusce nec sem tempor, efficitur lectus sed, porta sem. Pellentesque sollicitudin ut dui vitae malesuada.", + "language": "en" + } + }, + { + "type": "metadata", + "id": "8dc89ac4-d606-4f1a-8524-8f70a6b371de", + "attributes": { + "key": "dc.title", + "value": "Another Test Item", + "language": "en" + } + }, + { + "type": "metadata", + "id": "13185eb9-dc05-4bd7-9c2d-5322a2ac5326", + "attributes": { + "key": "dc.type", + "value": "(not specified)", + "language": "en" + } + } +]; From 7bf5c22e5f4b944e0cce9f7be1c58bb09d293406 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Thu, 15 Dec 2016 17:21:53 +0100 Subject: [PATCH 05/10] removed hardcoded included metadata from mock items --- src/backend/api.ts | 6 +- src/backend/items.ts | 186 +------------------------------------------ 2 files changed, 4 insertions(+), 188 deletions(-) diff --git a/src/backend/api.ts b/src/backend/api.ts index eaced294cd..055b4f4d3d 100644 --- a/src/backend/api.ts +++ b/src/backend/api.ts @@ -120,7 +120,7 @@ export function createMockApi() { console.log('GET'); // 70ms latency setTimeout(function() { - res.json(toJSONAPIResponse(req, ITEMS, METADATA)); + res.json(toJSONAPIResponse(req, ITEMS)); }, 0); // }) @@ -146,7 +146,7 @@ export function createMockApi() { try { req.item_id = id; req.item = ITEMS.find((item) => { - return item.id = id; + return item.id === id; }); next(); } catch (e) { @@ -157,7 +157,7 @@ export function createMockApi() { router.route('/items/:item_id') .get(function(req, res) { console.log('GET', util.inspect(req.item, { colors: true })); - const metadataIds: string[] = req.item.relationships.metadata.map(obj => obj.id); + const metadataIds: string[] = req.item.relationships.metadata.data.map(obj => obj.id); const itemMetadata: any[] = METADATA.filter((metadatum) => { return metadataIds.indexOf(metadatum.id) >= 0 }); diff --git a/src/backend/items.ts b/src/backend/items.ts index f7721317c7..9d85dce332 100644 --- a/src/backend/items.ts +++ b/src/backend/items.ts @@ -69,116 +69,6 @@ export const ITEMS = [ ] } }, - "included": [ - { - "type": "metadata", - "id": "d58a3098-b390-4cd6-8f52-b088b3daa637", - "attributes": { - "key": "dc.contributor.author", - "value": "Antelman, Kristin", - "language": "en" - } - }, - { - "type": "metadata", - "id": "56660730-0e0d-47ec-864a-bda2327d5716", - "attributes": { - "key": "dc.date.accessioned", - "value": "2016-10-14T10:41:13Z", - "language": null - } - }, - { - "type": "metadata", - "id": "b9d4ae74-2758-4964-a95e-eecd35b62f26", - "attributes": { - "key": "dc.date.available", - "value": "2016-10-14T10:41:13Z", - "language": null - } - }, - { - "type": "metadata", - "id": "311529ea-e339-4d8f-9292-813ebe515f03", - "attributes": { - "key": "dc.date.issued", - "value": "2004-09-01", - "language": "en" - } - }, - { - "type": "metadata", - "id": "fa875444-3faf-482a-b099-77233bda914d", - "attributes": { - "key": "dc.identifier.uri", - "value": "http://hdl.handle.net/123456789/8871", - "language": null - } - }, - { - "type": "metadata", - "id": "ddbb161b-6e52-4a90-9096-c8eae8cec4c9", - "attributes": { - "key": "dc.description.abstract", - "value": "Although many authors believe that their work has a greater research impact if it is freely available, studies to demonstrate that impact are few. This study looks at articles in four disciplines at varying stages of adoption of open access—philosophy, political science, electrical and electronic engineering and mathematics—to see whether they have a greater impact as measured by citations in the ISI Web of Science database when their authors make them freely available on the Internet. The finding is that, across all four disciplines, freely available articles do have a greater research impact. Shedding light on this category of open access reveals that scholars in diverse disciplines are adopting open-access practices and being rewarded for it.", - "language": "en" - } - }, - { - "type": "metadata", - "id": "ba51287d-a2c9-409b-8129-060b693a7570", - "attributes": { - "key": "dc.publisher", - "value": "College & Research Libraries News", - "language": "en" - } - }, - { - "type": "metadata", - "id": "e5c1c9d4-b4e2-4bdc-9153-6b769742b33f", - "attributes": { - "key": "dc.subject", - "value": "Publishing", - "language": "en" - } - }, - { - "type": "metadata", - "id": "4c125844-1eca-47aa-98f8-61c51a9c962f", - "attributes": { - "key": "dc.subject", - "value": "Intellectual Property", - "language": "en" - } - }, - { - "type": "metadata", - "id": "362c753c-a44d-468d-b256-486470b8c1e1", - "attributes": { - "key": "dc.subject", - "value": "Open Access", - "language": "en" - } - }, - { - "type": "metadata", - "id": " 69a02355-37bb-479f-9496-c8743fcacf3c", - "attributes": { - "key": "dc.title", - "value": "Do Open-Access Articles Have a Greater Research Impact?", - "language": "en" - } - }, - { - "type": "metadata", - "id": "ffbd75d5-bf3a-47ff-af22-490240f6fcc6", - "attributes": { - "key": "dc.type", - "value": "(not specified)", - "language": "en" - } - } - ] }, { "id": "be8325f7-243b-49f4-8a4b-df2b793ff3b5", @@ -233,80 +123,6 @@ export const ITEMS = [ } ] } - }, - "included": [ - { - "type": "metadata", - "id": "981c725e-53f3-4749-89ee-ef042f23c3c3", - "attributes": { - "key": "dc.contributor.author", - "value": "John Doe", - "language": "en" - } - }, - { - "type": "metadata", - "id": "521df61d-c541-4180-beb8-ac0a1bd1e852", - "attributes": { - "key": "dc.date.accessioned", - "value": "2016-05-27T07:45:04Z", - "language": null - } - }, - { - "type": "metadata", - "id": "551a216d-5350-4b15-9398-9bc2e95e7a3d", - "attributes": { - "key": "dc.date.available", - "value": "2016-05-27T07:45:04Z", - "language": null - } - }, - { - "type": "metadata", - "id": " eb17dce4-3892-47fe-b014-6ff8e17a93ef", - "attributes": { - "key": "dc.date.issued", - "value": "2016-05-27", - "language": "en" - } - }, - { - "type": "metadata", - "id": "3e840957-cb1b-4521-8f5d-fb5f6956f303", - "attributes": { - "key": "dc.identifier.uri", - "value": "http://hdl.handle.net/123456789/9978", - "language": null - } - }, - { - "type": "metadata", - "id": "ae0bc880-481b-4425-aa5b-354b38d24e4f", - "attributes": { - "key": "dc.description.abstract", - "value": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas lacus velit, lacinia eu ultrices nec, auctor in sem. Donec interdum convallis ornare. Aliquam et tortor risus. Praesent ut feugiat eros, eu consequat nibh. Morbi id quam eu mi pellentesque consequat vel vitae sem. Praesent sed velit ullamcorper, efficitur odio non, aliquet urna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque eu placerat urna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nulla non aliquet mauris. Nulla quis posuere lorem. Pellentesque tempus maximus ipsum ac pretium. Nunc hendrerit tempus sem, vitae luctus erat consectetur vestibulum. Nulla sodales felis in dictum sagittis.\n\nNullam porta magna quis magna vulputate elementum. Pellentesque dictum lorem id nisl tincidunt condimentum. Sed est dolor, dapibus sit amet augue at, malesuada cursus quam. Pellentesque elit felis, malesuada dictum congue tristique, iaculis euismod ligula. Donec dignissim dolor eu lacus pulvinar porttitor. Sed quis semper augue, dictum sollicitudin eros. \n\nMauris congue lectus at turpis viverra scelerisque. Praesent at urna rhoncus, condimentum odio ac, sagittis libero. Nulla aliquam ornare bibendum. Duis quis ornare urna. Suspendisse semper tincidunt neque nec consequat. Sed enim diam, mollis eu neque vitae, lacinia varius risus. Fusce nec sem tempor, efficitur lectus sed, porta sem. Pellentesque sollicitudin ut dui vitae malesuada.", - "language": "en" - } - }, - { - "type": "metadata", - "id": "8dc89ac4-d606-4f1a-8524-8f70a6b371de", - "attributes": { - "key": "dc.title", - "value": "Another Test Item", - "language": "en" - } - }, - { - "type": "metadata", - "id": "13185eb9-dc05-4bd7-9c2d-5322a2ac5326", - "attributes": { - "key": "dc.type", - "value": "(not specified)", - "language": "en" - } - } - ] + } } ]; From 6f3229fb3858847a3ceb6eda38d4d206b8b3a92a Mon Sep 17 00:00:00 2001 From: William Welling Date: Fri, 16 Dec 2016 15:16:03 -0600 Subject: [PATCH 06/10] Added rollup for Tree-shaking --- package.json | 61 ++++++++++++++++++++++++------------------ rollup-client.js | 18 +++++++++++++ rollup-server.js | 18 +++++++++++++ src/index-aot.html | 20 ++++++++++++++ src/server.aot.ts | 2 +- tsconfig.aot.json | 17 +++++++++--- tsconfig.json | 18 +++++++++---- webpack.prod.config.ts | 6 ++--- 8 files changed, 120 insertions(+), 40 deletions(-) create mode 100644 rollup-client.js create mode 100644 rollup-server.js create mode 100644 src/index-aot.html diff --git a/package.json b/package.json index f3972c23b5..520f7b3677 100644 --- a/package.json +++ b/package.json @@ -18,18 +18,21 @@ "clean:css:shim:ts": "rimraf **/*.css.shim.ts", "clean:scss:shim:ts": "rimraf **/*.scss.shim.ts", "clean:prod": "npm run clean:ngc && npm run clean:json && npm run clean:css && npm run clean:css:ts && npm run clean:scss:ts && npm run clean:css:shim:ts && npm run clean:scss:shim:ts && npm run clean:dist", - "clean": "npm run clean:log && npm run clean:dist && npm run clean:prod && npm run clean:node", + "clean": "npm run clean:log && npm run clean:prod && npm run clean:node", "sass": "node-sass src -o src --include-path node_modules --output-style compressed -q", "sass:watch": "node-sass -w src -o src --include-path node_modules --output-style compressed -q", + "rollup": "rollup -c rollup-server.js && rollup -c rollup-client.js", "prebuild": "npm run clean:dist && npm run sass", "build": "webpack --progress", "build:prod": "webpack --config webpack.prod.config.ts", - "build:prod:ngc": "npm run clean:prod && npm run sass && npm run ngc && npm run clean:dist && npm run build:prod", - "build:prod:ngc:json": "npm run clean:prod && npm run sass && npm run ngc && npm run clean:dist && npm run build:prod:json", + "build:prod:rollup": "npm run build:prod && npm run rollup", + "build:prod:ngc": "npm run clean:prod && npm run sass && npm run ngc && npm run build:prod:rollup", + "build:prod:ngc:json": "npm run clean:prod && npm run sass && npm run ngc && npm run build:prod:json:rollup", "build:prod:json": "webpack --config webpack.prod.config.ts --json | webpack-bundle-size-analyzer", + "build:prod:json:rollup": "npm run build:prod:json && npm run rollup", "ngc": "ngc -p tsconfig.aot.json", "prestart": "npm run build:prod:ngc:json", - "server": "node dist/server/index.js", + "server": "node dist/server/build.js", "server:dev": "nodemon --debug dist/server/index.js", "start": "npm run server", "start:dev": "npm run clean:prod && npm run build && npm run server", @@ -44,24 +47,25 @@ "debug:start": "npm run build && npm run debug:server", "debug:build": "node-nightly --inspect --debug-brk node_modules/webpack/bin/webpack.js", "debug:build:prod": "node-nightly --inspect --debug-brk node_modules/webpack/bin/webpack.js --config webpack.prod.config.ts", + "docs": "typedoc --options typedoc.json ./src", "lint": "tslint \"src/**/*.ts\" || true", - "global": "npm install -g angular-cli nodemon npm-check-updates rimraf ts-node typedoc typescript webpack webpack-bundle-size-analyzer marked node-gyp" + "global": "npm install -g angular-cli nodemon npm-check-updates rimraf ts-node typedoc typescript webpack webpack-bundle-size-analyzer rollup marked node-gyp" }, "dependencies": { - "@angular/common": "2.2.4", - "@angular/compiler": "2.2.4", - "@angular/compiler-cli": "2.2.4", - "@angular/core": "2.2.4", - "@angular/forms": "2.2.4", - "@angular/http": "2.2.4", - "@angular/platform-browser": "2.2.4", - "@angular/platform-browser-dynamic": "2.2.4", - "@angular/platform-server": "2.2.4", - "@angular/router": "3.2.4", - "@angular/upgrade": "2.2.4", + "@angular/common": "2.2.3", + "@angular/compiler": "2.2.3", + "@angular/compiler-cli": "2.2.3", + "@angular/core": "2.2.3", + "@angular/forms": "2.2.3", + "@angular/http": "2.2.3", + "@angular/platform-browser": "2.2.3", + "@angular/platform-browser-dynamic": "2.2.3", + "@angular/platform-server": "2.2.3", + "@angular/router": "3.2.3", + "@angular/upgrade": "2.2.3", "@angularclass/bootloader": "1.0.1", "@angularclass/idle-preload": "1.0.4", - "@ng-bootstrap/ng-bootstrap": "1.0.0-alpha.14", + "@ng-bootstrap/ng-bootstrap": "1.0.0-alpha.15", "@ngrx/core": "^1.2.0", "@ngrx/effects": "^2.0.0", "@ngrx/router-store": "^1.2.5", @@ -86,7 +90,7 @@ "zone.js": "0.6.26" }, "devDependencies": { - "@ngtools/webpack": "1.1.7", + "@ngtools/webpack": "1.1.9", "@types/body-parser": "0.0.33", "@types/compression": "0.0.33", "@types/cookie-parser": "1.3.30", @@ -96,26 +100,31 @@ "@types/memory-cache": "0.0.29", "@types/mime": "0.0.29", "@types/morgan": "1.7.32", - "@types/node": "6.0.51", + "@types/node": "6.0.52", "@types/serve-static": "1.7.31", "@types/webfontloader": "1.6.27", "angular2-template-loader": "0.6.0", - "autoprefixer": "6.5.3", + "autoprefixer": "6.5.4", "awesome-typescript-loader": "2.2.4", - "codelyzer": "2.0.0-beta.1", + "codelyzer": "2.0.0-beta.3", "concurrently": "3.1.0", "cookie-parser": "1.4.3", "copy-webpack-plugin": "4.0.1", - "imports-loader": "0.6.5", + "imports-loader": "0.7.0", "json-loader": "0.5.4", - "node-sass": "3.13.0", + "node-sass": "4.0.0", "nodemon": "1.11.0", "raw-loader": "0.5.1", "reflect-metadata": "0.1.8", "rimraf": "2.5.4", + "rollup": "0.37.0", + "rollup-plugin-commonjs": "6.0.0", + "rollup-plugin-node-globals": "1.1.0", + "rollup-plugin-node-resolve": "2.0.0", + "rollup-plugin-uglify": "1.0.1", "string-replace-loader": "1.0.5", "ts-helpers": "1.1.2", - "ts-node": "1.7.0", + "ts-node": "1.7.2", "tslint": "4.0.2", "tslint-loader": "3.3.0", "typedoc": "0.5.1", @@ -123,8 +132,8 @@ "v8-lazy-parse-webpack-plugin": "0.3.0", "webpack": "2.1.0-beta.27", "webpack-bundle-analyzer": "1.4.1", - "webpack-dev-middleware": "1.8.4", + "webpack-dev-middleware": "1.9.0", "webpack-dev-server": "2.1.0-beta.11", - "webpack-merge": "1.0.2" + "webpack-merge": "1.1.1" } } diff --git a/rollup-client.js b/rollup-client.js new file mode 100644 index 0000000000..1e50d256aa --- /dev/null +++ b/rollup-client.js @@ -0,0 +1,18 @@ +import rollup from 'rollup' +import nodeResolve from 'rollup-plugin-node-resolve' +import commonjs from 'rollup-plugin-commonjs'; +import uglify from 'rollup-plugin-uglify' + +export default { + entry: 'dist/client/main.bundle.js', + dest: 'dist/client/build.js', + sourceMap: false, + format: 'iife', + plugins: [ + nodeResolve({jsnext: true, module: true}), + commonjs({ + include: 'node_modules/rxjs/**', + }), + uglify() + ] +} diff --git a/rollup-server.js b/rollup-server.js new file mode 100644 index 0000000000..a7e1ae3ce8 --- /dev/null +++ b/rollup-server.js @@ -0,0 +1,18 @@ +import rollup from 'rollup' +import nodeResolve from 'rollup-plugin-node-resolve' +import commonjs from 'rollup-plugin-commonjs'; +import uglify from 'rollup-plugin-uglify' + +export default { + entry: 'dist/server/index.js', + dest: 'dist/server/build.js', + sourceMap: false, + format: 'iife', + plugins: [ + nodeResolve({jsnext: true, module: true}), + commonjs({ + include: 'node_modules/rxjs/**', + }), + uglify() + ] +} diff --git a/src/index-aot.html b/src/index-aot.html new file mode 100644 index 0000000000..58d8ac39b3 --- /dev/null +++ b/src/index-aot.html @@ -0,0 +1,20 @@ + + + + + + DSpace + + + + + + + + + Loading DSpace ... + + + + + diff --git a/src/server.aot.ts b/src/server.aot.ts index a649912eb3..e8c1e98a7d 100644 --- a/src/server.aot.ts +++ b/src/server.aot.ts @@ -79,7 +79,7 @@ app.get('/data.json', serverApi); app.use('/api', createMockApi()); function ngApp(req, res) { - res.render('index', { + res.render('index-aot', { req, res, // time: true, // use this to determine what part of your app is slow only in development diff --git a/tsconfig.aot.json b/tsconfig.aot.json index 468a6d392d..2d233217a4 100644 --- a/tsconfig.aot.json +++ b/tsconfig.aot.json @@ -1,15 +1,23 @@ { "compilerOptions": { + "target": "es5", + "module": "es2015", + "moduleResolution": "node", "declaration": false, + "removeComments": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "module": "commonjs", - "moduleResolution": "node", + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "noEmitHelpers": true, + "noImplicitAny": false, + "noImplicitReturns": false, + "noImplicitUseStrict": false, + "noFallthroughCasesInSwitch": true, + "pretty": false, "outDir": "dist", "sourceMap": true, "sourceRoot": "src", - "noEmitHelpers": true, - "target": "es5", "typeRoots": [ "node_modules/@types" ], @@ -20,6 +28,7 @@ "./src/*.d.ts" ], "angularCompilerOptions": { + "skipMetadataEmit": true, "debug": false }, "compileOnSave": false, diff --git a/tsconfig.json b/tsconfig.json index c10735a758..226f3dbe19 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,15 +1,23 @@ { "compilerOptions": { - "declaration": false, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, + "target": "es5", "module": "commonjs", "moduleResolution": "node", + "declaration": false, + "removeComments": false, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "noEmitHelpers": true, + "noImplicitAny": false, + "noImplicitReturns": false, + "noImplicitUseStrict": false, + "noFallthroughCasesInSwitch": true, + "pretty": true, "outDir": "dist", "sourceMap": true, "sourceRoot": "src", - "noEmitHelpers": true, - "target": "es5", "typeRoots": [ "node_modules/@types" ], diff --git a/webpack.prod.config.ts b/webpack.prod.config.ts index 7516b4da39..1a5fb02c30 100644 --- a/webpack.prod.config.ts +++ b/webpack.prod.config.ts @@ -12,10 +12,8 @@ export const commonPlugins = [ new V8LazyParseWebpackPlugin(), new webpack.DefinePlugin({ - 'process.env': { - 'NODE_ENV': JSON.stringify('production'), - 'AOT': true - } + 'process.env.NODE_ENV': JSON.stringify('production'), + 'process.env.AOT': true }), // Loader options From fa88856162cebd6b39160d8b41404b99c72ede93 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Mon, 19 Dec 2016 14:50:54 +0100 Subject: [PATCH 07/10] improve README.md --- README.md | 204 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 184 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index d8264fced5..53319b5cd3 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,194 @@ - # dspace-angular -> A UI for DSpace based on Angular 2 Universal. +> The next UI for DSpace, based on Angular 2 Universal. -Currently this contains the [Angular 2 Universal Starter](https://github.com/angular/universal-starter) codebase with a few tweaks. +This project is currently in pre-alpha. -## Links -- [The working group page on the DuraSpace Wiki](https://wiki.duraspace.org/display/DSPACE/DSpace+7+UI+Working+Group) -- [The project board (waffle.io)](https://waffle.io/DSpace/dspace-angular) -- [The prototype](https://github.com/DSpace-Labs/angular2-ui-prototype) +You can find additional information on the [wiki](https://wiki.duraspace.org/display/DSPACE/DSpace+7+-+Angular+2+UI) or [the project board (waffle.io)](https://waffle.io/DSpace/dspace-angular). + +If you're looking for the 2016 Angular 2 DSpace UI prototype, you can find it [here](https://github.com/DSpace-Labs/angular2-ui-prototype) + +## Quick start +**Make sure you have Node version >= 5.0 and NPM >= 3** + +```bash +# clone the repo +git clone https://github.com/DSpace/dspace-angular.git + +# change directory to our repo +cd dspace-angular + +# install the global dependencies +npm run global + +# install the repo with npm +npm install + +# start the server +npm start +``` +go to [http://localhost:3000](http://localhost:3000) in your browser + +## Table of Contents +* [Introduction to the technology](#introduction-to-the-technology) +* [Requirements](#requirements) +* [Installing](#installing) +* [Running the app](#running-the-app) +* [Running in production mode](#running-in-production-mode) +* [Cleaning:](#cleaning) +* [Other commands](#other-commands) +* [Recommended Editors/IDEs](#recommended-editorsides) +* [Collaborating](#collaborating) +* [File Structure](#file-structure) +* [3rd Party Library Installation](#3rd-party-library-installation) + +## Introduction to the technology +You can find more information on the technologies used in this project (Angular 2, Typescript, Angular Universal, RxJS, etc) on the [DuraSpace wiki](https://wiki.duraspace.org/display/DSPACE/DSpace+7+UI+Technology+Stack) ## Requirements - - [Node.js](https://nodejs.org/) +* [Node.js](https://nodejs.org) and [npm](https://www.npmjs.com/) +* Ensure you're running node >= `v5.x` and npm >= `v3.x` -## Installation -- `npm run global` to install global dependencies -- `npm install` to install local dependencies +If you have [`nvm`](https://github.com/creationix/nvm#install-script) or [`nvm-windows`](https://github.com/coreybutler/nvm-windows) installed, which is highly recommended, you can run `nvm install --lts && nvm use` to install and start using the latest Node LTS. -## Serve -- `npm start` to build your client app and start a web server -- `npm run build` to prepare a distributable bundle +## Installing +* `npm run global` to install the required global dependencies +* `npm install` to install the local dependencies -## Watch files -- `npm run watch` to build your client app and start a web server -## Development -- run `npm start` and `npm run watch` in two separate terminals to build your client app, start a web server, and allow file changes to update in realtime +## Running the app +After you have installed all dependencies you can now run the app. Run `npm run watch:dev` to start a local server which will watch for changes, rebuild the code, and reload the server for you. You can visit it at `http://localhost:3000`. -## AoT and Prod -- `npm run build:prod:ngc` to compile the ngfactory files and build prod +## Running in production mode +When building for production we're using Ahead of Time (AoT) compilation. With AoT, the browser downloads a pre-compiled version of the application, so it can render the application immediately, without waiting to compile the app first. The compiler is roughly half the size of Angular itself, so omitting it dramatically reduces the application payload. + +To build the app for production and start the server run: +```bash +npm start +``` +If you only want to build for production, without starting, run: +```bash +npm run build:prod:ngc:json +``` +This will build the application and put the result in the `dist` folder + +## Cleaning: +```bash +# clean everything, including node_modules. You'll need to run npm install again afterwards. +npm run clean + +# clean files generated by the production build (.ngfactory files, css files, etc) +npm run clean:prod + +# cleans the distribution directory +npm run clean:dist +``` + +## Other commands +There are many more commands in the `scripts` section of `package.json`. Most of these are executed by one of the commands mentioned above. +A command with a name that starts with `pre` or `post` will be executed automatically before or after the script with the matching name. e.g. if you type `npm run start` the `prestart` script will run first, then the `start` script will trigger. + + +## Recommended Editors/IDEs +To get the most out of TypeScript, you'll need a TypeScript-aware editor. We've had good experiences using these editors: + +* Free + * [Visual Studio Code](https://code.visualstudio.com/) + * [Debugger for Chrome](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome) + * [Atom](https://atom.io/) + * [TypeScript plugin](https://atom.io/packages/atom-typescript) +* Paid + * [Webstorm](https://www.jetbrains.com/webstorm/download/) or [IntelliJ IDEA Ultimate](https://www.jetbrains.com/idea/) + * [Sublime Text](http://www.sublimetext.com/3) + * [Typescript-Sublime-Plugin](https://github.com/Microsoft/Typescript-Sublime-plugin#installation) + +## Collaborating +See [the guide on the wiki](https://wiki.duraspace.org/display/DSPACE/DSpace+7+-+Angular+2+UI#DSpace7-Angular2UI-Howtocontribute) + +## File Structure +``` +dspace-angular +├── README.md * This document +├── app.json * Application manifest file +├── nodemon.json * Nodemon (https://nodemon.io/) configuration +├── package.json * This file describes the npm package for this project, its dependencies, scripts, etc. +├── resources * Folder for static resources +│   ├── i18n * Folder for i18n translations +│   └── images * Folder for images +├── rollup-client.js * Rollup (http://rollupjs.org/) configuration for the client +├── rollup-server.js * Rollup (http://rollupjs.org/) configuration for the server +├── src * The source of the application +│   ├── app * The location of the app module, and root of the application shared by client and server +│   ├── backend * Folder containing a mock of the REST API, hosted by the express server +│   ├── browser.module.ts * The root module for the client +│   ├── client.aot.ts * The bootstrap file for the client, in production +│   ├── client.ts * The bootstrap file for the client, during development +│   ├── index-aot.html * The index.html file, for production +│   ├── index.html * The index.html file, for development +│   ├── node.module.ts * The root module for the server +│   ├── server.aot.ts * The express (http://expressjs.com/) config and bootstrap file for the server, in production +│   ├── server.routes.ts * The routes file for the server +│   ├── server.ts * The express (http://expressjs.com/) config and bootstrap file for the server, during development +│   ├── styles * Folder containing global styles. +│   │   ├── main.scss * Global scss file +│   │   └── variables.scss * Global sass variables file +│   └── typings.d.ts * File that allows you to add custom typings for libraries without TypeScript support +├── tsconfig.aot.json * TypeScript config for production builds +├── tsconfig.json * TypeScript config for development build +├── tslint.json * TSLint (https://palantir.github.io/tslint/) configuration +├── webpack.config.ts * Webpack (https://webpack.github.io/) config for development builds +└── webpack.prod.config.ts * Webpack (https://webpack.github.io/) config for production builds +``` + +## 3rd Party Library Installation + +Install your library via `npm install lib-name --save` and import it in your code. `--save` will add it to `package.json`. + +If the library does not include typings, you can install them using npm: + +```bash +npm install d3 --save +npm install @types/d3 --save-dev +``` + +If the library doesn't have typings available at `@types/`, you can still use it by +manually adding typings for it: + +1. In `src/typings.d.ts`, add the following code: + + ```typescript + declare module 'typeless-package'; + ``` + +2. Then, in the component or file that uses the library, add the following code: + + ```typescript + import * as typelessPackage from 'typeless-package'; + typelessPackage.method(); + ``` + +Done. Note: you might need or find useful to define more typings for the library that you're trying to use. + + +If you're importing a module that uses CommonJS you need to import as + +```typescript +import * as _ from 'lodash'; +``` + +# Frequently asked questions +* Why is my service, aka provider, is not injecting a parameter correctly? + * Please use `@Injectable()` for your service for typescript to correctly attach the metadata +* Where do I write my tests? + * You can write your tests next to your component files. e.g. for `src/app/home/home.component.ts` call it `src/app/home/home.component.spec.ts` +* How do I start the app when I get `EACCES` and `EADDRINUSE` errors? + * The `EADDRINUSE` error means the port `3000` is currently being used and `EACCES` is lack of permission to build files to `./dist/` +* What are the naming conventions for Angular 2? + * See [the official angular 2 style guide](https://angular.io/styleguide) +* Why is the size of my app larger in development? + * The production build uses a whole host of techniques (ahead-of-time compilation, rollup to remove unreachable code, minification, etc.) to reduce the size, that aren't used during development in the intrest of build speed. +* node-pre-gyp ERR in npm install (Windows) + * install Python x86 version between 2.5 and 3.0 on windows. See [this issue](https://github.com/AngularClass/angular2-webpack-starter/issues/626) + + +# License +http://www.dspace.org/license From ec0dafc7397dfc600b1fd3774ed5266d1e20d6cd Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Mon, 19 Dec 2016 14:55:42 +0100 Subject: [PATCH 08/10] update toc --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 53319b5cd3..c30978b04b 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ npm install # start the server npm start ``` -go to [http://localhost:3000](http://localhost:3000) in your browser +Then go to [http://localhost:3000](http://localhost:3000) in your browser ## Table of Contents * [Introduction to the technology](#introduction-to-the-technology) @@ -40,6 +40,8 @@ go to [http://localhost:3000](http://localhost:3000) in your browser * [Collaborating](#collaborating) * [File Structure](#file-structure) * [3rd Party Library Installation](#3rd-party-library-installation) +* [Frequently asked questions](#frequently-asked-questions) +* [License](#license) ## Introduction to the technology You can find more information on the technologies used in this project (Angular 2, Typescript, Angular Universal, RxJS, etc) on the [DuraSpace wiki](https://wiki.duraspace.org/display/DSPACE/DSpace+7+UI+Technology+Stack) @@ -175,7 +177,7 @@ If you're importing a module that uses CommonJS you need to import as import * as _ from 'lodash'; ``` -# Frequently asked questions +## Frequently asked questions * Why is my service, aka provider, is not injecting a parameter correctly? * Please use `@Injectable()` for your service for typescript to correctly attach the metadata * Where do I write my tests? @@ -190,5 +192,5 @@ import * as _ from 'lodash'; * install Python x86 version between 2.5 and 3.0 on windows. See [this issue](https://github.com/AngularClass/angular2-webpack-starter/issues/626) -# License +## License http://www.dspace.org/license From be3d005d0d0b1b08b51767c00081efb27b81ef22 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Mon, 19 Dec 2016 14:56:23 +0100 Subject: [PATCH 09/10] removed a stray : --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c30978b04b..38674600c9 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Then go to [http://localhost:3000](http://localhost:3000) in your browser * [Installing](#installing) * [Running the app](#running-the-app) * [Running in production mode](#running-in-production-mode) -* [Cleaning:](#cleaning) +* [Cleaning](#cleaning) * [Other commands](#other-commands) * [Recommended Editors/IDEs](#recommended-editorsides) * [Collaborating](#collaborating) @@ -73,7 +73,7 @@ npm run build:prod:ngc:json ``` This will build the application and put the result in the `dist` folder -## Cleaning: +## Cleaning ```bash # clean everything, including node_modules. You'll need to run npm install again afterwards. npm run clean From 8cd58f824333de235535bdec5975c3b42fe0ba29 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Mon, 19 Dec 2016 15:11:16 +0100 Subject: [PATCH 10/10] Clarification --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 38674600c9..a7b658b5c4 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ cd dspace-angular # install the global dependencies npm run global -# install the repo with npm +# install the local dependencies npm install # start the server