@venizia/ignis-kernel 0.4.6 → 0.4.7-1

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 (174) hide show
  1. package/LICENSE.md +1 -4
  2. package/dist/esm/base/applications/artifact-group.d.ts.map +1 -1
  3. package/dist/esm/base/applications/artifact-group.js +4 -1
  4. package/dist/esm/base/applications/artifact-group.js.map +1 -1
  5. package/dist/esm/base/applications/artifact-index.d.ts.map +1 -1
  6. package/dist/esm/base/applications/artifact-index.js +2 -1
  7. package/dist/esm/base/applications/artifact-index.js.map +1 -1
  8. package/dist/esm/base/applications/cors.d.ts +12 -10
  9. package/dist/esm/base/applications/cors.d.ts.map +1 -1
  10. package/dist/esm/base/applications/cors.js +37 -35
  11. package/dist/esm/base/applications/cors.js.map +1 -1
  12. package/dist/esm/base/applications/rest.js +11 -11
  13. package/dist/esm/base/applications/rest.js.map +1 -1
  14. package/dist/esm/base/auth/authenticate/common/codecs.js +2 -2
  15. package/dist/esm/base/auth/authenticate/common/codecs.js.map +1 -1
  16. package/dist/esm/base/auth/authenticate/strategies/strategy-registry.d.ts +1 -1
  17. package/dist/esm/base/auth/authenticate/strategies/strategy-registry.js +1 -1
  18. package/dist/esm/base/auth/authenticate/strategies/strategy-registry.js.map +1 -1
  19. package/dist/esm/base/auth/authorize/providers/authorization.provider.d.ts.map +1 -1
  20. package/dist/esm/base/auth/authorize/providers/authorization.provider.js +14 -11
  21. package/dist/esm/base/auth/authorize/providers/authorization.provider.js.map +1 -1
  22. package/dist/esm/base/auth/authorize/providers/request-domain.d.ts +14 -11
  23. package/dist/esm/base/auth/authorize/providers/request-domain.d.ts.map +1 -1
  24. package/dist/esm/base/auth/authorize/providers/request-domain.js +42 -39
  25. package/dist/esm/base/auth/authorize/providers/request-domain.js.map +1 -1
  26. package/dist/esm/base/auth/base/abstract-auth-registry.js +2 -2
  27. package/dist/esm/base/auth/base/abstract-auth-registry.js.map +1 -1
  28. package/dist/esm/base/auth/models/requests/change-password.schema.js +3 -3
  29. package/dist/esm/base/auth/models/requests/change-password.schema.js.map +1 -1
  30. package/dist/esm/base/auth/models/requests/sign-in.schema.js +5 -5
  31. package/dist/esm/base/auth/models/requests/sign-in.schema.js.map +1 -1
  32. package/dist/esm/base/components/controller/rest/rest.component.js +2 -2
  33. package/dist/esm/base/components/controller/rest/rest.component.js.map +1 -1
  34. package/dist/esm/base/controllers/common/index.d.ts +0 -1
  35. package/dist/esm/base/controllers/common/index.d.ts.map +1 -1
  36. package/dist/esm/base/controllers/common/index.js +0 -1
  37. package/dist/esm/base/controllers/common/index.js.map +1 -1
  38. package/dist/esm/base/controllers/common/schema-builders.d.ts +0 -5
  39. package/dist/esm/base/controllers/common/schema-builders.d.ts.map +1 -1
  40. package/dist/esm/base/controllers/common/schema-builders.js +0 -14
  41. package/dist/esm/base/controllers/common/schema-builders.js.map +1 -1
  42. package/dist/esm/base/controllers/context.d.ts +7 -2
  43. package/dist/esm/base/controllers/context.d.ts.map +1 -1
  44. package/dist/esm/base/controllers/context.js +7 -4
  45. package/dist/esm/base/controllers/context.js.map +1 -1
  46. package/dist/esm/base/controllers/factory/controller.d.ts +33 -1
  47. package/dist/esm/base/controllers/factory/controller.d.ts.map +1 -1
  48. package/dist/esm/base/controllers/factory/controller.js +90 -6
  49. package/dist/esm/base/controllers/factory/controller.js.map +1 -1
  50. package/dist/esm/base/controllers/factory/crud/persistable.d.ts.map +1 -1
  51. package/dist/esm/base/controllers/factory/crud/persistable.js +40 -25
  52. package/dist/esm/base/controllers/factory/crud/persistable.js.map +1 -1
  53. package/dist/esm/base/controllers/factory/crud/readable.d.ts.map +1 -1
  54. package/dist/esm/base/controllers/factory/crud/readable.js +4 -3
  55. package/dist/esm/base/controllers/factory/crud/readable.js.map +1 -1
  56. package/dist/esm/base/controllers/factory/definition.d.ts +1 -8
  57. package/dist/esm/base/controllers/factory/definition.d.ts.map +1 -1
  58. package/dist/esm/base/controllers/factory/definition.js +17 -24
  59. package/dist/esm/base/controllers/factory/definition.js.map +1 -1
  60. package/dist/esm/base/controllers/factory/index.d.ts +0 -1
  61. package/dist/esm/base/controllers/factory/index.d.ts.map +1 -1
  62. package/dist/esm/base/controllers/factory/index.js +0 -1
  63. package/dist/esm/base/controllers/factory/index.js.map +1 -1
  64. package/dist/esm/base/controllers/rest/abstract.d.ts.map +1 -1
  65. package/dist/esm/base/controllers/rest/abstract.js +6 -6
  66. package/dist/esm/base/controllers/rest/abstract.js.map +1 -1
  67. package/dist/esm/base/controllers/rest/base.d.ts +0 -5
  68. package/dist/esm/base/controllers/rest/base.d.ts.map +1 -1
  69. package/dist/esm/base/controllers/rest/base.js +14 -14
  70. package/dist/esm/base/controllers/rest/base.js.map +1 -1
  71. package/dist/esm/base/datasources/abstract.js +2 -2
  72. package/dist/esm/base/datasources/abstract.js.map +1 -1
  73. package/dist/esm/base/events/event-bus.js +4 -4
  74. package/dist/esm/base/events/event-bus.js.map +1 -1
  75. package/dist/esm/base/metadata/injectable.d.ts +7 -4
  76. package/dist/esm/base/metadata/injectable.d.ts.map +1 -1
  77. package/dist/esm/base/metadata/injectable.js +26 -23
  78. package/dist/esm/base/metadata/injectable.js.map +1 -1
  79. package/dist/esm/base/metadata/model-metadata.d.ts +27 -13
  80. package/dist/esm/base/metadata/model-metadata.d.ts.map +1 -1
  81. package/dist/esm/base/metadata/model-metadata.js +56 -26
  82. package/dist/esm/base/metadata/model-metadata.js.map +1 -1
  83. package/dist/esm/base/metadata/persistents.d.ts.map +1 -1
  84. package/dist/esm/base/metadata/persistents.js +21 -13
  85. package/dist/esm/base/metadata/persistents.js.map +1 -1
  86. package/dist/esm/base/metadata/routes/controller.d.ts.map +1 -1
  87. package/dist/esm/base/metadata/routes/controller.js +5 -2
  88. package/dist/esm/base/metadata/routes/controller.js.map +1 -1
  89. package/dist/esm/base/middlewares/app-error/app-error.middleware.js +7 -7
  90. package/dist/esm/base/middlewares/app-error/app-error.middleware.js.map +1 -1
  91. package/dist/esm/base/middlewares/app-error/database.handler.d.ts +14 -12
  92. package/dist/esm/base/middlewares/app-error/database.handler.d.ts.map +1 -1
  93. package/dist/esm/base/middlewares/app-error/database.handler.js +37 -35
  94. package/dist/esm/base/middlewares/app-error/database.handler.js.map +1 -1
  95. package/dist/esm/base/middlewares/app-error/zod.handler.d.ts +28 -23
  96. package/dist/esm/base/middlewares/app-error/zod.handler.d.ts.map +1 -1
  97. package/dist/esm/base/middlewares/app-error/zod.handler.js +56 -53
  98. package/dist/esm/base/middlewares/app-error/zod.handler.js.map +1 -1
  99. package/dist/esm/base/middlewares/emoji-favicon/emoji-favicon.middleware.d.ts +6 -4
  100. package/dist/esm/base/middlewares/emoji-favicon/emoji-favicon.middleware.d.ts.map +1 -1
  101. package/dist/esm/base/middlewares/emoji-favicon/emoji-favicon.middleware.js +14 -12
  102. package/dist/esm/base/middlewares/emoji-favicon/emoji-favicon.middleware.js.map +1 -1
  103. package/dist/esm/base/middlewares/form-body/form-body.middleware.d.ts +15 -11
  104. package/dist/esm/base/middlewares/form-body/form-body.middleware.d.ts.map +1 -1
  105. package/dist/esm/base/middlewares/form-body/form-body.middleware.js +25 -21
  106. package/dist/esm/base/middlewares/form-body/form-body.middleware.js.map +1 -1
  107. package/dist/esm/base/models/common/schemas.d.ts +184 -105
  108. package/dist/esm/base/models/common/schemas.d.ts.map +1 -1
  109. package/dist/esm/base/models/common/schemas.js +105 -54
  110. package/dist/esm/base/models/common/schemas.js.map +1 -1
  111. package/dist/esm/base/models/common/utilities.d.ts +10 -5
  112. package/dist/esm/base/models/common/utilities.d.ts.map +1 -1
  113. package/dist/esm/base/models/common/utilities.js +22 -16
  114. package/dist/esm/base/models/common/utilities.js.map +1 -1
  115. package/dist/esm/base/repositories/common/types/results.d.ts +15 -7
  116. package/dist/esm/base/repositories/common/types/results.d.ts.map +1 -1
  117. package/dist/esm/base/repositories/common/types/results.js +16 -7
  118. package/dist/esm/base/repositories/common/types/results.js.map +1 -1
  119. package/dist/esm/base/repositories/core/abstract.d.ts.map +1 -1
  120. package/dist/esm/base/repositories/core/abstract.js +5 -3
  121. package/dist/esm/base/repositories/core/abstract.js.map +1 -1
  122. package/dist/esm/base/repositories/query-schemas/index.d.ts +1 -1
  123. package/dist/esm/base/repositories/query-schemas/index.d.ts.map +1 -1
  124. package/dist/esm/base/repositories/query-schemas/index.js +3 -3
  125. package/dist/esm/base/repositories/query-schemas/index.js.map +1 -1
  126. package/dist/esm/helpers/inversion/common/relation-builder.js.map +1 -1
  127. package/dist/esm/helpers/inversion/index.d.ts +1 -1
  128. package/dist/esm/helpers/inversion/index.d.ts.map +1 -1
  129. package/dist/esm/helpers/inversion/index.js +1 -1
  130. package/dist/esm/helpers/inversion/index.js.map +1 -1
  131. package/dist/esm/helpers/inversion/mixins/repository.mixin.d.ts.map +1 -1
  132. package/dist/esm/helpers/inversion/mixins/repository.mixin.js +5 -5
  133. package/dist/esm/helpers/inversion/mixins/repository.mixin.js.map +1 -1
  134. package/dist/esm/metadata.d.ts +1 -1
  135. package/dist/esm/metadata.d.ts.map +1 -1
  136. package/dist/esm/metadata.js +1 -1
  137. package/dist/esm/metadata.js.map +1 -1
  138. package/dist/esm/repository.d.ts +2 -2
  139. package/dist/esm/repository.d.ts.map +1 -1
  140. package/dist/esm/repository.js +2 -2
  141. package/dist/esm/repository.js.map +1 -1
  142. package/dist/esm/utilities/index.d.ts +1 -1
  143. package/dist/esm/utilities/index.d.ts.map +1 -1
  144. package/dist/esm/utilities/index.js +1 -1
  145. package/dist/esm/utilities/index.js.map +1 -1
  146. package/dist/esm/utilities/not-supported.utility.d.ts +11 -0
  147. package/dist/esm/utilities/not-supported.utility.d.ts.map +1 -0
  148. package/dist/esm/utilities/not-supported.utility.js +19 -0
  149. package/dist/esm/utilities/not-supported.utility.js.map +1 -0
  150. package/package.json +6 -7
  151. package/dist/esm/base/controllers/common/html-response.d.ts +0 -70
  152. package/dist/esm/base/controllers/common/html-response.d.ts.map +0 -1
  153. package/dist/esm/base/controllers/common/html-response.js +0 -30
  154. package/dist/esm/base/controllers/common/html-response.js.map +0 -1
  155. package/dist/esm/base/controllers/factory/authorize-guard.d.ts +0 -19
  156. package/dist/esm/base/controllers/factory/authorize-guard.d.ts.map +0 -1
  157. package/dist/esm/base/controllers/factory/authorize-guard.js +0 -56
  158. package/dist/esm/base/controllers/factory/authorize-guard.js.map +0 -1
  159. package/dist/esm/base/controllers/factory/helper.d.ts +0 -2
  160. package/dist/esm/base/controllers/factory/helper.d.ts.map +0 -1
  161. package/dist/esm/base/controllers/factory/helper.js +0 -2
  162. package/dist/esm/base/controllers/factory/helper.js.map +0 -1
  163. package/dist/esm/base/controllers/factory/repository-injection.d.ts +0 -14
  164. package/dist/esm/base/controllers/factory/repository-injection.d.ts.map +0 -1
  165. package/dist/esm/base/controllers/factory/repository-injection.js +0 -27
  166. package/dist/esm/base/controllers/factory/repository-injection.js.map +0 -1
  167. package/dist/esm/base/metadata/model-settings.d.ts +0 -11
  168. package/dist/esm/base/metadata/model-settings.d.ts.map +0 -1
  169. package/dist/esm/base/metadata/model-settings.js +0 -30
  170. package/dist/esm/base/metadata/model-settings.js.map +0 -1
  171. package/dist/esm/utilities/error.utility.d.ts +0 -8
  172. package/dist/esm/utilities/error.utility.d.ts.map +0 -1
  173. package/dist/esm/utilities/error.utility.js +0 -14
  174. package/dist/esm/utilities/error.utility.js.map +0 -1
