@pikku/core 0.6.26 → 0.7.0

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 (130) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/dist/channel/channel-handler.js +16 -38
  3. package/dist/channel/channel-runner.d.ts +7 -8
  4. package/dist/channel/channel-runner.js +58 -7
  5. package/dist/channel/channel.types.d.ts +14 -27
  6. package/dist/channel/local/local-channel-runner.js +9 -4
  7. package/dist/channel/log-channels.js +4 -4
  8. package/dist/channel/serverless/serverless-channel-runner.js +17 -6
  9. package/dist/function/function-runner.d.ts +12 -0
  10. package/dist/function/function-runner.js +38 -0
  11. package/dist/function/functions.types.d.ts +37 -0
  12. package/dist/function/functions.types.js +1 -0
  13. package/dist/function/index.d.ts +2 -0
  14. package/dist/function/index.js +2 -0
  15. package/dist/handle-error.d.ts +1 -1
  16. package/dist/http/http-route-runner.d.ts +3 -3
  17. package/dist/http/http-route-runner.js +60 -35
  18. package/dist/http/http-routes.types.d.ts +38 -7
  19. package/dist/http/http-runner.d.ts +90 -0
  20. package/dist/http/http-runner.js +336 -0
  21. package/dist/http/http.types.d.ts +177 -0
  22. package/dist/http/http.types.js +1 -0
  23. package/dist/http/index.d.ts +2 -2
  24. package/dist/http/index.js +1 -1
  25. package/dist/http/log-http-routes.js +7 -5
  26. package/dist/http/pikku-fetch-http-request.d.ts +1 -1
  27. package/dist/http/pikku-fetch-http-response.d.ts +4 -2
  28. package/dist/http/pikku-fetch-http-response.js +64 -12
  29. package/dist/http/pikku-http-request.d.ts +56 -0
  30. package/dist/http/pikku-http-request.js +95 -0
  31. package/dist/http/pikku-http-response.d.ts +13 -0
  32. package/dist/http/pikku-http-response.js +60 -0
  33. package/dist/index.d.ts +3 -2
  34. package/dist/index.js +3 -2
  35. package/dist/middleware/auth-apikey.js +5 -4
  36. package/dist/middleware/auth-bearer.js +5 -4
  37. package/dist/middleware/auth-cookie.js +10 -9
  38. package/dist/parse-relative-time-offset.d.ts +12 -0
  39. package/dist/parse-relative-time-offset.js +20 -0
  40. package/dist/permissions.d.ts +2 -2
  41. package/dist/pikku-func.d.ts +12 -0
  42. package/dist/pikku-func.js +39 -0
  43. package/dist/pikku-function.d.ts +1 -0
  44. package/dist/pikku-function.js +1 -0
  45. package/dist/pikku-state.d.ts +10 -5
  46. package/dist/pikku-state.js +7 -3
  47. package/dist/scheduler/scheduler-runner.d.ts +1 -1
  48. package/dist/scheduler/scheduler-runner.js +24 -6
  49. package/dist/scheduler/scheduler.types.d.ts +3 -2
  50. package/dist/services/content-service.d.ts +34 -36
  51. package/dist/services/index.d.ts +1 -0
  52. package/dist/services/index.js +1 -0
  53. package/dist/services/local-content.d.ts +4 -2
  54. package/dist/services/local-content.js +19 -9
  55. package/dist/types/core.types.d.ts +15 -1
  56. package/dist/types/functions.types.d.ts +11 -6
  57. package/dist/utils.d.ts +2 -0
  58. package/dist/utils.js +15 -0
  59. package/package.json +2 -1
  60. package/lcov.info +0 -4310
  61. package/src/channel/channel-handler.ts +0 -227
  62. package/src/channel/channel-runner.ts +0 -98
  63. package/src/channel/channel-store.ts +0 -29
  64. package/src/channel/channel.types.ts +0 -171
  65. package/src/channel/eventhub-service.ts +0 -30
  66. package/src/channel/eventhub-store.ts +0 -8
  67. package/src/channel/index.ts +0 -8
  68. package/src/channel/local/index.ts +0 -3
  69. package/src/channel/local/local-channel-handler.ts +0 -50
  70. package/src/channel/local/local-channel-runner.test.ts +0 -158
  71. package/src/channel/local/local-channel-runner.ts +0 -126
  72. package/src/channel/local/local-eventhub-service.test.ts +0 -95
  73. package/src/channel/local/local-eventhub-service.ts +0 -95
  74. package/src/channel/log-channels.ts +0 -20
  75. package/src/channel/pikku-abstract-channel-handler.test.ts +0 -52
  76. package/src/channel/pikku-abstract-channel-handler.ts +0 -38
  77. package/src/channel/serverless/index.ts +0 -1
  78. package/src/channel/serverless/serverless-channel-runner.ts +0 -209
  79. package/src/errors/error-handler.ts +0 -61
  80. package/src/errors/error.test.ts +0 -54
  81. package/src/errors/errors.ts +0 -339
  82. package/src/errors/index.ts +0 -2
  83. package/src/handle-error.ts +0 -73
  84. package/src/http/http-route-runner.test.ts +0 -117
  85. package/src/http/http-route-runner.ts +0 -460
  86. package/src/http/http-routes.types.ts +0 -211
  87. package/src/http/incomingmessage-to-request-convertor.ts +0 -0
  88. package/src/http/index.ts +0 -8
  89. package/src/http/log-http-routes.ts +0 -20
  90. package/src/http/pikku-fetch-http-request.test.ts +0 -237
  91. package/src/http/pikku-fetch-http-request.ts +0 -167
  92. package/src/http/pikku-fetch-http-response.test.ts +0 -82
  93. package/src/http/pikku-fetch-http-response.ts +0 -84
  94. package/src/index.ts +0 -19
  95. package/src/middleware/auth-apikey.ts +0 -65
  96. package/src/middleware/auth-bearer.ts +0 -65
  97. package/src/middleware/auth-cookie.ts +0 -98
  98. package/src/middleware/index.ts +0 -3
  99. package/src/middleware/timeout.ts +0 -13
  100. package/src/middleware-runner.ts +0 -43
  101. package/src/permissions.test.ts +0 -58
  102. package/src/permissions.ts +0 -45
  103. package/src/pikku-request.ts +0 -23
  104. package/src/pikku-response.ts +0 -5
  105. package/src/pikku-state.ts +0 -71
  106. package/src/scheduler/index.ts +0 -5
  107. package/src/scheduler/log-schedulers.ts +0 -20
  108. package/src/scheduler/scheduler-runner.ts +0 -87
  109. package/src/scheduler/scheduler.types.ts +0 -29
  110. package/src/schema.test.ts +0 -57
  111. package/src/schema.ts +0 -99
  112. package/src/services/content-service.ts +0 -69
  113. package/src/services/index.ts +0 -17
  114. package/src/services/jwt-service.ts +0 -30
  115. package/src/services/local-content.ts +0 -91
  116. package/src/services/local-secrets.ts +0 -43
  117. package/src/services/local-variables.ts +0 -17
  118. package/src/services/logger-console.ts +0 -97
  119. package/src/services/logger.ts +0 -57
  120. package/src/services/schema-service.ts +0 -26
  121. package/src/services/secret-service.ts +0 -17
  122. package/src/services/user-session-service.ts +0 -53
  123. package/src/services/variables-service.ts +0 -6
  124. package/src/time-utils.test.ts +0 -56
  125. package/src/time-utils.ts +0 -32
  126. package/src/types/core.types.ts +0 -159
  127. package/src/types/functions.types.ts +0 -63
  128. package/src/utils.ts +0 -21
  129. package/tsconfig.json +0 -13
  130. package/tsconfig.tsbuildinfo +0 -1
