@postxl/generators 1.18.0 → 1.20.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 (100) hide show
  1. package/dist/backend-actions/actions.generator.d.ts +1 -0
  2. package/dist/backend-actions/actions.generator.js +6 -0
  3. package/dist/backend-actions/actions.generator.js.map +1 -1
  4. package/dist/backend-actions/generators/actions-module.generator.js +3 -2
  5. package/dist/backend-actions/generators/actions-module.generator.js.map +1 -1
  6. package/dist/backend-actions/generators/authorization-policy-service.generator.d.ts +2 -0
  7. package/dist/backend-actions/generators/authorization-policy-service.generator.js +334 -0
  8. package/dist/backend-actions/generators/authorization-policy-service.generator.js.map +1 -0
  9. package/dist/backend-actions/generators/authorization-service.generator.d.ts +1 -1
  10. package/dist/backend-actions/generators/authorization-service.generator.js +20 -8
  11. package/dist/backend-actions/generators/authorization-service.generator.js.map +1 -1
  12. package/dist/backend-actions/generators/dispatcher-service.generator.js +10 -3
  13. package/dist/backend-actions/generators/dispatcher-service.generator.js.map +1 -1
  14. package/dist/backend-actions/generators/execution-class.generator.js +25 -4
  15. package/dist/backend-actions/generators/execution-class.generator.js.map +1 -1
  16. package/dist/backend-actions/generators/execution-interface.generator.js +4 -2
  17. package/dist/backend-actions/generators/execution-interface.generator.js.map +1 -1
  18. package/dist/backend-ai/generators/ai-route.generator.js +3 -3
  19. package/dist/backend-authentication/authentication.generator.js +22 -1
  20. package/dist/backend-authentication/authentication.generator.js.map +1 -1
  21. package/dist/backend-authentication/generators/auth-guard.generator.js +5 -8
  22. package/dist/backend-authentication/generators/auth-guard.generator.js.map +1 -1
  23. package/dist/backend-authentication/generators/authentication-module.generator.js +1 -1
  24. package/dist/backend-authentication/generators/authentication-service.generator.js +11 -8
  25. package/dist/backend-authentication/generators/authentication-service.generator.js.map +1 -1
  26. package/dist/backend-authentication/generators/authentication-types.generator.js +4 -3
  27. package/dist/backend-authentication/generators/authentication-types.generator.js.map +1 -1
  28. package/dist/backend-authentication/template/src/authentication.config.ts +9 -0
  29. package/dist/backend-authentication/template/src/authentication.mock.service.ts +77 -13
  30. package/dist/backend-authentication/template/src/utils.ts +45 -0
  31. package/dist/backend-core/backend.generator.js +17 -1
  32. package/dist/backend-core/backend.generator.js.map +1 -1
  33. package/dist/backend-core/generators/api-config.generator.js +5 -0
  34. package/dist/backend-core/generators/api-config.generator.js.map +1 -1
  35. package/dist/backend-core/types.d.ts +4 -0
  36. package/dist/backend-excel-io/generators/excel-io-service.generator.js +27 -11
  37. package/dist/backend-excel-io/generators/excel-io-service.generator.js.map +1 -1
  38. package/dist/backend-excel-io/template/excel-io.controller.ts +3 -3
  39. package/dist/backend-rest-api/generators/model-controller.generator.js +9 -5
  40. package/dist/backend-rest-api/generators/model-controller.generator.js.map +1 -1
  41. package/dist/backend-rest-api/template/restApi/src/restApi.utils.ts +9 -0
  42. package/dist/backend-router-trpc/generators/audit-log-route.generator.js +2 -2
  43. package/dist/backend-router-trpc/generators/excel-io-route.generator.js +1 -1
  44. package/dist/backend-router-trpc/generators/middleware.generator.js +8 -5
  45. package/dist/backend-router-trpc/generators/middleware.generator.js.map +1 -1
  46. package/dist/backend-router-trpc/generators/model-routes.generator.js +27 -7
  47. package/dist/backend-router-trpc/generators/model-routes.generator.js.map +1 -1
  48. package/dist/backend-router-trpc/generators/trpc-plugin.generator.js +9 -6
  49. package/dist/backend-router-trpc/generators/trpc-plugin.generator.js.map +1 -1
  50. package/dist/backend-router-trpc/generators/trpc-shared.generator.js +4 -24
  51. package/dist/backend-router-trpc/generators/trpc-shared.generator.js.map +1 -1
  52. package/dist/backend-router-trpc/router-trpc.generator.d.ts +4 -0
  53. package/dist/backend-router-trpc/router-trpc.generator.js +1 -0
  54. package/dist/backend-router-trpc/router-trpc.generator.js.map +1 -1
  55. package/dist/backend-router-trpc/template/viewer.router.ts +1 -6
  56. package/dist/backend-update/model-update-service.generator.js +72 -9
  57. package/dist/backend-update/model-update-service.generator.js.map +1 -1
  58. package/dist/backend-update/update-actions.decoders.d.ts +4 -4
  59. package/dist/backend-upload/template/src/upload.controller.ts +1 -1
  60. package/dist/backend-upload/template/src/upload.service.ts +11 -5
  61. package/dist/backend-view/model-view-service.generator.js +110 -52
  62. package/dist/backend-view/model-view-service.generator.js.map +1 -1
  63. package/dist/backend-view/view.generator.d.ts +2 -1
  64. package/dist/backend-view/view.generator.js +8 -1
  65. package/dist/backend-view/view.generator.js.map +1 -1
  66. package/dist/base/base.generator.js +2 -0
  67. package/dist/base/base.generator.js.map +1 -1
  68. package/dist/e2e/template/e2e/specs/example.spec.ts-snapshots/Navigate-to-homepage-and-take-snapshot-1-chromium-linux.png +0 -0
  69. package/dist/frontend-admin/admin.generator.js +2 -0
  70. package/dist/frontend-admin/admin.generator.js.map +1 -1
  71. package/dist/frontend-admin/generators/authorization-utils.generator.d.ts +1 -0
  72. package/dist/frontend-admin/generators/authorization-utils.generator.js +20 -0
  73. package/dist/frontend-admin/generators/authorization-utils.generator.js.map +1 -0
  74. package/dist/frontend-admin/generators/comment-sidebar.generator.js +9 -1
  75. package/dist/frontend-admin/generators/comment-sidebar.generator.js.map +1 -1
  76. package/dist/frontend-admin/generators/model-admin-page.generator.js +347 -184
  77. package/dist/frontend-admin/generators/model-admin-page.generator.js.map +1 -1
  78. package/dist/frontend-core/frontend.generator.d.ts +6 -0
  79. package/dist/frontend-core/frontend.generator.js +10 -3
  80. package/dist/frontend-core/frontend.generator.js.map +1 -1
  81. package/dist/frontend-core/template/README.md +2 -0
  82. package/dist/frontend-core/template/src/context-providers/auth-context-provider.tsx +1 -2
  83. package/dist/frontend-core/template/src/pages/dashboard/dashboard.page.tsx +10 -1
  84. package/dist/frontend-core/template/src/pages/login/login.page.tsx +1 -1
  85. package/dist/frontend-core/template/vite.config.ts +5 -0
  86. package/dist/frontend-core/types/component.d.ts +1 -1
  87. package/dist/frontend-core/types/contextprovider.d.ts +1 -1
  88. package/dist/frontend-core/types/hook.d.ts +1 -1
  89. package/dist/frontend-forms/generators/discriminated-union/inputs.generator.js +1 -1
  90. package/dist/frontend-forms/generators/discriminated-union/inputs.generator.js.map +1 -1
  91. package/dist/frontend-forms/generators/enum/inputs.generator.js +1 -1
  92. package/dist/frontend-forms/generators/enum/inputs.generator.js.map +1 -1
  93. package/dist/frontend-trpc-client/generators/model-hook.generator.js +104 -39
  94. package/dist/frontend-trpc-client/generators/model-hook.generator.js.map +1 -1
  95. package/dist/frontend-trpc-client/trpc-client.generator.js +28 -14
  96. package/dist/frontend-trpc-client/trpc-client.generator.js.map +1 -1
  97. package/dist/types/types.generator.d.ts +7 -0
  98. package/dist/types/types.generator.js +80 -0
  99. package/dist/types/types.generator.js.map +1 -1
  100. package/package.json +3 -3
