@webiny/api-core 6.4.5 → 6.6.0-alpha.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 (198) hide show
  1. package/ApiCoreFeature.d.ts +2 -2
  2. package/ApiCoreFeature.js +23 -5
  3. package/ApiCoreFeature.js.map +1 -1
  4. package/exports/api.d.ts +2 -1
  5. package/exports/api.js +2 -1
  6. package/features/ai/feature.js +4 -0
  7. package/features/ai/feature.js.map +1 -1
  8. package/features/ai/index.d.ts +2 -0
  9. package/features/ai/index.js +1 -0
  10. package/features/ai/toolPipeline/AiOutputToolRegistry.d.ts +11 -0
  11. package/features/ai/toolPipeline/AiOutputToolRegistry.js +31 -0
  12. package/features/ai/toolPipeline/AiOutputToolRegistry.js.map +1 -0
  13. package/features/ai/toolPipeline/AiToolPipelineRunner.d.ts +10 -0
  14. package/features/ai/toolPipeline/AiToolPipelineRunner.js +36 -0
  15. package/features/ai/toolPipeline/AiToolPipelineRunner.js.map +1 -0
  16. package/features/ai/toolPipeline/abstractions.d.ts +23 -0
  17. package/features/ai/toolPipeline/abstractions.js +7 -0
  18. package/features/ai/toolPipeline/abstractions.js.map +1 -0
  19. package/features/ai/toolPipeline/index.d.ts +2 -0
  20. package/features/ai/toolPipeline/index.js +1 -0
  21. package/features/hashing/ScryptHasher.d.ts +11 -0
  22. package/features/hashing/ScryptHasher.js +74 -0
  23. package/features/hashing/ScryptHasher.js.map +1 -0
  24. package/features/hashing/abstractions.d.ts +18 -0
  25. package/features/hashing/abstractions.js +5 -0
  26. package/features/hashing/abstractions.js.map +1 -0
  27. package/features/hashing/feature.d.ts +4 -0
  28. package/features/hashing/feature.js +11 -0
  29. package/features/hashing/feature.js.map +1 -0
  30. package/features/hashing/index.d.ts +2 -0
  31. package/features/hashing/index.js +1 -0
  32. package/features/requestContext/RawAuthToken.d.ts +14 -0
  33. package/features/requestContext/RawAuthToken.js +19 -0
  34. package/features/requestContext/RawAuthToken.js.map +1 -0
  35. package/features/requestContext/RawTenantId.d.ts +14 -0
  36. package/features/requestContext/RawTenantId.js +19 -0
  37. package/features/requestContext/RawTenantId.js.map +1 -0
  38. package/features/requestContext/RequestIdentityLoader.d.ts +19 -0
  39. package/features/requestContext/RequestIdentityLoader.js +26 -0
  40. package/features/requestContext/RequestIdentityLoader.js.map +1 -0
  41. package/features/requestContext/RequestTenantLoader.d.ts +18 -0
  42. package/features/requestContext/RequestTenantLoader.js +52 -0
  43. package/features/requestContext/RequestTenantLoader.js.map +1 -0
  44. package/features/requestContext/abstractions.d.ts +53 -0
  45. package/features/requestContext/abstractions.js +8 -0
  46. package/features/requestContext/abstractions.js.map +1 -0
  47. package/features/requestContext/feature.d.ts +11 -0
  48. package/features/requestContext/feature.js +17 -0
  49. package/features/requestContext/feature.js.map +1 -0
  50. package/features/requestContext/index.d.ts +2 -0
  51. package/features/requestContext/index.js +2 -0
  52. package/features/security/apiKeys/ApiKeyAuthenticator.d.ts +14 -0
  53. package/features/security/apiKeys/ApiKeyAuthenticator.js +36 -0
  54. package/features/security/apiKeys/ApiKeyAuthenticator.js.map +1 -0
  55. package/features/security/apiKeys/ApiKeyAuthorizer.d.ts +10 -0
  56. package/features/security/apiKeys/ApiKeyAuthorizer.js +15 -0
  57. package/features/security/apiKeys/ApiKeyAuthorizer.js.map +1 -0
  58. package/features/security/apiKeys/feature.js +4 -0
  59. package/features/security/apiKeys/feature.js.map +1 -1
  60. package/features/security/authorization/GroupsTeamsAuthorizer/GetPermissionsFromIdentity.d.ts +1 -1
  61. package/features/security/utils/getPermissionsFromRoles.d.ts +1 -1
  62. package/features/serviceDiscovery/ServiceDiscovery.d.ts +17 -0
  63. package/features/serviceDiscovery/ServiceDiscovery.js +22 -0
  64. package/features/serviceDiscovery/ServiceDiscovery.js.map +1 -0
  65. package/features/serviceDiscovery/__tests__/ServiceDiscovery.test.d.ts +1 -0
  66. package/features/serviceDiscovery/__tests__/ServiceDiscovery.test.js +111 -0
  67. package/features/serviceDiscovery/__tests__/ServiceDiscovery.test.js.map +1 -0
  68. package/features/serviceDiscovery/index.d.ts +3 -0
  69. package/features/serviceDiscovery/index.js +1 -0
  70. package/features/storageOperations/abstractions.d.ts +21 -0
  71. package/features/storageOperations/abstractions.js +10 -0
  72. package/features/storageOperations/abstractions.js.map +1 -0
  73. package/features/tenancy/CreateTenant/CreateTenantUseCase.d.ts +1 -1
  74. package/features/tenancy/InstallTenant/InstallTenantUseCase.d.ts +1 -1
  75. package/features/tenancy/UpdateTenant/UpdateTenantUseCase.d.ts +2 -2
  76. package/features/users/CreateUser/decorators/CreateUserWithWcpIncrement.d.ts +1 -1
  77. package/features/wcp/WcpContext/WcpContext.d.ts +4 -5
  78. package/features/wcp/WcpContext/WcpContext.js +5 -2
  79. package/features/wcp/WcpContext/WcpContext.js.map +1 -1
  80. package/features/wcp/WcpContext/decorators/WcpContextWithFeatureFlagsDecorator.d.ts +8 -8
  81. package/features/wcp/WcpContext/feature.d.ts +1 -2
  82. package/features/wcp/WcpContext/feature.js +2 -2
  83. package/features/wcp/WcpContext/feature.js.map +1 -1
  84. package/features/wcp/WcpContext/index.d.ts +0 -1
  85. package/features/wcp/WcpContext/types.d.ts +0 -4
  86. package/features/wcp/WcpFeature.d.ts +1 -1
  87. package/features/wcp/WcpFeature.js +5 -2
  88. package/features/wcp/WcpFeature.js.map +1 -1
  89. package/features/wcp/WcpLicenseProvider.d.ts +29 -0
  90. package/features/wcp/WcpLicenseProvider.js +18 -0
  91. package/features/wcp/WcpLicenseProvider.js.map +1 -0
  92. package/features/wcp/loadWcpLicense.d.ts +2 -0
  93. package/{legacy/wcp/context.js → features/wcp/loadWcpLicense.js} +24 -19
  94. package/features/wcp/loadWcpLicense.js.map +1 -0
  95. package/graphql/ApiCoreSchemaFactory.d.ts +15 -0
  96. package/graphql/ApiCoreSchemaFactory.js +52 -0
  97. package/graphql/ApiCoreSchemaFactory.js.map +1 -0
  98. package/graphql/security/NotAuthorizedResponse.d.ts +1 -1
  99. package/graphql/security/NotAuthorizedResponse.js +1 -1
  100. package/graphql/security/NotAuthorizedResponse.js.map +1 -1
  101. package/graphql/security/SecuritySchemaFactory.d.ts +14 -0
  102. package/graphql/security/SecuritySchemaFactory.js +23 -0
  103. package/graphql/security/SecuritySchemaFactory.js.map +1 -0
  104. package/graphql/security/addApiKeySchema.d.ts +2 -0
  105. package/graphql/security/{apiKey.gql.js → addApiKeySchema.js} +45 -27
  106. package/graphql/security/addApiKeySchema.js.map +1 -0
  107. package/graphql/security/addIdentitySchema.d.ts +2 -0
  108. package/graphql/security/{identity.gql.js → addIdentitySchema.js} +52 -35
  109. package/graphql/security/addIdentitySchema.js.map +1 -0
  110. package/graphql/security/addRoleSchema.d.ts +2 -0
  111. package/graphql/security/addRoleSchema.js +137 -0
  112. package/graphql/security/addRoleSchema.js.map +1 -0
  113. package/graphql/security/addSecurityBaseSchema.d.ts +2 -0
  114. package/graphql/security/{base.gql.js → addSecurityBaseSchema.js} +14 -16
  115. package/graphql/security/addSecurityBaseSchema.js.map +1 -0
  116. package/graphql/security/addTeamSchema.d.ts +2 -0
  117. package/graphql/security/addTeamSchema.js +157 -0
  118. package/graphql/security/addTeamSchema.js.map +1 -0
  119. package/graphql/system/SystemSchemaFactory.d.ts +9 -0
  120. package/graphql/system/SystemSchemaFactory.js +66 -0
  121. package/graphql/system/SystemSchemaFactory.js.map +1 -0
  122. package/graphql/users/UsersSchemaFactory.d.ts +9 -0
  123. package/graphql/users/UsersSchemaFactory.js +191 -0
  124. package/graphql/users/UsersSchemaFactory.js.map +1 -0
  125. package/graphql/wcp/WcpSchemaFactory.d.ts +9 -0
  126. package/graphql/wcp/{graphql.js → WcpSchemaFactory.js} +26 -18
  127. package/graphql/wcp/WcpSchemaFactory.js.map +1 -0
  128. package/index.d.ts +3 -1
  129. package/index.js +3 -1
  130. package/package.json +19 -22
  131. package/types/core.d.ts +17 -5
  132. package/types/security.d.ts +0 -6
  133. package/types/tenancy.d.ts +0 -17
  134. package/types/users.d.ts +0 -13
  135. package/createApiCore.d.ts +0 -7
  136. package/createApiCore.js +0 -22
  137. package/createApiCore.js.map +0 -1
  138. package/graphql/security/apiKey.gql.d.ts +0 -4
  139. package/graphql/security/apiKey.gql.js.map +0 -1
  140. package/graphql/security/base.gql.d.ts +0 -4
  141. package/graphql/security/base.gql.js.map +0 -1
  142. package/graphql/security/identity.gql.d.ts +0 -4
  143. package/graphql/security/identity.gql.js.map +0 -1
  144. package/graphql/security/index.d.ts +0 -1
  145. package/graphql/security/index.js +0 -15
  146. package/graphql/security/index.js.map +0 -1
  147. package/graphql/security/role.gql.d.ts +0 -4
  148. package/graphql/security/role.gql.js +0 -106
  149. package/graphql/security/role.gql.js.map +0 -1
  150. package/graphql/security/team.gql.d.ts +0 -4
  151. package/graphql/security/team.gql.js +0 -119
  152. package/graphql/security/team.gql.js.map +0 -1
  153. package/graphql/system/createSystemGraphQL.d.ts +0 -2
  154. package/graphql/system/createSystemGraphQL.js +0 -54
  155. package/graphql/system/createSystemGraphQL.js.map +0 -1
  156. package/graphql/users/user.gql.d.ts +0 -3
  157. package/graphql/users/user.gql.js +0 -167
  158. package/graphql/users/user.gql.js.map +0 -1
  159. package/graphql/wcp/graphql.d.ts +0 -2
  160. package/graphql/wcp/graphql.js.map +0 -1
  161. package/legacy/security/LegacyContext.d.ts +0 -36
  162. package/legacy/security/LegacyContext.js +0 -152
  163. package/legacy/security/LegacyContext.js.map +0 -1
  164. package/legacy/security/createSecurityContext.d.ts +0 -3
  165. package/legacy/security/createSecurityContext.js +0 -10
  166. package/legacy/security/createSecurityContext.js.map +0 -1
  167. package/legacy/security/plugins/apiKeyAuthentication.d.ts +0 -7
  168. package/legacy/security/plugins/apiKeyAuthentication.js +0 -20
  169. package/legacy/security/plugins/apiKeyAuthentication.js.map +0 -1
  170. package/legacy/security/plugins/apiKeyAuthorization.d.ts +0 -6
  171. package/legacy/security/plugins/apiKeyAuthorization.js +0 -13
  172. package/legacy/security/plugins/apiKeyAuthorization.js.map +0 -1
  173. package/legacy/security/plugins/authenticateUsingCookie.d.ts +0 -5
  174. package/legacy/security/plugins/authenticateUsingCookie.js +0 -23
  175. package/legacy/security/plugins/authenticateUsingCookie.js.map +0 -1
  176. package/legacy/security/plugins/authenticateUsingHttpHeader.d.ts +0 -5
  177. package/legacy/security/plugins/authenticateUsingHttpHeader.js +0 -20
  178. package/legacy/security/plugins/authenticateUsingHttpHeader.js.map +0 -1
  179. package/legacy/security/plugins/secureHeaders.d.ts +0 -1
  180. package/legacy/security/plugins/secureHeaders.js +0 -30
  181. package/legacy/security/plugins/secureHeaders.js.map +0 -1
  182. package/legacy/tenancy/LegacyContext.d.ts +0 -15
  183. package/legacy/tenancy/LegacyContext.js +0 -57
  184. package/legacy/tenancy/LegacyContext.js.map +0 -1
  185. package/legacy/tenancy/createTenancyContext.d.ts +0 -3
  186. package/legacy/tenancy/createTenancyContext.js +0 -31
  187. package/legacy/tenancy/createTenancyContext.js.map +0 -1
  188. package/legacy/users/LegacyContext.d.ts +0 -13
  189. package/legacy/users/LegacyContext.js +0 -55
  190. package/legacy/users/LegacyContext.js.map +0 -1
  191. package/legacy/users/createAdminUsersContext.d.ts +0 -3
  192. package/legacy/users/createAdminUsersContext.js +0 -12
  193. package/legacy/users/createAdminUsersContext.js.map +0 -1
  194. package/legacy/wcp/LegacyWcpContext.d.ts +0 -33
  195. package/legacy/wcp/LegacyWcpContext.js +0 -84
  196. package/legacy/wcp/LegacyWcpContext.js.map +0 -1
  197. package/legacy/wcp/context.d.ts +0 -5
  198. package/legacy/wcp/context.js.map +0 -1
