@pikku/core 0.6.9

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.
Files changed (167) hide show
  1. package/CHANGELOG.md +339 -0
  2. package/README.md +5 -0
  3. package/dist/channel/channel-handler.d.ts +3 -0
  4. package/dist/channel/channel-handler.js +97 -0
  5. package/dist/channel/channel-runner.d.ts +26 -0
  6. package/dist/channel/channel-runner.js +86 -0
  7. package/dist/channel/channel-store.d.ts +14 -0
  8. package/dist/channel/channel-store.js +2 -0
  9. package/dist/channel/channel.types.d.ts +106 -0
  10. package/dist/channel/channel.types.js +1 -0
  11. package/dist/channel/eventhub-forwarder.d.ts +17 -0
  12. package/dist/channel/eventhub-forwarder.js +1 -0
  13. package/dist/channel/eventhub-service.d.ts +23 -0
  14. package/dist/channel/eventhub-service.js +1 -0
  15. package/dist/channel/eventhub-store.d.ts +5 -0
  16. package/dist/channel/eventhub-store.js +2 -0
  17. package/dist/channel/index.d.ts +9 -0
  18. package/dist/channel/index.js +9 -0
  19. package/dist/channel/local/index.d.ts +3 -0
  20. package/dist/channel/local/index.js +3 -0
  21. package/dist/channel/local/local-channel-handler.d.ts +17 -0
  22. package/dist/channel/local/local-channel-handler.js +41 -0
  23. package/dist/channel/local/local-channel-runner.d.ts +3 -0
  24. package/dist/channel/local/local-channel-runner.js +46 -0
  25. package/dist/channel/local/local-eventhub-service.d.ts +44 -0
  26. package/dist/channel/local/local-eventhub-service.js +81 -0
  27. package/dist/channel/log-channels.d.ts +6 -0
  28. package/dist/channel/log-channels.js +17 -0
  29. package/dist/channel/pikku-abstract-channel-handler.d.ts +15 -0
  30. package/dist/channel/pikku-abstract-channel-handler.js +33 -0
  31. package/dist/channel/serverless/index.d.ts +1 -0
  32. package/dist/channel/serverless/index.js +1 -0
  33. package/dist/channel/serverless/serverless-channel-runner.d.ts +10 -0
  34. package/dist/channel/serverless/serverless-channel-runner.js +98 -0
  35. package/dist/errors/error-handler.d.ts +39 -0
  36. package/dist/errors/error-handler.js +54 -0
  37. package/dist/errors/errors.d.ts +190 -0
  38. package/dist/errors/errors.js +315 -0
  39. package/dist/errors/index.d.ts +2 -0
  40. package/dist/errors/index.js +2 -0
  41. package/dist/http/http-route-runner.d.ts +30 -0
  42. package/dist/http/http-route-runner.js +208 -0
  43. package/dist/http/http-routes.types.d.ts +127 -0
  44. package/dist/http/http-routes.types.js +1 -0
  45. package/dist/http/http-session-service.d.ts +15 -0
  46. package/dist/http/http-session-service.js +1 -0
  47. package/dist/http/index.d.ts +6 -0
  48. package/dist/http/index.js +5 -0
  49. package/dist/http/log-http-routes.d.ts +6 -0
  50. package/dist/http/log-http-routes.js +17 -0
  51. package/dist/http/pikku-http-abstract-request.d.ts +57 -0
  52. package/dist/http/pikku-http-abstract-request.js +69 -0
  53. package/dist/http/pikku-http-abstract-response.d.ts +58 -0
  54. package/dist/http/pikku-http-abstract-response.js +54 -0
  55. package/dist/http/pikku-http-session-service.d.ts +45 -0
  56. package/dist/http/pikku-http-session-service.js +92 -0
  57. package/dist/index.d.ts +14 -0
  58. package/dist/index.js +14 -0
  59. package/dist/permissions.d.ts +10 -0
  60. package/dist/permissions.js +32 -0
  61. package/dist/pikku-request.d.ts +14 -0
  62. package/dist/pikku-request.js +21 -0
  63. package/dist/pikku-response.d.ts +6 -0
  64. package/dist/pikku-response.js +6 -0
  65. package/dist/scheduler/index.d.ts +3 -0
  66. package/dist/scheduler/index.js +3 -0
  67. package/dist/scheduler/log-schedulers.d.ts +6 -0
  68. package/dist/scheduler/log-schedulers.js +17 -0
  69. package/dist/scheduler/scheduler-runner.d.ts +21 -0
  70. package/dist/scheduler/scheduler-runner.js +73 -0
  71. package/dist/scheduler/scheduler.types.d.ts +21 -0
  72. package/dist/scheduler/scheduler.types.js +1 -0
  73. package/dist/schema.d.ts +26 -0
  74. package/dist/schema.js +100 -0
  75. package/dist/services/content-service.d.ts +55 -0
  76. package/dist/services/content-service.js +1 -0
  77. package/dist/services/index.d.ts +12 -0
  78. package/dist/services/index.js +14 -0
  79. package/dist/services/jwt-service.d.ts +29 -0
  80. package/dist/services/jwt-service.js +1 -0
  81. package/dist/services/local-content.d.ts +33 -0
  82. package/dist/services/local-content.js +6 -0
  83. package/dist/services/local-secrets.d.ts +26 -0
  84. package/dist/services/local-secrets.js +39 -0
  85. package/dist/services/local-variables.d.ts +7 -0
  86. package/dist/services/local-variables.js +12 -0
  87. package/dist/services/logger-console.d.ts +52 -0
  88. package/dist/services/logger-console.js +82 -0
  89. package/dist/services/logger.d.ts +48 -0
  90. package/dist/services/logger.js +9 -0
  91. package/dist/services/schema-service.d.ts +24 -0
  92. package/dist/services/schema-service.js +1 -0
  93. package/dist/services/secret-service.d.ts +17 -0
  94. package/dist/services/secret-service.js +1 -0
  95. package/dist/services/user-session-service.d.ts +6 -0
  96. package/dist/services/user-session-service.js +1 -0
  97. package/dist/services/variables-service.d.ts +4 -0
  98. package/dist/services/variables-service.js +1 -0
  99. package/dist/types/core.types.d.ts +109 -0
  100. package/dist/types/core.types.js +1 -0
  101. package/dist/types/functions.types.d.ts +27 -0
  102. package/dist/types/functions.types.js +1 -0
  103. package/dist/utils.d.ts +2 -0
  104. package/dist/utils.js +15 -0
  105. package/package.json +48 -0
  106. package/run-tests.sh +53 -0
  107. package/src/channel/channel-handler.ts +179 -0
  108. package/src/channel/channel-runner.ts +156 -0
  109. package/src/channel/channel-store.ts +32 -0
  110. package/src/channel/channel.types.ts +202 -0
  111. package/src/channel/eventhub-forwarder.ts +25 -0
  112. package/src/channel/eventhub-service.ts +30 -0
  113. package/src/channel/eventhub-store.ts +8 -0
  114. package/src/channel/index.ts +9 -0
  115. package/src/channel/local/index.ts +3 -0
  116. package/src/channel/local/local-channel-handler.ts +56 -0
  117. package/src/channel/local/local-channel-runner.test.ts +128 -0
  118. package/src/channel/local/local-channel-runner.ts +94 -0
  119. package/src/channel/local/local-eventhub-service.test.ts +95 -0
  120. package/src/channel/local/local-eventhub-service.ts +95 -0
  121. package/src/channel/log-channels.ts +20 -0
  122. package/src/channel/pikku-abstract-channel-handler.test.ts +77 -0
  123. package/src/channel/pikku-abstract-channel-handler.ts +44 -0
  124. package/src/channel/serverless/index.ts +1 -0
  125. package/src/channel/serverless/serverless-channel-runner.ts +190 -0
  126. package/src/errors/error-handler.ts +74 -0
  127. package/src/errors/error.test.ts +54 -0
  128. package/src/errors/errors.ts +340 -0
  129. package/src/errors/index.ts +2 -0
  130. package/src/http/http-route-runner.test.ts +193 -0
  131. package/src/http/http-route-runner.ts +365 -0
  132. package/src/http/http-routes.types.ts +189 -0
  133. package/src/http/http-session-service.ts +19 -0
  134. package/src/http/index.ts +16 -0
  135. package/src/http/log-http-routes.ts +20 -0
  136. package/src/http/pikku-http-abstract-request.ts +95 -0
  137. package/src/http/pikku-http-abstract-response.ts +79 -0
  138. package/src/http/pikku-http-session-service.test.ts +106 -0
  139. package/src/http/pikku-http-session-service.ts +135 -0
  140. package/src/index.ts +15 -0
  141. package/src/permissions.test.ts +58 -0
  142. package/src/permissions.ts +45 -0
  143. package/src/pikku-request.ts +19 -0
  144. package/src/pikku-response.ts +5 -0
  145. package/src/scheduler/index.ts +11 -0
  146. package/src/scheduler/log-schedulers.ts +20 -0
  147. package/src/scheduler/scheduler-runner.ts +132 -0
  148. package/src/scheduler/scheduler.types.ts +27 -0
  149. package/src/schema.test.ts +57 -0
  150. package/src/schema.ts +124 -0
  151. package/src/services/content-service.ts +69 -0
  152. package/src/services/index.ts +16 -0
  153. package/src/services/jwt-service.ts +36 -0
  154. package/src/services/local-content.ts +39 -0
  155. package/src/services/local-secrets.ts +43 -0
  156. package/src/services/local-variables.ts +17 -0
  157. package/src/services/logger-console.ts +97 -0
  158. package/src/services/logger.ts +57 -0
  159. package/src/services/schema-service.ts +26 -0
  160. package/src/services/secret-service.ts +17 -0
  161. package/src/services/user-session-service.ts +7 -0
  162. package/src/services/variables-service.ts +6 -0
  163. package/src/types/core.types.ts +162 -0
  164. package/src/types/functions.types.ts +44 -0
  165. package/src/utils.ts +21 -0
  166. package/tsconfig.json +13 -0
  167. package/tsconfig.tsbuildinfo +1 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,339 @@
