@seliseblocks/client 0.1.0-beta.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.
- package/AI_USAGE_GUIDE.md +149 -0
- package/LICENSE +21 -0
- package/README.md +161 -0
- package/dist/auth/auth-client.d.ts +256 -0
- package/dist/auth/auth-client.js +427 -0
- package/dist/auth/types.d.ts +77 -0
- package/dist/auth/types.js +1 -0
- package/dist/client.d.ts +74 -0
- package/dist/client.js +49 -0
- package/dist/data/data-client.d.ts +178 -0
- package/dist/data/data-client.js +385 -0
- package/dist/data/types.d.ts +148 -0
- package/dist/data/types.js +1 -0
- package/dist/http/errors.d.ts +6 -0
- package/dist/http/errors.js +23 -0
- package/dist/http/http-client.d.ts +11 -0
- package/dist/http/http-client.js +82 -0
- package/dist/iam/iam-client.d.ts +226 -0
- package/dist/iam/iam-client.js +230 -0
- package/dist/iam/types.d.ts +56 -0
- package/dist/iam/types.js +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +6 -0
- package/dist/localization/localization-client.d.ts +71 -0
- package/dist/localization/localization-client.js +148 -0
- package/dist/localization/types.d.ts +35 -0
- package/dist/localization/types.js +1 -0
- package/dist/types.d.ts +13 -0
- package/dist/types.js +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
export class BlocksIAMClient {
|
|
2
|
+
http;
|
|
3
|
+
constructor(http) {
|
|
4
|
+
this.http = http;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Current authenticated IAM account from `GET /iam/v4/iam/me`.
|
|
8
|
+
* Use this for app profile bootstrapping because it returns the Blocks user record,
|
|
9
|
+
* roles, permissions, and active organization context according to the access token.
|
|
10
|
+
*/
|
|
11
|
+
me() {
|
|
12
|
+
return this.http.request("/iam/v4/iam/me");
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Updates the current authenticated user's IAM profile through `POST /iam/v4/iam/me`.
|
|
16
|
+
* The backend resolves the user id from the token; callers must not send another user's id.
|
|
17
|
+
*/
|
|
18
|
+
updateMe(request) {
|
|
19
|
+
return this.http.request("/iam/v4/iam/me", { body: request });
|
|
20
|
+
}
|
|
21
|
+
users = {
|
|
22
|
+
/**
|
|
23
|
+
* What: creates a user through `POST /iam/v4/iam/users/create`.
|
|
24
|
+
* Why: authorized admin UIs need to invite/provision users in the active tenant/organization.
|
|
25
|
+
* How: pass IAM's create-user payload; caller permissions determine whether the API accepts it.
|
|
26
|
+
*/
|
|
27
|
+
create: (request) => this.http.request("/iam/v4/iam/users/create", { body: request }),
|
|
28
|
+
/**
|
|
29
|
+
* What: updates a user through `POST /iam/v4/iam/users/{id}`.
|
|
30
|
+
* Why: authorized admin UIs need to edit IAM profile fields.
|
|
31
|
+
* How: pass the user id in the route and IAM's update payload in the body.
|
|
32
|
+
*/
|
|
33
|
+
update: (id, request) => this.http.request(`/iam/v4/iam/users/${encodeURIComponent(id)}`, { body: request }),
|
|
34
|
+
/**
|
|
35
|
+
* What: deactivates a user through `POST /iam/v4/iam/users/deactivate`.
|
|
36
|
+
* Why: admin UIs need to remove access without deleting the user record.
|
|
37
|
+
* How: pass IAM's deactivate payload for the target user.
|
|
38
|
+
*/
|
|
39
|
+
deactivate: (request) => this.http.request("/iam/v4/iam/users/deactivate", { body: request }),
|
|
40
|
+
/**
|
|
41
|
+
* What: activates a user through `POST /iam/v4/iam/users/activate`.
|
|
42
|
+
* Why: admin UIs need to restore access for a previously inactive account.
|
|
43
|
+
* How: pass IAM's activate payload for the target user.
|
|
44
|
+
*/
|
|
45
|
+
activate: (request) => this.http.request("/iam/v4/iam/users/activate", { body: request }),
|
|
46
|
+
/**
|
|
47
|
+
* What: queries users through `POST /iam/v4/iam/users`.
|
|
48
|
+
* Why: IAM uses a POST-read contract for paging/filtering user lists.
|
|
49
|
+
* How: pass `pageNo`, `pageSize`, search/filter fields, or the exact IAM list payload your UI needs.
|
|
50
|
+
*/
|
|
51
|
+
list: (request = {}) => this.http.request("/iam/v4/iam/users", { body: request }),
|
|
52
|
+
/**
|
|
53
|
+
* What: reads one user through `GET /iam/v4/iam/users/{id}`.
|
|
54
|
+
* Why: user detail screens need one IAM user record, optionally for a specific organization context.
|
|
55
|
+
* How: pass the user id and optional `organizationId`.
|
|
56
|
+
*/
|
|
57
|
+
get: (id, options = {}) => this.http.request(`/iam/v4/iam/users/${encodeURIComponent(id)}`, {
|
|
58
|
+
query: { organizationId: options.organizationId }
|
|
59
|
+
}),
|
|
60
|
+
/**
|
|
61
|
+
* What: updates user access through `POST /iam/v4/iam/users/access`.
|
|
62
|
+
* Why: admin UIs need to grant or change roles/permissions for a user.
|
|
63
|
+
* How: pass IAM's access payload; the active token and tenant header define allowed scope.
|
|
64
|
+
*/
|
|
65
|
+
updateAccess: (request) => this.http.request("/iam/v4/iam/users/access", { body: request }),
|
|
66
|
+
/**
|
|
67
|
+
* What: revokes user access through `POST /iam/v4/iam/users/revoke-access`.
|
|
68
|
+
* Why: admin UIs need to remove roles/permissions or organization access.
|
|
69
|
+
* How: pass IAM's revoke-access payload.
|
|
70
|
+
*/
|
|
71
|
+
revokeAccess: (request) => this.http.request("/iam/v4/iam/users/revoke-access", { body: request }),
|
|
72
|
+
/**
|
|
73
|
+
* What: checks email availability through `GET /iam/v4/iam/email/available`.
|
|
74
|
+
* Why: signup and invite forms can validate duplicate email state before submit.
|
|
75
|
+
* How: pass the email query fields IAM expects; this is public but still sends `x-blocks-key`.
|
|
76
|
+
*/
|
|
77
|
+
emailAvailable: (query) => this.http.request("/iam/v4/iam/email/available", {
|
|
78
|
+
auth: false,
|
|
79
|
+
query
|
|
80
|
+
}),
|
|
81
|
+
/**
|
|
82
|
+
* What: checks whether a user exists through `GET /iam/v4/iam/users/exists`.
|
|
83
|
+
* Why: account and invite flows may need an existence check by email.
|
|
84
|
+
* How: pass the email string; the SDK sends it as the `email` query parameter.
|
|
85
|
+
*/
|
|
86
|
+
exists: (email) => this.http.request("/iam/v4/iam/users/exists", { query: { email } })
|
|
87
|
+
};
|
|
88
|
+
permissions = {
|
|
89
|
+
/**
|
|
90
|
+
* What: creates a permission through `POST /iam/v4/iam/permissions/create`.
|
|
91
|
+
* Why: authorized admin tooling may manage custom IAM permission definitions.
|
|
92
|
+
* How: pass IAM's create-permission payload.
|
|
93
|
+
*/
|
|
94
|
+
create: (request) => this.http.request("/iam/v4/iam/permissions/create", { body: request }),
|
|
95
|
+
/**
|
|
96
|
+
* What: updates a permission through `POST /iam/v4/iam/permissions/{id}`.
|
|
97
|
+
* Why: admin tooling may need to edit permission metadata.
|
|
98
|
+
* How: pass the permission id and IAM's update payload.
|
|
99
|
+
*/
|
|
100
|
+
update: (id, request) => this.http.request(`/iam/v4/iam/permissions/${encodeURIComponent(id)}`, { body: request }),
|
|
101
|
+
/**
|
|
102
|
+
* What: queries permissions through `POST /iam/v4/iam/permissions`.
|
|
103
|
+
* Why: IAM uses a POST-read contract for permission paging/filtering.
|
|
104
|
+
* How: pass `pageNo`, `pageSize`, search/filter fields, or IAM's exact list payload.
|
|
105
|
+
*/
|
|
106
|
+
list: (request = {}) => this.http.request("/iam/v4/iam/permissions", { body: request }),
|
|
107
|
+
/**
|
|
108
|
+
* What: groups permissions by severity through `GET /iam/v4/iam/permissions/by-severity`.
|
|
109
|
+
* Why: role/access UIs often display permissions grouped by risk or category.
|
|
110
|
+
* How: call after an authorized token is available.
|
|
111
|
+
*/
|
|
112
|
+
bySeverity: () => this.http.request("/iam/v4/iam/permissions/by-severity"),
|
|
113
|
+
/**
|
|
114
|
+
* What: reads one permission through `GET /iam/v4/iam/permissions/{id}`.
|
|
115
|
+
* Why: admin detail/edit screens need one permission record.
|
|
116
|
+
* How: pass the permission id from IAM.
|
|
117
|
+
*/
|
|
118
|
+
get: (id) => this.http.request(`/iam/v4/iam/permissions/${encodeURIComponent(id)}`)
|
|
119
|
+
};
|
|
120
|
+
roles = {
|
|
121
|
+
/**
|
|
122
|
+
* What: creates a role through `POST /iam/v4/iam/roles/create`.
|
|
123
|
+
* Why: admin UIs need to define permission bundles users can be assigned to.
|
|
124
|
+
* How: pass IAM's create-role payload.
|
|
125
|
+
*/
|
|
126
|
+
create: (request) => this.http.request("/iam/v4/iam/roles/create", { body: request }),
|
|
127
|
+
/**
|
|
128
|
+
* What: updates a role through `POST /iam/v4/iam/roles/update`.
|
|
129
|
+
* Why: admin UIs need to edit role names, metadata, or other IAM-supported fields.
|
|
130
|
+
* How: pass IAM's role update payload.
|
|
131
|
+
*/
|
|
132
|
+
update: (request) => this.http.request("/iam/v4/iam/roles/update", { body: request }),
|
|
133
|
+
/**
|
|
134
|
+
* What: queries roles through `POST /iam/v4/iam/roles`.
|
|
135
|
+
* Why: IAM uses a POST-read contract for role paging/filtering.
|
|
136
|
+
* How: pass `pageNo`, `pageSize`, search/filter fields, or IAM's exact list payload.
|
|
137
|
+
*/
|
|
138
|
+
list: (request = {}) => this.http.request("/iam/v4/iam/roles", { body: request }),
|
|
139
|
+
/**
|
|
140
|
+
* What: reads one role through `GET /iam/v4/iam/roles/{id}`.
|
|
141
|
+
* Why: role detail/edit screens need one IAM role record.
|
|
142
|
+
* How: pass the role id from IAM.
|
|
143
|
+
*/
|
|
144
|
+
get: (id) => this.http.request(`/iam/v4/iam/roles/${encodeURIComponent(id)}`),
|
|
145
|
+
/**
|
|
146
|
+
* What: assigns permissions to a role through `POST /iam/v4/iam/roles/assign-permissions`.
|
|
147
|
+
* Why: role editors need to attach or replace permission sets.
|
|
148
|
+
* How: pass IAM's assign-permissions payload.
|
|
149
|
+
*/
|
|
150
|
+
assignPermissions: (request) => this.http.request("/iam/v4/iam/roles/assign-permissions", { body: request }),
|
|
151
|
+
/**
|
|
152
|
+
* What: lists assignable roles through `GET /iam/v4/iam/roles/assignable`.
|
|
153
|
+
* Why: user-access UIs should only show roles the current user can assign.
|
|
154
|
+
* How: call after an authorized token is available.
|
|
155
|
+
*/
|
|
156
|
+
assignable: () => this.http.request("/iam/v4/iam/roles/assignable")
|
|
157
|
+
};
|
|
158
|
+
resources = {
|
|
159
|
+
/**
|
|
160
|
+
* What: lists resource groups through `GET /iam/v4/iam/resource-groups`.
|
|
161
|
+
* Why: permission screens need resource grouping metadata for navigation and display.
|
|
162
|
+
* How: call after an authorized token is available.
|
|
163
|
+
*/
|
|
164
|
+
groups: () => this.http.request("/iam/v4/iam/resource-groups"),
|
|
165
|
+
/**
|
|
166
|
+
* What: lists feature/resource flags through `GET /iam/v4/iam/resource/features`.
|
|
167
|
+
* Why: frontends use this to feature-gate UI based on current roles and permissions.
|
|
168
|
+
* How: pass optional query fields supported by IAM; the active token defines the user context.
|
|
169
|
+
*/
|
|
170
|
+
features: (query = {}) => this.http.request("/iam/v4/iam/resource/features", { query })
|
|
171
|
+
};
|
|
172
|
+
organizations = {
|
|
173
|
+
/**
|
|
174
|
+
* What: creates an organization through `POST /iam/v4/iam/organizations/create`.
|
|
175
|
+
* Why: authorized admin UIs may need tenant organization management.
|
|
176
|
+
* How: pass IAM's create-organization payload.
|
|
177
|
+
*/
|
|
178
|
+
create: (request) => this.http.request("/iam/v4/iam/organizations/create", { body: request }),
|
|
179
|
+
/**
|
|
180
|
+
* What: updates an organization through `POST /iam/v4/iam/organizations/{id}`.
|
|
181
|
+
* Why: organization settings screens need to edit metadata/config.
|
|
182
|
+
* How: pass the organization id and IAM's update payload.
|
|
183
|
+
*/
|
|
184
|
+
update: (id, request) => this.http.request(`/iam/v4/iam/organizations/${encodeURIComponent(id)}`, { body: request }),
|
|
185
|
+
/**
|
|
186
|
+
* What: lists organizations through `GET /iam/v4/iam/organizations`.
|
|
187
|
+
* Why: admin UIs need organization browsing and selection.
|
|
188
|
+
* How: pass IAM-supported query fields such as paging/search options.
|
|
189
|
+
*/
|
|
190
|
+
list: (query = {}) => this.http.request("/iam/v4/iam/organizations", { query }),
|
|
191
|
+
/**
|
|
192
|
+
* What: reads one organization through `GET /iam/v4/iam/organizations/{id}`.
|
|
193
|
+
* Why: organization detail screens need one organization record.
|
|
194
|
+
* How: pass the organization id from IAM.
|
|
195
|
+
*/
|
|
196
|
+
get: (id) => this.http.request(`/iam/v4/iam/organizations/${encodeURIComponent(id)}`),
|
|
197
|
+
/**
|
|
198
|
+
* What: lists current-user organizations through `GET /iam/v4/iam/organizations/my`.
|
|
199
|
+
* Why: apps need available organizations for org switchers and context selectors.
|
|
200
|
+
* How: call with the current user's access token.
|
|
201
|
+
*/
|
|
202
|
+
my: () => this.http.request("/iam/v4/iam/organizations/my"),
|
|
203
|
+
/**
|
|
204
|
+
* What: reads organization configuration through `GET /iam/v4/iam/organizations/config`.
|
|
205
|
+
* Why: settings screens need the active organization's current configuration.
|
|
206
|
+
* How: call with an authorized token in the desired organization context.
|
|
207
|
+
*/
|
|
208
|
+
getConfig: () => this.http.request("/iam/v4/iam/organizations/config"),
|
|
209
|
+
/**
|
|
210
|
+
* What: saves organization configuration through `POST /iam/v4/iam/organizations/config`.
|
|
211
|
+
* Why: settings screens need to persist organization-level behavior.
|
|
212
|
+
* How: pass IAM's organization config payload.
|
|
213
|
+
*/
|
|
214
|
+
saveConfig: (request) => this.http.request("/iam/v4/iam/organizations/config", { body: request })
|
|
215
|
+
};
|
|
216
|
+
signupSettings = {
|
|
217
|
+
/**
|
|
218
|
+
* What: reads signup settings through `GET /iam/v4/iam/signup-settings`.
|
|
219
|
+
* Why: public signup screens need tenant policy before a user is authenticated.
|
|
220
|
+
* How: call without an access token; the SDK still sends `x-blocks-key`.
|
|
221
|
+
*/
|
|
222
|
+
get: () => this.http.request("/iam/v4/iam/signup-settings", { auth: false }),
|
|
223
|
+
/**
|
|
224
|
+
* What: saves signup settings through `POST /iam/v4/iam/signup-settings`.
|
|
225
|
+
* Why: admin/settings screens need to configure signup policy.
|
|
226
|
+
* How: pass IAM's signup-settings payload with an authorized token.
|
|
227
|
+
*/
|
|
228
|
+
save: (request) => this.http.request("/iam/v4/iam/signup-settings", { body: request })
|
|
229
|
+
};
|
|
230
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export type BlocksBaseResponse = Record<string, unknown> & {
|
|
2
|
+
errors?: unknown;
|
|
3
|
+
isSuccess?: boolean;
|
|
4
|
+
message?: string;
|
|
5
|
+
};
|
|
6
|
+
export type BlocksQueryResponse<T = unknown> = BlocksBaseResponse & {
|
|
7
|
+
data?: T;
|
|
8
|
+
};
|
|
9
|
+
export type BlocksQueryListResponse<T = unknown> = BlocksBaseResponse & {
|
|
10
|
+
data?: T[];
|
|
11
|
+
pageNo?: number;
|
|
12
|
+
pageSize?: number;
|
|
13
|
+
totalCount?: number;
|
|
14
|
+
};
|
|
15
|
+
export type BlocksUser = Record<string, unknown> & {
|
|
16
|
+
active?: boolean;
|
|
17
|
+
email?: string;
|
|
18
|
+
firstName?: string;
|
|
19
|
+
itemId?: string;
|
|
20
|
+
language?: string;
|
|
21
|
+
lastName?: string;
|
|
22
|
+
permissions?: string[];
|
|
23
|
+
roles?: string[];
|
|
24
|
+
status?: number;
|
|
25
|
+
};
|
|
26
|
+
export type BlocksPermission = Record<string, unknown> & {
|
|
27
|
+
itemId?: string;
|
|
28
|
+
resource?: string;
|
|
29
|
+
roles?: string[];
|
|
30
|
+
};
|
|
31
|
+
export type BlocksRole = Record<string, unknown> & {
|
|
32
|
+
itemId?: string;
|
|
33
|
+
name?: string;
|
|
34
|
+
slug?: string;
|
|
35
|
+
};
|
|
36
|
+
export type BlocksOrganization = Record<string, unknown> & {
|
|
37
|
+
itemId?: string;
|
|
38
|
+
name?: string;
|
|
39
|
+
};
|
|
40
|
+
export type BlocksIamListRequest<TFilter = Record<string, unknown>> = Record<string, unknown> & {
|
|
41
|
+
filter?: TFilter;
|
|
42
|
+
pageNo?: number;
|
|
43
|
+
pageNumber?: number;
|
|
44
|
+
pageSize?: number;
|
|
45
|
+
search?: string;
|
|
46
|
+
};
|
|
47
|
+
export type BlocksMeResponse = BlocksQueryResponse<BlocksUser>;
|
|
48
|
+
export type BlocksGetUserResponse = BlocksQueryResponse<BlocksUser>;
|
|
49
|
+
export type BlocksGetUsersResponse = BlocksQueryListResponse<BlocksUser>;
|
|
50
|
+
export type BlocksGetPermissionResponse = BlocksQueryResponse<BlocksPermission>;
|
|
51
|
+
export type BlocksGetPermissionsResponse = BlocksQueryListResponse<BlocksPermission>;
|
|
52
|
+
export type BlocksGetRoleResponse = BlocksQueryResponse<BlocksRole>;
|
|
53
|
+
export type BlocksGetRolesResponse = BlocksQueryListResponse<BlocksRole>;
|
|
54
|
+
export type BlocksGetOrganizationResponse = BlocksQueryResponse<BlocksOrganization>;
|
|
55
|
+
export type BlocksGetOrganizationsResponse = BlocksQueryListResponse<BlocksOrganization>;
|
|
56
|
+
export type BlocksGetMyOrganizationsResponse = BlocksQueryResponse<BlocksOrganization[]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { createBlocksClient } from "./client.js";
|
|
2
|
+
export { BlocksAuthenticationClient } from "./auth/auth-client.js";
|
|
3
|
+
export { BlocksDataClient } from "./data/data-client.js";
|
|
4
|
+
export type { BlocksClient, BlocksClientConfig, BlocksOidcConfig } from "./client.js";
|
|
5
|
+
export { BlocksApiError } from "./http/errors.js";
|
|
6
|
+
export { BlocksIAMClient } from "./iam/iam-client.js";
|
|
7
|
+
export { BlocksLocalizationClient } from "./localization/localization-client.js";
|
|
8
|
+
export type { BlocksAuthPassThroughResponse, BlocksAuthResponse, BlocksClientCredentialsRequest, BlocksAuthLoginRequest, BlocksIdpCallbackRequest, BlocksIdpInitiateRequest, BlocksIdpInitiateResponse, BlocksLoginOption, BlocksLogoutRequest, BlocksOidcRefreshRequest, BlocksOidcUserInfo, BlocksRefreshRequest, BlocksSocialLoginRequest, BlocksSwitchOrganizationRequest } from "./auth/auth-client.js";
|
|
9
|
+
export type { BlocksRequestOptions } from "./types.js";
|
|
10
|
+
export type { BlocksBaseResponse, BlocksGetMyOrganizationsResponse, BlocksGetOrganizationResponse, BlocksGetOrganizationsResponse, BlocksGetPermissionResponse, BlocksGetPermissionsResponse, BlocksGetRoleResponse, BlocksGetRolesResponse, BlocksGetUserResponse, BlocksGetUsersResponse, BlocksIamListRequest, BlocksMeResponse, BlocksOrganization, BlocksPermission, BlocksQueryListResponse, BlocksQueryResponse, BlocksRole, BlocksUser } from "./iam/types.js";
|
|
11
|
+
export type { BlocksDataCollection, BlocksDataListOptions, BlocksDmsCreateFolderRequest, BlocksDmsListRequest, BlocksDmsMetaDataValue, BlocksDmsUploadItem, BlocksDmsUploadRequest, BlocksFileDeleteRequest, BlocksFileGetOptions, BlocksFileInfoListRequest, BlocksFileListRequest, BlocksFileUpdateAdditionalInfoRequest, BlocksFileUploadRequest, BlocksFolderDeleteRequest, BlocksGraphqlRequest, BlocksLocalStorageUploadRequest, BlocksPagedResult, BlocksRegexGenerateRequest, BlocksSchemaFieldValidationOptions, BlocksSchemaListOptions, BlocksSchemaValidationListOptions, BlocksUploadToUrlRequest } from "./data/types.js";
|
|
12
|
+
export type { BlocksLocalizationDictionary, BlocksLocalizationKey, BlocksLocalizationKeysByNamesRequest, BlocksLocalizationKeysByNamesResponse, BlocksLocalizationLanguage, BlocksLocalizationModule, BlocksLocalizationTranslationOptions } from "./localization/types.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { createBlocksClient } from "./client.js";
|
|
2
|
+
export { BlocksAuthenticationClient } from "./auth/auth-client.js";
|
|
3
|
+
export { BlocksDataClient } from "./data/data-client.js";
|
|
4
|
+
export { BlocksApiError } from "./http/errors.js";
|
|
5
|
+
export { BlocksIAMClient } from "./iam/iam-client.js";
|
|
6
|
+
export { BlocksLocalizationClient } from "./localization/localization-client.js";
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { BlocksHttpClient } from "../http/http-client.js";
|
|
2
|
+
import { BlocksLocalizationDictionary, BlocksLocalizationKeysByNamesRequest, BlocksLocalizationKeysByNamesResponse, BlocksLocalizationLanguage, BlocksLocalizationModule } from "./types.js";
|
|
3
|
+
export declare class BlocksLocalizationClient {
|
|
4
|
+
private readonly http;
|
|
5
|
+
private readonly dictionaries;
|
|
6
|
+
private activeLanguage;
|
|
7
|
+
constructor(http: BlocksHttpClient);
|
|
8
|
+
/**
|
|
9
|
+
* What: lists available languages through `GET /localization/v4/Language/Gets`.
|
|
10
|
+
* Why: apps need tenant-supported cultures for language pickers and startup locale selection.
|
|
11
|
+
* How: call without an access token; the SDK still sends `x-blocks-key`.
|
|
12
|
+
*/
|
|
13
|
+
languages(): Promise<BlocksLocalizationLanguage[]>;
|
|
14
|
+
/**
|
|
15
|
+
* What: lists available localization modules through `GET /localization/v4/Module/Gets`.
|
|
16
|
+
* Why: apps can discover which translation bundles exist for the tenant.
|
|
17
|
+
* How: call without an access token; the SDK still sends `x-blocks-key`.
|
|
18
|
+
*/
|
|
19
|
+
modules(): Promise<BlocksLocalizationModule[]>;
|
|
20
|
+
/**
|
|
21
|
+
* What: loads one module dictionary through `GET /localization/v4/Key/GetUilmFile`.
|
|
22
|
+
* Why: framework-neutral apps need raw translation dictionaries without adopting a specific i18n library.
|
|
23
|
+
* How: pass `moduleName` and `language`; the SDK normalizes string values and caches the dictionary in this client instance.
|
|
24
|
+
*/
|
|
25
|
+
translations(moduleName: string, language: string): Promise<BlocksLocalizationDictionary>;
|
|
26
|
+
/**
|
|
27
|
+
* What: lists languages resolved for the active Blocks tenant through `GET /localization/v4/Language/GetLanguagesForCurrentTenant`.
|
|
28
|
+
* Why: multi-tenant apps should show the languages actually enabled for the tenant behind the current `x-blocks-key`.
|
|
29
|
+
* How: call during app startup or settings screen load; the SDK sends `x-blocks-key` and the caller access token when configured.
|
|
30
|
+
*/
|
|
31
|
+
languagesForCurrentTenant(): Promise<BlocksLocalizationLanguage[]>;
|
|
32
|
+
/**
|
|
33
|
+
* What: lists localization modules resolved for the active Blocks tenant through `GET /localization/v4/Module/GetModulesForCurrentTenant`.
|
|
34
|
+
* Why: apps can discover tenant-scoped bundles such as `common`, `dashboard`, or feature modules before loading translations.
|
|
35
|
+
* How: call with the configured client; the tenant is selected by `x-blocks-key`, not by a `ProjectKey` query/body value.
|
|
36
|
+
*/
|
|
37
|
+
modulesForCurrentTenant(): Promise<BlocksLocalizationModule[]>;
|
|
38
|
+
/**
|
|
39
|
+
* What: loads the authorized cloud UILM dictionary through `GET /localization/v4/Key/GetCloudUilmFile`.
|
|
40
|
+
* Why: signed-in app surfaces can load protected tenant dictionaries while keeping session/token ownership in the caller app.
|
|
41
|
+
* How: pass `moduleName` and `language`; the SDK sends the caller access token when configured, normalizes string values, and caches the result for `t()`.
|
|
42
|
+
*/
|
|
43
|
+
cloudTranslations(moduleName: string, language: string): Promise<BlocksLocalizationDictionary>;
|
|
44
|
+
/**
|
|
45
|
+
* What: retrieves exact localization key records through `POST /localization/v4/Key/GetsByKeyNames`.
|
|
46
|
+
* Why: apps sometimes need key metadata or selected translations without downloading a whole module dictionary.
|
|
47
|
+
* How: pass `keyNames` and optional `moduleId`; the SDK posts the body as-is except it removes any accidental `ProjectKey`/`projectKey`.
|
|
48
|
+
*/
|
|
49
|
+
keysByNames(request: BlocksLocalizationKeysByNamesRequest): Promise<BlocksLocalizationKeysByNamesResponse>;
|
|
50
|
+
/**
|
|
51
|
+
* What: loads multiple module dictionaries and merges them.
|
|
52
|
+
* Why: most apps need several translation modules during startup.
|
|
53
|
+
* How: pass a language and module list; later modules overwrite earlier keys if the same key appears twice.
|
|
54
|
+
*/
|
|
55
|
+
load(language: string, modules: string[]): Promise<BlocksLocalizationDictionary>;
|
|
56
|
+
/**
|
|
57
|
+
* What: loads multiple authorized cloud UILM dictionaries and merges them.
|
|
58
|
+
* Why: signed-in runtime areas can hydrate all protected translation modules needed for a screen in one app-level call.
|
|
59
|
+
* How: pass a language and module list; later modules overwrite earlier keys if the same key appears twice.
|
|
60
|
+
*/
|
|
61
|
+
loadCloud(language: string, modules: string[]): Promise<BlocksLocalizationDictionary>;
|
|
62
|
+
/**
|
|
63
|
+
* What: resolves a translated string from dictionaries already loaded by `translations()` or `load()`.
|
|
64
|
+
* Why: simple apps can read labels without adding a framework-specific localization package.
|
|
65
|
+
* How: pass a key, optional fallback, and optional `language`/`moduleName`; missing keys return fallback or the key.
|
|
66
|
+
*/
|
|
67
|
+
t(key: string, fallback?: string, options?: {
|
|
68
|
+
language?: string;
|
|
69
|
+
moduleName?: string;
|
|
70
|
+
}): string;
|
|
71
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
const LOCALIZATION_API = "/localization/v4";
|
|
2
|
+
export class BlocksLocalizationClient {
|
|
3
|
+
http;
|
|
4
|
+
dictionaries = new Map();
|
|
5
|
+
activeLanguage = "";
|
|
6
|
+
constructor(http) {
|
|
7
|
+
this.http = http;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* What: lists available languages through `GET /localization/v4/Language/Gets`.
|
|
11
|
+
* Why: apps need tenant-supported cultures for language pickers and startup locale selection.
|
|
12
|
+
* How: call without an access token; the SDK still sends `x-blocks-key`.
|
|
13
|
+
*/
|
|
14
|
+
languages() {
|
|
15
|
+
return this.http.request(`${LOCALIZATION_API}/Language/Gets`, {
|
|
16
|
+
auth: false
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* What: lists available localization modules through `GET /localization/v4/Module/Gets`.
|
|
21
|
+
* Why: apps can discover which translation bundles exist for the tenant.
|
|
22
|
+
* How: call without an access token; the SDK still sends `x-blocks-key`.
|
|
23
|
+
*/
|
|
24
|
+
modules() {
|
|
25
|
+
return this.http.request(`${LOCALIZATION_API}/Module/Gets`, {
|
|
26
|
+
auth: false
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* What: loads one module dictionary through `GET /localization/v4/Key/GetUilmFile`.
|
|
31
|
+
* Why: framework-neutral apps need raw translation dictionaries without adopting a specific i18n library.
|
|
32
|
+
* How: pass `moduleName` and `language`; the SDK normalizes string values and caches the dictionary in this client instance.
|
|
33
|
+
*/
|
|
34
|
+
async translations(moduleName, language) {
|
|
35
|
+
const result = await this.http.request(`${LOCALIZATION_API}/Key/GetUilmFile`, {
|
|
36
|
+
auth: false,
|
|
37
|
+
query: { Language: language, ModuleName: moduleName }
|
|
38
|
+
});
|
|
39
|
+
const dictionary = normalizeDictionary(result);
|
|
40
|
+
this.dictionaries.set(cacheKey(language, moduleName), dictionary);
|
|
41
|
+
this.activeLanguage = language;
|
|
42
|
+
return dictionary;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* What: lists languages resolved for the active Blocks tenant through `GET /localization/v4/Language/GetLanguagesForCurrentTenant`.
|
|
46
|
+
* Why: multi-tenant apps should show the languages actually enabled for the tenant behind the current `x-blocks-key`.
|
|
47
|
+
* How: call during app startup or settings screen load; the SDK sends `x-blocks-key` and the caller access token when configured.
|
|
48
|
+
*/
|
|
49
|
+
languagesForCurrentTenant() {
|
|
50
|
+
return this.http.request(`${LOCALIZATION_API}/Language/GetLanguagesForCurrentTenant`);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* What: lists localization modules resolved for the active Blocks tenant through `GET /localization/v4/Module/GetModulesForCurrentTenant`.
|
|
54
|
+
* Why: apps can discover tenant-scoped bundles such as `common`, `dashboard`, or feature modules before loading translations.
|
|
55
|
+
* How: call with the configured client; the tenant is selected by `x-blocks-key`, not by a `ProjectKey` query/body value.
|
|
56
|
+
*/
|
|
57
|
+
modulesForCurrentTenant() {
|
|
58
|
+
return this.http.request(`${LOCALIZATION_API}/Module/GetModulesForCurrentTenant`);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* What: loads the authorized cloud UILM dictionary through `GET /localization/v4/Key/GetCloudUilmFile`.
|
|
62
|
+
* Why: signed-in app surfaces can load protected tenant dictionaries while keeping session/token ownership in the caller app.
|
|
63
|
+
* How: pass `moduleName` and `language`; the SDK sends the caller access token when configured, normalizes string values, and caches the result for `t()`.
|
|
64
|
+
*/
|
|
65
|
+
async cloudTranslations(moduleName, language) {
|
|
66
|
+
const result = await this.http.request(`${LOCALIZATION_API}/Key/GetCloudUilmFile`, {
|
|
67
|
+
query: { Language: language, ModuleName: moduleName }
|
|
68
|
+
});
|
|
69
|
+
const dictionary = normalizeDictionary(result);
|
|
70
|
+
this.dictionaries.set(cacheKey(language, moduleName), dictionary);
|
|
71
|
+
this.activeLanguage = language;
|
|
72
|
+
return dictionary;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* What: retrieves exact localization key records through `POST /localization/v4/Key/GetsByKeyNames`.
|
|
76
|
+
* Why: apps sometimes need key metadata or selected translations without downloading a whole module dictionary.
|
|
77
|
+
* How: pass `keyNames` and optional `moduleId`; the SDK posts the body as-is except it removes any accidental `ProjectKey`/`projectKey`.
|
|
78
|
+
*/
|
|
79
|
+
keysByNames(request) {
|
|
80
|
+
return this.http.request(`${LOCALIZATION_API}/Key/GetsByKeyNames`, {
|
|
81
|
+
body: withoutProjectKey(request),
|
|
82
|
+
method: "POST"
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* What: loads multiple module dictionaries and merges them.
|
|
87
|
+
* Why: most apps need several translation modules during startup.
|
|
88
|
+
* How: pass a language and module list; later modules overwrite earlier keys if the same key appears twice.
|
|
89
|
+
*/
|
|
90
|
+
async load(language, modules) {
|
|
91
|
+
const dictionaries = await Promise.all(modules.map((moduleName) => this.translations(moduleName, language)));
|
|
92
|
+
return Object.assign({}, ...dictionaries);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* What: loads multiple authorized cloud UILM dictionaries and merges them.
|
|
96
|
+
* Why: signed-in runtime areas can hydrate all protected translation modules needed for a screen in one app-level call.
|
|
97
|
+
* How: pass a language and module list; later modules overwrite earlier keys if the same key appears twice.
|
|
98
|
+
*/
|
|
99
|
+
async loadCloud(language, modules) {
|
|
100
|
+
const dictionaries = await Promise.all(modules.map((moduleName) => this.cloudTranslations(moduleName, language)));
|
|
101
|
+
return Object.assign({}, ...dictionaries);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* What: resolves a translated string from dictionaries already loaded by `translations()` or `load()`.
|
|
105
|
+
* Why: simple apps can read labels without adding a framework-specific localization package.
|
|
106
|
+
* How: pass a key, optional fallback, and optional `language`/`moduleName`; missing keys return fallback or the key.
|
|
107
|
+
*/
|
|
108
|
+
t(key, fallback, options = {}) {
|
|
109
|
+
const language = options.language ?? this.activeLanguage;
|
|
110
|
+
if (options.moduleName) {
|
|
111
|
+
return this.dictionaries.get(cacheKey(language, options.moduleName))?.[key] ?? fallback ?? key;
|
|
112
|
+
}
|
|
113
|
+
for (const [dictionaryKey, dictionary] of this.dictionaries) {
|
|
114
|
+
if (language && !dictionaryKey.startsWith(`${language}:`))
|
|
115
|
+
continue;
|
|
116
|
+
const value = dictionary[key];
|
|
117
|
+
if (value)
|
|
118
|
+
return value;
|
|
119
|
+
}
|
|
120
|
+
return fallback ?? key;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function normalizeDictionary(value) {
|
|
124
|
+
if (typeof value === "object" && value) {
|
|
125
|
+
const record = value;
|
|
126
|
+
if (typeof record.data === "object" && record.data)
|
|
127
|
+
return stringifyValues(record.data);
|
|
128
|
+
return stringifyValues(record);
|
|
129
|
+
}
|
|
130
|
+
return {};
|
|
131
|
+
}
|
|
132
|
+
function stringifyValues(record) {
|
|
133
|
+
const result = {};
|
|
134
|
+
for (const [key, value] of Object.entries(record)) {
|
|
135
|
+
if (typeof value === "string")
|
|
136
|
+
result[key] = value;
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
function cacheKey(language, moduleName) {
|
|
141
|
+
return `${language}:${moduleName}`;
|
|
142
|
+
}
|
|
143
|
+
function withoutProjectKey(value) {
|
|
144
|
+
const clone = { ...value };
|
|
145
|
+
delete clone.ProjectKey;
|
|
146
|
+
delete clone.projectKey;
|
|
147
|
+
return clone;
|
|
148
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type BlocksLocalizationLanguage = Record<string, unknown> & {
|
|
2
|
+
itemId?: string;
|
|
3
|
+
code?: string;
|
|
4
|
+
culture?: string;
|
|
5
|
+
displayName?: string;
|
|
6
|
+
isDefault?: boolean;
|
|
7
|
+
languageCode?: string;
|
|
8
|
+
languageName?: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
};
|
|
11
|
+
export type BlocksLocalizationModule = Record<string, unknown> & {
|
|
12
|
+
itemId?: string;
|
|
13
|
+
moduleName?: string;
|
|
14
|
+
name?: string;
|
|
15
|
+
};
|
|
16
|
+
export type BlocksLocalizationDictionary = Record<string, string>;
|
|
17
|
+
export type BlocksLocalizationTranslationOptions = {
|
|
18
|
+
language: string;
|
|
19
|
+
moduleName: string;
|
|
20
|
+
};
|
|
21
|
+
export type BlocksLocalizationKey = Record<string, unknown> & {
|
|
22
|
+
itemId?: string;
|
|
23
|
+
keyName?: string;
|
|
24
|
+
moduleId?: string;
|
|
25
|
+
moduleName?: string;
|
|
26
|
+
values?: Record<string, unknown>;
|
|
27
|
+
};
|
|
28
|
+
export type BlocksLocalizationKeysByNamesRequest = {
|
|
29
|
+
keyNames: string[];
|
|
30
|
+
moduleId?: string;
|
|
31
|
+
};
|
|
32
|
+
export type BlocksLocalizationKeysByNamesResponse = Record<string, unknown> & {
|
|
33
|
+
keys?: BlocksLocalizationKey[];
|
|
34
|
+
errorMessage?: string;
|
|
35
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type BlocksRequestOptions = {
|
|
2
|
+
accessToken?: string;
|
|
3
|
+
auth?: boolean;
|
|
4
|
+
body?: unknown;
|
|
5
|
+
headers?: HeadersInit;
|
|
6
|
+
method?: string;
|
|
7
|
+
query?: Record<string, boolean | number | string | undefined>;
|
|
8
|
+
};
|
|
9
|
+
export type BlocksExternalRequestOptions = {
|
|
10
|
+
body?: BodyInit | null;
|
|
11
|
+
headers?: HeadersInit;
|
|
12
|
+
method?: string;
|
|
13
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@seliseblocks/client",
|
|
3
|
+
"version": "0.1.0-beta.0",
|
|
4
|
+
"description": "Framework-neutral TypeScript client SDK for SELISE Blocks frontend applications.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"selise",
|
|
9
|
+
"blocks",
|
|
10
|
+
"sdk",
|
|
11
|
+
"typescript",
|
|
12
|
+
"frontend"
|
|
13
|
+
],
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./package.json": "./package.json"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"sideEffects": false,
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md",
|
|
30
|
+
"AI_USAGE_GUIDE.md",
|
|
31
|
+
"LICENSE"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
35
|
+
"build": "npm run clean && tsc -p tsconfig.json",
|
|
36
|
+
"lint": "tsc -p tsconfig.json --noEmit",
|
|
37
|
+
"test": "npm run build && node --test test/*.test.mjs",
|
|
38
|
+
"prepack": "npm run build",
|
|
39
|
+
"prepublishOnly": "npm test"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=20"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^22.0.0",
|
|
46
|
+
"typescript": "^5.5.0"
|
|
47
|
+
}
|
|
48
|
+
}
|