@things-factory/shell 6.0.18 → 6.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -204,50 +204,50 @@ $ yarn workspace @things-factory/operato-mms run serve
204
204
  ```
205
205
  # generate new application (ie. @things-factory/operato-xyz)
206
206
  $ yarn generate app
207
- ? What should this application's name be? Ex. operato-abc > # type "operato-xyz"
207
+ ? What should this application's name be? e.g. operato-abc > # type "operato-xyz"
208
208
 
209
209
  # generate new module (ie. @things-factory/notification)
210
210
  $ yarn generate module
211
- ? What should this module's name be? Ex. menu > # type "notification"
211
+ ? What should this module's name be? e.g. menu > # type "notification"
212
212
 
213
213
  # generate new entity in a module (ie. "sms" entity in @things-factory/notification module)
214
214
  $ yarn generate entity
215
- ? What is target package's name? Ex. biz-base, operato-mms > # type "notification"
216
- ? What should this entitie's name be? Ex. company, company-ext > # type "sms"
215
+ ? What is target package's name? e.g. biz-base, operato-mms > # type "notification"
216
+ ? What should this entitie's name be? e.g. company, company-ext > # type "sms"
217
217
 
218
218
  # generate new page in a module (ie. "sms-view" page in @things-factory/notification module)
219
219
  $ yarn generate page
220
- ? What is target package's name? Ex. biz-base, operato-mms > # type "notification"
221
- ? What should this pages's name be? Ex. abc-viewer > # type "sms-view"
220
+ ? What is target package's name? e.g. biz-base, operato-mms > # type "notification"
221
+ ? What should this pages's name be? e.g. abc-viewer > # type "sms-view"
222
222
 
223
223
  # generate new scene-module from scratch (ie. @things-factory/scene-random)
224
224
  $ yarn generate app
225
- ? What should this module's name be? Ex. random > # type "scene-random"
225
+ ? What should this module's name be? e.g. random > # type "scene-random"
226
226
 
227
227
  # generate new scene-component in a module (ie. "button" component in @things-factory/scene-switch module)
228
228
  $ yarn generate component
229
- ? What is target package's name? Ex. switch > # type "switch"
230
- ? What should this component's name be? Ex. button > # type "button"
229
+ ? What is target package's name? e.g. switch > # type "switch"
230
+ ? What should this component's name be? e.g. button > # type "button"
231
231
 
232
232
  # generate new container component in a module (ie. "button" container component in @things-factory/scene-switch module)
233
233
  $ yarn generate container
234
- ? What is target package's name? Ex. switch > # type "switch"
235
- ? What should this component's name be? Ex. button > # type "button"
234
+ ? What is target package's name? e.g. switch > # type "switch"
235
+ ? What should this component's name be? e.g. button > # type "button"
236
236
 
237
237
  # generate new html base scene component in a module (ie. "button" html-component in @things-factory/scene-switch module)
238
238
  $ yarn generate html-component
239
- ? What is target package's name? Ex. switch > # type "switch"
240
- ? What should this component's name be? Ex. button > # type "button"
239
+ ? What is target package's name? e.g. switch > # type "switch"
240
+ ? What should this component's name be? e.g. button > # type "button"
241
241
 
242
242
  # generate new data source scene component in a module (ie. "button" component in @things-factory/scene-switch module)
243
243
  $ yarn generate data-source
244
- ? What is target package's name? Ex. switch > # type "switch"
245
- ? What should this component's name be? Ex. button > # type "button"
244
+ ? What is target package's name? e.g. switch > # type "switch"
245
+ ? What should this component's name be? e.g. button > # type "button"
246
246
 
247
247
  # generate new data transform scene component in a module (ie. "button" component in @things-factory/scene-switch module)
248
248
  $ yarn generate data-transform
249
- ? What is target package's name? Ex. switch > # type "switch"
250
- ? What should this component's name be? Ex. button > # type "button"
249
+ ? What is target package's name? e.g. switch > # type "switch"
250
+ ? What should this component's name be? e.g. button > # type "button"
251
251
  ```
252
252
 
253
253
  ## References