@@ -11,7 +11,8 @@ function generateActionExecutionInterface({ actions, types }) {
11
11
  .from(execution.interface.location)
12
12
  .addType(actions.summary.action)
13
13
  .addType(types.modelNames)
14
- .addType(types.user);
14
+ .addType(types.user)
15
+ .addType(types.userRoles);
15
16
  return /* ts */ `
16
17
  ${imports.generate()}
17
18
 
@@ -28,7 +29,8 @@ export const ${execution.interface.toBrandedActionOperationId.name} = (id: strin
28
29
  export interface ${execution.interface.name} {
29
30
  name: string
30
31
  user: User
31
- init({ action, user }: { action: Action; user: User }): Promise<void>
32
+ userRoles: UserRoles
33
+ init({ action, user, userRoles }: { action: Action; user: User; userRoles: UserRoles }): Promise<void>
32
34
 
33
35
  /**
34
36
  * Marks the ActionExecution as finished successfully.
@@ -1 +1 @@
1
- {"version":3,"file":"execution-interface.generator.js","sourceRoot":"","sources":["../../../src/backend-actions/generators/execution-interface.generator.ts"],"names":[],"mappings":";;AAIA,4EAyOC;AA7OD,iDAAmD;AAInD,SAAgB,gCAAgC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAiB;IAChF,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAA;IAC7B,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,GAAG,SAAS,CAAA;IAC/D,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,CAAA;IAErD,MAAM,OAAO,GAAG,2BAAe;QAC7B,EAAE;SACD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC;SAClC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;SAC/B,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;SACzB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAEtB,OAAO,QAAQ,CAAC;EAChB,OAAO,CAAC,QAAQ,EAAE;;cAEN,EAAE;;;iCAGiB,EAAE;;eAEpB,SAAS,CAAC,SAAS,CAAC,0BAA0B,CAAC,IAAI,oBAAoB,EAAE,aAAa,EAAE;;;;;mBAKpF,SAAS,CAAC,SAAS,CAAC,IAAI;;;;;;;;;;;;;;;;;;;IAmBvC,SAAS,CAAC,MAAM,CAAC,KAAK;;;;;;gBAMV,EAAE;;IAEd,SAAS,CAAC,UAAU,CAAC,KAAK;;;;;;gBAMd,EAAE;;IAEd,SAAS,CAAC,MAAM,CAAC,KAAK;;;;;;;;;;gBAUV,EAAE;;IAEd,SAAS,CAAC,UAAU,CAAC,KAAK;;;;;;;;gBAQd,EAAE;;IAEd,SAAS,CAAC,MAAM,CAAC,KAAK;;;;;;;;gBAQV,EAAE;;IAEd,SAAS,CAAC,UAAU,CAAC,KAAK;;;;;;;;gBAQd,EAAE;;IAEd,SAAS,CAAC,KAAK,CAAC,KAAK;;;;;;;;gBAQT,EAAE;;IAEd,SAAS,CAAC,MAAM,CAAC,MAAM;;;;;yBAKF,EAAE;;;;;IAKvB,SAAS,CAAC,UAAU,CAAC,MAAM;;;;;yBAKN,EAAE;;;;;IAKvB,SAAS,CAAC,MAAM,CAAC,MAAM,+DAA+D,EAAE;;IAExF,SAAS,CAAC,UAAU,CAAC,MAAM,gEAAgE,EAAE;;IAE7F,SAAS,CAAC,MAAM,CAAC,MAAM,gDAAgD,EAAE;;IAEzE,SAAS,CAAC,UAAU,CAAC,MAAM,gDAAgD,EAAE;;IAE7E,SAAS,CAAC,KAAK,CAAC,MAAM,8DAA8D,EAAE;;IAEtF,cAAc,CAAC,eAAe;;;;IAI9B,cAAc,CAAC,eAAe;;;;;;;IAO9B,cAAc,CAAC,eAAe;;;;;;;;IAQ9B,cAAc,CAAC,eAAe;;;;;;;;;IAS9B,cAAc,CAAC,eAAe;;;;;;;;;;IAU9B,cAAc,CAAC,eAAe;;;;;;;;;;;IAW9B,cAAc,CAAC,eAAe;;;;;;;;;;;;;IAa9B,cAAc,CAAC,aAAa;;;;;;;;;;IAU5B,cAAc,CAAC,KAAK;;;;;;gBAMR,EAAE;;IAEd,cAAc,CAAC,MAAM;;;;yBAIA,EAAE;;;;IAIvB,cAAc,uDAAuD,EAAE;;CAE1E,CAAA;AACD,CAAC"}
1
+ {"version":3,"file":"execution-interface.generator.js","sourceRoot":"","sources":["../../../src/backend-actions/generators/execution-interface.generator.ts"],"names":[],"mappings":";;AAIA,4EA2OC;AA/OD,iDAAmD;AAInD,SAAgB,gCAAgC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAiB;IAChF,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAA;IAC7B,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,GAAG,SAAS,CAAA;IAC/D,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,CAAA;IAErD,MAAM,OAAO,GAAG,2BAAe;QAC7B,EAAE;SACD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC;SAClC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;SAC/B,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;SACzB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;SACnB,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IAE3B,OAAO,QAAQ,CAAC;EAChB,OAAO,CAAC,QAAQ,EAAE;;cAEN,EAAE;;;iCAGiB,EAAE;;eAEpB,SAAS,CAAC,SAAS,CAAC,0BAA0B,CAAC,IAAI,oBAAoB,EAAE,aAAa,EAAE;;;;;mBAKpF,SAAS,CAAC,SAAS,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;IAoBvC,SAAS,CAAC,MAAM,CAAC,KAAK;;;;;;gBAMV,EAAE;;IAEd,SAAS,CAAC,UAAU,CAAC,KAAK;;;;;;gBAMd,EAAE;;IAEd,SAAS,CAAC,MAAM,CAAC,KAAK;;;;;;;;;;gBAUV,EAAE;;IAEd,SAAS,CAAC,UAAU,CAAC,KAAK;;;;;;;;gBAQd,EAAE;;IAEd,SAAS,CAAC,MAAM,CAAC,KAAK;;;;;;;;gBAQV,EAAE;;IAEd,SAAS,CAAC,UAAU,CAAC,KAAK;;;;;;;;gBAQd,EAAE;;IAEd,SAAS,CAAC,KAAK,CAAC,KAAK;;;;;;;;gBAQT,EAAE;;IAEd,SAAS,CAAC,MAAM,CAAC,MAAM;;;;;yBAKF,EAAE;;;;;IAKvB,SAAS,CAAC,UAAU,CAAC,MAAM;;;;;yBAKN,EAAE;;;;;IAKvB,SAAS,CAAC,MAAM,CAAC,MAAM,+DAA+D,EAAE;;IAExF,SAAS,CAAC,UAAU,CAAC,MAAM,gEAAgE,EAAE;;IAE7F,SAAS,CAAC,MAAM,CAAC,MAAM,gDAAgD,EAAE;;IAEzE,SAAS,CAAC,UAAU,CAAC,MAAM,gDAAgD,EAAE;;IAE7E,SAAS,CAAC,KAAK,CAAC,MAAM,8DAA8D,EAAE;;IAEtF,cAAc,CAAC,eAAe;;;;IAI9B,cAAc,CAAC,eAAe;;;;;;;IAO9B,cAAc,CAAC,eAAe;;;;;;;;IAQ9B,cAAc,CAAC,eAAe;;;;;;;;;IAS9B,cAAc,CAAC,eAAe;;;;;;;;;;IAU9B,cAAc,CAAC,eAAe;;;;;;;;;;;IAW9B,cAAc,CAAC,eAAe;;;;;;;;;;;;;IAa9B,cAAc,CAAC,aAAa;;;;;;;;;;IAU5B,cAAc,CAAC,KAAK;;;;;;gBAMR,EAAE;;IAEd,cAAc,CAAC,MAAM;;;;yBAIA,EAAE;;;;IAIvB,cAAc,uDAAuD,EAAE;;CAE1E,CAAA;AACD,CAAC"}
@@ -14,15 +14,15 @@ export const ai = router({
14
14
  ask: procedure
15
15
  .use(authMiddleware)
16
16
  .input(zAskTaskInput)
17
- .mutation(async ({ input, ctx }) => ctx.aiAgent.startExecution(input, ctx.user.id)),
17
+ .mutation(async ({ input, ctx }) => ctx.aiAgent.startExecution(input, ctx.viewer.user.id)),
18
18
  step: procedure
19
19
  .use(authMiddleware)
20
20
  .input(zAskStepInput)
21
- .mutation(async ({ input, ctx }) => ctx.aiAgent.continueExecution(input, ctx.user.id)),
21
+ .mutation(async ({ input, ctx }) => ctx.aiAgent.continueExecution(input, ctx.viewer.user.id)),
22
22
  cancel: procedure
23
23
  .use(authMiddleware)
24
24
  .input(z.object({ conversation: z.string() }))
25
- .mutation(({ input, ctx }) => ctx.aiAgent.cancelExecution(input.conversation, ctx.user.id)),
25
+ .mutation(({ input, ctx }) => ctx.aiAgent.cancelExecution(input.conversation, ctx.viewer.user.id)),
26
26
  })
27
27
  `;
28
28
  }