@@ -0,0 +1,18 @@
1
+ import { RequestTenantLoader as Abstraction } from "./abstractions.js";
2
+ import type { IRawTenantId } from "./abstractions.js";
3
+ import type { ITenantContext } from "../../features/tenancy/TenantContext/abstractions.js";
4
+ import type { IGetTenantByIdUseCase } from "../../features/tenancy/GetTenantById/abstractions.js";
5
+ /**
6
+ * LOAD step: reads the raw tenant id (set by the transport's EXTRACT step into RawTenantId),
7
+ * resolves the Tenant, and sets TenantContext. Transport-agnostic.
8
+ */
9
+ export declare class RequestTenantLoaderImpl implements Abstraction.Interface {
10
+ private tenantContext;
11
+ private getTenantById;
12
+ private rawTenantId;
13
+ constructor(tenantContext: ITenantContext, getTenantById: IGetTenantByIdUseCase, rawTenantId: IRawTenantId);
14
+ establish(): Promise<void>;
15
+ }
16
+ export declare const RequestTenantLoader: typeof RequestTenantLoaderImpl & {
17
+ __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IRequestTenantLoader>;
18
+ };
@@ -0,0 +1,52 @@
1
+ import { RawTenantId, RequestTenantLoader } from "./abstractions.js";
2
+ import { TenantContext } from "../tenancy/TenantContext/index.js";
3
+ import { GetTenantByIdUseCase } from "../tenancy/GetTenantById/index.js";
4
+ const DEFAULT_TENANT_ID = "root";
5
+ const createBootstrapRootTenant = ()=>{
6
+ const now = new Date().toISOString();
7
+ return {
8
+ id: DEFAULT_TENANT_ID,
9
+ name: "Root",
10
+ description: "",
11
+ status: "enabled",
12
+ isInstalled: false,
13
+ settings: {
14
+ name: {
15
+ full: "Root",
16
+ slug: "root"
17
+ },
18
+ social: {},
19
+ favicon: {},
20
+ logo: {}
21
+ },
22
+ tags: [],
23
+ parent: null,
24
+ createdOn: now,
25
+ savedOn: now
26
+ };
27
+ };
28
+ class RequestTenantLoaderImpl {
29
+ constructor(tenantContext, getTenantById, rawTenantId){
30
+ this.tenantContext = tenantContext;
31
+ this.getTenantById = getTenantById;
32
+ this.rawTenantId = rawTenantId;
33
+ }
34
+ async establish() {
35
+ const resolvedId = this.rawTenantId.get() || DEFAULT_TENANT_ID;
36
+ const result = await this.getTenantById.execute(resolvedId);
37
+ if (result.isOk()) return void this.tenantContext.setTenant(result.value);
38
+ if (resolvedId === DEFAULT_TENANT_ID) return void this.tenantContext.setTenant(createBootstrapRootTenant());
39
+ console.warn(`[RequestTenantLoader] Tenant "${resolvedId}" not found.`);
40
+ }
41
+ }
42
+ const RequestTenantLoader_RequestTenantLoader = RequestTenantLoader.createImplementation({
43
+ implementation: RequestTenantLoaderImpl,
44
+ dependencies: [
45
+ TenantContext,
46
+ GetTenantByIdUseCase,
47
+ RawTenantId
48
+ ]
49
+ });
50
+ export { RequestTenantLoaderImpl, RequestTenantLoader_RequestTenantLoader as RequestTenantLoader };
51
+
52
+ //# sourceMappingURL=RequestTenantLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/requestContext/RequestTenantLoader.js","sources":["../../../src/features/requestContext/RequestTenantLoader.ts"],"sourcesContent":["import { RequestTenantLoader as Abstraction, RawTenantId } from \"./abstractions.js\";\nimport type { IRawTenantId } from \"./abstractions.js\";\nimport { TenantContext } from \"~/features/tenancy/TenantContext/index.js\";\nimport type { ITenantContext } from \"~/features/tenancy/TenantContext/abstractions.js\";\nimport { GetTenantByIdUseCase } from \"~/features/tenancy/GetTenantById/index.js\";\nimport type { IGetTenantByIdUseCase } from \"~/features/tenancy/GetTenantById/abstractions.js\";\nimport type { Tenant } from \"~/types/tenancy.js\";\n\nconst DEFAULT_TENANT_ID = \"root\";\n\n/**\n * A minimal in-memory root tenant used only before the system is installed, when the real root\n * tenant record doesn't exist yet. It keeps the request pipeline + GraphQL schema build functional\n * (nothing dereferences a null tenant) so the install mutation can run and create the real root.\n * Once installed, getTenantById returns the persisted record and this is never used.\n */\nconst createBootstrapRootTenant = (): Tenant => {\n const now = new Date().toISOString();\n return {\n id: DEFAULT_TENANT_ID,\n name: \"Root\",\n description: \"\",\n status: \"enabled\",\n isInstalled: false,\n settings: {\n name: { full: \"Root\", slug: \"root\" },\n social: {},\n favicon: {},\n logo: {}\n } as any,\n tags: [],\n parent: null,\n createdOn: now,\n savedOn: now\n };\n};\n\n/**\n * LOAD step: reads the raw tenant id (set by the transport's EXTRACT step into RawTenantId),\n * resolves the Tenant, and sets TenantContext. Transport-agnostic.\n */\nexport class RequestTenantLoaderImpl implements Abstraction.Interface {\n constructor(\n private tenantContext: ITenantContext,\n private getTenantById: IGetTenantByIdUseCase,\n private rawTenantId: IRawTenantId\n ) {}\n\n async establish(): Promise<void> {\n const resolvedId = this.rawTenantId.get() || DEFAULT_TENANT_ID;\n const result = await this.getTenantById.execute(resolvedId);\n if (result.isOk()) {\n this.tenantContext.setTenant(result.value);\n return;\n }\n\n // Fresh, not-yet-installed environment: the root tenant record doesn't exist yet. Establish a\n // bootstrap root so the request pipeline + GraphQL schema build work and the install mutation\n // can create the real root tenant. Only ever taken for the root tenant pre-install.\n if (resolvedId === DEFAULT_TENANT_ID) {\n this.tenantContext.setTenant(createBootstrapRootTenant());\n return;\n }\n\n console.warn(`[RequestTenantLoader] Tenant \"${resolvedId}\" not found.`);\n }\n}\n\nexport const RequestTenantLoader = Abstraction.createImplementation({\n implementation: RequestTenantLoaderImpl,\n dependencies: [TenantContext, GetTenantByIdUseCase, RawTenantId]\n});\n"],"names":["DEFAULT_TENANT_ID","createBootstrapRootTenant","now","Date","RequestTenantLoaderImpl","tenantContext","getTenantById","rawTenantId","resolvedId","result","console","RequestTenantLoader","Abstraction","TenantContext","GetTenantByIdUseCase","RawTenantId"],"mappings":";;;AAQA,MAAMA,oBAAoB;AAQ1B,MAAMC,4BAA4B;IAC9B,MAAMC,MAAM,IAAIC,OAAO,WAAW;IAClC,OAAO;QACH,IAAIH;QACJ,MAAM;QACN,aAAa;QACb,QAAQ;QACR,aAAa;QACb,UAAU;YACN,MAAM;gBAAE,MAAM;gBAAQ,MAAM;YAAO;YACnC,QAAQ,CAAC;YACT,SAAS,CAAC;YACV,MAAM,CAAC;QACX;QACA,MAAM,EAAE;QACR,QAAQ;QACR,WAAWE;QACX,SAASA;IACb;AACJ;AAMO,MAAME;IACT,YACYC,aAA6B,EAC7BC,aAAoC,EACpCC,WAAyB,CACnC;aAHUF,aAAa,GAAbA;aACAC,aAAa,GAAbA;aACAC,WAAW,GAAXA;IACT;IAEH,MAAM,YAA2B;QAC7B,MAAMC,aAAa,IAAI,CAAC,WAAW,CAAC,GAAG,MAAMR;QAC7C,MAAMS,SAAS,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAACD;QAChD,IAAIC,OAAO,IAAI,IAAI,YACf,IAAI,CAAC,aAAa,CAAC,SAAS,CAACA,OAAO,KAAK;QAO7C,IAAID,eAAeR,mBAAmB,YAClC,IAAI,CAAC,aAAa,CAAC,SAAS,CAACC;QAIjCS,QAAQ,IAAI,CAAC,CAAC,8BAA8B,EAAEF,WAAW,YAAY,CAAC;IAC1E;AACJ;AAEO,MAAMG,0CAAsBC,oBAAAA,oBAAgC,CAAC;IAChE,gBAAgBR;IAChB,cAAc;QAACS;QAAeC;QAAsBC;KAAY;AACpE"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Per-request holder for the raw tenant id EXTRACTED by the transport (e.g. the `x-tenant` header
3
+ * of an API Gateway event, the bucket name of an S3 event, or `payload.tenant` of a background
4
+ * task). The transport-specific EXTRACT step sets this; the transport-agnostic LOAD step
5
+ * (RequestTenantLoader) reads it, resolves the Tenant, and sets TenantContext.
6
+ */
7
+ export interface IRawTenantId {
8
+ get(): string | null;
9
+ set(id: string | null): void;
10
+ }
11
+ export declare const RawTenantId: import("@webiny/di").Abstraction<IRawTenantId>;
12
+ export declare namespace RawTenantId {
13
+ type Interface = IRawTenantId;
14
+ }
15
+ /**
16
+ * Per-request holder for the raw auth token EXTRACTED by the transport (e.g. the `Authorization`
17
+ * bearer header or an auth cookie of an API Gateway event). Only token-based transports set this;
18
+ * the transport-agnostic LOAD step (RequestIdentityLoader) reads it, authenticates it, and
19
+ * sets IdentityContext. A null/absent value authenticates as anonymous.
20
+ *
21
+ * Note: non-token transports (S3, background tasks) never set this — S3 has no user identity, and
22
+ * background-task identity is derived from `task.createdBy` after the task is fetched.
23
+ */
24
+ export interface IRawAuthToken {
25
+ get(): string | null;
26
+ set(token: string | null): void;
27
+ }
28
+ export declare const RawAuthToken: import("@webiny/di").Abstraction<IRawAuthToken>;
29
+ export declare namespace RawAuthToken {
30
+ type Interface = IRawAuthToken;
31
+ }
32
+ /**
33
+ * LOAD step: authenticates the token held by RawAuthToken and sets IdentityContext. Fully
34
+ * transport-agnostic — transports only EXTRACT the token into RawAuthToken.
35
+ */
36
+ export interface IRequestIdentityLoader {
37
+ establish(): Promise<void>;
38
+ }
39
+ export declare const RequestIdentityLoader: import("@webiny/di").Abstraction<IRequestIdentityLoader>;
40
+ export declare namespace RequestIdentityLoader {
41
+ type Interface = IRequestIdentityLoader;
42
+ }
43
+ /**
44
+ * LOAD step: resolves the Tenant for the id held by RawTenantId and sets TenantContext. Fully
45
+ * transport-agnostic — transports only EXTRACT the id into RawTenantId.
46
+ */
47
+ export interface IRequestTenantLoader {
48
+ establish(): Promise<void>;
49
+ }
50
+ export declare const RequestTenantLoader: import("@webiny/di").Abstraction<IRequestTenantLoader>;
51
+ export declare namespace RequestTenantLoader {
52
+ type Interface = IRequestTenantLoader;
53
+ }
@@ -0,0 +1,8 @@
1
+ import { createAbstraction } from "@webiny/feature/api";
2
+ const RawTenantId = createAbstraction("RequestContext/RawTenantId");
3
+ const RawAuthToken = createAbstraction("RequestContext/RawAuthToken");
4
+ const RequestIdentityLoader = createAbstraction("RequestContext/RequestIdentityLoader");
5
+ const RequestTenantLoader = createAbstraction("RequestContext/RequestTenantLoader");
6
+ export { RawAuthToken, RawTenantId, RequestIdentityLoader, RequestTenantLoader };
7
+
8
+ //# sourceMappingURL=abstractions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/requestContext/abstractions.js","sources":["../../../src/features/requestContext/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\n\n/**\n * Per-request holder for the raw tenant id EXTRACTED by the transport (e.g. the `x-tenant` header\n * of an API Gateway event, the bucket name of an S3 event, or `payload.tenant` of a background\n * task). The transport-specific EXTRACT step sets this; the transport-agnostic LOAD step\n * (RequestTenantLoader) reads it, resolves the Tenant, and sets TenantContext.\n */\nexport interface IRawTenantId {\n get(): string | null;\n set(id: string | null): void;\n}\n\nexport const RawTenantId = createAbstraction<IRawTenantId>(\"RequestContext/RawTenantId\");\n\nexport namespace RawTenantId {\n export type Interface = IRawTenantId;\n}\n\n/**\n * Per-request holder for the raw auth token EXTRACTED by the transport (e.g. the `Authorization`\n * bearer header or an auth cookie of an API Gateway event). Only token-based transports set this;\n * the transport-agnostic LOAD step (RequestIdentityLoader) reads it, authenticates it, and\n * sets IdentityContext. A null/absent value authenticates as anonymous.\n *\n * Note: non-token transports (S3, background tasks) never set this — S3 has no user identity, and\n * background-task identity is derived from `task.createdBy` after the task is fetched.\n */\nexport interface IRawAuthToken {\n get(): string | null;\n set(token: string | null): void;\n}\n\nexport const RawAuthToken = createAbstraction<IRawAuthToken>(\"RequestContext/RawAuthToken\");\n\nexport namespace RawAuthToken {\n export type Interface = IRawAuthToken;\n}\n\n/**\n * LOAD step: authenticates the token held by RawAuthToken and sets IdentityContext. Fully\n * transport-agnostic — transports only EXTRACT the token into RawAuthToken.\n */\nexport interface IRequestIdentityLoader {\n establish(): Promise<void>;\n}\n\nexport const RequestIdentityLoader = createAbstraction<IRequestIdentityLoader>(\n \"RequestContext/RequestIdentityLoader\"\n);\n\nexport namespace RequestIdentityLoader {\n export type Interface = IRequestIdentityLoader;\n}\n\n/**\n * LOAD step: resolves the Tenant for the id held by RawTenantId and sets TenantContext. Fully\n * transport-agnostic — transports only EXTRACT the id into RawTenantId.\n */\nexport interface IRequestTenantLoader {\n establish(): Promise<void>;\n}\n\nexport const RequestTenantLoader = createAbstraction<IRequestTenantLoader>(\n \"RequestContext/RequestTenantLoader\"\n);\n\nexport namespace RequestTenantLoader {\n export type Interface = IRequestTenantLoader;\n}\n"],"names":["RawTenantId","createAbstraction","RawAuthToken","RequestIdentityLoader","RequestTenantLoader"],"mappings":";AAaO,MAAMA,cAAcC,kBAAgC;AAoBpD,MAAMC,eAAeD,kBAAiC;AActD,MAAME,wBAAwBF,kBACjC;AAeG,MAAMG,sBAAsBH,kBAC/B"}
@@ -0,0 +1,11 @@
1
+ import type { Container } from "@webiny/di";
2
+ /**
3
+ * Registers the request-context pieces:
4
+ * - RawTenantId / RawAuthToken: per-request holders that the transport's EXTRACT step writes to.
5
+ * - RequestIdentityLoader / RequestTenantLoader: transport-agnostic LOAD steps that read
6
+ * the holders and set IdentityContext / TenantContext.
7
+ */
8
+ export declare const RequestContextFeature: {
9
+ name: string;
10
+ register(container: Container): void;
11
+ };
@@ -0,0 +1,17 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { RawTenantId } from "./RawTenantId.js";
3
+ import { RawAuthToken } from "./RawAuthToken.js";
4
+ import { RequestIdentityLoader } from "./RequestIdentityLoader.js";
5
+ import { RequestTenantLoader } from "./RequestTenantLoader.js";
6
+ const RequestContextFeature = createFeature({
7
+ name: "RequestContext",
8
+ register (container) {
9
+ container.register(RawTenantId).inSingletonScope();
10
+ container.register(RawAuthToken).inSingletonScope();
11
+ container.register(RequestIdentityLoader);
12
+ container.register(RequestTenantLoader);
13
+ }
14
+ });
15
+ export { RequestContextFeature };
16
+
17
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/requestContext/feature.js","sources":["../../../src/features/requestContext/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport type { Container } from \"@webiny/di\";\nimport { RawTenantId } from \"./RawTenantId.js\";\nimport { RawAuthToken } from \"./RawAuthToken.js\";\nimport { RequestIdentityLoader } from \"./RequestIdentityLoader.js\";\nimport { RequestTenantLoader } from \"./RequestTenantLoader.js\";\n\n/**\n * Registers the request-context pieces:\n * - RawTenantId / RawAuthToken: per-request holders that the transport's EXTRACT step writes to.\n * - RequestIdentityLoader / RequestTenantLoader: transport-agnostic LOAD steps that read\n * the holders and set IdentityContext / TenantContext.\n */\nexport const RequestContextFeature = createFeature({\n name: \"RequestContext\",\n register(container: Container) {\n // Singleton so the value the transport's EXTRACT step sets is the same instance the LOAD\n // establisher reads. Registered per request (RequestContextFeature runs per-request), so it's\n // singleton *within the request container* — a fresh holder per request.\n container.register(RawTenantId).inSingletonScope();\n container.register(RawAuthToken).inSingletonScope();\n container.register(RequestIdentityLoader);\n container.register(RequestTenantLoader);\n }\n});\n"],"names":["RequestContextFeature","createFeature","container","RawTenantId","RawAuthToken","RequestIdentityLoader","RequestTenantLoader"],"mappings":";;;;;AAaO,MAAMA,wBAAwBC,cAAc;IAC/C,MAAM;IACN,UAASC,SAAoB;QAIzBA,UAAU,QAAQ,CAACC,aAAa,gBAAgB;QAChDD,UAAU,QAAQ,CAACE,cAAc,gBAAgB;QACjDF,UAAU,QAAQ,CAACG;QACnBH,UAAU,QAAQ,CAACI;IACvB;AACJ"}
@@ -0,0 +1,2 @@
1
+ export { RawTenantId, RawAuthToken, RequestIdentityLoader, RequestTenantLoader } from "./abstractions.js";
2
+ export { RequestContextFeature } from "./feature.js";
@@ -0,0 +1,2 @@
1
+ export { RawAuthToken, RawTenantId, RequestIdentityLoader, RequestTenantLoader } from "./abstractions.js";
2
+ export { RequestContextFeature } from "./feature.js";
@@ -0,0 +1,14 @@
1
+ import { Logger } from "../../../features/logger/index.js";
2
+ import type { IAuthenticator } from "../../../features/security/authentication/Authenticator/abstractions.js";
3
+ import type { IApiKeysRepository } from "./shared/abstractions.js";
4
+ import type { IdentityData } from "../../../features/security/IdentityContext/Identity.js";
5
+ declare class ApiKeyAuthenticatorImpl implements IAuthenticator {
6
+ private repository;
7
+ private logger;
8
+ constructor(repository: IApiKeysRepository, logger: Logger.Interface);
9
+ authenticate(token: string): Promise<IdentityData | null>;
10
+ }
11
+ export declare const ApiKeyAuthenticator: typeof ApiKeyAuthenticatorImpl & {
12
+ __abstraction: import("@webiny/di").Abstraction<IAuthenticator>;
13
+ };
14
+ export {};
@@ -0,0 +1,36 @@
1
+ import { Authenticator } from "../authentication/Authenticator/abstractions.js";
2
+ import { ApiKeysRepository } from "./shared/abstractions.js";
3
+ import { Logger } from "../../logger/index.js";
4
+ class ApiKeyAuthenticatorImpl {
5
+ constructor(repository, logger){
6
+ this.repository = repository;
7
+ this.logger = logger;
8
+ }
9
+ async authenticate(token) {
10
+ if ("string" != typeof token || !token.startsWith("wat_")) return null;
11
+ const result = await this.repository.getByToken(token);
12
+ if (!result.isOk()) {
13
+ this.logger.warn({
14
+ error: result.error
15
+ }, "API key authentication failed; request will proceed as anonymous.");
16
+ return null;
17
+ }
18
+ const apiKey = result.value;
19
+ return {
20
+ id: apiKey.id,
21
+ displayName: apiKey.name,
22
+ type: "api-key",
23
+ permissions: apiKey.permissions
24
+ };
25
+ }
26
+ }
27
+ const ApiKeyAuthenticator = Authenticator.createImplementation({
28
+ implementation: ApiKeyAuthenticatorImpl,
29
+ dependencies: [
30
+ ApiKeysRepository,
31
+ Logger
32
+ ]
33
+ });
34
+ export { ApiKeyAuthenticator };
35
+
36
+ //# sourceMappingURL=ApiKeyAuthenticator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/security/apiKeys/ApiKeyAuthenticator.js","sources":["../../../../src/features/security/apiKeys/ApiKeyAuthenticator.ts"],"sourcesContent":["import { Authenticator } from \"~/features/security/authentication/Authenticator/abstractions.js\";\nimport { ApiKeysRepository } from \"./shared/abstractions.js\";\nimport { Logger } from \"~/features/logger/index.js\";\nimport type { IAuthenticator } from \"~/features/security/authentication/Authenticator/abstractions.js\";\nimport type { IApiKeysRepository } from \"./shared/abstractions.js\";\nimport type { IdentityData } from \"~/features/security/IdentityContext/Identity.js\";\n\nclass ApiKeyAuthenticatorImpl implements IAuthenticator {\n constructor(\n private repository: IApiKeysRepository,\n private logger: Logger.Interface\n ) {}\n\n async authenticate(token: string): Promise<IdentityData | null> {\n if (typeof token !== \"string\" || !token.startsWith(\"wat_\")) {\n return null;\n }\n const result = await this.repository.getByToken(token);\n if (!result.isOk()) {\n // The token looked like an API key (\"wat_\") but could not be resolved. Log it — otherwise\n // this degrades silently to an anonymous request (which is what made the tenant-ordering\n // bug so hard to find). A genuine unknown/revoked key logs here too, which is acceptable.\n this.logger.warn(\n { error: result.error },\n \"API key authentication failed; request will proceed as anonymous.\"\n );\n return null;\n }\n const apiKey = result.value;\n return {\n id: apiKey.id,\n displayName: apiKey.name,\n type: \"api-key\",\n permissions: apiKey.permissions\n };\n }\n}\n\nexport const ApiKeyAuthenticator = Authenticator.createImplementation({\n implementation: ApiKeyAuthenticatorImpl,\n dependencies: [ApiKeysRepository, Logger]\n});\n"],"names":["ApiKeyAuthenticatorImpl","repository","logger","token","result","apiKey","ApiKeyAuthenticator","Authenticator","ApiKeysRepository","Logger"],"mappings":";;;AAOA,MAAMA;IACF,YACYC,UAA8B,EAC9BC,MAAwB,CAClC;aAFUD,UAAU,GAAVA;aACAC,MAAM,GAANA;IACT;IAEH,MAAM,aAAaC,KAAa,EAAgC;QAC5D,IAAI,AAAiB,YAAjB,OAAOA,SAAsB,CAACA,MAAM,UAAU,CAAC,SAC/C,OAAO;QAEX,MAAMC,SAAS,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAACD;QAChD,IAAI,CAACC,OAAO,IAAI,IAAI;YAIhB,IAAI,CAAC,MAAM,CAAC,IAAI,CACZ;gBAAE,OAAOA,OAAO,KAAK;YAAC,GACtB;YAEJ,OAAO;QACX;QACA,MAAMC,SAASD,OAAO,KAAK;QAC3B,OAAO;YACH,IAAIC,OAAO,EAAE;YACb,aAAaA,OAAO,IAAI;YACxB,MAAM;YACN,aAAaA,OAAO,WAAW;QACnC;IACJ;AACJ;AAEO,MAAMC,sBAAsBC,cAAc,oBAAoB,CAAC;IAClE,gBAAgBP;IAChB,cAAc;QAACQ;QAAmBC;KAAO;AAC7C"}
@@ -0,0 +1,10 @@
1
+ import type { IAuthorizer } from "../../../features/security/authorization/Authorizer/abstractions.js";
2
+ import type { Identity } from "../../../features/security/IdentityContext/Identity.js";
3
+ import type { SecurityPermission } from "../../../types/security.js";
4
+ declare class ApiKeyAuthorizerImpl implements IAuthorizer {
5
+ authorize(identity: Identity): Promise<SecurityPermission[] | null>;
6
+ }
7
+ export declare const ApiKeyAuthorizer: typeof ApiKeyAuthorizerImpl & {
8
+ __abstraction: import("@webiny/di").Abstraction<IAuthorizer>;
9
+ };
10
+ export {};
@@ -0,0 +1,15 @@
1
+ import { Authorizer } from "../authorization/Authorizer/abstractions.js";
2
+ class ApiKeyAuthorizerImpl {
3
+ async authorize(identity) {
4
+ if (!identity || "api-key" !== identity.type) return null;
5
+ const permissions = identity.permissions;
6
+ return Array.isArray(permissions) ? permissions : [];
7
+ }
8
+ }
9
+ const ApiKeyAuthorizer = Authorizer.createImplementation({
10
+ implementation: ApiKeyAuthorizerImpl,
11
+ dependencies: []
12
+ });
13
+ export { ApiKeyAuthorizer };
14
+
15
+ //# sourceMappingURL=ApiKeyAuthorizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/security/apiKeys/ApiKeyAuthorizer.js","sources":["../../../../src/features/security/apiKeys/ApiKeyAuthorizer.ts"],"sourcesContent":["import { Authorizer } from \"~/features/security/authorization/Authorizer/abstractions.js\";\nimport type { IAuthorizer } from \"~/features/security/authorization/Authorizer/abstractions.js\";\nimport type { Identity } from \"~/features/security/IdentityContext/Identity.js\";\nimport type { SecurityPermission } from \"~/types/security.js\";\n\nclass ApiKeyAuthorizerImpl implements IAuthorizer {\n async authorize(identity: Identity): Promise<SecurityPermission[] | null> {\n if (!identity || identity.type !== \"api-key\") {\n return null;\n }\n const permissions = (identity as any).permissions;\n return Array.isArray(permissions) ? (permissions as SecurityPermission[]) : [];\n }\n}\n\nexport const ApiKeyAuthorizer = Authorizer.createImplementation({\n implementation: ApiKeyAuthorizerImpl,\n dependencies: []\n});\n"],"names":["ApiKeyAuthorizerImpl","identity","permissions","Array","ApiKeyAuthorizer","Authorizer"],"mappings":";AAKA,MAAMA;IACF,MAAM,UAAUC,QAAkB,EAAwC;QACtE,IAAI,CAACA,YAAYA,AAAkB,cAAlBA,SAAS,IAAI,EAC1B,OAAO;QAEX,MAAMC,cAAeD,SAAiB,WAAW;QACjD,OAAOE,MAAM,OAAO,CAACD,eAAgBA,cAAuC,EAAE;IAClF;AACJ;AAEO,MAAME,mBAAmBC,WAAW,oBAAoB,CAAC;IAC5D,gBAAgBL;IAChB,cAAc,EAAE;AACpB"}
@@ -8,11 +8,15 @@ import { CreateApiKeyFeature } from "./CreateApiKey/feature.js";
8
8
  import { UpdateApiKeyFeature } from "./UpdateApiKey/feature.js";