@@ -207,50 +207,50 @@ $ yarn workspace @things-factory/operato-mms run serve
207
207
  ```
208
208
  # generate new application (ie. @things-factory/operato-xyz)
209
209
  $ yarn generate app
210
- ? What should this application's name be? Ex. operato-abc > # type "operato-xyz"
210
+ ? What should this application's name be? e.g. operato-abc > # type "operato-xyz"
211
211
 
212
212
  # generate new module (ie. @things-factory/notification)
213
213
  $ yarn generate module
214
- ? What should this module's name be? Ex. menu > # type "notification"
214
+ ? What should this module's name be? e.g. menu > # type "notification"
215
215
 
216
216
  # generate new entity in a module (ie. "sms" entity in @things-factory/notification module)
217
217
  $ yarn generate entity
218
- ? What is target package's name? Ex. biz-base, operato-mms > # type "notification"
219
- ? What should this entitie's name be? Ex. company, company-ext > # type "sms"
218
+ ? What is target package's name? e.g. biz-base, operato-mms > # type "notification"
219
+ ? What should this entitie's name be? e.g. company, company-ext > # type "sms"
220
220
 
221
221
  # generate new page in a module (ie. "sms-view" page in @things-factory/notification module)
222
222
  $ yarn generate page
223
- ? What is target package's name? Ex. biz-base, operato-mms > # type "notification"
224
- ? What should this pages's name be? Ex. abc-viewer > # type "sms-view"
223
+ ? What is target package's name? e.g. biz-base, operato-mms > # type "notification"
224
+ ? What should this pages's name be? e.g. abc-viewer > # type "sms-view"
225
225
 
226
226
  # generate new scene-module from scratch (ie. @things-factory/scene-random)
227
227
  $ yarn generate app
228
- ? What should this module's name be? Ex. random > # type "scene-random"
228
+ ? What should this module's name be? e.g. random > # type "scene-random"
229
229
 
230
230
  # generate new scene-component in a module (ie. "button" component in @things-factory/scene-switch module)
231
231
  $ yarn generate component
232
- ? What is target package's name? Ex. switch > # type "switch"
233
- ? What should this component's name be? Ex. button > # type "button"
232
+ ? What is target package's name? e.g. switch > # type "switch"
233
+ ? What should this component's name be? e.g. button > # type "button"
234
234
 
235
235
  # generate new container component in a module (ie. "button" container component in @things-factory/scene-switch module)
236
236
  $ yarn generate container
237
- ? What is target package's name? Ex. switch > # type "switch"
238
- ? What should this component's name be? Ex. button > # type "button"
237
+ ? What is target package's name? e.g. switch > # type "switch"
238
+ ? What should this component's name be? e.g. button > # type "button"
239
239
 
240
240
  # generate new html base scene component in a module (ie. "button" html-component in @things-factory/scene-switch module)
241
241
  $ yarn generate html-component
242
- ? What is target package's name? Ex. switch > # type "switch"
243
- ? What should this component's name be? Ex. button > # type "button"
242
+ ? What is target package's name? e.g. switch > # type "switch"
243
+ ? What should this component's name be? e.g. button > # type "button"
244
244
 
245
245
  # generate new data source scene component in a module (ie. "button" component in @things-factory/scene-switch module)
246
246
  $ yarn generate data-source
247
- ? What is target package's name? Ex. switch > # type "switch"
248
- ? What should this component's name be? Ex. button > # type "button"
247
+ ? What is target package's name? e.g. switch > # type "switch"
248
+ ? What should this component's name be? e.g. button > # type "button"
249
249
 
250
250
  # generate new data transform scene component in a module (ie. "button" component in @things-factory/scene-switch module)
251
251
  $ yarn generate data-transform
252
- ? What is target package's name? Ex. switch > # type "switch"
253
- ? What should this component's name be? Ex. button > # type "button"
252
+ ? What is target package's name? e.g. switch > # type "switch"
253
+ ? What should this component's name be? e.g. button > # type "button"
254
254
  ```
255
255
 
256
256
  ## References
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/shell",
3
- "version": "6.0.18",
3
+ "version": "6.0.19",
4
4
  "description": "Core module for framework",
5
5
  "bin": {
6
6
  "things-factory": "bin/things-factory",
@@ -31,6 +31,8 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@apollo/client": "^3.6.9",
34
+ "@apollo/server": "^4.5.0",
35
+ "@as-integrations/koa": "^0.3.0",
34
36
  "@graphql-tools/merge": "^8.3.0",
35
37
  "@graphql-tools/schema": "^8.5.0",
36
38
  "@graphql-tools/utils": "^8.8.0",
@@ -57,10 +59,6 @@
57
59
  "@things-factory/utils": "^6.0.7",
58
60
  "@webcomponents/webcomponentsjs": "^2.6.0",
59
61
  "@webpack-contrib/schema-utils": "^1.0.0-beta.0",
60
- "apollo-server-core": "^3.10.0",
61
- "apollo-server-koa": "^3.10.0",
62
- "apollo-server-types": "^3.6.2",
63
- "apollo-upload-client": "^17.0.0",
64
62
  "args": "^5.0.0",
65
63
  "broadcastchannel-polyfill": "^1.0.1",
66
64
  "chalk": "^4.1.0",
@@ -131,5 +129,5 @@
131
129
  "pg": "^8.7.3",
132
130
  "sqlite3": "^5.0.8"
133
131
  },