@@ -63,6 +63,7 @@ exports.generator = {
63
63
  code: Generator.ts(`AuthenticationModule.forRoot(config.auth)`),
64
64
  },
65
65
  envConfig: {
66
+ imports: [Generator.ts(`import { parseStringList } from '@authentication/utils'`)],
66
67
  decoder: Generator.ts(`
67
68
  AUTH: zEnvBoolean.optional().default(true),
68
69
  KEYCLOAK_URL: z.string().url().transform((val) => new URL(val)),
@@ -70,10 +71,17 @@ exports.generator = {
70
71
  KEYCLOAK_CLIENT_SECRET: z.string(),
71
72
  KEYCLOAK_REALM: z.string(),
72
73
  KEYCLOAK_REDIRECT_URL: z.string().url().transform((val) => new URL(val)),
73
- KEYCLOAK_LOGOUT_REDIRECT_URL: z.string().url().transform((val) => new URL(val)),`),
74
+ KEYCLOAK_LOGOUT_REDIRECT_URL: z.string().url().transform((val) => new URL(val)),
75
+ AUTH_MOCK_SUB: z.string().optional(),
76
+ AUTH_MOCK_NAME: z.string().optional(),
77
+ AUTH_MOCK_EMAIL: z.string().optional(),
78
+ AUTH_MOCK_ROLES: z.string().optional(),
79
+ AUTH_MOCK_GROUPS: z.string().optional(),
80
+ AUTH_TEST_OVERRIDES: zEnvBoolean.optional().default(false),`),
74
81
  transformer: Generator.ts(`
75
82
  auth: val.AUTH ? {
76
83
  enableAuthentication: true as const,
84
+ roleClaimPath: ${JSON.stringify(context.schema.auth?.roleClaimPath ?? 'realm_access.roles')},
77
85
  url: val.API_URL,
78
86
  urlPrefix: val.API_PREFIX,
79
87
 
@@ -89,6 +97,14 @@ exports.generator = {
89
97
  postLogoutRedirectUrl: val.KEYCLOAK_LOGOUT_REDIRECT_URL,
90
98
  } : {
91
99
  enableAuthentication: false as const,
100
+ mockIdentity: {
101
+ sub: val.AUTH_MOCK_SUB ?? 'test',
102
+ name: val.AUTH_MOCK_NAME ?? 'Test User',
103
+ email: val.AUTH_MOCK_EMAIL ?? 'test@postxl.com',
104
+ roles: parseStringList(val.AUTH_MOCK_ROLES, ['viewer']),
105
+ groups: parseStringList(val.AUTH_MOCK_GROUPS),
106
+ },
107
+ allowTestOverrides: val.AUTH_TEST_OVERRIDES,
92
108
  }`),
93
109
  dotEnvExample: `
94
110
  KEYCLOAK_URL=http://localhost:8080
@@ -97,6 +113,11 @@ exports.generator = {
97
113
  KEYCLOAK_REALM=postxl
98
114
  KEYCLOAK_REDIRECT_URL=\${API_URL}/auth/callback
99
115
  KEYCLOAK_LOGOUT_REDIRECT_URL=\${FRONTEND_URL}
116
+ AUTH_MOCK_SUB=test
117
+ AUTH_MOCK_NAME="Test User"
118
+ AUTH_MOCK_EMAIL=test@postxl.com
119
+ AUTH_MOCK_GROUPS=
120
+ AUTH_TEST_OVERRIDES=false
100
121
  `,
101
122
  },
102
123
  };
@@ -1 +1 @@
1
- {"version":3,"file":"authentication.generator.js","sourceRoot":"","sources":["../../src/backend-authentication/authentication.generator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authentication.generator.js","sourceRoot":"","sources":["../../src/backend-authentication/authentication.generator.ts"],"names":[],"mappings":"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"}
@@ -39,7 +39,6 @@ function generateAuthGuard(context) {
39
39
  const imports = Generator.ImportGenerator.from(context.authentication.guard._filePath);
40
40
  imports.add(context.view.service);
41
41
  imports.add(context.actions.dispatcher);
42
- imports.add(context.types.user);
43
42
  imports.add({ name: context.authentication.service.name, location: context.authentication.service._filePath });
44
43
  return /* ts */ `
45
44
  import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'
@@ -48,9 +47,10 @@ import { FastifyRequest } from 'fastify'
48
47
 
49
48
  ${imports.generate()}
50
49
 
51
- import { UserInfo, UserRoles } from './authentication.types'
50
+ import type { AuthorizationContext } from '@types'
51
+ import { UserInfo } from './authentication.types'
52
52
 
53
- export type Viewer = { userInfo: UserInfo; userRoles: UserRoles; user: User; isAuthorized: boolean }
53
+ export type Viewer = AuthorizationContext
54
54
 
55
55
  export type FastifyRequestWithViewer = FastifyRequest & { viewer: Viewer }
56
56
  @Injectable()
@@ -68,10 +68,7 @@ export class ${context.authentication.guard.name} implements CanActivate {
68
68
  let viewer: Viewer | null = null
69
69
 
70
70
  let userInfo: UserInfo | null = null
71
- let userRoles: UserRoles = []
72
-
73
- // TODO: Add authorization check
74
- const isAuthorized = true
71
+ let userRoles: Viewer['userRoles'] = []
75
72
 
76
73
  const associatedUserInfo = await this.authService.getUserInfoFromRequest(req)
77
74
 
@@ -105,7 +102,7 @@ export class ${context.authentication.guard.name} implements CanActivate {
105
102
  }
106
103
  }
107
104
 
108
- viewer = { userInfo, userRoles, user, isAuthorized }
105
+ viewer = { userRoles, user }
109
106
  }
110
107
 
111
108
  if (!viewer) {
@@ -1 +1 @@
1
- {"version":3,"file":"auth-guard.generator.js","sourceRoot":"","sources":["../../../src/backend-authentication/generators/auth-guard.generator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,8CAmFC;AAvFD,6DAA8C;AAI9C,SAAgB,iBAAiB,CAAC,OAAsB;IACtD,MAAM,OAAO,GAAG,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IAEtF,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACjC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IACvC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC/B,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;IAC9G,OAAO,QAAQ,CAAC;;;;;EAKhB,OAAO,CAAC,QAAQ,EAAE;;;;;;;;eAQL,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI;;oCAEZ,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI;oCACnC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI;0CACnB,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0DvE,CAAA;AACF,CAAC"}
1
+ {"version":3,"file":"auth-guard.generator.js","sourceRoot":"","sources":["../../../src/backend-authentication/generators/auth-guard.generator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,8CAgFC;AApFD,6DAA8C;AAI9C,SAAgB,iBAAiB,CAAC,OAAsB;IACtD,MAAM,OAAO,GAAG,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IAEtF,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACjC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IACvC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;IAC9G,OAAO,QAAQ,CAAC;;;;;EAKhB,OAAO,CAAC,QAAQ,EAAE;;;;;;;;;eASL,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI;;oCAEZ,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI;oCACnC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI;0CACnB,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuDvE,CAAA;AACF,CAAC"}
@@ -63,7 +63,7 @@ export class ${context.authentication.module.name} {
63
63
  }
64
64
  : {
65
65
  provide: ${context.authentication.service.name},
66
- useClass: MockAuthenticationService,
66
+ useValue: new MockAuthenticationService(config),
67
67
  }
68
68
 
69
69
  return {
@@ -14,9 +14,12 @@ import jwt from 'jsonwebtoken'
14
14
  import { JwksClient } from 'jwks-rsa'
15
15
  import { OidcClient } from 'oidc-client-ts'
16
16
 
17
+ import { USER_ROLES } from '@types'
18
+ import type { UserRole, UserRoles } from '@types'
19
+
17
20
  import type { AuthenticationConfig_EnabledKeycloak } from './authentication.config'
18
- import { authenticationCookieName, UserInfo, UserRoles, zUserInfo, zUserRoles } from './authentication.types'
19
- import { unknownToErrorMessage } from './utils'
21
+ import { authenticationCookieName, UserInfo, zUserInfo } from './authentication.types'
22
+ import { getByPath, parseStringList, unknownToErrorMessage } from './utils'
20
23
 
21
24
  /**
22
25
  * State object for the authentication service.
@@ -282,14 +285,14 @@ export class ${context.authentication.service.name} implements OnModuleInit {
282
285
  const decoded = await _jwtVerify(accessToken, getKey, { algorithms: ['RS256'] })
283
286
 
284
287
  if (typeof decoded === 'object' && decoded !== null) {
285
- const rawUserRoles = decoded.realm_access?.roles || []
288
+ const rawUserRoles = getByPath(decoded, this.config.roleClaimPath)
289
+ const normalizedUserRoles = Array.isArray(rawUserRoles) ? rawUserRoles : parseStringList(rawUserRoles)
286
290
 
287
- const userRoles = zUserRoles.safeParse(rawUserRoles)
288
- if (userRoles.success) {
289
- return { ok: true, userRoles: userRoles.data }
290
- }
291
+ const filteredRoles = normalizedUserRoles.filter(
292
+ (role): role is UserRole => typeof role === 'string' && USER_ROLES.includes(role as UserRole),
293
+ )
291
294
 
292
- return { ok: false }
295
+ return { ok: true, userRoles: filteredRoles }
293
296
  }
294
297
 
295
298
  return { ok: true, userRoles: [] }
@@ -1 +1 @@
1
- {"version":3,"file":"authentication-service.generator.js","sourceRoot":"","sources":["../../../src/backend-authentication/generators/authentication-service.generator.ts"],"names":[],"mappings":";;AAEA,sEAoYC;AApYD,SAAgB,6BAA6B,CAAC,OAAsB;IAClE,OAAO,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eA6BH,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI;yCACT,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoW1E,CAAA;AACF,CAAC"}
1
+ {"version":3,"file":"authentication-service.generator.js","sourceRoot":"","sources":["../../../src/backend-authentication/generators/authentication-service.generator.ts"],"names":[],"mappings":";;AAEA,sEAuYC;AAvYD,SAAgB,6BAA6B,CAAC,OAAsB;IAClE,OAAO,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAgCH,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI;yCACT,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoW1E,CAAA;AACF,CAAC"}
@@ -5,6 +5,7 @@ function generateAuthenticationTypes(context) {
5
5
  return /* ts */ `
6
6
  import { z } from 'zod'
7
7
  import { Result } from '@postxl/utils'
8
+ import { USER_ROLES } from '@types'
8
9
  import { Viewer } from '@authentication/auth.guard'
9
10
 
10
11
  /**
@@ -42,12 +43,12 @@ export const z${context.authentication.types.userInfo.name} = z.object({
42
43
  */
43
44
  export type ${context.authentication.types.userInfo.name} = z.infer<typeof z${context.authentication.types.userInfo.name}>
44
45
 
45
- export const z${context.authentication.types.userRoles.name} = z.array(z.enum(['admin', 'user', 'unauthorized']))
46
+ export const zUserRole = z.enum(USER_ROLES)
46
47
 
47
- export type ${context.authentication.types.userRoles.name} = z.infer<typeof z${context.authentication.types.userRoles.name}>
48
+ export const z${context.authentication.types.userRoles.name} = z.array(zUserRole)
48
49
 
49
50
  export type ViewerResult = Result<
50
- Omit<Viewer, 'userInfo'>,
51
+ Viewer,
51
52
  | {
52
53
  type: 'redirect'
53
54
  redirectUrl: string
@@ -1 +1 @@
1
- {"version":3,"file":"authentication-types.generator.js","sourceRoot":"","sources":["../../../src/backend-authentication/generators/authentication-types.generator.ts"],"names":[],"mappings":";;AAEA,kEA2DC;AA3DD,SAAgB,2BAA2B,CAAC,OAAsB;IAChE,OAAO,QAAQ,CAAC;;;;;;KAMb,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI;;;gBAG/B,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2BrD,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI;;cAEjC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,sBAAsB,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI;;gBAExG,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI;;cAE7C,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,sBAAsB,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI;;;;;;;;;;;;;;;CAezH,CAAA;AACD,CAAC"}
1
+ {"version":3,"file":"authentication-types.generator.js","sourceRoot":"","sources":["../../../src/backend-authentication/generators/authentication-types.generator.ts"],"names":[],"mappings":";;AAEA,kEA4DC;AA5DD,SAAgB,2BAA2B,CAAC,OAAsB;IAChE,OAAO,QAAQ,CAAC;;;;;;;KAOb,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI;;;gBAG/B,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2BrD,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI;;cAEjC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,sBAAsB,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI;;;;gBAIxG,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI;;;;;;;;;;;;;;;CAe1D,CAAA;AACD,CAAC"}
@@ -1,9 +1,18 @@
1
1
  export type AuthenticationConfig = AuthenticationConfig_Disabled | AuthenticationConfig_EnabledKeycloak
2
2
  export type AuthenticationConfig_Disabled = {
3
3
  enableAuthentication: false
4
+ mockIdentity: {
5
+ sub: string
6
+ name: string
7
+ email: string
8
+ roles: string[]
9
+ groups: string[]
10
+ }
11
+ allowTestOverrides: boolean
4
12
  }
5
13
  export type AuthenticationConfig_EnabledKeycloak = {
6
14
  enableAuthentication: true
15
+ roleClaimPath: string
7
16
  /**
8
17
  * The URL of the backend server.
9
18
  */
@@ -1,7 +1,14 @@
1
1
  // We import Fastify cookie here to ensure that the cookie plugin and its types are registered.
2
2
  import '@fastify/cookie'
3
3
 
4
- import type { UserInfo, UserRoles } from './authentication.types'
4
+ import type { FastifyRequest } from 'fastify'
5
+
6
+ import type { UserRoles } from '@types'
7
+
8
+ import type { AuthenticationConfig_Disabled } from './authentication.config'
9
+ import { zUserRoles } from './authentication.types'
10
+ import type { UserInfo } from './authentication.types'
11
+ import { parseStringList } from './utils'
5
12
 
6
13
  type MockAuthenticationResult = {
7
14
  /**
@@ -49,6 +56,54 @@ const mockResult: MockAuthenticationResult = {
49
56
 
50
57
  export class MockAuthenticationService {
51
58
  public readonly cookieDomain = 'localhost'
59
+ private readonly mockResult: MockAuthenticationResult
60
+
61
+ constructor(private readonly config: AuthenticationConfig_Disabled) {
62
+ const parsedConfigRoles = zUserRoles.safeParse(config.mockIdentity.roles)
63
+
64
+ this.mockResult = {
65
+ ...mockResult,
66
+ userInfo: {
67
+ ...mockResult.userInfo,
68
+ sub: config.mockIdentity.sub,
69
+ name: config.mockIdentity.name,
70
+ preferred_username: config.mockIdentity.email,
71
+ given_name: config.mockIdentity.name.split(' ').at(0) ?? config.mockIdentity.name,
72
+ family_name: config.mockIdentity.name.split(' ').slice(1).join(' ') || config.mockIdentity.name,
73
+ email: config.mockIdentity.email,
74
+ groups: config.mockIdentity.groups,
75
+ },
76
+ userRoles: parsedConfigRoles.success ? parsedConfigRoles.data : mockResult.userRoles,
77
+ }
78
+ }
79
+
80
+ private parseHeaderRoles(raw: unknown): UserRoles {
81
+ const parsed = zUserRoles.safeParse(parseStringList(raw, this.mockResult.userRoles))
82
+ return parsed.success ? parsed.data : this.mockResult.userRoles
83
+ }
84
+
85
+ private getTestOverrideRoles(req: FastifyRequest | undefined): UserRoles | null {
86
+ // Test override headers are only honored when:
87
+ // - authentication is disabled (`AUTH=false`) and
88
+ // - explicit test overrides are enabled (`AUTH_TEST_OVERRIDES=true`) and
89
+ // - runtime is test (`NODE_ENV=test`)
90
+ if (!this.config.allowTestOverrides || process.env.NODE_ENV !== 'test' || !req) {
91
+ return null
92
+ }
93
+ const rawRoles = req.headers['x-pxl-test-roles']
94
+ return this.parseHeaderRoles(rawRoles)
95
+ }
96
+
97
+ private getTestOverrideSub(req: FastifyRequest | undefined): string | undefined {
98
+ if (!this.config.allowTestOverrides || process.env.NODE_ENV !== 'test' || !req) {
99
+ return undefined
100
+ }
101
+ const rawSub = req.headers['x-pxl-test-sub']
102
+ if (typeof rawSub !== 'string' || rawSub.trim().length === 0) {
103
+ return undefined
104
+ }
105
+ return rawSub.trim()
106
+ }
52
107
 
53
108
  public refreshAccessToken(): Promise<
54
109
  | {
@@ -62,7 +117,7 @@ export class MockAuthenticationService {
62
117
  error: unknown
63
118
  }
64
119
  > {
65
- return Promise.resolve({ ok: true, accessToken: mockResult.accessToken, state: null }) // NOSONAR - We want to adhere to the interface
120
+ return Promise.resolve({ ok: true, accessToken: this.mockResult.accessToken, state: null }) // NOSONAR - We want to adhere to the interface
66
121
  }
67
122
  public getAccessTokenFromURL(): Promise<
68
123
  | {
@@ -75,36 +130,45 @@ export class MockAuthenticationService {
75
130
  error: unknown
76
131
  }
77
132
  > {
78
- return Promise.resolve({ ok: true, accessToken: mockResult.accessToken, state: null }) // NOSONAR - We want to adhere to the interface
133
+ return Promise.resolve({ ok: true, accessToken: this.mockResult.accessToken, state: null }) // NOSONAR - We want to adhere to the interface
79
134
  }
80
135
  public getAuthenticationUrl(): Promise<string> {
81
- return Promise.resolve(mockResult.authRedirectUrl) // NOSONAR - We want to adhere to the interface
136
+ return Promise.resolve(this.mockResult.authRedirectUrl) // NOSONAR - We want to adhere to the interface
82
137
  }
83
138
 
84
- public async getUserInfoFromRequest(): Promise<{ ok: true; userInfo: UserInfo } | { ok: false }> {
85
- const info = await this.getUserInfo()
139
+ public async getUserInfoFromRequest(req?: FastifyRequest): Promise<{ ok: true; userInfo: UserInfo } | { ok: false }> {
140
+ const info = await this.getUserInfo(req)
86
141
 
87
142
  return info
88
143
  }
89
144
 
90
- public getUserInfo(): Promise<{ ok: true; userInfo: UserInfo } | { ok: false }> {
145
+ public getUserInfo(req?: FastifyRequest): Promise<{ ok: true; userInfo: UserInfo } | { ok: false }> {
146
+ const overrideSub = this.getTestOverrideSub(req)
91
147
  // NOSONAR - We want to keep all validations async to adhere to the same interface
92
148
  return Promise.resolve({
93
149
  ok: true,
94
- userInfo: mockResult.userInfo,
150
+ userInfo: {
151
+ ...this.mockResult.userInfo,
152
+ sub: overrideSub ?? this.mockResult.userInfo.sub,
153
+ },
95
154
  })
96
155
  }
97
156
 
98
- public async getUserRolesFromRequest(): Promise<{ ok: true; userRoles: UserRoles } | { ok: false }> {
99
- const roles = await this.getUserRoles()
157
+ public async getUserRolesFromRequest(
158
+ req?: FastifyRequest,
159
+ ): Promise<{ ok: true; userRoles: UserRoles } | { ok: false }> {
160
+ const roles = await this.getUserRoles(req)
100
161
 
101
162
  return roles
102
163
  }
103
164
 
104
- public getUserRoles(): Promise<{ ok: true; userRoles: UserRoles } | { ok: false }> {
105
- return Promise.resolve({ ok: true, userRoles: mockResult.userRoles }) // NOSONAR - We want to adhere to the interface
165
+ public getUserRoles(req?: FastifyRequest): Promise<{ ok: true; userRoles: UserRoles } | { ok: false }> {
166
+ return Promise.resolve({
167
+ ok: true,
168
+ userRoles: this.getTestOverrideRoles(req) ?? this.mockResult.userRoles,
169
+ }) // NOSONAR - We want to adhere to the interface
106
170
  }
107
171
  public getLogoutUrl(): Promise<string> {
108
- return Promise.resolve(mockResult.logoutRedirectUrl) // NOSONAR - We want to adhere to the interface
172
+ return Promise.resolve(this.mockResult.logoutRedirectUrl) // NOSONAR - We want to adhere to the interface
109
173
  }
110
174
  }
@@ -11,3 +11,48 @@ export function unknownToErrorMessage(error: unknown, message: string): string {
11
11
  export const normalizeUrl = (url: string): string => {
12
12
  return url.endsWith('/') ? url : `${url}/`
13
13
  }
14
+
15
+ /**
16
+ * Parses role/group lists from JSON-array or CSV strings.
17
+ */
18
+ export function parseStringList(raw: unknown, fallback: string[] = []): string[] {
19
+ if (typeof raw !== 'string' || raw.trim().length === 0) {
20
+ return fallback
21
+ }
22
+
23
+ try {
24
+ const parsed = JSON.parse(raw)
25
+ if (Array.isArray(parsed)) {
26
+ return parsed
27
+ .filter((entry): entry is string => typeof entry === 'string')
28
+ .map((entry) => entry.trim())
29
+ .filter(Boolean)
30
+ }
31
+ } catch {
32
+ // ignore and use csv fallback
33
+ }
34
+
35
+ return raw
36
+ .split(',')
37
+ .map((entry) => entry.trim())
38
+ .filter(Boolean)
39
+ }
40
+
41
+ /**
42
+ * Resolves a nested value by dot-path (e.g. "realm_access.roles").
43
+ */
44
+ export function getByPath(input: unknown, path: string): unknown {
45
+ if (!path) {
46
+ return undefined
47
+ }
48
+
49
+ let current: unknown = input
50
+ for (const segment of path.split('.').filter(Boolean)) {
51
+ if (typeof current !== 'object' || current === null || !(segment in current)) {
52
+ return undefined
53
+ }
54
+ current = (current as Record<string, unknown>)[segment]
55
+ }
56
+
57
+ return current
58
+ }
@@ -78,7 +78,23 @@ const baseScripts = [
78
78
  { name: 'start', command: 'node ./dist/apps/api/apps/api/src/main.js' },
79
79
  {
80
80
  name: 'dev',
81
- command: 'dotenvx run -f ./apps/api/.env --env STATEFUL=false --env AUTH=false -- nest start --debug --watch',
81
+ command: 'dotenvx run -f ./apps/api/.env --env STATEFUL=false --env AUTH=false --env AUTH_MOCK_ROLES=admin -- nest start --debug --watch',
82
+ },
83
+ {
84
+ name: 'dev:viewer',
85
+ command: 'dotenvx run -f ./apps/api/.env --env STATEFUL=false --env AUTH=false --env AUTH_MOCK_ROLES=viewer -- nest start --debug --watch',
86
+ },
87
+ {
88
+ name: 'dev:editor',
89
+ command: 'dotenvx run -f ./apps/api/.env --env STATEFUL=false --env AUTH=false --env AUTH_MOCK_ROLES=editor -- nest start --debug --watch',
90
+ },
91
+ {
92
+ name: 'dev:admin',
93
+ command: 'dotenvx run -f ./apps/api/.env --env STATEFUL=false --env AUTH=false --env AUTH_MOCK_ROLES=admin -- nest start --debug --watch',
94
+ },
95
+ {
96
+ name: 'dev:superadmin',
97
+ command: 'dotenvx run -f ./apps/api/.env --env STATEFUL=false --env AUTH=false --env AUTH_MOCK_ROLES=superadmin -- nest start --debug --watch',
82
98
  },
83
99
  {
84
100
  name: 'dev:auth',
@@ -1 +1 @@
1
- {"version":3,"file":"backend.generator.js","sourceRoot":"","sources":["../../src/backend-core/backend.generator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"backend.generator.js","sourceRoot":"","sources":["../../src/backend-core/backend.generator.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateApiConfig = generateApiConfig;
4
4
  function generateApiConfig({ backend: { modules } }) {
5
+ const envConfigImports = Array.from(new Set(modules
6
+ .flatMap((module) => module.envConfig?.imports ?? [])
7
+ .map((statement) => statement.trim())
8
+ .filter(Boolean)));
5
9
  return /*ts*/ `
6
10
  import z from 'zod'
11
+ ${envConfigImports.join('\n')}
7
12
 
8
13
  const zEnvBoolean = z.union([
9
14
  //
@@ -1 +1 @@
1
- {"version":3,"file":"api-config.generator.js","sourceRoot":"","sources":["../../../src/backend-core/generators/api-config.generator.ts"],"names":[],"mappings":";;AAEA,8CAgEC;AAhED,SAAgB,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAe;IACrE,OAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA8BV,OAAO;SACN,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;SAC1B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,SAAU,CAAC,OAAO,CAAC,EAAE,CAAC;SAC1D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;SACvB,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;MAeZ,OAAO;SACN,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;SAC1B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,SAAU,CAAC,WAAW,CAAC,EAAE,CAAC;SAC9D,IAAI,CAAC,KAAK,CAAC;;;;;;EAMhB,OAAO;SACN,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC;SAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,SAAU,CAAC,IAAK,CAAC,EAAE,CAAC,CAAC,qDAAqD;SAC9G,IAAI,CAAC,IAAI,CAAC;CACZ,CAAA;AACD,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;AACnC,CAAC"}
1
+ {"version":3,"file":"api-config.generator.js","sourceRoot":"","sources":["../../../src/backend-core/generators/api-config.generator.ts"],"names":[],"mappings":";;AAEA,8CA0EC;AA1ED,SAAgB,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAe;IACrE,MAAM,gBAAgB,GAAG,KAAK,CAAC,IAAI,CACjC,IAAI,GAAG,CACL,OAAO;SACJ,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,IAAI,EAAE,CAAC;SACpD,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;SACpC,MAAM,CAAC,OAAO,CAAC,CACnB,CACF,CAAA;IAED,OAAO,MAAM,CAAC;;EAEd,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA6BvB,OAAO;SACN,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;SAC1B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,SAAU,CAAC,OAAO,CAAC,EAAE,CAAC;SAC1D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;SACvB,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;MAeZ,OAAO;SACN,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;SAC1B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,SAAU,CAAC,WAAW,CAAC,EAAE,CAAC;SAC9D,IAAI,CAAC,KAAK,CAAC;;;;;;EAMhB,OAAO;SACN,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC;SAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,SAAU,CAAC,IAAK,CAAC,EAAE,CAAC,CAAC,qDAAqD;SAC9G,IAAI,CAAC,IAAI,CAAC;CACZ,CAAA;AACD,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;AACnC,CAAC"}
@@ -100,6 +100,10 @@ export type NestJSModule = {
100
100
  vfs?: Generator.VirtualFileSystem;
101
101
  };
102
102
  export type EnvConfig = {
103
+ /**
104
+ * Optional import statements required by decoder/transformer code.
105
+ */
106
+ imports?: Generator.Typescript[];
103
107
  /**
104
108
  * Example:
105
109
  * AWS_ACCESS_KEY: z.string(),