@@ -1,46 +1,49 @@
1
1
  import { AuthorizationDomainScopes, AuthorizationDomainSources } from '../common/constants/index.js';
2
- /** Read a domain value from a declarative source on the Hono context. */
3
- export const readDeclarative = (opts) => {
4
- const { source, context } = opts;
5
- switch (source.from) {
6
- case AuthorizationDomainSources.PARAM: {
7
- return context.req.param(source.key) ?? null;
2
+ /** Reads the domain of an authorization check off the request. */
3
+ export class RequestDomainResolver {
4
+ /** Read a domain value from a declarative source on the Hono context. */
5
+ static readDeclarative(opts) {
6
+ const { source, context } = opts;
7
+ switch (source.from) {
8
+ case AuthorizationDomainSources.PARAM: {
9
+ return context.req.param(source.key) ?? null;
10
+ }
11
+ case AuthorizationDomainSources.HEADER: {
12
+ return context.req.header(source.key) ?? null;
13
+ }
14
+ case AuthorizationDomainSources.QUERY: {
15
+ return context.req.query(source.key) ?? null;
16
+ }
17
+ case AuthorizationDomainSources.CONTEXT: {
18
+ const value = context.get(source.key);
19
+ return value == null ? null : String(value);
20
+ }
21
+ default: {
22
+ return null;
23
+ }
8
24
  }
9
- case AuthorizationDomainSources.HEADER: {
10
- return context.req.header(source.key) ?? null;
11
- }
12
- case AuthorizationDomainSources.QUERY: {
13
- return context.req.query(source.key) ?? null;
25
+ }
26
+ /** Resolve the request domain, precedence spec.domain (method | declarative) -> options.domainResolver -> SYSTEM_WIDE, as a casbin domain string ("<type>_<id>") or the SYSTEM_WIDE sentinel. */
27
+ static async resolveRequestDomain(opts) {
28
+ const { spec, context, options } = opts;
29
+ if (typeof spec.domain === 'function') {
30
+ const resolved = await spec.domain({ context });
31
+ return resolved
32
+ ? [resolved.type, resolved.id].join('_')
33
+ : AuthorizationDomainScopes.SYSTEM_WIDE;
14
34
  }
15
- case AuthorizationDomainSources.CONTEXT: {
16
- const value = context.get(source.key);
17
- return value == null ? null : String(value);
35
+ if (spec.domain) {
36
+ const id = RequestDomainResolver.readDeclarative({ source: spec.domain, context });
37
+ return id ? [spec.domain.type, id].join('_') : AuthorizationDomainScopes.SYSTEM_WIDE;
18
38
  }
19
- default: {
20
- return null;
39
+ const globalResolver = options?.domainResolver ?? null;
40
+ if (globalResolver) {
41
+ const resolved = await globalResolver({ context });
42
+ return resolved
43
+ ? [resolved.type, resolved.id].join('_')
44
+ : AuthorizationDomainScopes.SYSTEM_WIDE;
21
45
  }
46
+ return AuthorizationDomainScopes.SYSTEM_WIDE;
22
47
  }
23
- };
24
- /** Resolve the request domain, precedence spec.domain (method | declarative) -> options.domainResolver -> SYSTEM_WIDE, as a casbin domain string ("<type>_<id>") or the SYSTEM_WIDE sentinel. */
25
- export const resolveRequestDomain = async (opts) => {
26
- const { spec, context, options } = opts;
27
- if (typeof spec.domain === 'function') {
28
- const resolved = await spec.domain({ context });
29
- return resolved
30
- ? [resolved.type, resolved.id].join('_')
31
- : AuthorizationDomainScopes.SYSTEM_WIDE;
32
- }
33
- if (spec.domain) {
34
- const id = readDeclarative({ source: spec.domain, context });
35
- return id ? [spec.domain.type, id].join('_') : AuthorizationDomainScopes.SYSTEM_WIDE;
36
- }
37
- const globalResolver = options?.domainResolver ?? null;
38
- if (globalResolver) {
39
- const resolved = await globalResolver({ context });
40
- return resolved
41
- ? [resolved.type, resolved.id].join('_')
42
- : AuthorizationDomainScopes.SYSTEM_WIDE;
43
- }
44
- return AuthorizationDomainScopes.SYSTEM_WIDE;
45
- };
48
+ }
46
49
  //# sourceMappingURL=request-domain.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"request-domain.js","sourceRoot":"","sources":["../../../../../../src/base/auth/authorize/providers/request-domain.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAO5F,yEAAyE;AACzE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAG/B,EAAqB,EAAE;IACtB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjC,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,0BAA0B,CAAC,KAAK,CAAC,CAAC,CAAC;YACtC,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;QAC/C,CAAC;QACD,KAAK,0BAA0B,CAAC,MAAM,CAAC,CAAC,CAAC;YACvC,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;QAChD,CAAC;QACD,KAAK,0BAA0B,CAAC,KAAK,CAAC,CAAC,CAAC;YACtC,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;QAC/C,CAAC;QACD,KAAK,0BAA0B,CAAC,OAAO,CAAC,CAAC,CAAC;YACxC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAU,CAAC,CAAC;YAC7C,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACR,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF,iMAAiM;AACjM,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,IAI1C,EAAmB,EAAE;IACpB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAExC,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAChD,OAAO,QAAQ;YACb,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YACxC,CAAC,CAAC,yBAAyB,CAAC,WAAW,CAAC;IAC5C,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7D,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,WAAW,CAAC;IACvF,CAAC;IAED,MAAM,cAAc,GAAG,OAAO,EAAE,cAAc,IAAI,IAAI,CAAC;IACvD,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACnD,OAAO,QAAQ;YACb,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YACxC,CAAC,CAAC,yBAAyB,CAAC,WAAW,CAAC;IAC5C,CAAC;IAED,OAAO,yBAAyB,CAAC,WAAW,CAAC;AAC/C,CAAC,CAAC","sourcesContent":["import type { TContext } from '@/base/controllers/common/types';\nimport type { TNullable } from '@venizia/ignis-helpers/common';\nimport type { Env } from 'hono';\nimport { AuthorizationDomainScopes, AuthorizationDomainSources } from '../common/constants';\nimport type {\n IAuthorizationDomainSource,\n IAuthorizationSpec,\n IAuthorizeOptions,\n} from '../common/types';\n\n/** Read a domain value from a declarative source on the Hono context. */\nexport const readDeclarative = (opts: {\n source: IAuthorizationDomainSource;\n context: TContext<Env, string>;\n}): TNullable<string> => {\n const { source, context } = opts;\n switch (source.from) {\n case AuthorizationDomainSources.PARAM: {\n return context.req.param(source.key) ?? null;\n }\n case AuthorizationDomainSources.HEADER: {\n return context.req.header(source.key) ?? null;\n }\n case AuthorizationDomainSources.QUERY: {\n return context.req.query(source.key) ?? null;\n }\n case AuthorizationDomainSources.CONTEXT: {\n const value = context.get(source.key as any);\n return value == null ? null : String(value);\n }\n default: {\n return null;\n }\n }\n};\n\n/** Resolve the request domain, precedence spec.domain (method | declarative) -> options.domainResolver -> SYSTEM_WIDE, as a casbin domain string (\"<type>_<id>\") or the SYSTEM_WIDE sentinel. */\nexport const resolveRequestDomain = async (opts: {\n spec: IAuthorizationSpec;\n context: TContext<Env, string>;\n options: TNullable<IAuthorizeOptions>;\n}): Promise<string> => {\n const { spec, context, options } = opts;\n\n if (typeof spec.domain === 'function') {\n const resolved = await spec.domain({ context });\n return resolved\n ? [resolved.type, resolved.id].join('_')\n : AuthorizationDomainScopes.SYSTEM_WIDE;\n }\n\n if (spec.domain) {\n const id = readDeclarative({ source: spec.domain, context });\n return id ? [spec.domain.type, id].join('_') : AuthorizationDomainScopes.SYSTEM_WIDE;\n }\n\n const globalResolver = options?.domainResolver ?? null;\n if (globalResolver) {\n const resolved = await globalResolver({ context });\n return resolved\n ? [resolved.type, resolved.id].join('_')\n : AuthorizationDomainScopes.SYSTEM_WIDE;\n }\n\n return AuthorizationDomainScopes.SYSTEM_WIDE;\n};\n"]}
1
+ {"version":3,"file":"request-domain.js","sourceRoot":"","sources":["../../../../../../src/base/auth/authorize/providers/request-domain.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAO5F,kEAAkE;AAClE,MAAM,OAAO,qBAAqB;IAChC,yEAAyE;IACzE,MAAM,CAAC,eAAe,CAAC,IAGtB;QACC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QACjC,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,0BAA0B,CAAC,KAAK,CAAC,CAAC,CAAC;gBACtC,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;YAC/C,CAAC;YACD,KAAK,0BAA0B,CAAC,MAAM,CAAC,CAAC,CAAC;gBACvC,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;YAChD,CAAC;YACD,KAAK,0BAA0B,CAAC,KAAK,CAAC,CAAC,CAAC;gBACtC,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;YAC/C,CAAC;YACD,KAAK,0BAA0B,CAAC,OAAO,CAAC,CAAC,CAAC;gBACxC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAU,CAAC,CAAC;gBAC7C,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC9C,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACR,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAED,iMAAiM;IACjM,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,IAIjC;QACC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QAExC,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YACtC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;YAChD,OAAO,QAAQ;gBACb,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;gBACxC,CAAC,CAAC,yBAAyB,CAAC,WAAW,CAAC;QAC5C,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,EAAE,GAAG,qBAAqB,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;YACnF,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,WAAW,CAAC;QACvF,CAAC;QAED,MAAM,cAAc,GAAG,OAAO,EAAE,cAAc,IAAI,IAAI,CAAC;QACvD,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;YACnD,OAAO,QAAQ;gBACb,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;gBACxC,CAAC,CAAC,yBAAyB,CAAC,WAAW,CAAC;QAC5C,CAAC;QAED,OAAO,yBAAyB,CAAC,WAAW,CAAC;IAC/C,CAAC;CACF","sourcesContent":["import type { TContext } from '@/base/controllers/common/types';\nimport type { TNullable } from '@venizia/ignis-helpers/common';\nimport type { Env } from 'hono';\nimport { AuthorizationDomainScopes, AuthorizationDomainSources } from '../common/constants';\nimport type {\n IAuthorizationDomainSource,\n IAuthorizationSpec,\n IAuthorizeOptions,\n} from '../common/types';\n\n/** Reads the domain of an authorization check off the request. */\nexport class RequestDomainResolver {\n /** Read a domain value from a declarative source on the Hono context. */\n static readDeclarative(opts: {\n source: IAuthorizationDomainSource;\n context: TContext<Env, string>;\n }): TNullable<string> {\n const { source, context } = opts;\n switch (source.from) {\n case AuthorizationDomainSources.PARAM: {\n return context.req.param(source.key) ?? null;\n }\n case AuthorizationDomainSources.HEADER: {\n return context.req.header(source.key) ?? null;\n }\n case AuthorizationDomainSources.QUERY: {\n return context.req.query(source.key) ?? null;\n }\n case AuthorizationDomainSources.CONTEXT: {\n const value = context.get(source.key as any);\n return value == null ? null : String(value);\n }\n default: {\n return null;\n }\n }\n }\n\n /** Resolve the request domain, precedence spec.domain (method | declarative) -> options.domainResolver -> SYSTEM_WIDE, as a casbin domain string (\"<type>_<id>\") or the SYSTEM_WIDE sentinel. */\n static async resolveRequestDomain(opts: {\n spec: IAuthorizationSpec;\n context: TContext<Env, string>;\n options: TNullable<IAuthorizeOptions>;\n }): Promise<string> {\n const { spec, context, options } = opts;\n\n if (typeof spec.domain === 'function') {\n const resolved = await spec.domain({ context });\n return resolved\n ? [resolved.type, resolved.id].join('_')\n : AuthorizationDomainScopes.SYSTEM_WIDE;\n }\n\n if (spec.domain) {\n const id = RequestDomainResolver.readDeclarative({ source: spec.domain, context });\n return id ? [spec.domain.type, id].join('_') : AuthorizationDomainScopes.SYSTEM_WIDE;\n }\n\n const globalResolver = options?.domainResolver ?? null;\n if (globalResolver) {\n const resolved = await globalResolver({ context });\n return resolved\n ? [resolved.type, resolved.id].join('_')\n : AuthorizationDomainScopes.SYSTEM_WIDE;\n }\n\n return AuthorizationDomainScopes.SYSTEM_WIDE;\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { isEmpty } from '@venizia/ignis-helpers/common';
1
+ import { ObjectUtility } from '@venizia/ignis-helpers/common';
2
2
  import { BindingScopes } from '@venizia/ignis-inversion';
3
3
  import { BaseHelper, getError } from '@venizia/ignis-helpers/core';
4
4
  export class AbstractAuthRegistry extends BaseHelper {
@@ -7,7 +7,7 @@ export class AbstractAuthRegistry extends BaseHelper {
7
7
  this.descriptors = new Map();
8
8
  }
9
9
  getKey(opts) {
10
- if (!opts?.name || isEmpty({ value: opts.name })) {
10
+ if (!opts?.name || ObjectUtility.isEmpty({ value: opts.name })) {
11
11
  throw getError({ message: `[getKey] Invalid name | name: ${opts.name}` });
12
12
  }
13
13
  return [this.getBindingPrefix(), opts.name].join('.');
@@ -1 +1 @@
1
- {"version":3,"file":"abstract-auth-registry.js","sourceRoot":"","sources":["../../../../../src/base/auth/base/abstract-auth-registry.ts"],"names":[],"mappings":"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","sourcesContent":["import { isEmpty } from '@venizia/ignis-helpers/common';\nimport { BindingScopes } from '@venizia/ignis-inversion';\nimport type { Container } from '@/helpers/inversion/container';\nimport type { TClass } from '@venizia/ignis-helpers/common';\nimport { BaseHelper, getError } from '@venizia/ignis-helpers/core';\n\nexport type TRegistryDescriptor<TItem> = {\n container: Container;\n targetClass: TClass<TItem>;\n};\n\nexport abstract class AbstractAuthRegistry<TItem> extends BaseHelper {\n protected descriptors: Map<string, TRegistryDescriptor<TItem>>;\n\n constructor(opts: { scope: string }) {\n super(opts);\n this.descriptors = new Map();\n }\n\n protected abstract getBindingPrefix(): string;\n\n getKey(opts: { name: string }): string {\n if (!opts?.name || isEmpty({ value: opts.name })) {\n throw getError({ message: `[getKey] Invalid name | name: ${opts.name}` });\n }\n\n return [this.getBindingPrefix(), opts.name].join('.');\n }\n\n /**\n * Whether a name resolves. The registry is the only source of truth for that: the strategy type is\n * open (`TAuthStrategy` accepts any string), so nothing upstream can tell a registered name from a\n * typo. `AuthenticateStrategy.isValid` knows the two built-ins only and must not be used here.\n */\n has(opts: { name: string }): boolean {\n return this.descriptors.has(opts.name);\n }\n\n /** Every registered name, for a caller building its own startup check or an error message. */\n getNames(): string[] {\n return [...this.descriptors.keys()];\n }\n\n getDefaultName(): string {\n const firstName = this.descriptors.keys().next().value;\n if (!firstName) {\n throw getError({\n message: `[${this.constructor.name}] No items registered`,\n });\n }\n return firstName;\n }\n\n protected registerDescriptor(opts: {\n container: Container;\n target: TClass<TItem>;\n name: string;\n }): void {\n const { container, target, name } = opts;\n\n this.descriptors.set(name, { container, targetClass: target });\n container\n .bind({ key: this.getKey({ name }) })\n .toClass(target)\n .setScope(BindingScopes.SINGLETON);\n }\n\n reset(): void {\n this.descriptors.clear();\n }\n\n protected resolveDescriptor(opts: { name: string }): TItem {\n const { name } = opts;\n const metadata = this.descriptors.get(name);\n\n if (!metadata) {\n throw getError({\n message: `[${this.constructor.name}] Descriptor not found: ${name}`,\n });\n }\n\n const { container } = metadata;\n const instance = container.get<TItem>({\n key: this.getKey({ name }),\n });\n\n if (!instance) {\n throw getError({\n message: `[${this.constructor.name}] Failed to resolve: ${name}`,\n });\n }\n\n return instance;\n }\n}\n"]}
1
+ {"version":3,"file":"abstract-auth-registry.js","sourceRoot":"","sources":["../../../../../src/base/auth/base/abstract-auth-registry.ts"],"names":[],"mappings":"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","sourcesContent":["import { ObjectUtility } from '@venizia/ignis-helpers/common';\nimport { BindingScopes } from '@venizia/ignis-inversion';\nimport type { Container } from '@/helpers/inversion/container';\nimport type { TClass } from '@venizia/ignis-helpers/common';\nimport { BaseHelper, getError } from '@venizia/ignis-helpers/core';\n\nexport type TRegistryDescriptor<TItem> = {\n container: Container;\n targetClass: TClass<TItem>;\n};\n\nexport abstract class AbstractAuthRegistry<TItem> extends BaseHelper {\n protected descriptors: Map<string, TRegistryDescriptor<TItem>>;\n\n constructor(opts: { scope: string }) {\n super(opts);\n this.descriptors = new Map();\n }\n\n protected abstract getBindingPrefix(): string;\n\n getKey(opts: { name: string }): string {\n if (!opts?.name || ObjectUtility.isEmpty({ value: opts.name })) {\n throw getError({ message: `[getKey] Invalid name | name: ${opts.name}` });\n }\n\n return [this.getBindingPrefix(), opts.name].join('.');\n }\n\n /**\n * Whether a name resolves. The registry is the only source of truth for that: the strategy type is\n * open (`TAuthStrategy` accepts any string), so nothing upstream can tell a registered name from a\n * typo. `AuthenticateStrategy.isValid` knows the two built-ins only and must not be used here.\n */\n has(opts: { name: string }): boolean {\n return this.descriptors.has(opts.name);\n }\n\n /** Every registered name, for a caller building its own startup check or an error message. */\n getNames(): string[] {\n return [...this.descriptors.keys()];\n }\n\n getDefaultName(): string {\n const firstName = this.descriptors.keys().next().value;\n if (!firstName) {\n throw getError({\n message: `[${this.constructor.name}] No items registered`,\n });\n }\n return firstName;\n }\n\n protected registerDescriptor(opts: {\n container: Container;\n target: TClass<TItem>;\n name: string;\n }): void {\n const { container, target, name } = opts;\n\n this.descriptors.set(name, { container, targetClass: target });\n container\n .bind({ key: this.getKey({ name }) })\n .toClass(target)\n .setScope(BindingScopes.SINGLETON);\n }\n\n reset(): void {\n this.descriptors.clear();\n }\n\n protected resolveDescriptor(opts: { name: string }): TItem {\n const { name } = opts;\n const metadata = this.descriptors.get(name);\n\n if (!metadata) {\n throw getError({\n message: `[${this.constructor.name}] Descriptor not found: ${name}`,\n });\n }\n\n const { container } = metadata;\n const instance = container.get<TItem>({\n key: this.getKey({ name }),\n });\n\n if (!instance) {\n throw getError({\n message: `[${this.constructor.name}] Failed to resolve: ${name}`,\n });\n }\n\n return instance;\n }\n}\n"]}
@@ -1,10 +1,10 @@
1
- import { requiredString } from '../../../controllers/common/schema-builders.js';
1
+ import { OpenApiSchemas } from '../../../models/common/index.js';
2
2
  import { z } from '@hono/zod-openapi';
3
3
  export const ChangePasswordRequestSchema = z
4
4
  .object({
5
5
  scheme: z.string(),
6
- oldCredential: requiredString({ min: 8 }),
7
- newCredential: requiredString({ min: 8 }),
6
+ oldCredential: OpenApiSchemas.requiredString({ min: 8 }),
7
+ newCredential: OpenApiSchemas.requiredString({ min: 8 }),
8
8
  userId: z.string().or(z.number()),
9
9
  })
10
10
  .openapi({
@@ -1 +1 @@
1
- {"version":3,"file":"change-password.schema.js","sourceRoot":"","sources":["../../../../../../src/base/auth/models/requests/change-password.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC;KACzC,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,aAAa,EAAE,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IACzC,aAAa,EAAE,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IACzC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CAClC,CAAC;KACD,OAAO,CAAC;IACP,QAAQ,EAAE;QACR;YACE,MAAM,EAAE,OAAO;YACf,aAAa,EAAE,cAAc;YAC7B,aAAa,EAAE,cAAc;YAC7B,MAAM,EAAE,SAAS;SAClB;KACF;CACF,CAAC,CAAC","sourcesContent":["import { requiredString } from '@/base/controllers/common/schema-builders';\nimport { z } from '@hono/zod-openapi';\n\nexport const ChangePasswordRequestSchema = z\n .object({\n scheme: z.string(),\n oldCredential: requiredString({ min: 8 }),\n newCredential: requiredString({ min: 8 }),\n userId: z.string().or(z.number()),\n })\n .openapi({\n examples: [\n {\n scheme: 'basic',\n oldCredential: 'old_password',\n newCredential: 'new_password',\n userId: 'user-id',\n },\n ],\n });\n\nexport type TChangePasswordRequest = z.infer<typeof ChangePasswordRequestSchema>;\n"]}
1
+ {"version":3,"file":"change-password.schema.js","sourceRoot":"","sources":["../../../../../../src/base/auth/models/requests/change-password.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC;KACzC,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,aAAa,EAAE,cAAc,CAAC,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IACxD,aAAa,EAAE,cAAc,CAAC,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IACxD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CAClC,CAAC;KACD,OAAO,CAAC;IACP,QAAQ,EAAE;QACR;YACE,MAAM,EAAE,OAAO;YACf,aAAa,EAAE,cAAc;YAC7B,aAAa,EAAE,cAAc;YAC7B,MAAM,EAAE,SAAS;SAClB;KACF;CACF,CAAC,CAAC","sourcesContent":["import { OpenApiSchemas } from '@/base/models/common';\nimport { z } from '@hono/zod-openapi';\n\nexport const ChangePasswordRequestSchema = z\n .object({\n scheme: z.string(),\n oldCredential: OpenApiSchemas.requiredString({ min: 8 }),\n newCredential: OpenApiSchemas.requiredString({ min: 8 }),\n userId: z.string().or(z.number()),\n })\n .openapi({\n examples: [\n {\n scheme: 'basic',\n oldCredential: 'old_password',\n newCredential: 'new_password',\n userId: 'user-id',\n },\n ],\n });\n\nexport type TChangePasswordRequest = z.infer<typeof ChangePasswordRequestSchema>;\n"]}
@@ -1,11 +1,11 @@
1
- import { requiredString } from '../../../controllers/common/schema-builders.js';
1
+ import { OpenApiSchemas } from '../../../models/common/index.js';
2
2
  import { z } from '@hono/zod-openapi';
3
3
  export const SignInRequestSchema = z
4
4
  .object({
5
5
  identifier: z
6
6
  .object({
7
- scheme: requiredString({ min: 4 }),
8
- value: requiredString({ min: 8 }),
7
+ scheme: OpenApiSchemas.requiredString({ min: 4 }),
8
+ value: OpenApiSchemas.requiredString({ min: 8 }),
9
9
  })
10
10
  .openapi({
11
11
  required: ['scheme', 'value'],
@@ -13,8 +13,8 @@ export const SignInRequestSchema = z
13
13
  }),
14
14
  credential: z
15
15
  .object({
16
- scheme: requiredString(),
17
- value: requiredString({ min: 8 }),
16
+ scheme: OpenApiSchemas.requiredString(),
17
+ value: OpenApiSchemas.requiredString({ min: 8 }),
18
18
  })
19
19
  .openapi({
20
20
  required: ['scheme', 'value'],
@@ -1 +1 @@
1
- {"version":3,"file":"sign-in.schema.js","sourceRoot":"","sources":["../../../../../../src/base/auth/models/requests/sign-in.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC;KACjC,MAAM,CAAC;IACN,UAAU,EAAE,CAAC;SACV,MAAM,CAAC;QACN,MAAM,EAAE,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;QAClC,KAAK,EAAE,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;KAClC,CAAC;SACD,OAAO,CAAC;QACP,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC7B,WAAW,EAAE,oBAAoB;KAClC,CAAC;IACJ,UAAU,EAAE,CAAC;SACV,MAAM,CAAC;QACN,MAAM,EAAE,cAAc,EAAE;QACxB,KAAK,EAAE,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;KAClC,CAAC;SACD,OAAO,CAAC;QACP,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC7B,WAAW,EAAE,oBAAoB;KAClC,CAAC;IACJ,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC;QACtC,WAAW,EAAE,uBAAuB;KACrC,CAAC;CACH,CAAC;KACD,OAAO,CAAC;IACP,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC;IACtC,QAAQ,EAAE;QACR;YACE,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE;YAC1D,UAAU,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE;SACxD;QACD;YACE,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE;YAC1D,UAAU,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE;YACvD,QAAQ,EAAE,eAAe;SAC1B;KACF;CACF,CAAC,CAAC","sourcesContent":["import { requiredString } from '@/base/controllers/common/schema-builders';\nimport { z } from '@hono/zod-openapi';\n\nexport const SignInRequestSchema = z\n .object({\n identifier: z\n .object({\n scheme: requiredString({ min: 4 }),\n value: requiredString({ min: 8 }),\n })\n .openapi({\n required: ['scheme', 'value'],\n description: 'Sign-In Identifier',\n }),\n credential: z\n .object({\n scheme: requiredString(),\n value: requiredString({ min: 8 }),\n })\n .openapi({\n required: ['scheme', 'value'],\n description: 'Sign-In Credential',\n }),\n clientId: z.string().optional().openapi({\n description: 'Authenticate Provider',\n }),\n })\n .openapi({\n required: ['identifier', 'credential'],\n examples: [\n {\n identifier: { scheme: 'username', value: 'test_username' },\n credential: { scheme: 'basic', value: 'test_password' },\n },\n {\n identifier: { scheme: 'username', value: 'test_username' },\n credential: { scheme: 'basic', value: 'test_password' },\n clientId: 'auth-provider',\n },\n ],\n });\n\nexport type TSignInRequest = z.infer<typeof SignInRequestSchema>;\n"]}
1
+ {"version":3,"file":"sign-in.schema.js","sourceRoot":"","sources":["../../../../../../src/base/auth/models/requests/sign-in.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC;KACjC,MAAM,CAAC;IACN,UAAU,EAAE,CAAC;SACV,MAAM,CAAC;QACN,MAAM,EAAE,cAAc,CAAC,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;QACjD,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;KACjD,CAAC;SACD,OAAO,CAAC;QACP,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC7B,WAAW,EAAE,oBAAoB;KAClC,CAAC;IACJ,UAAU,EAAE,CAAC;SACV,MAAM,CAAC;QACN,MAAM,EAAE,cAAc,CAAC,cAAc,EAAE;QACvC,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;KACjD,CAAC;SACD,OAAO,CAAC;QACP,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC7B,WAAW,EAAE,oBAAoB;KAClC,CAAC;IACJ,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC;QACtC,WAAW,EAAE,uBAAuB;KACrC,CAAC;CACH,CAAC;KACD,OAAO,CAAC;IACP,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC;IACtC,QAAQ,EAAE;QACR;YACE,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE;YAC1D,UAAU,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE;SACxD;QACD;YACE,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE;YAC1D,UAAU,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE;YACvD,QAAQ,EAAE,eAAe;SAC1B;KACF;CACF,CAAC,CAAC","sourcesContent":["import { OpenApiSchemas } from '@/base/models/common';\nimport { z } from '@hono/zod-openapi';\n\nexport const SignInRequestSchema = z\n .object({\n identifier: z\n .object({\n scheme: OpenApiSchemas.requiredString({ min: 4 }),\n value: OpenApiSchemas.requiredString({ min: 8 }),\n })\n .openapi({\n required: ['scheme', 'value'],\n description: 'Sign-In Identifier',\n }),\n credential: z\n .object({\n scheme: OpenApiSchemas.requiredString(),\n value: OpenApiSchemas.requiredString({ min: 8 }),\n })\n .openapi({\n required: ['scheme', 'value'],\n description: 'Sign-In Credential',\n }),\n clientId: z.string().optional().openapi({\n description: 'Authenticate Provider',\n }),\n })\n .openapi({\n required: ['identifier', 'credential'],\n examples: [\n {\n identifier: { scheme: 'username', value: 'test_username' },\n credential: { scheme: 'basic', value: 'test_password' },\n },\n {\n identifier: { scheme: 'username', value: 'test_username' },\n credential: { scheme: 'basic', value: 'test_password' },\n clientId: 'auth-provider',\n },\n ],\n });\n\nexport type TSignInRequest = z.infer<typeof SignInRequestSchema>;\n"]}
@@ -3,7 +3,7 @@ import { BindingNamespaces } from '../../../../common/bindings.js';
3
3
  import { Binding, BindingValueTypes, MetadataRegistry } from '../../../../helpers/inversion/index.js';
4
4
  import { BaseComponent } from '../../base.js';
5
5
  import { getError } from '@venizia/ignis-helpers/core';
6
- import { HTTP, isEmpty } from '@venizia/ignis-helpers/common';
6
+ import { HTTP, ObjectUtility } from '@venizia/ignis-helpers/common';
7
7
  import { RestBindingKeys } from './common/types.js';
8
8
  const DEFAULT_OPTIONS = {};
9
9
  /**
@@ -42,7 +42,7 @@ export class RestComponent extends BaseComponent {
42
42
  if (metadata?.transport === ControllerTransports.GRPC) {
43
43
  return;
44
44
  }
45
- if (!metadata?.path || isEmpty({ value: metadata.path })) {
45
+ if (!metadata?.path || ObjectUtility.isEmpty({ value: metadata.path })) {
46
46
  throw getError({
47
47
  statusCode: HTTP.ResultCodes.RS_5.InternalServerError,
48
48
  message: `[registerControllers] key: '${binding.key}' | Invalid controller metadata, 'path' is required for controller metadata`,
@@ -1 +1 @@
1
- {"version":3,"file":"rest.component.js","sourceRoot":"","sources":["../../../../../../src/base/components/controller/rest/rest.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAE9D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,eAAe,GAAyB,EAAE,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,OAAO,aAIX,SAAQ,aAAa;IACrB,YAAoB,WAAyD;QAC3E,KAAK,CAAC;YACJ,KAAK,EAAE,aAAa,CAAC,IAAI;YACzB,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE;YACrD,QAAQ,EAAE;gBACR,CAAC,eAAe,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC,IAAI,CAAuB;oBAC3E,GAAG,EAAE,eAAe,CAAC,sBAAsB;iBAC5C,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC;aAC5B;SACF,CAAC,CAAC;QATe,gBAAW,GAAX,WAAW,CAA8C;IAU7E,CAAC;IAEQ,KAAK,CAAC,OAAO;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC;QAEhD,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAyB;YACxD,GAAG,EAAE,iBAAiB,CAAC,UAAU;YACjC,UAAU,EAAE,IAAI,GAAG,EAAU;YAC7B,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBAC5B,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,KAAK,EAAE,CAAC,CAAC;gBACzE,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,OAAO;gBACT,CAAC;gBAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC,WAAW,EAAE,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;gBAElF,+DAA+D;gBAC/D,IAAI,QAAQ,EAAE,SAAS,KAAK,oBAAoB,CAAC,IAAI,EAAE,CAAC;oBACtD,OAAO;gBACT,CAAC;gBAED,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;oBACzD,MAAM,QAAQ,CAAC;wBACb,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,mBAAmB;wBACrD,OAAO,EAAE,+BAA+B,OAAO,CAAC,GAAG,6EAA6E;qBACjI,CAAC,CAAC;gBACL,CAAC;gBAED,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAyB;oBAC5D,GAAG,EAAE,OAAO,CAAC,GAAG;oBAChB,UAAU,EAAE,KAAK;iBAClB,CAAC,CAAC;gBAEH,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;oBAC3D,OAAO;gBACT,CAAC;gBAED,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC;gBAC3B,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;gBAElD,MAAM,CAAC,IAAI,CAAC,iDAAiD,EAAE,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC7F,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["import type { RestApplication } from '@/base/applications/rest';\nimport { ControllerTransports } from '@/base/controllers/common/constants';\nimport type { AbstractRestController } from '@/base/controllers/rest/abstract';\nimport { BindingNamespaces } from '@/common/bindings';\nimport { Binding, BindingValueTypes, MetadataRegistry } from '@/helpers/inversion';\nimport { BaseComponent } from '../../base';\nimport type { Env, Schema } from 'hono';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport { HTTP, isEmpty } from '@venizia/ignis-helpers/common';\nimport type { IRestComponentConfig } from './common/types';\nimport { RestBindingKeys } from './common/types';\n\nconst DEFAULT_OPTIONS: IRestComponentConfig = {};\n\n/**\n * Generic over the same Hono env/schema/base-path `RestApplication` is: a bare `RestApplication`\n * parameter (defaulting to `RestApplication<Env, {}, '/'>`) fails to typecheck when passed `this`\n * from inside a differently-instantiated generic `RestApplication` subclass - `defaultHook`'s\n * contravariance makes the defaulted instantiation incompatible with an arbitrary one. Matching the\n * caller's own instantiation here removes the mismatch instead of widening to `any`.\n */\nexport class RestComponent<\n AppEnv extends Env = Env,\n AppSchema extends Schema = {},\n BasePath extends string = '/',\n> extends BaseComponent {\n constructor(private application: RestApplication<AppEnv, AppSchema, BasePath>) {\n super({\n scope: RestComponent.name,\n initDefault: { enable: true, container: application },\n bindings: {\n [RestBindingKeys.REST_COMPONENT_OPTIONS]: Binding.bind<IRestComponentConfig>({\n key: RestBindingKeys.REST_COMPONENT_OPTIONS,\n }).toValue(DEFAULT_OPTIONS),\n },\n });\n }\n\n override async binding(): Promise<void> {\n const logger = this.logger.for(this.binding.name);\n const router = this.application.getRootRouter();\n\n await this.application.drainByTag<AbstractRestController>({\n tag: BindingNamespaces.CONTROLLER,\n configured: new Set<string>(),\n onEach: async ({ binding }) => {\n const target = binding.getBindingMeta({ type: BindingValueTypes.CLASS });\n if (!target) {\n return;\n }\n\n const metadata = MetadataRegistry.getInstance().getControllerMetadata({ target });\n\n // Skip gRPC controllers - they are configured by GrpcComponent\n if (metadata?.transport === ControllerTransports.GRPC) {\n return;\n }\n\n if (!metadata?.path || isEmpty({ value: metadata.path })) {\n throw getError({\n statusCode: HTTP.ResultCodes.RS_5.InternalServerError,\n message: `[registerControllers] key: '${binding.key}' | Invalid controller metadata, 'path' is required for controller metadata`,\n });\n }\n\n const instance = this.application.get<AbstractRestController>({\n key: binding.key,\n isOptional: false,\n });\n\n if (!instance) {\n logger.debug('No binding instance | key: %s', binding.key);\n return;\n }\n\n await instance.configure();\n router.route(metadata.path, instance.getRouter());\n\n logger.info('Configured REST controller | key: %s | path: %s', binding.key, metadata.path);\n },\n });\n }\n}\n"]}
1
+ {"version":3,"file":"rest.component.js","sourceRoot":"","sources":["../../../../../../src/base/components/controller/rest/rest.component.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RestApplication } from '@/base/applications/rest';\nimport { ControllerTransports } from '@/base/controllers/common/constants';\nimport type { AbstractRestController } from '@/base/controllers/rest/abstract';\nimport { BindingNamespaces } from '@/common/bindings';\nimport { Binding, BindingValueTypes, MetadataRegistry } from '@/helpers/inversion';\nimport { BaseComponent } from '../../base';\nimport type { Env, Schema } from 'hono';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport { HTTP, ObjectUtility } from '@venizia/ignis-helpers/common';\nimport type { IRestComponentConfig } from './common/types';\nimport { RestBindingKeys } from './common/types';\n\nconst DEFAULT_OPTIONS: IRestComponentConfig = {};\n\n/**\n * Generic over the same Hono env/schema/base-path `RestApplication` is: a bare `RestApplication`\n * parameter (defaulting to `RestApplication<Env, {}, '/'>`) fails to typecheck when passed `this`\n * from inside a differently-instantiated generic `RestApplication` subclass - `defaultHook`'s\n * contravariance makes the defaulted instantiation incompatible with an arbitrary one. Matching the\n * caller's own instantiation here removes the mismatch instead of widening to `any`.\n */\nexport class RestComponent<\n AppEnv extends Env = Env,\n AppSchema extends Schema = {},\n BasePath extends string = '/',\n> extends BaseComponent {\n constructor(private application: RestApplication<AppEnv, AppSchema, BasePath>) {\n super({\n scope: RestComponent.name,\n initDefault: { enable: true, container: application },\n bindings: {\n [RestBindingKeys.REST_COMPONENT_OPTIONS]: Binding.bind<IRestComponentConfig>({\n key: RestBindingKeys.REST_COMPONENT_OPTIONS,\n }).toValue(DEFAULT_OPTIONS),\n },\n });\n }\n\n override async binding(): Promise<void> {\n const logger = this.logger.for(this.binding.name);\n const router = this.application.getRootRouter();\n\n await this.application.drainByTag<AbstractRestController>({\n tag: BindingNamespaces.CONTROLLER,\n configured: new Set<string>(),\n onEach: async ({ binding }) => {\n const target = binding.getBindingMeta({ type: BindingValueTypes.CLASS });\n if (!target) {\n return;\n }\n\n const metadata = MetadataRegistry.getInstance().getControllerMetadata({ target });\n\n // Skip gRPC controllers - they are configured by GrpcComponent\n if (metadata?.transport === ControllerTransports.GRPC) {\n return;\n }\n\n if (!metadata?.path || ObjectUtility.isEmpty({ value: metadata.path })) {\n throw getError({\n statusCode: HTTP.ResultCodes.RS_5.InternalServerError,\n message: `[registerControllers] key: '${binding.key}' | Invalid controller metadata, 'path' is required for controller metadata`,\n });\n }\n\n const instance = this.application.get<AbstractRestController>({\n key: binding.key,\n isOptional: false,\n });\n\n if (!instance) {\n logger.debug('No binding instance | key: %s', binding.key);\n return;\n }\n\n await instance.configure();\n router.route(metadata.path, instance.getRouter());\n\n logger.info('Configured REST controller | key: %s | path: %s', binding.key, metadata.path);\n },\n });\n }\n}\n"]}
@@ -1,6 +1,5 @@
1
1
  export * from './constants.js';
2
2
  export * from './schemas.js';
3
- export * from './html-response.js';
4
3
  export * from './schema-builders.js';
5
4
  export * from './types/index.js';
6
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/base/controllers/common/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAE5B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/base/controllers/common/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAE5B,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC"}
@@ -1,7 +1,6 @@
1
1
  export * from './constants.js';
2
2
  // Carries zod. Kept out of `constants.ts` so importing `Container` does not pull zod into a bundle.
3
3
  export * from './schemas.js';
4
- export * from './html-response.js';
5
4
  export * from './schema-builders.js';
6
5
  export * from './types/index.js';
7
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/base/controllers/common/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,oGAAoG;AACpG,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC","sourcesContent":["export * from './constants';\n// Carries zod. Kept out of `constants.ts` so importing `Container` does not pull zod into a bundle.\nexport * from './schemas';\nexport * from './html-response';\nexport * from './schema-builders';\nexport * from './types';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/base/controllers/common/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,oGAAoG;AACpG,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC","sourcesContent":["export * from './constants';\n// Carries zod. Kept out of `constants.ts` so importing `Container` does not pull zod into a bundle.\nexport * from './schemas';\nexport * from './schema-builders';\nexport * from './types';\n"]}
@@ -1,9 +1,4 @@
1
1
  import { z } from '@hono/zod-openapi';
2
- export declare const requiredString: (opts?: {
3
- min?: number;
4
- max?: number;
5
- fixed?: number;
6
- }) => z.ZodString;
7
2
  export declare const AnyObjectSchema: z.ZodObject<{}, z.core.$catchall<z.ZodAny>>;
8
3
  export type TAnyObjectSchema = z.ZodObject<z.ZodRawShape>;
9
4
  export type TInferSchema<T extends z.ZodType> = z.infer<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"schema-builders.d.ts","sourceRoot":"","sources":["../../../../../src/base/controllers/common/schema-builders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,eAAO,MAAM,cAAc,GAAI,OAAO;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,gBAiBnF,CAAC;AAEF,eAAO,MAAM,eAAe,6CAE1B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;AAC1D,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"schema-builders.d.ts","sourceRoot":"","sources":["../../../../../src/base/controllers/common/schema-builders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,eAAO,MAAM,eAAe,6CAE1B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;AAC1D,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC"}
@@ -1,18 +1,4 @@
1
1
  import { z } from '@hono/zod-openapi';
2
- export const requiredString = (opts) => {
3
- const { min, max, fixed } = opts ?? {};
4
- let rs = z.string().nonempty();
5
- if (min) {
6
- rs = rs.min(min);
7
- }
8
- if (max) {
9
- rs = rs.max(max);
10
- }
11
- if (fixed) {
12
- rs = rs.length(fixed);
13
- }
14
- return rs;
15
- };
16
2
  export const AnyObjectSchema = z.object().catchall(z.any()).openapi({
17
3
  description: 'Unknown schema',
18
4
  });
@@ -1 +1 @@
1
- {"version":3,"file":"schema-builders.js","sourceRoot":"","sources":["../../../../../src/base/controllers/common/schema-builders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAqD,EAAE,EAAE;IACtF,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC;IACvC,IAAI,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC;IAE/B,IAAI,GAAG,EAAE,CAAC;QACR,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAED,IAAI,GAAG,EAAE,CAAC;QACR,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACV,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC;IAClE,WAAW,EAAE,gBAAgB;CAC9B,CAAC,CAAC","sourcesContent":["import { z } from '@hono/zod-openapi';\n\nexport const requiredString = (opts?: { min?: number; max?: number; fixed?: number }) => {\n const { min, max, fixed } = opts ?? {};\n let rs = z.string().nonempty();\n\n if (min) {\n rs = rs.min(min);\n }\n\n if (max) {\n rs = rs.max(max);\n }\n\n if (fixed) {\n rs = rs.length(fixed);\n }\n\n return rs;\n};\n\nexport const AnyObjectSchema = z.object().catchall(z.any()).openapi({\n description: 'Unknown schema',\n});\n\nexport type TAnyObjectSchema = z.ZodObject<z.ZodRawShape>;\nexport type TInferSchema<T extends z.ZodType> = z.infer<T>;\n"]}
1
+ {"version":3,"file":"schema-builders.js","sourceRoot":"","sources":["../../../../../src/base/controllers/common/schema-builders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC;IAClE,WAAW,EAAE,gBAAgB;CAC9B,CAAC,CAAC","sourcesContent":["import { z } from '@hono/zod-openapi';\n\nexport const AnyObjectSchema = z.object().catchall(z.any()).openapi({\n description: 'Unknown schema',\n});\n\nexport type TAnyObjectSchema = z.ZodObject<z.ZodRawShape>;\nexport type TInferSchema<T extends z.ZodType> = z.infer<T>;\n"]}
@@ -1,5 +1,10 @@
1
1
  import type { TContext } from './common/types/index.js';
2
2
  import type { Env } from 'hono';
3
- /** Casts middleware context to TContext (safe -- structurally identical to Context). */
4
- export declare const asTypedContext: <E extends Env>(context: unknown) => TContext<E, string>;
3
+ /** Casts of the Hono context that the types cannot prove. */
4
+ export declare class ContextUtility {
5
+ /** Casts middleware context to TContext (safe -- structurally identical to Context). */
6
+ static asTypedContext<E extends Env>(opts: {
7
+ context: unknown;
8
+ }): TContext<E, string>;
9
+ }
5
10
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../src/base/controllers/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEhC,wFAAwF;AACxF,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,GAAG,EAAE,SAAS,OAAO,KAAG,QAAQ,CAAC,CAAC,EAAE,MAAM,CAElF,CAAC"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../src/base/controllers/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEhC,6DAA6D;AAC7D,qBAAa,cAAc;IACzB,wFAAwF;IACxF,MAAM,CAAC,cAAc,CAAC,CAAC,SAAS,GAAG,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CAGtF"}
@@ -1,5 +1,8 @@
1
- /** Casts middleware context to TContext (safe -- structurally identical to Context). */
2
- export const asTypedContext = (context) => {
3
- return context;
4
- };
1
+ /** Casts of the Hono context that the types cannot prove. */
2
+ export class ContextUtility {
3
+ /** Casts middleware context to TContext (safe -- structurally identical to Context). */
4
+ static asTypedContext(opts) {
5
+ return opts.context;
6
+ }
7
+ }
5
8
  //# sourceMappingURL=context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../src/base/controllers/context.ts"],"names":[],"mappings":"AAGA,wFAAwF;AACxF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAgB,OAAgB,EAAuB,EAAE;IACrF,OAAO,OAA8B,CAAC;AACxC,CAAC,CAAC","sourcesContent":["import type { TContext } from './common/types';\nimport type { Env } from 'hono';\n\n/** Casts middleware context to TContext (safe -- structurally identical to Context). */\nexport const asTypedContext = <E extends Env>(context: unknown): TContext<E, string> => {\n return context as TContext<E, string>;\n};\n"]}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../src/base/controllers/context.ts"],"names":[],"mappings":"AAGA,6DAA6D;AAC7D,MAAM,OAAO,cAAc;IACzB,wFAAwF;IACxF,MAAM,CAAC,cAAc,CAAgB,IAA0B;QAC7D,OAAO,IAAI,CAAC,OAA8B,CAAC;IAC7C,CAAC;CACF","sourcesContent":["import type { TContext } from './common/types';\nimport type { Env } from 'hono';\n\n/** Casts of the Hono context that the types cannot prove. */\nexport class ContextUtility {\n /** Casts middleware context to TContext (safe -- structurally identical to Context). */\n static asTypedContext<E extends Env>(opts: { context: unknown }): TContext<E, string> {\n return opts.context as TContext<E, string>;\n }\n}\n"]}
@@ -1,13 +1,28 @@
1
+ import type { IAuthorizationSpec } from '../../auth/authorize/common/types/index.js';
1
2
  import type { AbstractEntity } from '../../models/index.js';
2
3
  import type { AbstractRepository } from '../../repositories/index.js';
3
4
  import type { TAnyObjectSchema } from '../common/schema-builders.js';
4
- import type { AnyType, ValueOrPromise } from '@venizia/ignis-helpers/common';
5
+ import type { AnyType, TClass, ValueOrPromise } from '@venizia/ignis-helpers/common';
5
6
  import { BaseHelper } from '@venizia/ignis-helpers/core';
6
7
  import type { Env, Schema } from 'hono';
7
8
  import type { ICrudControllerOptions, ICustomizableRoutes, TEntityDataObject, TEntityPersistObject } from '../common/index.js';
8
9
  /** Factory for generating typed CRUD controllers from entity definitions. */
9
10
  export declare class ControllerFactory extends BaseHelper {
11
+ /** The generated routes that change data: the ones that must never be answered by a `read` permission. */
12
+ private static readonly WRITE_VERBS;
10
13
  constructor();
14
+ /**
15
+ * Injects `repositories.<repositoryName>` into constructor parameter 0 of a factory-generated
16
+ * controller, so a subclass needs no constructor. Recorded as metadata rather than a parameter
17
+ * decorator, which Bun drops in some configurations. A subclass that declares its own `@inject` at
18
+ * index 0 wins, and a sibling subclass keeps the factory's key.
19
+ */
20
+ static registerRepositoryInjection(opts: {
21
+ target: TClass<unknown>;
22
+ factoryName: string;
23
+ controllerName: string;
24
+ repositoryName: string;
25
+ }): void;
11
26
  static defineCrudController<TEntity extends AbstractEntity<TAnyObjectSchema> = AbstractEntity<TAnyObjectSchema>, Routes extends ICustomizableRoutes = ICustomizableRoutes, RouteEnv extends Env = Env, RouteSchema extends Schema = {}, BasePath extends string = '/', ConfigurableOptions extends object = {}, TDataObject extends object = TEntityDataObject<TEntity>, TPersistObject extends object = TEntityPersistObject<TEntity>>(defOpts: ICrudControllerOptions<TEntity, Routes>): {
12
27
  new (repository: AbstractRepository<TDataObject, TPersistObject, AnyType>): {
13
28
  /** Registers each CRUD route whose handler tier supplies it, honoring enabledRoutes/readonly. */
@@ -206,5 +221,22 @@ export declare class ControllerFactory extends BaseHelper {
206
221
  getLogger(): import("@venizia/ignis-helpers/core").ILogger;
207
222
  };
208
223
  };
224
+ private static describeSpec;
225
+ /**
226
+ * Refuses a CRUD controller whose enabled write verb would inherit a controller-level `authorize`
227
+ * that is only a `read` permission: the verb would then answer to anyone who may read.
228
+ *
229
+ * A write verb is fine when it declares its own `authorize` (a spec, an array, or `{ skip: true }`),
230
+ * skips authentication, is not enabled, or the controller is `readonly`. Only the literal action
231
+ * `read` is detected; a custom action name is the application's own vocabulary. An array counts when
232
+ * every spec in it is `read`, since the specs of one route must all pass.
233
+ */
234
+ static assertWriteVerbsDeclareAuthorize(opts: {
235
+ controllerName: string;
236
+ authorize: IAuthorizationSpec | IAuthorizationSpec[] | undefined;
237
+ routes: ICustomizableRoutes | undefined;
238
+ readonly: boolean | undefined;
239
+ enabledRoutes: Array<keyof ICustomizableRoutes> | undefined;
240
+ }): void;
209
241
  }
210
242
  //# sourceMappingURL=controller.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../../src/base/controllers/factory/controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAClF,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAY,MAAM,6BAA6B,CAAC;AAEnE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,WAAW,CAAC;AAMnB,6EAA6E;AAC7E,qBAAa,iBAAkB,SAAQ,UAAU;;IAK/C,MAAM,CAAC,oBAAoB,CACzB,OAAO,SAAS,cAAc,CAAC,gBAAgB,CAAC,GAAG,cAAc,CAAC,gBAAgB,CAAC,EACnF,MAAM,SAAS,mBAAmB,GAAG,mBAAmB,EACxD,QAAQ,SAAS,GAAG,GAAG,GAAG,EAC1B,WAAW,SAAS,MAAM,GAAG,EAAE,EAC/B,QAAQ,SAAS,MAAM,GAAG,GAAG,EAC7B,mBAAmB,SAAS,MAAM,GAAG,EAAE,EACvC,WAAW,SAAS,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,EACvD,cAAc,SAAS,MAAM,GAAG,oBAAoB,CAAC,OAAO,CAAC,EAC7D,OAAO,EAAE,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC;yBAiDtB,kBAAkB,CAAC,WAAW,EAAE,cAAc,EAAE,OAAO,CAAC;YAUhF,iGAAiG;uBAC7E,cAAc,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAXG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmGjD"}
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../../src/base/controllers/factory/controller.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAGlF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACrF,OAAO,EAAE,UAAU,EAAY,MAAM,6BAA6B,CAAC;AAEnE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,WAAW,CAAC;AAInB,6EAA6E;AAC7E,qBAAa,iBAAkB,SAAQ,UAAU;IAC/C,0GAA0G;IAC1G,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAMxB;;IAMX;;;;;OAKG;IACH,MAAM,CAAC,2BAA2B,CAAC,IAAI,EAAE;QACvC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;KACxB,GAAG,IAAI;IAoBR,MAAM,CAAC,oBAAoB,CACzB,OAAO,SAAS,cAAc,CAAC,gBAAgB,CAAC,GAAG,cAAc,CAAC,gBAAgB,CAAC,EACnF,MAAM,SAAS,mBAAmB,GAAG,mBAAmB,EACxD,QAAQ,SAAS,GAAG,GAAG,GAAG,EAC1B,WAAW,SAAS,MAAM,GAAG,EAAE,EAC/B,QAAQ,SAAS,MAAM,GAAG,GAAG,EAC7B,mBAAmB,SAAS,MAAM,GAAG,EAAE,EACvC,WAAW,SAAS,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,EACvD,cAAc,SAAS,MAAM,GAAG,oBAAoB,CAAC,OAAO,CAAC,EAC7D,OAAO,EAAE,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC;yBAiDtB,kBAAkB,CAAC,WAAW,EAAE,cAAc,EAAE,OAAO,CAAC;YAUhF,iGAAiG;uBAC7E,cAAc,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAxDxC,CAAH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAiJD,OAAO,CAAC,MAAM,CAAC,YAAY;IAK3B;;;;;;;;OAQG;IACH,MAAM,CAAC,gCAAgC,CAAC,IAAI,EAAE;QAC5C,cAAc,EAAE,MAAM,CAAC;QACvB,SAAS,EAAE,kBAAkB,GAAG,kBAAkB,EAAE,GAAG,SAAS,CAAC;QACjE,MAAM,EAAE,mBAAmB,GAAG,SAAS,CAAC;QACxC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;QAC9B,aAAa,EAAE,KAAK,CAAC,MAAM,mBAAmB,CAAC,GAAG,SAAS,CAAC;KAC7D,GAAG,IAAI;CAgDT"}
@@ -1,15 +1,47 @@
1
+ import { AuthorizationActions } from '../../auth/authorize/common/constants/index.js';
1
2
  import { SchemaTypes } from '../../models/common/constants.js';
3
+ import { BindingNamespaces } from '../../../common/bindings.js';
4
+ import { BindingKeys, MetadataRegistry } from '../../../helpers/inversion/index.js';
2
5
  import { BaseHelper, getError } from '@venizia/ignis-helpers/core';
3
6
  import { isClass } from '@venizia/ignis-inversion';
4
7
  import { PersistableCrudController } from './crud/index.js';
5
- import { assertWriteVerbsDeclareAuthorize } from './authorize-guard.js';
6
- import { defineControllerRouteConfigs } from './definition.js';
7
- import { registerFactoryRepositoryInjection } from './repository-injection.js';
8
+ import { RouteConfigResolver } from './definition.js';
8
9
  /** Factory for generating typed CRUD controllers from entity definitions. */
9
10
  export class ControllerFactory extends BaseHelper {
11
+ /** The generated routes that change data: the ones that must never be answered by a `read` permission. */
12
+ static { this.WRITE_VERBS = [
13
+ 'create',
14
+ 'updateById',
15
+ 'updateBy',
16
+ 'deleteById',
17
+ 'deleteBy',
18
+ ]; }
10
19
  constructor() {
11
20
  super({ scope: ControllerFactory.name });
12
21
  }
22
+ /**
23
+ * Injects `repositories.<repositoryName>` into constructor parameter 0 of a factory-generated
24
+ * controller, so a subclass needs no constructor. Recorded as metadata rather than a parameter
25
+ * decorator, which Bun drops in some configurations. A subclass that declares its own `@inject` at
26
+ * index 0 wins, and a sibling subclass keeps the factory's key.
27
+ */
28
+ static registerRepositoryInjection(opts) {
29
+ const { target, factoryName, controllerName, repositoryName } = opts;
30
+ if (!repositoryName) {
31
+ throw getError({
32
+ message: `[${factoryName}] Invalid repository name | controller: ${controllerName} | repository.name must name the repository binding`,
33
+ });
34
+ }
35
+ MetadataRegistry.getInstance().setInjectMetadata({
36
+ target,
37
+ index: 0,
38
+ metadata: {
39
+ key: BindingKeys.build({ namespace: BindingNamespaces.REPOSITORY, key: repositoryName }),
40
+ index: 0,
41
+ isOptional: false,
42
+ },
43
+ });
44
+ }
13
45
  static defineCrudController(defOpts) {
14
46
  const { controller, entity, authenticate, authorize, routes } = defOpts;
15
47
  const { name, basePath = 'unknown_path', isStrict = { path: true, requestSchema: true }, } = controller;
@@ -18,7 +50,7 @@ export class ControllerFactory extends BaseHelper {
18
50
  message: `[defineCrudController] Invalid controller basePath | name: ${name} | basePath: ${basePath}`,
19
51
  });
20
52
  }
21
- assertWriteVerbsDeclareAuthorize({
53
+ ControllerFactory.assertWriteVerbsDeclareAuthorize({
22
54
  controllerName: name,
23
55
  authorize,
24
56
  routes,
@@ -27,7 +59,7 @@ export class ControllerFactory extends BaseHelper {
27
59
  });
28
60
  const entityClass = isClass(entity) ? entity : entity();
29
61
  const entityInstance = new entityClass();
30
- const routeDefinitions = defineControllerRouteConfigs({
62
+ const routeDefinitions = RouteConfigResolver.defineControllerRouteConfigs({
31
63
  isStrict: isStrict.requestSchema ?? true,
32
64
  idType: entityInstance.getIdType(),
33
65
  authenticate,
@@ -121,7 +153,7 @@ export class ControllerFactory extends BaseHelper {
121
153
  }
122
154
  };
123
155
  Object.defineProperty(controllerClass, 'name', { value: name, configurable: true });
124
- registerFactoryRepositoryInjection({
156
+ ControllerFactory.registerRepositoryInjection({
125
157
  target: controllerClass,
126
158
  factoryName: 'defineCrudController',
127
159
  controllerName: name,
@@ -129,5 +161,57 @@ export class ControllerFactory extends BaseHelper {
129
161
  });
130
162
  return controllerClass;
131
163
  }
164
+ static describeSpec(opts) {
165
+ const { spec } = opts;
166
+ return `{ action: ${String(spec.action)}, resource: ${String(spec.resource)} }`;
167
+ }
168
+ /**
169
+ * Refuses a CRUD controller whose enabled write verb would inherit a controller-level `authorize`
170
+ * that is only a `read` permission: the verb would then answer to anyone who may read.
171
+ *
172
+ * A write verb is fine when it declares its own `authorize` (a spec, an array, or `{ skip: true }`),
173
+ * skips authentication, is not enabled, or the controller is `readonly`. Only the literal action
174
+ * `read` is detected; a custom action name is the application's own vocabulary. An array counts when
175
+ * every spec in it is `read`, since the specs of one route must all pass.
176
+ */
177
+ static assertWriteVerbsDeclareAuthorize(opts) {
178
+ const { controllerName, authorize, routes, readonly, enabledRoutes } = opts;
179
+ if (readonly || authorize == null) {
180
+ return;
181
+ }
182
+ const specs = Array.isArray(authorize) ? authorize : [authorize];
183
+ const isReadOnlyPermission = specs.length > 0 && specs.every((spec) => spec.action === AuthorizationActions.READ);
184
+ if (!isReadOnlyPermission) {
185
+ return;
186
+ }
187
+ const offending = ControllerFactory.WRITE_VERBS.filter((verb) => {
188
+ const isEnabled = enabledRoutes
189
+ ? enabledRoutes.includes(verb)
190
+ : routes?.[verb]?.enabled !== false;
191
+ if (!isEnabled) {
192
+ return false;
193
+ }
194
+ const route = routes?.[verb];
195
+ return route?.authenticate?.skip !== true && route?.authorize == null;
196
+ });
197
+ if (offending.length === 0) {
198
+ return;
199
+ }
200
+ const inherited = specs.map((spec) => ControllerFactory.describeSpec({ spec })).join(', ');
201
+ const verbs = offending.map((verb) => `${controllerName}.${verb}`).join(', ');
202
+ const hasBulkVerb = offending.some((verb) => verb === 'updateBy' || verb === 'deleteBy');
203
+ throw getError({
204
+ message: [
205
+ `[defineCrudController] Write routes would inherit a read-only authorize | controller: ${controllerName} | routes: ${verbs} | inherited: ${inherited}`,
206
+ 'Anyone allowed to read could then create, update or delete.',
207
+ `Fix: declare routes.<verb>.authorize for each of them (a spec, an array or { skip: true }), or set controller.readonly, or leave them out of controller.enabledRoutes.`,
208
+ ...(hasBulkVerb
209
+ ? [
210
+ 'updateBy and deleteBy are bulk routes on the collection and are generated unless controller.enabledRoutes lists the routes you want, so dropping them there closes this too.',
211
+ ]
212
+ : []),
213
+ ].join(' | '),
214
+ });
215
+ }
132
216
  }
133
217
  //# sourceMappingURL=controller.js.map