134
- "gitHead": "2e3e970ad20b2d7b67653ce04341bdf150ae7ebc"
132
+ "gitHead": "05a9514944178c345d8eec9009cc912b2e55c389"
135
133
  }
@@ -1,75 +1,18 @@
1
- import { ApolloServerBase } from 'apollo-server-core'
2
- import { GraphQLResponse } from 'apollo-server-types'
3
- import { print, DocumentNode } from 'graphql'
4
-
5
- type StringOrAst = string | DocumentNode
6
-
7
- // A query must not come with a mutation (and vice versa).
8
- type Query = {
9
- query: StringOrAst
10
- mutation?: undefined
11
- variables?: {
12
- [name: string]: any
13
- }
14
- operationName?: string
15
- }
16
-
17
- type Mutation = {
18
- mutation: StringOrAst
19
- query?: undefined
20
- variables?: {
21
- [name: string]: any
22
- }
23
- operationName?: string
24
- }
25
-
26
- export interface ApolloServerLocalClient {
27
- query: (query: Query) => Promise<GraphQLResponse>
28
- mutate: (mutation: Mutation) => Promise<GraphQLResponse>
29
- }
1
+ import { SchemaLink } from '@apollo/client/link/schema'
2
+ import { ApolloClient, InMemoryCache, NormalizedCacheObject } from '@apollo/client'
30
3
 