9
9
  import { DeleteApiKeyFeature } from "./DeleteApiKey/feature.js";
10
10
  import { ApiKeyProvider } from "./shared/ApiKeyProvider.js";
11
+ import { ApiKeyAuthenticator } from "./ApiKeyAuthenticator.js";
12
+ import { ApiKeyAuthorizer } from "./ApiKeyAuthorizer.js";
11
13
  const ApiKeysFeature = createFeature({
12
14
  name: "ApiKeys",
13
15
  register (container) {
14
16
  container.register(ApiKeysRepository).inSingletonScope();
15
17
  container.register(ApiKeyProvider).inSingletonScope();
18
+ container.register(ApiKeyAuthenticator);
19
+ container.register(ApiKeyAuthorizer);
16
20
  GetApiKeyFeature.register(container);
17
21
  GetApiKeyByTokenFeature.register(container);
18
22
  GetApiKeyBySlugFeature.register(container);
@@ -1 +1 @@
1
- {"version":3,"file":"features/security/apiKeys/feature.js","sources":["../../../../src/features/security/apiKeys/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { ApiKeysRepository } from \"./shared/ApiKeysRepository.js\";\nimport { GetApiKeyFeature } from \"./GetApiKey/feature.js\";\nimport { GetApiKeyByTokenFeature } from \"./GetApiKeyByToken/feature.js\";\nimport { GetApiKeyBySlugFeature } from \"./GetApiKeyBySlug/feature.js\";\nimport { ListApiKeysFeature } from \"./ListApiKeys/feature.js\";\nimport { CreateApiKeyFeature } from \"./CreateApiKey/feature.js\";\nimport { UpdateApiKeyFeature } from \"./UpdateApiKey/feature.js\";\nimport { DeleteApiKeyFeature } from \"./DeleteApiKey/feature.js\";\nimport { ApiKeyProvider } from \"./shared/ApiKeyProvider.js\";\n\nexport const ApiKeysFeature = createFeature({\n name: \"ApiKeys\",\n register(container) {\n // Register repository in singleton scope\n container.register(ApiKeysRepository).inSingletonScope();\n container.register(ApiKeyProvider).inSingletonScope();\n\n // Register all use cases\n GetApiKeyFeature.register(container);\n GetApiKeyByTokenFeature.register(container);\n GetApiKeyBySlugFeature.register(container);\n ListApiKeysFeature.register(container);\n CreateApiKeyFeature.register(container);\n UpdateApiKeyFeature.register(container);\n DeleteApiKeyFeature.register(container);\n }\n});\n"],"names":["ApiKeysFeature","createFeature","container","ApiKeysRepository","ApiKeyProvider","GetApiKeyFeature","GetApiKeyByTokenFeature","GetApiKeyBySlugFeature","ListApiKeysFeature","CreateApiKeyFeature","UpdateApiKeyFeature","DeleteApiKeyFeature"],"mappings":";;;;;;;;;;AAWO,MAAMA,iBAAiBC,cAAc;IACxC,MAAM;IACN,UAASC,SAAS;QAEdA,UAAU,QAAQ,CAACC,mBAAmB,gBAAgB;QACtDD,UAAU,QAAQ,CAACE,gBAAgB,gBAAgB;QAGnDC,iBAAiB,QAAQ,CAACH;QAC1BI,wBAAwB,QAAQ,CAACJ;QACjCK,uBAAuB,QAAQ,CAACL;QAChCM,mBAAmB,QAAQ,CAACN;QAC5BO,oBAAoB,QAAQ,CAACP;QAC7BQ,oBAAoB,QAAQ,CAACR;QAC7BS,oBAAoB,QAAQ,CAACT;IACjC;AACJ"}
1
+ {"version":3,"file":"features/security/apiKeys/feature.js","sources":["../../../../src/features/security/apiKeys/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { ApiKeysRepository } from \"./shared/ApiKeysRepository.js\";\nimport { GetApiKeyFeature } from \"./GetApiKey/feature.js\";\nimport { GetApiKeyByTokenFeature } from \"./GetApiKeyByToken/feature.js\";\nimport { GetApiKeyBySlugFeature } from \"./GetApiKeyBySlug/feature.js\";\nimport { ListApiKeysFeature } from \"./ListApiKeys/feature.js\";\nimport { CreateApiKeyFeature } from \"./CreateApiKey/feature.js\";\nimport { UpdateApiKeyFeature } from \"./UpdateApiKey/feature.js\";\nimport { DeleteApiKeyFeature } from \"./DeleteApiKey/feature.js\";\nimport { ApiKeyProvider } from \"./shared/ApiKeyProvider.js\";\nimport { ApiKeyAuthenticator } from \"./ApiKeyAuthenticator.js\";\nimport { ApiKeyAuthorizer } from \"./ApiKeyAuthorizer.js\";\n\nexport const ApiKeysFeature = createFeature({\n name: \"ApiKeys\",\n register(container) {\n // Register repository in singleton scope\n container.register(ApiKeysRepository).inSingletonScope();\n container.register(ApiKeyProvider).inSingletonScope();\n container.register(ApiKeyAuthenticator);\n container.register(ApiKeyAuthorizer);\n\n // Register all use cases\n GetApiKeyFeature.register(container);\n GetApiKeyByTokenFeature.register(container);\n GetApiKeyBySlugFeature.register(container);\n ListApiKeysFeature.register(container);\n CreateApiKeyFeature.register(container);\n UpdateApiKeyFeature.register(container);\n DeleteApiKeyFeature.register(container);\n }\n});\n"],"names":["ApiKeysFeature","createFeature","container","ApiKeysRepository","ApiKeyProvider","ApiKeyAuthenticator","ApiKeyAuthorizer","GetApiKeyFeature","GetApiKeyByTokenFeature","GetApiKeyBySlugFeature","ListApiKeysFeature","CreateApiKeyFeature","UpdateApiKeyFeature","DeleteApiKeyFeature"],"mappings":";;;;;;;;;;;;AAaO,MAAMA,iBAAiBC,cAAc;IACxC,MAAM;IACN,UAASC,SAAS;QAEdA,UAAU,QAAQ,CAACC,mBAAmB,gBAAgB;QACtDD,UAAU,QAAQ,CAACE,gBAAgB,gBAAgB;QACnDF,UAAU,QAAQ,CAACG;QACnBH,UAAU,QAAQ,CAACI;QAGnBC,iBAAiB,QAAQ,CAACL;QAC1BM,wBAAwB,QAAQ,CAACN;QACjCO,uBAAuB,QAAQ,CAACP;QAChCQ,mBAAmB,QAAQ,CAACR;QAC5BS,oBAAoB,QAAQ,CAACT;QAC7BU,oBAAoB,QAAQ,CAACV;QAC7BW,oBAAoB,QAAQ,CAACX;IACjC;AACJ"}
@@ -13,8 +13,8 @@ declare class GetPermissionsFromGroupsAndTeamsImpl implements PermissionsProcess
13
13
  private teamsRepository;
14
14
  constructor(wcpContext: WcpContext.Interface, usersRepository: AdminUsersRepository.Interface, rolesRepository: RolesRepository.Interface, teamsRepository: TeamsRepository.Interface);
15
15
  getPermissions(identity: Identity): Promise<{
16
- _src: string;
17
16
  name: string;
17
+ _src: string;
18
18
  }[] | null>;
19
19
  }
20
20
  export declare const GetPermissionsFromIdentity: typeof GetPermissionsFromGroupsAndTeamsImpl & {
@@ -3,6 +3,6 @@ export declare const getPermissionsFromRoles: (securityGroups: Array<{
3
3
  permissions: SecurityPermission[];
4
4
  id: string;
5
5
  }>) => {
6
- _src: string;
7
6
  name: string;
7
+ _src: string;
8
8
  }[];
@@ -0,0 +1,17 @@
1
+ import type { GenericRecord } from "@webiny/api/types.js";
2
+ export interface IServiceManifest {
3
+ name: string;
4
+ manifest: GenericRecord<string>;
5
+ }
6
+ export interface IServiceManifestLoader {
7
+ load(): Promise<IServiceManifest[] | undefined>;
8
+ }
9
+ type Manifest = GenericRecord<string>;
10
+ export declare class ServiceDiscovery {
11
+ private static loader;
12
+ private static manifest;
13
+ static setLoader(loader: IServiceManifestLoader): void;
14
+ static load(): Promise<Manifest | undefined>;
15
+ static clear(): void;
16
+ }
17
+ export {};
@@ -0,0 +1,22 @@
1
+ class ServiceDiscovery {
2
+ static setLoader(loader) {
3
+ this.loader = loader;
4
+ }
5
+ static async load() {
6
+ if (this.manifest) return this.manifest;
7
+ if (!this.loader) throw new Error("ServiceDiscovery loader not configured. Call ServiceDiscovery.setLoader() before loading manifests.");
8
+ const manifests = await this.loader.load();
9
+ if (!manifests) return;
10
+ this.manifest = manifests.reduce((acc, item)=>({
11
+ ...acc,
12
+ [item.name]: item.manifest
13
+ }), {});
14
+ return this.manifest;
15
+ }
16
+ static clear() {
17
+ this.manifest = void 0;
18
+ }
19
+ }
20
+ export { ServiceDiscovery };
21
+
22
+ //# sourceMappingURL=ServiceDiscovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/serviceDiscovery/ServiceDiscovery.js","sources":["../../../src/features/serviceDiscovery/ServiceDiscovery.ts"],"sourcesContent":["import type { GenericRecord } from \"@webiny/api/types.js\";\n\nexport interface IServiceManifest {\n name: string;\n manifest: GenericRecord<string>;\n}\n\nexport interface IServiceManifestLoader {\n load(): Promise<IServiceManifest[] | undefined>;\n}\n\ntype Manifest = GenericRecord<string>;\n\nexport class ServiceDiscovery {\n private static loader: IServiceManifestLoader | undefined;\n private static manifest: Manifest | undefined;\n\n static setLoader(loader: IServiceManifestLoader): void {\n this.loader = loader;\n }\n\n static async load(): Promise<Manifest | undefined> {\n if (this.manifest) {\n return this.manifest;\n }\n\n if (!this.loader) {\n throw new Error(\n \"ServiceDiscovery loader not configured. Call ServiceDiscovery.setLoader() before loading manifests.\"\n );\n }\n\n const manifests = await this.loader.load();\n\n if (!manifests) {\n return undefined;\n }\n\n this.manifest = manifests.reduce<Manifest>((acc, item) => {\n return { ...acc, [item.name]: item.manifest };\n }, {});\n\n return this.manifest;\n }\n\n static clear(): void {\n this.manifest = undefined;\n }\n}\n"],"names":["ServiceDiscovery","loader","Error","manifests","acc","item","undefined"],"mappings":"AAaO,MAAMA;IAIT,OAAO,UAAUC,MAA8B,EAAQ;QACnD,IAAI,CAAC,MAAM,GAAGA;IAClB;IAEA,aAAa,OAAsC;QAC/C,IAAI,IAAI,CAAC,QAAQ,EACb,OAAO,IAAI,CAAC,QAAQ;QAGxB,IAAI,CAAC,IAAI,CAAC,MAAM,EACZ,MAAM,IAAIC,MACN;QAIR,MAAMC,YAAY,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI;QAExC,IAAI,CAACA,WACD;QAGJ,IAAI,CAAC,QAAQ,GAAGA,UAAU,MAAM,CAAW,CAACC,KAAKC,OACtC;gBAAE,GAAGD,GAAG;gBAAE,CAACC,KAAK,IAAI,CAAC,EAAEA,KAAK,QAAQ;YAAC,IAC7C,CAAC;QAEJ,OAAO,IAAI,CAAC,QAAQ;IACxB;IAEA,OAAO,QAAc;QACjB,IAAI,CAAC,QAAQ,GAAGC;IACpB;AACJ"}
@@ -0,0 +1,111 @@
1
+ import { beforeEach, describe, expect, it } from "vitest";
2
+ import { ServiceDiscovery } from "../ServiceDiscovery.js";
3
+ describe("ServiceDiscovery", ()=>{
4
+ beforeEach(()=>{
5
+ ServiceDiscovery.clear();
6
+ });
7
+ it("should throw if no loader is set", async ()=>{
8
+ ServiceDiscovery.loader = void 0;
9
+ await expect(ServiceDiscovery.load()).rejects.toThrow("ServiceDiscovery loader not configured");
10
+ });
11
+ it("should load manifests and combine them by name", async ()=>{
12
+ const loader = {
13
+ async load () {
14
+ return [
15
+ {
16
+ name: "api",
17
+ manifest: {
18
+ cloudfront: {
19
+ distributionId: "123"
20
+ }
21
+ }
22
+ },
23
+ {
24
+ name: "core",
25
+ manifest: {
26
+ bucket: {
27
+ name: "my-bucket"
28
+ }
29
+ }
30
+ }
31
+ ];
32
+ }
33
+ };
34
+ ServiceDiscovery.setLoader(loader);
35
+ const result = await ServiceDiscovery.load();
36
+ expect(result).toEqual({
37
+ api: {
38
+ cloudfront: {
39
+ distributionId: "123"
40
+ }
41
+ },
42
+ core: {
43
+ bucket: {
44
+ name: "my-bucket"
45
+ }
46
+ }
47
+ });
48
+ });
49
+ it("should cache the result and not call loader again", async ()=>{
50
+ let callCount = 0;
51
+ const loader = {
52
+ async load () {
53
+ callCount++;
54
+ return [
55
+ {
56
+ name: "api",
57
+ manifest: {
58
+ url: "https://example.com"
59
+ }
60
+ }
61
+ ];
62
+ }
63
+ };
64
+ ServiceDiscovery.setLoader(loader);
65
+ await ServiceDiscovery.load();
66
+ await ServiceDiscovery.load();
67
+ await ServiceDiscovery.load();
68
+ expect(callCount).toBe(1);
69
+ });
70
+ it("should return undefined when loader returns undefined", async ()=>{
71
+ const loader = {
72
+ async load () {}
73
+ };
74
+ ServiceDiscovery.setLoader(loader);
75
+ const result = await ServiceDiscovery.load();
76
+ expect(result).toBeUndefined();
77
+ });
78
+ it("should reload after clear()", async ()=>{
79
+ let callCount = 0;
80
+ const loader = {
81
+ async load () {
82
+ callCount++;
83
+ return [
84
+ {
85
+ name: "api",
86
+ manifest: {
87
+ version: callCount
88
+ }
89
+ }
90
+ ];
91
+ }
92
+ };
93
+ ServiceDiscovery.setLoader(loader);
94
+ const first = await ServiceDiscovery.load();
95
+ expect(first).toEqual({
96
+ api: {
97
+ version: 1
98
+ }
99
+ });
100
+ ServiceDiscovery.clear();
101
+ const second = await ServiceDiscovery.load();
102
+ expect(second).toEqual({
103
+ api: {
104
+ version: 2
105
+ }
106
+ });
107
+ expect(callCount).toBe(2);
108
+ });
109
+ });
110
+
111
+ //# sourceMappingURL=ServiceDiscovery.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/serviceDiscovery/__tests__/ServiceDiscovery.test.js","sources":["../../../../src/features/serviceDiscovery/__tests__/ServiceDiscovery.test.ts"],"sourcesContent":["import { describe, it, expect, beforeEach } from \"vitest\";\nimport { ServiceDiscovery } from \"../ServiceDiscovery.js\";\nimport type { IServiceManifestLoader } from \"../ServiceDiscovery.js\";\n\ndescribe(\"ServiceDiscovery\", () => {\n beforeEach(() => {\n ServiceDiscovery.clear();\n });\n\n it(\"should throw if no loader is set\", async () => {\n (ServiceDiscovery as any).loader = undefined;\n\n await expect(ServiceDiscovery.load()).rejects.toThrow(\n \"ServiceDiscovery loader not configured\"\n );\n });\n\n it(\"should load manifests and combine them by name\", async () => {\n const loader: IServiceManifestLoader = {\n async load() {\n return [\n { name: \"api\", manifest: { cloudfront: { distributionId: \"123\" } } },\n { name: \"core\", manifest: { bucket: { name: \"my-bucket\" } } }\n ];\n }\n };\n\n ServiceDiscovery.setLoader(loader);\n\n const result = await ServiceDiscovery.load();\n\n expect(result).toEqual({\n api: { cloudfront: { distributionId: \"123\" } },\n core: { bucket: { name: \"my-bucket\" } }\n });\n });\n\n it(\"should cache the result and not call loader again\", async () => {\n let callCount = 0;\n const loader: IServiceManifestLoader = {\n async load() {\n callCount++;\n return [{ name: \"api\", manifest: { url: \"https://example.com\" } }];\n }\n };\n\n ServiceDiscovery.setLoader(loader);\n\n await ServiceDiscovery.load();\n await ServiceDiscovery.load();\n await ServiceDiscovery.load();\n\n expect(callCount).toBe(1);\n });\n\n it(\"should return undefined when loader returns undefined\", async () => {\n const loader: IServiceManifestLoader = {\n async load() {\n return undefined;\n }\n };\n\n ServiceDiscovery.setLoader(loader);\n\n const result = await ServiceDiscovery.load();\n expect(result).toBeUndefined();\n });\n\n it(\"should reload after clear()\", async () => {\n let callCount = 0;\n const loader: IServiceManifestLoader = {\n async load() {\n callCount++;\n return [{ name: \"api\", manifest: { version: callCount } }];\n }\n };\n\n ServiceDiscovery.setLoader(loader);\n\n const first = await ServiceDiscovery.load();\n expect(first).toEqual({ api: { version: 1 } });\n\n ServiceDiscovery.clear();\n\n const second = await ServiceDiscovery.load();\n expect(second).toEqual({ api: { version: 2 } });\n expect(callCount).toBe(2);\n });\n});\n"],"names":["describe","beforeEach","ServiceDiscovery","it","undefined","expect","loader","result","callCount","first","second"],"mappings":";;AAIAA,SAAS,oBAAoB;IACzBC,WAAW;QACPC,iBAAiB,KAAK;IAC1B;IAEAC,GAAG,oCAAoC;QAClCD,iBAAAA,MAA+B,GAAGE;QAEnC,MAAMC,OAAOH,iBAAiB,IAAI,IAAI,OAAO,CAAC,OAAO,CACjD;IAER;IAEAC,GAAG,kDAAkD;QACjD,MAAMG,SAAiC;YACnC,MAAM;gBACF,OAAO;oBACH;wBAAE,MAAM;wBAAO,UAAU;4BAAE,YAAY;gCAAE,gBAAgB;4BAAM;wBAAE;oBAAE;oBACnE;wBAAE,MAAM;wBAAQ,UAAU;4BAAE,QAAQ;gCAAE,MAAM;4BAAY;wBAAE;oBAAE;iBAC/D;YACL;QACJ;QAEAJ,iBAAiB,SAAS,CAACI;QAE3B,MAAMC,SAAS,MAAML,iBAAiB,IAAI;QAE1CG,OAAOE,QAAQ,OAAO,CAAC;YACnB,KAAK;gBAAE,YAAY;oBAAE,gBAAgB;gBAAM;YAAE;YAC7C,MAAM;gBAAE,QAAQ;oBAAE,MAAM;gBAAY;YAAE;QAC1C;IACJ;IAEAJ,GAAG,qDAAqD;QACpD,IAAIK,YAAY;QAChB,MAAMF,SAAiC;YACnC,MAAM;gBACFE;gBACA,OAAO;oBAAC;wBAAE,MAAM;wBAAO,UAAU;4BAAE,KAAK;wBAAsB;oBAAE;iBAAE;YACtE;QACJ;QAEAN,iBAAiB,SAAS,CAACI;QAE3B,MAAMJ,iBAAiB,IAAI;QAC3B,MAAMA,iBAAiB,IAAI;QAC3B,MAAMA,iBAAiB,IAAI;QAE3BG,OAAOG,WAAW,IAAI,CAAC;IAC3B;IAEAL,GAAG,yDAAyD;QACxD,MAAMG,SAAiC;YACnC,MAAM,SAEN;QACJ;QAEAJ,iBAAiB,SAAS,CAACI;QAE3B,MAAMC,SAAS,MAAML,iBAAiB,IAAI;QAC1CG,OAAOE,QAAQ,aAAa;IAChC;IAEAJ,GAAG,+BAA+B;QAC9B,IAAIK,YAAY;QAChB,MAAMF,SAAiC;YACnC,MAAM;gBACFE;gBACA,OAAO;oBAAC;wBAAE,MAAM;wBAAO,UAAU;4BAAE,SAASA;wBAAU;oBAAE;iBAAE;YAC9D;QACJ;QAEAN,iBAAiB,SAAS,CAACI;QAE3B,MAAMG,QAAQ,MAAMP,iBAAiB,IAAI;QACzCG,OAAOI,OAAO,OAAO,CAAC;YAAE,KAAK;gBAAE,SAAS;YAAE;QAAE;QAE5CP,iBAAiB,KAAK;QAEtB,MAAMQ,SAAS,MAAMR,iBAAiB,IAAI;QAC1CG,OAAOK,QAAQ,OAAO,CAAC;YAAE,KAAK;gBAAE,SAAS;YAAE;QAAE;QAC7CL,OAAOG,WAAW,IAAI,CAAC;IAC3B;AACJ"}
@@ -0,0 +1,3 @@
1
+ export { ServiceDiscovery } from "./ServiceDiscovery.js";
2
+ export type { IServiceManifestLoader } from "./ServiceDiscovery.js";
3
+ export type { IServiceManifest } from "./ServiceDiscovery.js";
@@ -0,0 +1 @@
1
+ export { ServiceDiscovery } from "./ServiceDiscovery.js";
@@ -0,0 +1,21 @@
1
+ import type { Container } from "@webiny/di";
2
+ import type { ApiCoreStorageOperations } from "../../types/core.js";
3
+ /**
4
+ * Builds the api-core storage operations. Resolved + built synchronously inside
5
+ * ApiCoreFeature.register, so storage is wired the same way for every event — there is no
6
+ * out-of-feature construction or per-request async initializer. The concrete implementation is
7
+ * provided by a storage adapter (ApiCoreDdbFeature / ApiCoreSqlFeature) or, in tests, by
8
+ * registerApiCoreStorageOperations.
9
+ */
10
+ export interface IApiCoreStorageOperationsFactory {
11
+ create(): ApiCoreStorageOperations;
12
+ }
13
+ export declare const ApiCoreStorageOperationsFactory: import("@webiny/di").Abstraction<IApiCoreStorageOperationsFactory>;
14
+ export declare namespace ApiCoreStorageOperationsFactory {
15
+ type Interface = IApiCoreStorageOperationsFactory;
16
+ }
17
+ /**
18
+ * Register pre-built storage operations as the factory. Used by tests (and anywhere the ops are
19
+ * already constructed) so ApiCoreFeature.register can resolve them like any adapter-provided factory.
20
+ */
21
+ export declare const registerApiCoreStorageOperations: (container: Container, storageOperations: ApiCoreStorageOperations) => void;
@@ -0,0 +1,10 @@
1
+ import { createAbstraction } from "@webiny/feature/api";
2
+ const ApiCoreStorageOperationsFactory = createAbstraction("ApiCoreStorageOperationsFactory");
3
+ const registerApiCoreStorageOperations = (container, storageOperations)=>{
4
+ container.registerInstance(ApiCoreStorageOperationsFactory, {
5
+ create: ()=>storageOperations
6
+ });
7
+ };
8
+ export { ApiCoreStorageOperationsFactory, registerApiCoreStorageOperations };
9
+
10
+ //# sourceMappingURL=abstractions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/storageOperations/abstractions.js","sources":["../../../src/features/storageOperations/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { Container } from \"@webiny/di\";\nimport type { ApiCoreStorageOperations } from \"~/types/core.js\";\n\n/**\n * Builds the api-core storage operations. Resolved + built synchronously inside\n * ApiCoreFeature.register, so storage is wired the same way for every event — there is no\n * out-of-feature construction or per-request async initializer. The concrete implementation is\n * provided by a storage adapter (ApiCoreDdbFeature / ApiCoreSqlFeature) or, in tests, by\n * registerApiCoreStorageOperations.\n */\nexport interface IApiCoreStorageOperationsFactory {\n create(): ApiCoreStorageOperations;\n}\n\nexport const ApiCoreStorageOperationsFactory = createAbstraction<IApiCoreStorageOperationsFactory>(\n \"ApiCoreStorageOperationsFactory\"\n);\n\nexport namespace ApiCoreStorageOperationsFactory {\n export type Interface = IApiCoreStorageOperationsFactory;\n}\n\n/**\n * Register pre-built storage operations as the factory. Used by tests (and anywhere the ops are\n * already constructed) so ApiCoreFeature.register can resolve them like any adapter-provided factory.\n */\nexport const registerApiCoreStorageOperations = (\n container: Container,\n storageOperations: ApiCoreStorageOperations\n): void => {\n container.registerInstance(ApiCoreStorageOperationsFactory, {\n create: () => storageOperations\n });\n};\n"],"names":["ApiCoreStorageOperationsFactory","createAbstraction","registerApiCoreStorageOperations","container","storageOperations"],"mappings":";AAeO,MAAMA,kCAAkCC,kBAC3C;AAWG,MAAMC,mCAAmC,CAC5CC,WACAC;IAEAD,UAAU,gBAAgB,CAACH,iCAAiC;QACxD,QAAQ,IAAMI;IAClB;AACJ"}
@@ -8,7 +8,7 @@ declare class CreateTenantUseCaseImpl implements UseCaseAbstraction.Interface {
8
8
  private eventPublisher;
9
9
  private repository;
10
10
  constructor(eventPublisher: EventPublisher.Interface, repository: CreateTenantRepository.Interface);
11
- execute(data: CreateTenantInput): Promise<Result<Tenant, never> | Result<never, CreateTenantError>>;
11
+ execute(data: CreateTenantInput): Promise<Result<never, CreateTenantError> | Result<Tenant, never>>;
12
12
  }
13
13
  export declare const CreateTenantUseCase: import("@webiny/di").Implementation<typeof CreateTenantUseCaseImpl>;
14
14
  export {};
@@ -13,7 +13,7 @@ declare class InstallTenantUseCaseImpl implements UseCaseAbstraction.Interface {
13
13
  private updateTenantUseCase;
14
14
  private resolver;
15
15
  constructor(tenantContext: TenantContext.Interface, eventPublisher: EventPublisher.Interface, appInstallers: AppInstaller.Interface[], updateTenantUseCase: UpdateTenantUseCase.Interface);
16
- execute({ tenant, installationInput }: TenantInstallationInput): Promise<Result<void, never> | Result<never, InstallationDependencyError> | Result<never, InstallTenantError>>;
16
+ execute({ tenant, installationInput }: TenantInstallationInput): Promise<Result<void, never> | Result<never, InstallTenantError> | Result<never, InstallationDependencyError>>;
17
17
  private rollback;
18
18
  }
19
19
  export declare const InstallTenantUseCase: import("@webiny/di").Implementation<typeof InstallTenantUseCaseImpl>;
@@ -9,9 +9,9 @@ declare class UpdateTenantUseCaseImpl implements UseCaseAbstraction.Interface {
9
9
  private eventPublisher;
10
10
  private repository;
11
11
  constructor(getTenantById: GetTenantByIdUseCase.Interface, eventPublisher: EventPublisher.Interface, repository: UpdateTenantRepository.Interface);
12
- execute(id: string, data: Partial<Tenant>): Promise<({
12
+ execute(id: string, data: Partial<Tenant>): Promise<Result<Tenant, never> | ({
13
13
  _error: import("../GetTenantById/abstractions.js").GetTenantByIdError;
14
- } & Result<Tenant, import("../GetTenantById/abstractions.js").GetTenantByIdError>) | Result<Tenant, never>>;
14
+ } & Result<Tenant, import("../GetTenantById/abstractions.js").GetTenantByIdError>)>;
15
15
  }
16
16
  export declare const UpdateTenantUseCase: import("@webiny/di").Implementation<typeof UpdateTenantUseCaseImpl>;
17
17
  export {};
@@ -5,7 +5,7 @@ declare class CreateUserWithWcpIncrementImpl implements CreateUserUseCase.Interf
5
5
  private wcp;
6
6
  private decoratee;
7
7
  constructor(wcp: WcpContext.Interface, decoratee: CreateUserUseCase.Interface);
8
- execute(input: CreateUserInput): Promise<import("@webiny/feature/api").Result<import("~/features/users/shared/types.js").AdminUser, import("../../shared/errors.js").UserStorageError | import("../../shared/errors.js").UserNotFoundError | import("../../shared/errors.js").EmailTakenError | import("../../shared/errors.js").UserValidationError | import("../../shared/errors.js").NotAuthorizedError>>;
8
+ execute(input: CreateUserInput): Promise<import("@webiny/feature/api").Result<import("~/features/users/shared/types.js").AdminUser, import("../../shared/errors.js").EmailTakenError | import("../../shared/errors.js").NotAuthorizedError | import("../../shared/errors.js").UserNotFoundError | import("../../shared/errors.js").UserStorageError | import("../../shared/errors.js").UserValidationError>>;
9
9
  }
10
10
  export declare const CreateUserWithWcpIncrement: typeof CreateUserWithWcpIncrementImpl;
11
11
  export {};