@@ -1,82 +0,0 @@
1
- import { describe, test } from 'node:test'
2
- import assert from 'assert'
3
- import { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js' // Adjust path if needed
4
-
5
- describe('PikkuFetchHTTPResponse', () => {
6
- test('sets status code', () => {
7
- const res = new PikkuFetchHTTPResponse().status(404).toResponse()
8
- assert.strictEqual(res.status, 404)
9
- })
10
-
11
- test('sets headers', async () => {
12
- const res = new PikkuFetchHTTPResponse()
13
- .header('X-Test', 'value')
14
- .header('X-Multi', ['a', 'b'])
15
- .toResponse()
16
-
17
- assert.strictEqual(res.headers.get('X-Test'), 'value')
18
- const multi = res.headers.get('X-Multi')?.split(', ')
19
- assert.deepEqual(multi, ['a', 'b'])
20
- })
21
-
22
- test('sets cookies', () => {
23
- const res = new PikkuFetchHTTPResponse()
24
- .cookie('token', 'abc123', { httpOnly: true, path: '/' })
25
- .cookie('other', 'val', { maxAge: 3600 })
26
- .toResponse()
27
-
28
- const setCookieHeader = res.headers.get('Set-Cookie')
29
- assert.ok(setCookieHeader)
30
-
31
- const cookies = setCookieHeader!.split(', ')
32
- assert.ok(cookies.some((c) => c.startsWith('token=abc123')))
33
- assert.ok(cookies.some((c) => c.startsWith('other=val')))
34
- })
35
-
36
- test('json sets correct content type and body', async () => {
37
- const res = new PikkuFetchHTTPResponse()
38
- .json({ hello: 'world' })
39
- .toResponse()
40
-
41
- assert.strictEqual(res.headers.get('Content-Type'), 'application/json')
42
- const body = await res.json()
43
- assert.deepEqual(body, { hello: 'world' })
44
- })
45
-
46
- test('text sets correct content type and body', async () => {
47
- const res = new PikkuFetchHTTPResponse().text('hello').toResponse()
48
-
49
- assert.strictEqual(res.headers.get('Content-Type'), 'text/plain')
50
- const text = await res.text()
51
- assert.strictEqual(text, 'hello')
52
- })
53
-
54
- test('html sets correct content type and body', async () => {
55
- const res = new PikkuFetchHTTPResponse().html('<p>hi</p>').toResponse()
56
-
57
- assert.strictEqual(res.headers.get('Content-Type'), 'text/html')
58
- const text = await res.text()
59
- assert.strictEqual(text, '<p>hi</p>')
60
- })
61
-
62
- test('arrayBuffer sets correct content type', async () => {
63
- const buffer = new Uint8Array([1, 2, 3]).buffer
64
- const res = new PikkuFetchHTTPResponse().arrayBuffer(buffer).toResponse()
65
-
66
- assert.strictEqual(
67
- res.headers.get('Content-Type'),
68
- 'application/octet-stream'
69
- )
70
- const body = await res.arrayBuffer()
71
- assert.deepEqual(new Uint8Array(body), new Uint8Array([1, 2, 3]))
72
- })
73
-
74
- test('redirect sets Location header and status', () => {
75
- const res = new PikkuFetchHTTPResponse()
76
- .redirect('/login', 301)
77
- .toResponse()
78
-
79
- assert.strictEqual(res.status, 301)
80
- assert.strictEqual(res.headers.get('Location'), '/login')
81
- })
82
- })
@@ -1,84 +0,0 @@
1
- import { PikkuHTTPResponse } from './http-routes.types.js'
2
- import {
3
- SerializeOptions as CookieSerializeOptions,
4
- serialize as serializeCookie,
5
- } from 'cookie'
6
-
7
- export class PikkuFetchHTTPResponse implements PikkuHTTPResponse {
8
- #statusCode: number = 200
9
- #headers = new Headers()
10
- #cookies = new Map<string, { value: string; flags: CookieSerializeOptions }>()
11
-
12
- #body: BodyInit | null = null
13
-
14
- public status(code: number): this {
15
- this.#statusCode = code
16
- return this
17
- }
18
-
19
- public cookie(
20
- name: string,
21
- value: string,
22
- flags: CookieSerializeOptions
23
- ): this {
24
- this.#cookies.set(name, { value, flags })
25
- return this
26
- }
27
-
28
- public header(name: string, value: string | string[]): this {
29
- this.#headers.delete(name)
30
- if (Array.isArray(value)) {
31
- value.forEach((v) => this.#headers.append(name, v))
32
- } else {
33
- this.#headers.set(name, value)
34
- }
35
- return this
36
- }
37
-
38
- public arrayBuffer(data: XMLHttpRequestBodyInit): this {
39
- this.#body = data
40
- this.header('Content-Type', 'application/octet-stream')
41
- return this
42
- }
43
-
44
- public json(data: unknown): this {
45
- this.#body = JSON.stringify(data)
46
- this.header('Content-Type', 'application/json')
47
- return this
48
- }
49
-
50
- public text(content: string): this {
51
- this.#body = content
52
- this.header('Content-Type', 'text/plain')
53
- return this
54
- }
55
-
56
- public html(content: string): this {
57
- this.#body = content
58
- this.header('Content-Type', 'text/html')
59
- return this
60
- }
61
-
62
- public body(body: BodyInit): this {
63
- this.#body = body
64
- return this
65
- }
66
-
67
- public redirect(location: string, status: number = 302): this {
68
- this.#statusCode = status
69
- this.header('Location', location)
70
- return this
71
- }
72
-
73
- public toResponse(args?: Record<string, any>): Response {
74
- const cookieHeader = Array.from(this.#cookies.entries()).map(
75
- ([name, { value, flags }]) => serializeCookie(name, value, flags)
76
- )
77
- this.#headers.set('Set-Cookie', cookieHeader.join(', '))
78
- return new Response(this.#body, {
79
- ...args,
80
- status: this.#statusCode,
81
- headers: this.#headers,
82
- })
83
- }
84
- }
package/src/index.ts DELETED
@@ -1,19 +0,0 @@
1
- /**
2
- * @module @pikku/core
3
- */
4
- export * from './types/core.types.js'
5
- export * from './types/functions.types.js'
6
- export * from './pikku-request.js'
7
- export * from './pikku-response.js'
8
- export * from './services/index.js'
9
- export * from './http/index.js'
10
- export * from './channel/index.js'
11
- export * from './scheduler/index.js'
12
- export * from './errors/index.js'
13
- export * from './middleware/index.js'
14
- export * from './time-utils.js'
15
- export { pikkuState } from './pikku-state.js'
16
- export { runMiddleware } from './middleware-runner.js'
17
- export { addRoute, addMiddleware } from './http/http-route-runner.js'
18
- export { addChannel } from './channel/channel-runner.js'
19
- export { addScheduledTask } from './scheduler/scheduler-runner.js'
@@ -1,65 +0,0 @@
1
- import {
2
- CoreConfig,
3
- CoreSingletonServices,
4
- CoreUserSession,
5
- PikkuMiddleware,
6
- } from '../types/core.types.js'
7
-
8
- /**
9
- * API key middleware that retrieves a session from the 'x-api-key' header using a provided callback.
10
- *
11
- * @param options.getSessionForAPIKey - A function that returns a session when provided an API key.
12
- */
13
- export const authAPIKey = <
14
- SingletonServices extends CoreSingletonServices<CoreConfig>,
15
- UserSession extends CoreUserSession,
16
- >({
17
- source,
18
- getSessionForAPIKey,
19
- jwt,
20
- }: {
21
- source: 'header' | 'query' | 'all'
22
- } & (
23
- | {
24
- getSessionForAPIKey?: undefined
25
- jwt?: true
26
- }
27
- | {
28
- getSessionForAPIKey: (
29
- services: SingletonServices,
30
- apiKey: string
31
- ) => Promise<any>
32
- jwt?: false
33
- }
34
- )) => {
35
- const middleware: PikkuMiddleware = async (services, { http }, next) => {
36
- if (!http?.request || services.userSession.get()) {
37
- return next()
38
- }
39
-
40
- let apiKey: string | null = null
41
- if (source === 'header' || source === 'all') {
42
- apiKey = http.request.header('x-api-key') as string | null
43
- }
44
- if (!apiKey && (source === 'query' || source === 'all')) {
45
- apiKey = http.request.query().apiKey as string | null
46
- }
47
- if (apiKey) {
48
- let userSession: UserSession | null = null
49
- if (jwt) {
50
- if (!services.jwt) {
51
- throw new Error('JWT service is required for JWT decoding.')
52
- }
53
- userSession = await services.jwt.decode(apiKey)
54
- } else {
55
- userSession = await getSessionForAPIKey!(services as any, apiKey)
56
- }
57
- if (userSession) {
58
- services.userSession.setInitial(userSession)
59
- }
60
- }
61
- return next()
62
- }
63
-
64
- return middleware
65
- }
@@ -1,65 +0,0 @@
1
- import { InvalidSessionError } from '../errors/errors.js'
2
- import {
3
- CoreConfig,
4
- CoreSingletonServices,
5
- CoreUserSession,
6
- PikkuMiddleware,
7
- } from '../types/core.types.js'
8
-
9
- /**
10
- * Extracts the Bearer token from the Authorization header
11
- */
12
- export const authBearer = <
13
- SingletonServices extends CoreSingletonServices<CoreConfig>,
14
- UserSession extends CoreUserSession,
15
- >({
16
- token,
17
- jwt,
18
- getSession,
19
- }: {
20
- token?: {
21
- value: string
22
- userSession: UserSession
23
- }
24
- jwt?: boolean
25
- getSession?: (
26
- services: SingletonServices,
27
- token: string
28
- ) => Promise<UserSession> | UserSession
29
- } = {}): PikkuMiddleware => {
30
- const middleware: PikkuMiddleware = async (services, { http }, next) => {
31
- // Skip if session already exists.
32
- if (!http?.request || services.userSession.get()) {
33
- return next()
34
- }
35
-
36
- const authHeader =
37
- http.request.header('authorization') ||
38
- http.request.header('Authorization')
39
- if (authHeader) {
40
- const [scheme, bearerToken] = authHeader.split(' ')
41
- if (scheme !== 'Bearer' || !token || !bearerToken) {
42
- throw new InvalidSessionError()
43
- }
44
- let userSession: UserSession | null = null
45
- if (jwt) {
46
- if (!services.jwt) {
47
- throw new Error('JWT service is required for JWT decoding.')
48
- }
49
- userSession = await services.jwt.decode(bearerToken)
50
- } else if (token) {
51
- if (bearerToken === token.value) {
52
- userSession = token.userSession
53
- }
54
- } else if (getSession) {
55
- userSession = await getSession(services as any, token)
56
- }
57
-
58
- if (userSession) {
59
- services.userSession.setInitial(userSession)
60
- }
61
- }
62
- return next()
63
- }
64
- return middleware
65
- }
@@ -1,98 +0,0 @@
1
- import { SerializeOptions } from 'cookie'
2
- import {
3
- CoreConfig,
4
- CoreSingletonServices,
5
- CoreUserSession,
6
- PikkuMiddleware,
7
- } from '../types/core.types.js'
8
- import {
9
- getRelativeTimeOffsetFromNow,
10
- RelativeTimeInput,
11
- } from '../time-utils.js'
12
-
13
- /**
14
- * Cookie middleware that extracts a session from cookies.
15
- *
16
- * @param options.name - List of cookie names to check.
17
- * @param options.getSessionForCookieValue - Function to retrieve a session using a cookie value.
18
- */
19
- export const authCookie = <
20
- SingletonServices extends CoreSingletonServices<CoreConfig>,
21
- UserSession extends CoreUserSession,
22
- >({
23
- name,
24
- getSessionForCookieValue,
25
- jwt,
26
- options,
27
- expiresIn,
28
- }: {
29
- name: string
30
- options: SerializeOptions
31
- expiresIn: RelativeTimeInput
32
- } & (
33
- | {
34
- getSessionForCookieValue: (
35
- services: SingletonServices,
36
- cookieValue: string,
37
- cookieName: string
38
- ) => Promise<UserSession>
39
- jwt?: false
40
- }
41
- | {
42
- getSessionForCookieValue?: undefined
43
- jwt: true
44
- }
45
- )): PikkuMiddleware => {
46
- const middleware: PikkuMiddleware = async (services, { http }, next) => {
47
- if (!http?.request || services.userSession.get()) {
48
- return next()
49
- }
50
-
51
- let userSession: UserSession | null = null
52
- const cookieValue = http.request.cookie(name)
53
- if (cookieValue) {
54
- if (jwt) {
55
- if (!services.jwt) {
56
- throw new Error('JWT service is required for JWT decoding.')
57
- }
58
- userSession = await services.jwt.decode(cookieValue)
59
- } else if (getSessionForCookieValue) {
60
- userSession = await getSessionForCookieValue(
61
- services as any,
62
- cookieValue,
63
- name
64
- )
65
- }
66
- }
67
-
68
- if (userSession) {
69
- services.userSession.setInitial(userSession)
70
- }
71
- await next()
72
-
73
- // Set the cookie in the response if the session has changed
74
- if (!http?.response) {
75
- return
76
- }
77
-
78
- if (services.userSession.sessionChanged) {
79
- const session = services.userSession.get()
80
- if (jwt) {
81
- if (!services.jwt) {
82
- throw new Error('JWT service is required for JWT encoding.')
83
- }
84
- http.response.cookie(
85
- name,
86
- await services.jwt.encode(expiresIn, session),
87
- {
88
- ...options,
89
- expires: getRelativeTimeOffsetFromNow(expiresIn),
90
- }
91
- )
92
- } else {
93
- services.logger.warn('No JWT service available, unable to set cookie')
94
- }
95
- }
96
- }
97
- return middleware
98
- }
@@ -1,3 +0,0 @@
1
- export * from './auth-apikey.js'
2
- export * from './auth-cookie.js'
3
- export * from './auth-bearer.js'
@@ -1,13 +0,0 @@
1
- import { RequestTimeoutError } from '../errors/errors.js'
2
- import { PikkuMiddleware } from '../types/core.types.js'
3
-
4
- export const timeout = (timeout: number) => {
5
- const middleware: PikkuMiddleware = async (_services, _interaction, next) => {
6
- setTimeout(() => {
7
- throw new RequestTimeoutError()
8
- }, timeout)
9
-
10
- await next()
11
- }
12
- return middleware
13
- }
@@ -1,43 +0,0 @@
1
- import { UserSessionService } from './services/user-session-service.js'
2
- import {
3
- CoreSingletonServices,
4
- PikkuInteraction,
5
- PikkuMiddleware,
6
- } from './types/core.types.js'
7
-
8
- /**
9
- * Runs a chain of middleware functions in sequence before executing the main function.
10
- *
11
- * @param services - An object containing services (e.g., singletonServices, userSession, etc.)
12
- * @param interaction - The interaction context, e.g., { http }.
13
- * @param middlewares - An array of middleware functions to run.
14
- * @param main - The main function to execute after all middleware have run.
15
- * @returns A promise resolving to the result of the main function.
16
- *
17
- * @example
18
- * runMiddleware(
19
- * { ...services, userSession },
20
- * { http },
21
- * [middleware1, middleware2, middleware3],
22
- * async () => { return await runMain(); }
23
- * );
24
- */
25
- export const runMiddleware = async (
26
- services: CoreSingletonServices & {
27
- userSession: UserSessionService<any>
28
- },
29
- interaction: PikkuInteraction,
30
- middlewares: PikkuMiddleware[],
31
- main?: () => Promise<void>
32
- ): Promise<void> => {
33
- const dispatch = async (index: number): Promise<any> => {
34
- if (middlewares && index < middlewares.length) {
35
- await middlewares[index]!(services, interaction, () =>
36
- dispatch(index + 1)
37
- )
38
- } else if (main) {
39
- return await main()
40
- }
41
- }
42
- await dispatch(0)
43
- }
@@ -1,58 +0,0 @@
1
- import { test, describe } from 'node:test'
2
- import assert from 'assert'
3
- import { getErrorResponse, addError } from './errors/error-handler.js'
4
- import {
5
- ForbiddenError,
6
- BadRequestError,
7
- NotFoundError,
8
- } from './errors/errors.js'
9
-
10
- describe('getErrorResponse', () => {
11
- test('should return the correct error response for BadRequestError', () => {
12
- const error = new BadRequestError()
13
- const response = getErrorResponse(error)
14
- assert.deepStrictEqual(response, {
15
- status: 400,
16
- message:
17
- 'The server cannot or will not process the request due to client error (e.g., malformed request syntax).',
18
- })
19
- })
20
-
21
- test('should return the correct error response for NotFoundError', () => {
22
- const error = new NotFoundError()
23
- const response = getErrorResponse(error)
24
- assert.deepStrictEqual(response, {
25
- status: 404,
26
- message: 'The server cannot find the requested resource.',
27
- })
28
- })
29
-
30
- test('should return the correct error response for ForbiddenError', () => {
31
- const error = new ForbiddenError()
32
- const response = getErrorResponse(error)
33
- assert.deepStrictEqual(response, {
34
- status: 403,
35
- message:
36
- 'The client does not have permission to access the requested resource.',
37
- })
38
- })
39
-
40
- test('should return undefined for an unknown error', () => {
41
- class UnknownError extends Error {}
42
- const error = new UnknownError()
43
- const response = getErrorResponse(error)
44
- assert.strictEqual(response, undefined)
45
- })
46
-
47
- test('should return the correct error response for a custom error added to apiErrors', () => {
48
- class CustomError extends Error {}
49
- const customError = new CustomError()
50
- const customErrorDetails = { status: 400, message: 'Custom Error' }
51
-
52
- // Add the custom error to the apiErrors map
53
- addError(CustomError, customErrorDetails)
54
-
55
- const response = getErrorResponse(customError)
56
- assert.deepStrictEqual(response, customErrorDetails)
57
- })
58
- })
@@ -1,45 +0,0 @@
1
- import { CoreServices, CoreUserSession } from './types/core.types.js'
2
- import { CoreAPIPermission } from './types/functions.types.js'
3
-
4
- /**
5
- * This function validates permissions by iterating over permission groups and executing the corresponding permission functions. If all functions in at least one group return true, the permission is considered valid.
6
- * @param services - The core services required for permission validation.
7
- * @param data - The data to be used in the permission validation functions.
8
- * @param session - An optional user session for permission validation.
9
- * @returns A promise that resolves to void.
10
- */
11
- export const verifyPermissions = async (
12
- permissions:
13
- | Record<string, CoreAPIPermission<any>[] | CoreAPIPermission<any>>
14
- | undefined,
15
- services: CoreServices,
16
- data: any,
17
- session?: CoreUserSession
18
- ): Promise<boolean> => {
19
- if (!permissions) {
20
- return true
21
- }
22
-
23
- let valid = false
24
- const permissionGroups = Object.values(permissions)
25
- if (permissionGroups.length === 0) {
26
- return true
27
- }
28
-
29
- for (const funcs of permissionGroups) {
30
- if (funcs instanceof Array) {
31
- const permissioned = await Promise.all(
32
- funcs.map((func) => func(services, data, session))
33
- )
34
- if (permissioned.every((result) => result)) {
35
- valid = true
36
- }
37
- } else {
38
- valid = await funcs(services, data, session)
39
- }
40
- if (valid) {
41
- return true
42
- }
43
- }
44
- return false
45
- }
@@ -1,23 +0,0 @@
1
- /**
2
- * Simplest class to represent a pikku request.
3
- * @template In - The type of the request body.
4
- * @group RequestResponse
5
- */
6
- export abstract class PikkuRequest<In = any> {
7
- #data: In | undefined
8
-
9
- constructor(data: In) {
10
- this.#data = data
11
- }
12
-
13
- /**
14
- * Retrieves the data
15
- * @returns A promise that resolves to an object containing the combined data.
16
- */
17
- public async data(): Promise<In> {
18
- if (!this.#data) {
19
- throw new Error('Data not found')
20
- }
21
- return this.#data
22
- }
23
- }
@@ -1,5 +0,0 @@
1
- /**
2
- * Abstract class representing a pikku response.
3
- * @group RequestResponse
4
- */
5
- export abstract class PikkuResponse {}
@@ -1,71 +0,0 @@
1
- import { ChannelsMeta, CoreAPIChannels } from './channel/channel.types.js'
2
- import {
3
- CoreHTTPFunctionRoutes,
4
- HTTPRoutesMeta,
5
- } from './http/http-routes.types.js'
6
- import { PikkuMiddleware } from './types/core.types.js'
7
- import {
8
- CoreScheduledTask,
9
- ScheduledTasksMeta,
10
- } from './scheduler/scheduler.types.js'
11
- import { ErrorDetails, PikkuError } from './errors/error-handler.js'
12
-
13
- interface PikkuState {
14
- http: {
15
- middleware: Array<{ route: string; middleware: PikkuMiddleware[] }>
16
- routes: CoreHTTPFunctionRoutes
17
- meta: HTTPRoutesMeta
18
- }
19
- channel: {
20
- channels: CoreAPIChannels
21
- meta: ChannelsMeta
22
- }
23
- scheduler: {
24
- tasks: Map<string, CoreScheduledTask>
25
- meta: ScheduledTasksMeta
26
- }
27
- misc: {
28
- errors: Map<PikkuError, ErrorDetails>
29
- schemas: Map<string, any>
30
- }
31
- }
32
-
33
- export const resetPikkuState = () => {
34
- globalThis.pikkuState = {
35
- http: {
36
- middleware: [],
37
- routes: [],
38
- meta: [],
39
- },
40
- channel: {
41
- channels: [],
42
- meta: [],
43
- },
44
- scheduler: {
45
- tasks: new Map(),
46
- meta: [],
47
- },
48
- misc: {
49
- errors: globalThis.pikkuState?.misc?.errors || new Map(),
50
- schemas: globalThis.pikkuState?.misc?.schema || new Map(),
51
- },
52
- }
53
- }
54
-
55
- if (!globalThis.pikkuState) {
56
- resetPikkuState()
57
- }
58
-
59
- export const pikkuState = <
60
- Type extends keyof PikkuState,
61
- Content extends keyof PikkuState[Type],
62
- >(
63
- type: Type,
64
- content: Content,
65
- value?: PikkuState[Type][Content]
66
- ): PikkuState[Type][Content] => {
67
- if (value) {
68
- globalThis.pikkuState[type][content] = value
69
- }
70
- return globalThis.pikkuState[type][content]
71
- }
@@ -1,5 +0,0 @@
1
- export * from './scheduler.types.js'
2
-
3
- export { runScheduledTask, addScheduledTask } from './scheduler-runner.js'
4
-
5
- export * from './log-schedulers.js'