31
4
  export class GraphqlLocalClient {
32
- static client: ApolloServerLocalClient
5
+ static client: ApolloClient<NormalizedCacheObject>
33
6
 
34
7
  static init(schema, app) {
35
- const resolve = async ({ query, mutation, variables, context }) => {
36
- // Create a new Apollo Server for each request
37
- const server = new ApolloServerBase({
8
+ GraphqlLocalClient.client = new ApolloClient({
9
+ cache: new InMemoryCache(),
10
+ link: new SchemaLink({
38
11
  schema,
39
- context: {
40
- // ⚠️ Note: here you should construct your GraphQL
41
- // context! When calling the query/mutation, I
42
- // usually like to override some properties (eg the
43
- // authed user which I attach to the context). Here
44
- // is where you need to put all your default GraphQL
45
- // context data. Eg dataloaders etc.
46
- ...context,
47
- app
12
+ context: (obj, args, context, info) => {
13
+ return obj.getContext()
48
14
  }
49
15
  })
50
-
51
- const executeOperation = server.executeOperation.bind(server)
52
- const operation = query || mutation
53
- if (!operation || (!!query && !!mutation)) {
54
- throw new Error('Either query or mutation must be passed, but not both')
55
- }
56
-
57
- // Execute the actual operation
58
- const res = await executeOperation({
59
- variables,
60
- query: typeof operation === 'string' ? operation : print(operation)
61
- })
62
-
63
- // Throw an error with all the messages of the
64
- // errors to make them easy to match using Jest
65
- if (!!res.errors && !!res.errors.length) {
66
- const message = res.errors.map(error => error.message).join('\n')
67
- throw new Error(message)
68
- }
69
-
70
- return res
71
- }
72
-
73
- GraphqlLocalClient.client = { query: resolve, mutate: resolve }
16
+ })
74
17
  }
75
18
  }
@@ -10,6 +10,14 @@ export const globalPrivateRouter = new Router()
10
10
  /* even though global private router, catch domain for information */
11
11
  globalPrivateRouter.use(domainMiddleware)
12
12
 
13
+ if (process.env.NODE_ENV != 'production') {
14
+ globalPublicRouter.get('/graphql', async (context, next) => {
15
+ const initialEndpoint = context.request.href
16
+
17
+ await context.render('graphql', { initialEndpoint })
18
+ })
19
+ }
20
+
13
21
  globalPublicRouter.get('/dependencies', async (context, next) => {
14
22
  const { dependencyGraph } = require('@things-factory/env')
15
23
 
@@ -0,0 +1,3 @@
1
+ import Router from 'koa-router'
2
+
3
+ export const graphqlRouter = new Router()
@@ -1,2 +1,3 @@
1
1
  export * from './global-router'
2
2
  export * from './domain-router'
3
+ export * from './graphql-router'
@@ -4,8 +4,11 @@
4
4
  process.env.NODE_ENV = 'development'
5
5
  process.setMaxListeners(0)
6
6
 
7
- import { ApolloServerPluginDrainHttpServer, ApolloServerPluginLandingPageLocalDefault } from 'apollo-server-core'
8
- import { ApolloServer } from 'apollo-server-koa'
7
+ import { ApolloServer } from '@apollo/server'
8
+ import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer'
9
+ import { ApolloServerPluginLandingPageLocalDefault } from '@apollo/server/plugin/landingPage/default'
10
+
11
+ import { koaMiddleware } from '@as-integrations/koa'
9
12
  import bytesFormat from 'bytes'
10
13
  import graphqlUploadKoa from 'graphql-upload/graphqlUploadKoa.js'
11
14
  import { useServer } from 'graphql-ws/lib/use/ws'
@@ -25,7 +28,13 @@ import { config, loader, logger, orderedModuleNames } from '@things-factory/env'
25
28
 
26
29
  import { GraphqlLocalClient } from './graphql-local-client'
27
30
  import { databaseInitializer } from './initializers/database'
28
- import { domainPrivateRouter, domainPublicRouter, globalPrivateRouter, globalPublicRouter } from './routers'
31
+ import {
32
+ domainPrivateRouter,
33
+ domainPublicRouter,
34
+ globalPrivateRouter,
35
+ globalPublicRouter,
36
+ graphqlRouter
37
+ } from './routers'
29
38
  import { schema } from './schema'
30
39
  import { Domain } from './service'
31
40
  import { EntityManager } from 'typeorm'
@@ -176,16 +185,7 @@ const bootstrap = async () => {
176
185
  logger.error(error)
177
186
  return error
178
187
  },
179
- formatResponse: response => {
180
- return response
181
- },
182
- context: async ({ connection, ctx }) => {
183
- if (connection) {
184
- return connection.context
185
- } else {
186
- return ctx
187
- }
188
- },
188
+ introspection: true,
189
189
  csrfPrevention: true,
190
190
  plugins: [
191
191
  // Proper shutdown for the HTTP server.
@@ -200,8 +200,11 @@ const bootstrap = async () => {
200
200
  }
201
201
  }
202
202
  },
203
+ // TODO make this landing page work
203
204
  ApolloServerPluginLandingPageLocalDefault({
204
- embed: true
205
+ footer: false,
206
+ embed: true,
207
+ includeCookies: true
205
208
  })
206
209
  ],
207
210
  cache: 'bounded'
@@ -260,7 +263,15 @@ const bootstrap = async () => {
260
263
 
261
264
  /* Graphql Upload's multipart/form-data handling affects the restful file upload feature, so it should be placed after the routers configuration. */
262
265
  app.use(graphqlUploadKoa(fileUploadOption))
263
- server.applyMiddleware({ app, path: '/graphql' })
266
+
267
+ graphqlRouter.post(
268
+ '/graphql',
269
+ koaMiddleware(server, {
270
+ context: async ({ ctx }) => ctx
271
+ })
272
+ )
273
+ app.use(graphqlRouter.routes())
274
+ app.use(graphqlRouter.allowedMethods())
264
275
 
265
276
  /* should follow this order : history-fallback => webpack-middleware => koaStatic */
266
277
  app.use(historyApiFallback({ whiteList: [] }))
@@ -274,8 +285,8 @@ const bootstrap = async () => {
274
285
  )
275
286
 
276
287
  httpServer.listen({ port: PORT }, () => {
277
- logger.info(`🚀 Server ready at http://0.0.0.0:${PORT}${server.graphqlPath}`)
278
- logger.info(`🚀 Subscriptions ready at ws://0.0.0.0:${PORT}${server.graphqlPath}`)
288
+ logger.info(`🚀 Server ready at http://0.0.0.0:${PORT}/graphql`)
289
+ logger.info(`🚀 Subscriptions ready at ws://0.0.0.0:${PORT}/graphql`)
279
290
 
280
291
  process.emit('bootstrap-module-start' as any, { app, config, builtSchema, httpServer } as any)
281
292
  })
package/server/server.ts CHANGED
@@ -4,8 +4,11 @@
4
4
  process.env.NODE_ENV = 'production'
5
5
  process.setMaxListeners(0)
6
6
 
7
- import { ApolloServerPluginDrainHttpServer, ApolloServerPluginLandingPageGraphQLPlayground } from 'apollo-server-core'
8
- import { ApolloServer } from 'apollo-server-koa'
7
+ import { ApolloServer } from '@apollo/server'
8
+ import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer'
9
+ import { ApolloServerPluginLandingPageProductionDefault } from '@apollo/server/plugin/landingPage/default'
10
+ import { koaMiddleware } from '@as-integrations/koa'
11
+
9
12
  import bytesFormat from 'bytes'
10
13
  import graphqlUploadKoa from 'graphql-upload/graphqlUploadKoa.js'
11
14
  import { useServer } from 'graphql-ws/lib/use/ws'
@@ -24,7 +27,13 @@ import { config, loader, logger, orderedModuleNames } from '@things-factory/env'
24
27
 
25
28
  import { GraphqlLocalClient } from './graphql-local-client'
26
29
  import { databaseInitializer } from './initializers/database'
27
- import { domainPrivateRouter, domainPublicRouter, globalPrivateRouter, globalPublicRouter } from './routers'
30
+ import {
31
+ domainPrivateRouter,
32
+ domainPublicRouter,
33
+ globalPrivateRouter,
34
+ globalPublicRouter,
35
+ graphqlRouter
36
+ } from './routers'
28
37
  import { schema } from './schema'
29
38
 
30
39
  process.on('uncaughtException', error => {
@@ -153,20 +162,12 @@ const bootstrap = async () => {
153
162
  logger.error(error)
154
163
  return error
155
164
  },
156
- formatResponse: response => {
157
- // logger.info('response %s', JSON.stringify(response, null, 2))
158
- return response
159
- },
160
165
  introspection: true,
161
- context: async ({ connection, ctx }) => {
162
- if (connection) {
163
- return connection.context
164
- } else {
165
- return ctx
166
- }
167
- },
166
+ csrfPrevention: true,
168
167
  plugins: [
168
+ // Proper shutdown for the HTTP server.
169
169
  ApolloServerPluginDrainHttpServer({ httpServer }),
170
+ // Proper shutdown for the WebSocket server.
170
171
  {
171
172
  async serverWillStart() {
172
173
  return {
@@ -175,7 +176,12 @@ const bootstrap = async () => {
175
176
  }
176
177
  }
177
178
  }
178
- }
179
+ },
180
+ // TODO make this landing page work
181
+ ApolloServerPluginLandingPageProductionDefault({
182
+ graphRef: 'my-graph-id@my-graph-variant',
183
+ footer: false
184
+ })
179
185
  ],
180
186
  cache: 'bounded'
181
187
  })
@@ -219,7 +225,15 @@ const bootstrap = async () => {
219
225
 
220
226
  /* Graphql Upload's multipart/form-data handling affects the restful file upload feature, so it should be placed after the routers configuration. */
221
227
  app.use(graphqlUploadKoa(fileUploadOption))
222
- server.applyMiddleware({ app, path: '/graphql' })
228
+
229
+ graphqlRouter.post(
230
+ '/graphql',
231
+ koaMiddleware(server, {
232
+ context: async ({ ctx }) => ctx
233
+ })
234
+ )
235
+ app.use(graphqlRouter.routes())
236
+ app.use(graphqlRouter.allowedMethods())
223
237
 
224
238
  /* should follow this order : history-fallback => koaStatic */
225
239
  app.use(historyApiFallback({ whiteList: [] }))
@@ -231,8 +245,8 @@ const bootstrap = async () => {
231
245
  )
232
246
 
233
247
  httpServer.listen({ port: PORT }, () => {
234
- logger.info(`🚀 Server ready at http://0.0.0.0:${PORT}${server.graphqlPath}`)
235
- logger.info(`🚀 Subscriptions ready at ws://0.0.0.0:${PORT}${server.graphqlPath}`)
248
+ logger.info(`🚀 Server ready at http://0.0.0.0:${PORT}/graphql`)
249
+ logger.info(`🚀 Subscriptions ready at ws://0.0.0.0:${PORT}/graphql`)
236
250
 
237
251
  process.emit('bootstrap-module-start' as any, { app, config, builtSchema, httpServer } as any)
238
252
  })
@@ -0,0 +1,15 @@
1
+ <style>
2
+ body {
3
+ margin: 0;
4
+ }
5
+ </style>
6
+
7
+ <div style="width: 100%; height: 100%" id="embedded-sandbox"></div>
8
+ <script src="https://embeddable-sandbox.cdn.apollographql.com/_latest/embeddable-sandbox.umd.production.min.js"></script>
9
+ <script>
10
+ new window.EmbeddedSandbox({
11
+ target: '#embedded-sandbox',
12
+ initialEndpoint: '<%- initialEndpoint %>',
13
+ includeCookies: true
14
+ })
15
+ </script>