1
+ ## 0.6
2
+
3
+ ## 0.6.9
4
+
5
+ ### Patch Changes
6
+
7
+ - f3550d8: feat: changing singleton constructor to accept a prtial map of existing services
8
+
9
+ ## 0.6.8
10
+
11
+ ### Patch Changes
12
+
13
+ - b19aa86: refactor: switching aws to using @aws-sdk/cloudfront-signer
14
+
15
+ ## 0.6.7
16
+
17
+ ### Patch Changes
18
+
19
+ - 0a92fa7: refactor: pulling schema into seperate package since ajv doesnt work on cloudflare (also keeps bundle size small!)
20
+
21
+ ## 0.6.6
22
+
23
+ ### Patch Changes
24
+
25
+ - 4357bca: feat: fixing up nextjs apis
26
+
27
+ ## 0.6.5
28
+
29
+ ### Patch Changes
30
+
31
+ - a40a508: fix: Fixing some generation bugs and other minors
32
+
33
+ ## 0.6.4
34
+
35
+ ### Patch Changes
36
+
37
+ - f26880f: feat: extracting inspector and adding unique type references
38
+
39
+ ## 0.6.3
40
+
41
+ ### Patch Changes
42
+
43
+ - 09fc52c: feat: adding cloudflare and lambda websockets
44
+ breaking change: moved subscription from channel to services and renamed to event hub
45
+ - adecb52: feat: changes required to get cloudflare functions to work
46
+
47
+ ## 0.6.2
48
+
49
+ ### Patch Changes
50
+
51
+ - ed45ca9: feat: adding lambda serverless
52
+ - adeb392: feat: more channel improvements, and adding bubble option to runners to avoid all the empty try catches
53
+
54
+ ## 0.6.1
55
+
56
+ ### Patch Changes
57
+
58
+ - dee2e9f: feat: adding a subscription service change handler
59
+
60
+ Marking a major release to include channels and scheduled tasks
61
+
62
+ ## 0.5.29
63
+
64
+ ### Patch Changes
65
+
66
+ - 662a6cf: feat: adding scheduled tasks names
67
+ - c8578ea: fix: getting websocket auth to work on individual messages
68
+ - d2f8edf: feat: adding channelId to channels for serverless compatability
69
+
70
+ ## 0.5.28
71
+
72
+ ### Patch Changes
73
+
74
+ - a768bad: feat: adding channel permission service
75
+ - 886a2fb: refactor: moving singletons (like routes and channels) to global to avoid nodemodule overrides
76
+ - 886a2fb: fix: making core routes global to avoid state overrides
77
+
78
+ ## 0.5.27
79
+
80
+ ### Patch Changes
81
+
82
+ - aa8435c: fix: fixing up channel apis and implementations
83
+
84
+ ## 0.5.26
85
+
86
+ ### Patch Changes
87
+
88
+ - ab42f18: chore: upgrading to next15 and dropping pages support
89
+
90
+ ## 0.5.25
91
+
92
+ ### Patch Changes
93
+
94
+ - 0f96787: refactor: dropping cjs support
95
+ - 64e4a1e: refactor: seperating core into cleaner sub-packages
96
+ - c23524a: refactor: bump to versions to ensure correct package usage
97
+
98
+ ## 0.5.24
99
+
100
+ ### Patch Changes
101
+
102
+ - bba25cc: chore: updating all packages to reflect major changes
103
+ - 9deb482: refactor: finalizing stream api
104
+ - ee0c6ea: feat: adding ws server
105
+
106
+ ## 0.5.23
107
+
108
+ ### Patch Changes
109
+
110
+ - 7fa64a0: feat: making schedule session services optional
111
+ - 539937e: refactor: use a map instead for scheduled tasks
112
+ - e9a9968: refactor: completing rename of stream to channel
113
+
114
+ ## 0.5.22
115
+
116
+ ### Patch Changes
117
+
118
+ - 73973ec: fix: data type for methods is optional
119
+
120
+ ## 0.5.21
121
+
122
+ ### Patch Changes
123
+
124
+ - 179b9c2: fix: fixing stream types
125
+
126
+ ## 0.5.20
127
+
128
+ ### Patch Changes
129
+
130
+ - 5be6da1: feat: adding streams to uws (and associated refactors)
131
+
132
+ ## 0.5.19
133
+
134
+ ### Patch Changes
135
+
136
+ - cbcc75b: feat: adding scheduler types to core
137
+ - d58c440: refactor: making http requests explicit to support other types
138
+ - 11c50d4: feat: adding streams to cli
139
+
140
+ ## 0.5.18
141
+
142
+ ### Patch Changes
143
+
144
+ - bed9ab4: revert: reverting ajv array transformation
145
+ - d4dd093: feat: coerce top level strings to arrays
146
+
147
+ ## 0.5.17
148
+
149
+ ### Patch Changes
150
+
151
+ - 2f77f5f: feat: coerce array types if needed via ajv validation
152
+
153
+ ## 0.5.16
154
+
155
+ ### Patch Changes
156
+
157
+ - 4046a85: feat: adding more error types
158
+
159
+ ## 0.5.15
160
+
161
+ ### Patch Changes
162
+
163
+ - 816eaaa: fix: don't throw an error if auth isnt required for a route
164
+
165
+ ## 0.5.14
166
+
167
+ ### Patch Changes
168
+
169
+ - 8531c5e: fix: export log routes in index since bundler can't find it
170
+
171
+ ## 0.5.13
172
+
173
+ ### Patch Changes
174
+
175
+ - 30b46aa: fix: looks like using patch lowercase breaks the node fetch client sometimes
176
+
177
+ ## 0.5.12
178
+
179
+ ### Patch Changes
180
+
181
+ - ff8a563: feat: only log warning errors for status codes we care about
182
+
183
+ ## 0.5.11
184
+
185
+ ### Patch Changes
186
+
187
+ - be68efb: fix: allow error handler to use errors other than EError
188
+ - 5295380: refactor: changing config object a getConfig function
189
+ - f24a653: feat: coerce types in ajv for correct validation / usage later on
190
+
191
+ ## 0.5.10
192
+
193
+ ### Patch Changes
194
+
195
+ - effbb4c: doc: adding readme to all packages
196
+
197
+ ## 0.5.9
198
+
199
+ ### Patch Changes
200
+
201
+ - 3541ab7: refactor: rename nextDeclarationFile to nextJSFile
202
+ - 725723d: docs: adding typedocs
203
+
204
+ ## 0.5.8
205
+
206
+ ### Patch Changes
207
+
208
+ - 1876d7a: feat: add error return codes to doc generation
209
+ - 8d85f7e: feat: load all schemas on start optionally instead of validating they were loaded
210
+
211
+ ## 0.5.7
212
+
213
+ ### Patch Changes
214
+
215
+ - df62faf: fix: bumping up routes meta
216
+
217
+ ## 0.5.6
218
+
219
+ ### Patch Changes
220
+
221
+ - 0883f00: fix: schema generation error
222
+
223
+ ## 0.5.5
224
+
225
+ ### Patch Changes
226
+
227
+ - 93b80a3: feat: adding a beta openapi standard
228
+
229
+ ## 0.5.4
230
+
231
+ ### Patch Changes
232
+
233
+ - 6cac8ab: feat: adding a do not edit to cli generated files
234
+
235
+ ## 0.5.3
236
+
237
+ ### Patch Changes
238
+
239
+ - 8065e48: refactor: large cli refactor for a better dev experience
240
+
241
+ ## 0.5.2
242
+
243
+ ### Patch Changes
244
+
245
+ - 5e0f033: feat: adding a routes map output file to support frontend sdks in the future
246
+
247
+ ## 0.5.1
248
+
249
+ ### Patch Changes
250
+
251
+ - 97900d2: fix: exporting plugins from default barrel files
252
+ - d939d46: refactor: extracting nextjs and fastify to plugins
253
+ - 45e07de: refactor: renaming packages and pikku structure
254
+
255
+ ## 0.4.7
256
+
257
+ ### Patch Changes
258
+
259
+ - ddaf58f: feat: adding hostname to servers
260
+
261
+ ## 0.4.6
262
+
263
+ ### Patch Changes
264
+
265
+ - 2a2402b: republish since something went wrong
266
+
267
+ ## 0.4.5
268
+
269
+ ### Patch Changes
270
+
271
+ - c73afd6: this should have been published..
272
+
273
+ ## 0.4.4
274
+
275
+ ### Patch Changes
276
+
277
+ - 0650348: fix: export schemas using \*
278
+ - 1a708a7: refactor: renaming PikkuCLIConfig back to PikkuConfig
279
+ feat: adding .end() to pikku response for servers that need it
280
+ - 642d370: fix: adding schema error logs on fail
281
+
282
+ ## 0.4.3
283
+
284
+ ### Patch Changes
285
+
286
+ - 94f8a74: fix: finalizing cjs and esm packages
287
+
288
+ ## 0.4.2
289
+
290
+ ### Patch Changes
291
+
292
+ - 28f62ea: refactor: using cjs and esm builds!
293
+ - 14783ee: fix: including all types as dependencies to avoid users needing to install them
294
+
295
+ ## 0.0.18 - 05.09.2022
296
+
297
+ feat: adding a maximum compute time for better error handling on lambda timeouts
298
+
299
+ ## 0.0.17 - 24.08.2022
300
+
301
+ fix: use error name instead of constructor for better management of instanceof
302
+
303
+ ## 0.0.10 - 21.07.2022
304
+
305
+ feat: add a transform session call incase jwt provided belongs to a third-party like aws cognito
306
+
307
+ ## 0.0.9 - 26.06.2022
308
+
309
+ chore: Upgrading dependencies
310
+
311
+ ## 0.0.6 - 13.04.2022
312
+
313
+ chore: Upgrading dependencies
314
+
315
+ ## 0.0.5 - 19.02.2022
316
+
317
+ chore: Upgrading dependencies
318
+
319
+ ## 0.0.4 - 26.09.2021
320
+
321
+ feat: Adding writeFile, readFile and deleteFile APIs
322
+
323
+ ## 0.0.3 - 02.09.2021
324
+
325
+ chore: Updating dependencies
326
+
327
+ ## 0.0.2 - 02.08.2021
328
+
329
+ Fix: deleting files with correct path in local files
330
+
331
+ ## 0.0.1 - 27.07.2021
332
+
333
+ Fix: Using global space for schemas as it appears to not always return the same file
334
+
335
+ ## 23.07.2021
336
+
337
+ ### Initial Release
338
+
339
+ A package that contains pikku types
package/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # @pikku/core
2
+
3
+ This package is part of @pikku/mono and is responsible for the runtime in pikku.
4
+
5
+ It is used by most other packages, contains all the core types and minimal requirements.
@@ -0,0 +1,3 @@
1
+ import { CoreServices, CoreUserSession } from '../types/core.types.js';
2
+ import { CoreAPIChannel, PikkuChannelHandler } from './channel.types.js';
3
+ export declare const processMessageHandlers: (services: CoreServices, channelConfig: CoreAPIChannel<any, any>, channelHandler: PikkuChannelHandler<CoreUserSession, unknown>) => (rawData: any) => Promise<unknown>;
@@ -0,0 +1,97 @@
1
+ import { verifyPermissions } from '../permissions.js';
2
+ import { getChannels } from './channel-runner.js';
3
+ const validateSchema = (logger, data, channelName, routingProperty, routerValue) => {
4
+ const { channelsMeta } = getChannels();
5
+ for (const channelMeta of channelsMeta) {
6
+ if (routingProperty && routerValue) {
7
+ const channelRoute = channelMeta.messageRoutes[routingProperty]?.[routerValue];
8
+ if (channelRoute) {
9
+ const schemaNames = channelRoute.inputs;
10
+ if (schemaNames) {
11
+ // TODO
12
+ // loadSchema(schemaNames, logger)
13
+ // validateJson(schemaNames, data)
14
+ }
15
+ return;
16
+ }
17
+ }
18
+ }
19
+ };
20
+ const validateAuth = (requiresSession, channelHandler, onMessage) => {
21
+ const auth = typeof onMessage === 'function'
22
+ ? requiresSession
23
+ : onMessage.auth === undefined
24
+ ? requiresSession
25
+ : onMessage.auth;
26
+ if (auth && !channelHandler.getChannel().userSession) {
27
+ return false;
28
+ }
29
+ return true;
30
+ };
31
+ const validatePermissions = async (services, channelHandler, onMessage, data) => {
32
+ const permissions = typeof onMessage === 'function' ? {} : onMessage.permissions;
33
+ return await verifyPermissions(permissions, services, data, channelHandler.getChannel().userSession);
34
+ };
35
+ const runFunction = async (services, channelHandler, onMessage, data) => {
36
+ const func = typeof onMessage === 'function' ? onMessage : onMessage.func;
37
+ return await func(services, channelHandler.getChannel(), data);
38
+ };
39
+ export const processMessageHandlers = (services, channelConfig, channelHandler) => {
40
+ const logger = services.logger;
41
+ const requiresSession = channelConfig.auth !== false;
42
+ const processMessage = async (data, onMessage, routingProperty, routerValue) => {
43
+ if (!validateAuth(requiresSession, channelHandler, onMessage)) {
44
+ const routeMessage = routingProperty
45
+ ? `route '${routingProperty}:${routerValue}'`
46
+ : 'the default message route';
47
+ logger.error(`Channel ${channelConfig.name} with id ${channelHandler.getChannel().channelId} requires a session for ${routeMessage}`);
48
+ // TODO: Send error message back breaks typescript, but should be implemented somehow
49
+ channelHandler.getChannel().send(`Unauthorized for ${routeMessage}`);
50
+ return;
51
+ }
52
+ validateSchema(services.logger, data, channelConfig.name, routingProperty, routerValue);
53
+ const hasPermission = await validatePermissions(services, channelHandler, onMessage, data);
54
+ if (!hasPermission) {
55
+ logger.error(`Channel ${channelConfig.name} requires permissions for ${routingProperty || 'default message route'}`);
56
+ }
57
+ return await runFunction(services, channelHandler, onMessage, data);
58
+ };
59
+ const onMessage = async (rawData) => {
60
+ let result;
61
+ let processed = false;
62
+ // Route-specific handling
63
+ if (typeof rawData === 'string' && channelConfig.onMessageRoute) {
64
+ try {
65
+ const messageData = JSON.parse(rawData);
66
+ const entries = Object.entries(channelConfig.onMessageRoute);
67
+ for (const [routingProperty, routes] of entries) {
68
+ const routerValue = messageData[routingProperty];
69
+ if (routerValue && routes[routerValue]) {
70
+ processed = true;
71
+ result = await processMessage(messageData, routes[routerValue], routingProperty, routerValue);
72
+ break;
73
+ }
74
+ }
75
+ // Default handler if no routes matched but json data was parsed
76
+ if (!processed && channelConfig.onMessage) {
77
+ processed = true;
78
+ result = await processMessage(messageData, channelConfig.onMessage);
79
+ }
80
+ }
81
+ catch (error) {
82
+ // Most likely a json error.. ignore
83
+ }
84
+ }
85
+ // Default handler if no routes matched and json data wasn't parsed
86
+ if (!processed && channelConfig.onMessage) {
87
+ processed = true;
88
+ result = await processMessage(rawData, channelConfig.onMessage);
89
+ }
90
+ if (!processed) {
91
+ logger.error(`No handler found for message in channel ${channelConfig.name} for ${rawData}`);
92
+ logger.error(`Channel ${channelConfig}`);
93
+ }
94
+ return result;
95
+ };
96
+ return onMessage;
97
+ };
@@ -0,0 +1,26 @@
1
+ import { CoreUserSession } from '../types/core.types.js';
2
+ import { CoreAPIChannel, ChannelsMeta, CoreAPIChannels, RunChannelOptions, RunChannelParams } from './channel.types.js';
3
+ /**
4
+ * Returns all the registered routes and associated metadata.
5
+ * @internal
6
+ */
7
+ export declare const getChannels: () => {
8
+ channels: CoreAPIChannels;
9
+ channelsMeta: ChannelsMeta;
10
+ };
11
+ export declare const addChannel: <In, Channel extends string, ChannelFunction, ChannelFunctionSessionless, APIPermission>(channel: CoreAPIChannel<In, Channel, ChannelFunction, ChannelFunctionSessionless, APIPermission>) => void;
12
+ /**
13
+ * @ignore
14
+ */
15
+ export declare const setChannelsMeta: (_channelsMeta: ChannelsMeta) => void;
16
+ export declare const getMatchingChannelConfig: (request: string) => {
17
+ matchedPath: import("path-to-regexp").MatchResult<Partial<Record<string, string | string[]>>>;
18
+ params: Partial<Record<string, string | string[]>>;
19
+ channelConfig: CoreAPIChannel<any, string, import("./channel.types.js").CoreChannelConnection<any, unknown, import("../types/core.types.js").CoreServices, unknown>, import("./channel.types.js").CoreChannelConnection<any, unknown, import("../types/core.types.js").CoreServices, unknown>, import("./channel.types.js").CoreChannelMessage<unknown, unknown, unknown, import("../types/core.types.js").CoreServices, unknown>, import("./channel.types.js").CoreChannelMessage<unknown, unknown, unknown, import("../types/core.types.js").CoreServices, unknown>, import("../index.js").CoreAPIPermission<any>>;
20
+ schemaName: string | null | undefined;
21
+ } | null;
22
+ export declare const openChannel: ({ route, singletonServices, skipUserSession, coerceToArray, http, }: Pick<CoreAPIChannel<unknown, string>, "route"> & Omit<RunChannelParams<unknown>, "response" | "request"> & RunChannelOptions) => Promise<{
23
+ userSession?: CoreUserSession;
24
+ openingData: unknown;
25
+ channelConfig: CoreAPIChannel<unknown, any>;
26
+ }>;
@@ -0,0 +1,86 @@
1
+ import { NotFoundError } from '../errors/errors.js';
2
+ import { loadUserSession } from '../http/http-route-runner.js';
3
+ import { validateAndCoerce } from '../schema.js';
4
+ import { match } from 'path-to-regexp';
5
+ if (!globalThis.pikku?.channels) {
6
+ globalThis.pikku = globalThis.pikku || {};
7
+ globalThis.pikku.channels = [];
8
+ globalThis.pikku.channelsMeta = [];
9
+ }
10
+ const channels = (data) => {
11
+ if (data) {
12
+ globalThis.pikku.channels = data;
13
+ }
14
+ return globalThis.pikku.channels;
15
+ };
16
+ const channelsMeta = (data) => {
17
+ if (data) {
18
+ globalThis.pikku.channelsMeta = data;
19
+ }
20
+ return globalThis.pikku.channelsMeta;
21
+ };
22
+ /**
23
+ * Returns all the registered routes and associated metadata.
24
+ * @internal
25
+ */
26
+ export const getChannels = () => {
27
+ return {
28
+ channels: channels(),
29
+ channelsMeta: channelsMeta(),
30
+ };
31
+ };
32
+ export const addChannel = (channel) => {
33
+ channels().push(channel);
34
+ };
35
+ /**
36
+ * @ignore
37
+ */
38
+ export const setChannelsMeta = (_channelsMeta) => {
39
+ channelsMeta(_channelsMeta);
40
+ };
41
+ export const getMatchingChannelConfig = (request) => {
42
+ const { channels, channelsMeta } = getChannels();
43
+ for (const channelConfig of channels) {
44
+ const cleanedRoute = channelConfig.route.replace(/^\/\//, '/');
45
+ const cleanedRequest = request.replace(/^\/\//, '/');
46
+ const matchFunc = match(cleanedRoute, {
47
+ decode: decodeURIComponent,
48
+ });
49
+ const matchedPath = matchFunc(cleanedRequest);
50
+ if (matchedPath) {
51
+ const schemaName = channelsMeta.find((channelMeta) => channelMeta.route === channelConfig.route)?.input;
52
+ return {
53
+ matchedPath,
54
+ params: matchedPath.params,
55
+ channelConfig,
56
+ schemaName,
57
+ };
58
+ }
59
+ }
60
+ return null;
61
+ };
62
+ export const openChannel = async ({ route, singletonServices, skipUserSession = false, coerceToArray = false, http, }) => {
63
+ const matchingChannel = getMatchingChannelConfig(route);
64
+ if (!matchingChannel) {
65
+ singletonServices.logger.info(`Channel not found: ${route}`);
66
+ throw new NotFoundError(`Channel not found: ${route}`);
67
+ }
68
+ const { matchedPath, params, channelConfig, schemaName } = matchingChannel;
69
+ const requiresSession = channelConfig.auth !== false;
70
+ http?.request?.setParams(params);
71
+ singletonServices.logger.info(`Matched channel: ${channelConfig.name} | route: ${channelConfig.route} | auth: ${requiresSession.toString()}`);
72
+ const userSession = await loadUserSession(skipUserSession,
73
+ // We may require a session, but we don't actually need it
74
+ // on connect since channels can authenticate later given
75
+ // how websocket sessions work (cookie or queryParam based)
76
+ false, http, matchedPath, channelConfig, singletonServices.logger, singletonServices.httpSessionService);
77
+ if (singletonServices.enforceChannelAccess) {
78
+ await singletonServices.enforceChannelAccess(matchingChannel.channelConfig, userSession);
79
+ }
80
+ let openingData;
81
+ if (http?.request) {
82
+ openingData = await http.request.getData();
83
+ validateAndCoerce(singletonServices.logger, singletonServices.schemaService, schemaName, openingData, coerceToArray);
84
+ }
85
+ return { userSession, openingData, channelConfig };
86
+ };
@@ -0,0 +1,14 @@
1
+ import { CoreUserSession } from '../types/core.types.js';
2
+ export type Channel<ChannelType = unknown, OpeningData = unknown, UserSession extends CoreUserSession = CoreUserSession> = {
3
+ channelId: string;
4
+ channelName: string;
5
+ channelObject?: ChannelType;
6
+ openingData?: OpeningData;
7
+ userSession?: UserSession;
8
+ };
9
+ export declare abstract class ChannelStore<ChannelType = unknown, OpeningData = unknown, UserSession extends CoreUserSession = CoreUserSession, TypedChannel = Channel<ChannelType, OpeningData, UserSession>> {
10
+ abstract addChannel(channel: Channel<ChannelType, OpeningData, UserSession>): Promise<void> | void;
11
+ abstract removeChannels(channelId: string[]): Promise<void> | void;
12
+ abstract setUserSession(channelId: string, userSession: any): Promise<void> | void;
13
+ abstract getChannel(channelId: string): Promise<TypedChannel> | TypedChannel;
14
+ }
@@ -0,0 +1,2 @@
1
+ export class ChannelStore {
2
+ }
@@ -0,0 +1,106 @@
1
+ import { EError } from '../errors/error-handler.js';
2
+ import { HTTPFunctionMetaInputTypes, PikkuHTTP } from '../http/http-routes.types.js';
3
+ import { PikkuHTTPAbstractRequest } from '../http/pikku-http-abstract-request.js';
4
+ import { PikkuHTTPAbstractResponse } from '../http/pikku-http-abstract-response.js';
5
+ import { APIDocs, CoreServices, CoreSingletonServices, CoreUserSession, CreateSessionServices, MakeRequired } from '../types/core.types.js';
6
+ import { CoreAPIPermission } from '../types/functions.types.js';
7
+ import { PikkuRequest } from '../pikku-request.js';
8
+ import { PikkuResponse } from '../pikku-response.js';
9
+ export type RunChannelOptions = Partial<{
10
+ skipUserSession: boolean;
11
+ respondWith404: boolean;
12
+ coerceToArray: boolean;
13
+ logWarningsForStatusCodes: number[];
14
+ bubbleErrors: boolean;
15
+ }>;
16
+ export type RunChannelParams<ChannelData> = {
17
+ channelId: string;
18
+ singletonServices: MakeRequired<CoreSingletonServices, 'eventHub'>;
19
+ request?: PikkuRequest<ChannelData> | PikkuHTTPAbstractRequest<ChannelData>;
20
+ response?: PikkuResponse | PikkuHTTPAbstractResponse;
21
+ http?: PikkuHTTP;
22
+ createSessionServices?: CreateSessionServices;
23
+ };
24
+ export interface HandlerMeta {
25
+ }
26
+ export interface ChannelMeta {
27
+ name: string;
28
+ route: string;
29
+ params?: string[];
30
+ query?: string[];
31
+ input: string | null;
32
+ inputTypes?: HTTPFunctionMetaInputTypes;
33
+ connect: boolean;
34
+ disconnect: boolean;
35
+ message: {
36
+ inputs: string[] | null;
37
+ outputs: string[] | null;
38
+ } | null;
39
+ messageRoutes: Record<string, Record<string, {
40
+ inputs: string[] | null;
41
+ outputs: string[] | null;
42
+ }>>;
43
+ docs?: APIDocs;
44
+ }
45
+ export type ChannelsMeta = ChannelMeta[];
46
+ export type CoreChannelConnection<ChannelData, Out = unknown, Services extends CoreServices = CoreServices, Session extends CoreUserSession = CoreUserSession> = (services: MakeRequired<Services, 'eventHub'>, channel: PikkuChannel<Session, ChannelData, Out>) => Promise<void>;
47
+ export type CoreChannelDisconnection<ChannelData, Services extends CoreServices = CoreServices, Session extends CoreUserSession = CoreUserSession> = (services: MakeRequired<Services, 'eventHub'>, channel: PikkuChannel<Session, ChannelData, never>) => Promise<void>;
48
+ /**
49
+ * Represents a core channel function that performs an operation using core services and a user session.
50
+ *
51
+ * @template In - The input type.
52
+ * @template Services - The services type, defaults to `CoreServices`.
53
+ * @template Session - The session type, defaults to `CoreUserSession`.
54
+ */
55
+ export type CoreChannelMessage<In, Out, ChannelData, Services extends CoreServices = CoreServices, Session extends CoreUserSession = CoreUserSession> = (services: MakeRequired<Services, 'eventHub'>, channel: PikkuChannel<Session, ChannelData, Out>, data: In) => Promise<void | Out>;
56
+ export type CoreAPIChannelMessage<ChannelFunctionMessage = CoreChannelMessage<unknown, unknown, unknown>> = {
57
+ func: ChannelFunctionMessage;
58
+ route: string;
59
+ };
60
+ export type CoreAPIChannel<ChannelData, Channel extends string, ChannelFunctionConnection = CoreChannelConnection<ChannelData>, ChannelFunctionDisconnection = CoreChannelConnection<ChannelData>, ChannelFunctionDefaultMessage = CoreChannelMessage<unknown, unknown, unknown>, ChannelFunctionMessageRoute = CoreChannelMessage<unknown, unknown, unknown>, APIPermission = CoreAPIPermission<ChannelData>> = {
61
+ name: string;
62
+ route: Channel;
63
+ onConnect?: ChannelFunctionConnection;
64
+ onDisconnect?: ChannelFunctionDisconnection;
65
+ onMessage?: {
66
+ func: ChannelFunctionDefaultMessage;
67
+ permissions?: Record<string, APIPermission[] | APIPermission>;
68
+ auth?: boolean;
69
+ } | ChannelFunctionDefaultMessage;
70
+ onMessageRoute?: Record<string, Record<string, ChannelFunctionMessageRoute | {
71
+ func: ChannelFunctionMessageRoute;
72
+ permissions?: Record<string, APIPermission[] | APIPermission>;
73
+ auth?: boolean;
74
+ }>>;
75
+ permissions?: Record<string, APIPermission[] | APIPermission>;
76
+ auth?: boolean;
77
+ docs?: Partial<{
78
+ description: string;
79
+ response: string;
80
+ errors: Array<typeof EError>;
81
+ tags: string[];
82
+ }>;
83
+ };
84
+ export type CoreAPIChannels = CoreAPIChannel<any, string>[];
85
+ export interface PikkuChannel<UserSession, OpeningData, Out> {
86
+ channelId: string;
87
+ userSession?: UserSession;
88
+ setUserSession: (userSession: UserSession) => Promise<void> | void;
89
+ openingData: OpeningData;
90
+ send: (data: Out, isBinary?: boolean) => Promise<void> | void;
91
+ close: () => Promise<void> | void;
92
+ state: 'initial' | 'open' | 'closed';
93
+ }
94
+ export interface PikkuChannelHandler<UserSession extends CoreUserSession = CoreUserSession, OpeningData = unknown, Out = unknown> {
95
+ setUserSession(session: UserSession): Promise<void> | void;
96
+ send(message: Out, isBinary?: boolean): Promise<void> | void;
97
+ getChannel(): PikkuChannel<UserSession, OpeningData, Out>;
98
+ }
99
+ export type PikkuChannelHandlerFactory<OpeningData = unknown, UserSession extends CoreUserSession = CoreUserSession, Out = unknown> = (channelId: string, channelName: string, openingData: OpeningData, userSession: UserSession | undefined) => PikkuChannelHandler<UserSession, OpeningData, Out>;
100
+ /**
101
+ * Enfore access to a channel.
102
+ * @param route - The channel to verify access for.
103
+ * @param session - The user session.
104
+ * @returns A promise that resolves if access is granted.
105
+ */
106
+ export type enforceChannelAccess = (channel: CoreAPIChannel<unknown, any>, session?: CoreUserSession) => Promise<void> | void;
@@ -0,0 +1 @@
1
+ export {};