@seliseblocks/client 0.1.4 → 0.1.6

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 CHANGED
@@ -100,7 +100,8 @@ Data:
100
100
  - `blocks.data.collection("Name").list/get/create/update/delete`
101
101
  - `blocks.data.graphql(...)`
102
102
  - `blocks.data.files.*` for file/storage helpers
103
- - `blocks.data.dms.*` for DMS file/folder helpers
103
+ - `blocks.data.directories.*` for directory create/get/update/delete/move
104
+ - `blocks.data.objects.*` for browse/search/trash/shared/restore/share/access/inheritance
104
105
  - `blocks.data.utilities.*` for runtime utility helpers
105
106
 
106
107
  Localization:
package/README.md CHANGED
@@ -118,15 +118,15 @@ is an admin concern handled by `@seliseblocks/cli-os`'s `notification *` command
118
118
  ## Common Runtime Calls
119
119
 
120
120
  ```ts
121
- const me = await blocks.iam.me();
122
- const orgs = await blocks.iam.organizations.my();
123
- const features = await blocks.iam.resources.features();
124
- ```
125
-
126
- `iam.organizations.my()` returns the IAM envelope with `organizations`, not `data`.
127
-
128
- ```ts
129
- const schemas = await blocks.data.schemas.list();
121
+ const me = await blocks.iam.me();
122
+ const orgs = await blocks.iam.organizations.my();
123
+ const features = await blocks.iam.resources.features();
124
+ ```
125
+
126
+ `iam.organizations.my()` returns the IAM envelope with `organizations`, not `data`.
127
+
128
+ ```ts
129
+ const schemas = await blocks.data.schemas.list();
130
130
  const schemaInfo = await blocks.data.schemas.infoByName("Student");
131
131
  const schemaRules = await blocks.data.validations.bySchemaId("schema-id");
132
132
 
@@ -153,11 +153,15 @@ await blocks.data.files.uploadToUrl({
153
153
  contentType: file.type
154
154
  });
155
155
 
156
- const items = await blocks.data.dms.list({
157
- configurationName: "default",
158
- parentId: "root",
159
- skip: 0,
160
- take: 20
156
+ const items = await blocks.data.objects.list({
157
+ parentDirectoryId: "root",
158
+ limit: 20
159
+ });
160
+
161
+ const directory = await blocks.data.directories.create({
162
+ name: "Contracts",
163
+ parentDirectoryId: "root",
164
+ allowedFileExtensions: ["pdf", "docx"]
161
165
  });
162
166
  ```
163
167
 
@@ -177,7 +181,7 @@ const selectedKeys = await blocks.localization.keysByNames({
177
181
  - `blocks.auth.idp`: hosted IdP initiate, browser redirect, callback, UI config.
178
182
  - `blocks.auth.oidc`: refresh-token and client-credentials token endpoint helpers.
179
183
  - `blocks.iam`: current user, users, roles, permissions, resources, organizations, signup settings (`blocks.iam.signupSettings`).
180
- - `blocks.data`: schema reads, validation reads, GraphQL gateway execution, file/storage helpers, DMS file/folder helpers, runtime collection CRUD.
184
+ - `blocks.data`: schema reads, validation reads, GraphQL gateway execution, file/directory/object-tree storage helpers, and runtime collection CRUD.
181
185
  - `blocks.localization`: tenant language/module discovery, UILM dictionary loading, selected key lookup, simple `t()` lookup.
182
186
  - `blocks.mfa`: tenant MFA policy read/save, TOTP enrollment, OTP generate/resend/verify, method switch, disable, and backup codes.
183
187
  - `blocks.mail`: `send`/`sendToAny` transactional email through the tenant's configured mail provider.
package/dist/client.d.ts CHANGED
@@ -42,6 +42,13 @@ export type BlocksClientConfig = {
42
42
  * Optional fetch-compatible function for tests, SSR, or custom runtimes.
43
43
  */
44
44
  fetch?: typeof fetch;
45
+ /**
46
+ * Caller-owned hook invoked at most once per request when a protected call comes back 401.
47
+ * Should resolve a fresh token (deduping concurrent callers itself, e.g. via a shared
48
+ * in-flight refresh promise) or `undefined` if the session cannot be recovered -- the SDK
49
+ * retries the request once with the returned token, or leaves the 401 to throw if none.
50
+ */
51
+ onUnauthorized?: () => Promise<string | undefined> | string | undefined;
45
52
  /**
46
53
  * Optional hosted IdP/OIDC browser-flow configuration.
47
54
  */
@@ -66,6 +73,7 @@ export type RequiredConfig = {
66
73
  accessToken?: string | (() => Promise<string | undefined> | string | undefined);
67
74
  apiUrl: string;
68
75
  appDomain?: string;
76
+ onUnauthorized?: () => Promise<string | undefined> | string | undefined;
69
77
  oidc?: BlocksOidcConfig & {
70
78
  redirectUri: string;
71
79
  scope: string;
package/dist/client.js CHANGED
@@ -36,6 +36,7 @@ function normalizeConfig(config) {
36
36
  accessToken: config.accessToken,
37
37
  apiUrl: trimTrailingSlash(config.apiUrl),
38
38
  appDomain: config.appDomain,
39
+ onUnauthorized: config.onUnauthorized,
39
40
  oidc: config.oidc ? {
40
41
  ...config.oidc,
41
42
  redirectUri: config.oidc.redirectUri ?? browserRedirectUri(),
@@ -1,5 +1,5 @@
1
1
  import { BlocksHttpClient } from "../http/http-client.js";
2
- import { BlocksDataCollection, BlocksDataCollectionOptions, BlocksDmsCreateFolderRequest, BlocksDmsListRequest, BlocksDmsUploadRequest, BlocksFileDeleteRequest, BlocksFileGetOptions, BlocksFileInfoListRequest, BlocksDataSchema, BlocksFileListRequest, BlocksFileUpdateAdditionalInfoRequest, BlocksFileUploadRequest, BlocksFolderDeleteRequest, BlocksGraphqlRequest, BlocksLocalStorageUploadRequest, BlocksPagedResult, BlocksRegexGenerateRequest, BlocksSchemaFieldValidationOptions, BlocksSchemaListOptions, BlocksSchemaValidationListOptions, BlocksUploadToUrlRequest } from "./types.js";
2
+ import { BlocksDataCollection, BlocksDataCollectionOptions, BlocksDirectoryCreateRequest, BlocksDirectoryDeleteRequest, BlocksDirectoryMoveRequest, BlocksDirectoryUpdateRequest, BlocksFileCopyRequest, BlocksFileCreateVersionRequest, BlocksFileDeleteRequest, BlocksFileGetOptions, BlocksFileInfoListRequest, BlocksFileMoveRequest, BlocksFileRenameRequest, BlocksFileVersionsRequest, BlocksDataSchema, BlocksFileListRequest, BlocksFileUpdateAdditionalInfoRequest, BlocksFileUploadRequest, BlocksGraphqlRequest, BlocksLocalStorageUploadRequest, BlocksPagedResult, BlocksRegexGenerateRequest, BlocksSchemaFieldValidationOptions, BlocksSchemaListOptions, BlocksSchemaValidationListOptions, BlocksStorageAccessPolicyRequest, BlocksStorageObjectListRequest, BlocksStorageObjectPageRequest, BlocksStorageObjectSearchRequest, BlocksStorageObjectsResponse, BlocksStorageResourceRequest, BlocksStorageRevokeAccessRequest, BlocksStorageShareRequest, BlocksStorageToggleInheritanceRequest, BlocksUploadToUrlRequest } from "./types.js";
3
3
  export declare class BlocksDataClient {
4
4
  private readonly http;
5
5
  constructor(http: BlocksHttpClient);
@@ -43,27 +43,27 @@ export declare class BlocksDataClient {
43
43
  };
44
44
  files: {
45
45
  /**
46
- * What: reads one file record through `GET /data/v4/Files/GetFile`.
46
+ * What: reads one file record through the current file download operation.
47
47
  * Why: frontend views need file metadata or a downloadable reference by file id.
48
48
  * How: pass `fileId` and optional Data file configuration/version fields.
49
49
  */
50
50
  get: (fileId: string, options?: BlocksFileGetOptions) => Promise<unknown>;
51
51
  /**
52
- * What: batch-reads files through `POST /data/v4/Files/GetFiles`.
52
+ * What: batch-reads file metadata and download URLs.
53
53
  * Why: pages with many attachments should avoid one request per file.
54
54
  * How: pass the file-list payload exactly as Data expects; the SDK does not inject project fields.
55
55
  */
56
56
  getMany: (request: BlocksFileListRequest) => Promise<unknown>;
57
57
  /**
58
- * What: lists file records and metadata through `POST /data/v4/Files/GetFilesInfo`.
58
+ * What: lists file records and metadata.
59
59
  * Why: storage browsers and attachment managers need paged file metadata before downloading content.
60
60
  * How: pass paging, sort, and filter fields; the SDK sends your request without any `projectKey`.
61
61
  */
62
62
  info: (request: BlocksFileInfoListRequest) => Promise<unknown>;
63
63
  /**
64
- * What: requests an upload URL through `POST /data/v4/Files/GetPreSignedUrlForUpload`.
64
+ * What: creates file/version metadata and requests a pre-signed upload URL.
65
65
  * Why: browser apps should upload binary content through the URL issued by Blocks Data.
66
- * How: pass file metadata such as `name`, `contentType`, `configurationName`, and optional DMS fields.
66
+ * How: pass file metadata plus a parent directory id or module default.
67
67
  */
68
68
  presignedUploadUrl: (request: BlocksFileUploadRequest) => Promise<unknown>;
69
69
  /**
@@ -73,55 +73,50 @@ export declare class BlocksDataClient {
73
73
  */
74
74
  uploadToUrl: (request: BlocksUploadToUrlRequest) => Promise<unknown>;
75
75
  /**
76
- * What: uploads a file through `POST /data/v4/Files/UploadFileToLocalStorage`.
76
+ * What: creates a file/version and uploads its bytes to local storage.
77
77
  * Why: local-storage deployments need multipart upload through Blocks Data instead of a pre-signed cloud URL.
78
78
  * How: pass a `Blob`/`File` and metadata; the SDK builds `FormData` and does not add `projectKey`.
79
79
  */
80
80
  uploadToLocalStorage: (request: BlocksLocalStorageUploadRequest) => Promise<unknown>;
81
81
  /**
82
- * What: deletes a file through `POST /data/v4/Files/DeleteFile`.
82
+ * What: moves a file to trash or permanently deletes it.
83
83
  * Why: storage UIs need to remove files when permissions and Data rules allow it.
84
- * How: pass `fileId` and optional `configurationName`; the SDK sends no project key.
84
+ * How: pass `fileId` and an explicit `permanent` choice; false moves to trash.
85
85
  */
86
86
  delete: (request: BlocksFileDeleteRequest) => Promise<unknown>;
87
87
  /**
88
- * What: updates file additional properties through `POST /data/v4/Files/UpdateFileAdditionalInfo`.
88
+ * What: updates file additional properties.
89
89
  * Why: apps often need to attach searchable metadata such as agent status or business references to a file.
90
90
  * How: pass `itemId` and `additionalProperties`; the SDK forwards the request as-is except for not adding project fields.
91
91
  */
92
92
  updateAdditionalInfo: (request: BlocksFileUpdateAdditionalInfoRequest) => Promise<unknown>;
93
- /**
94
- * What: reads DMS file/folder entries through `POST /data/v4/Files/GetDmsFileAndFolder`.
95
- * Why: document-management views need combined folder and file listings.
96
- * How: pass Data's DMS listing payload exactly as your app builds it.
97
- */
98
- listFolder: (request: BlocksFileListRequest) => Promise<unknown>;
93
+ versions: (request: BlocksFileVersionsRequest) => Promise<unknown>;
94
+ createVersion: (request: BlocksFileCreateVersionRequest) => Promise<unknown>;
95
+ copy: (request: BlocksFileCopyRequest) => Promise<unknown>;
96
+ move: (request: BlocksFileMoveRequest) => Promise<unknown>;
97
+ rename: (request: BlocksFileRenameRequest) => Promise<unknown>;
99
98
  };
100
- dms: {
101
- /**
102
- * What: lists DMS files and folders through `POST /data/v4/Files/GetDmsFileAndFolder`.
103
- * Why: document-management screens need folder contents, search, skip/take paging, and file entries together.
104
- * How: pass DMS listing fields such as `parentId`, `configurationName`, `searchKey`, `skip`, and `take`.
105
- */
106
- list: (request: BlocksDmsListRequest) => Promise<unknown>;
107
- /**
108
- * What: registers uploaded files in DMS through `POST /data/v4/Files/UploadFile`.
109
- * Why: after binary upload, DMS needs artifact metadata so files appear in document folders.
110
- * How: pass the `upload` array with file storage ids and metadata returned from the upload flow.
111
- */
112
- uploadFiles: (request: BlocksDmsUploadRequest) => Promise<unknown>;
113
- /**
114
- * What: creates a DMS folder through `POST /data/v4/Files/CreateFolder`.
115
- * Why: document-management UIs need to create folder hierarchy for uploaded files.
116
- * How: pass folder metadata such as `artifactName`, `parentId`, and optional `configurationName`.
117
- */
118
- createFolder: (request: BlocksDmsCreateFolderRequest) => Promise<unknown>;
119
- /**
120
- * What: deletes a DMS folder through `POST /data/v4/Files/DeleteFolder`.
121
- * Why: document-management UIs need to remove empty or allowed folders.
122
- * How: pass `folderId` and optional `configurationName`; the SDK sends no project key.
123
- */
124
- deleteFolder: (request: BlocksFolderDeleteRequest) => Promise<unknown>;
99
+ directories: {
100
+ create: (request: BlocksDirectoryCreateRequest) => Promise<unknown>;
101
+ get: (directoryId: string) => Promise<unknown>;
102
+ update: (request: BlocksDirectoryUpdateRequest) => Promise<unknown>;
103
+ delete: (request: BlocksDirectoryDeleteRequest) => Promise<unknown>;
104
+ move: (request: BlocksDirectoryMoveRequest) => Promise<unknown>;
105
+ };
106
+ objects: {
107
+ list: (request?: BlocksStorageObjectListRequest) => Promise<BlocksStorageObjectsResponse>;
108
+ search: (request: BlocksStorageObjectSearchRequest) => Promise<BlocksStorageObjectsResponse>;
109
+ trash: (request?: BlocksStorageObjectPageRequest) => Promise<BlocksStorageObjectsResponse>;
110
+ shared: (request?: BlocksStorageObjectPageRequest) => Promise<BlocksStorageObjectsResponse>;
111
+ restore: (request: BlocksStorageResourceRequest) => Promise<unknown>;
112
+ deleteFromTrash: (request: BlocksStorageResourceRequest) => Promise<unknown>;
113
+ accessPolicies: (resourceId: string) => Promise<unknown>;
114
+ grantAccess: (request: BlocksStorageAccessPolicyRequest) => Promise<unknown>;
115
+ updateAccess: (request: BlocksStorageAccessPolicyRequest) => Promise<unknown>;
116
+ revokeAccess: (request: BlocksStorageRevokeAccessRequest) => Promise<unknown>;
117
+ resolveAccess: (resourceId: string) => Promise<unknown>;
118
+ toggleInheritance: (request: BlocksStorageToggleInheritanceRequest) => Promise<unknown>;
119
+ share: (request: BlocksStorageShareRequest) => Promise<unknown>;
125
120
  };
126
121
  validations: {
127
122
  /**
@@ -54,11 +54,11 @@ export class BlocksDataClient {
54
54
  };
55
55
  files = {
56
56
  /**
57
- * What: reads one file record through `GET /data/v4/Files/GetFile`.
57
+ * What: reads one file record through the current file download operation.
58
58
  * Why: frontend views need file metadata or a downloadable reference by file id.
59
59
  * How: pass `fileId` and optional Data file configuration/version fields.
60
60
  */
61
- get: (fileId, options = {}) => this.http.request(`${DATA_API}/Files/GetFile`, {
61
+ get: (fileId, options = {}) => this.http.request(`${DATA_API}/files/get-file`, {
62
62
  query: {
63
63
  ConfigurationName: options.configurationName,
64
64
  FileId: fileId,
@@ -66,27 +66,27 @@ export class BlocksDataClient {
66
66
  }
67
67
  }),
68
68
  /**
69
- * What: batch-reads files through `POST /data/v4/Files/GetFiles`.
69
+ * What: batch-reads file metadata and download URLs.
70
70
  * Why: pages with many attachments should avoid one request per file.
71
71
  * How: pass the file-list payload exactly as Data expects; the SDK does not inject project fields.
72
72
  */
73
- getMany: (request) => this.http.request(`${DATA_API}/Files/GetFiles`, {
73
+ getMany: (request) => this.http.request(`${DATA_API}/files/get-files`, {
74
74
  body: normalizeFileListRequest(request)
75
75
  }),
76
76
  /**
77
- * What: lists file records and metadata through `POST /data/v4/Files/GetFilesInfo`.
77
+ * What: lists file records and metadata.
78
78
  * Why: storage browsers and attachment managers need paged file metadata before downloading content.
79
79
  * How: pass paging, sort, and filter fields; the SDK sends your request without any `projectKey`.
80
80
  */
81
- info: (request) => this.http.request(`${DATA_API}/Files/GetFilesInfo`, {
81
+ info: (request) => this.http.request(`${DATA_API}/files/get-files-info`, {
82
82
  body: withoutProjectKey(request)
83
83
  }),
84
84
  /**
85
- * What: requests an upload URL through `POST /data/v4/Files/GetPreSignedUrlForUpload`.
85
+ * What: creates file/version metadata and requests a pre-signed upload URL.
86
86
  * Why: browser apps should upload binary content through the URL issued by Blocks Data.
87
- * How: pass file metadata such as `name`, `contentType`, `configurationName`, and optional DMS fields.
87
+ * How: pass file metadata plus a parent directory id or module default.
88
88
  */
89
- presignedUploadUrl: (request) => this.http.request(`${DATA_API}/Files/GetPreSignedUrlForUpload`, {
89
+ presignedUploadUrl: (request) => this.http.request(`${DATA_API}/files/get-pre-signed-url-for-upload`, {
90
90
  body: normalizeUploadRequest(request)
91
91
  }),
92
92
  /**
@@ -107,71 +107,102 @@ export class BlocksDataClient {
107
107
  });
108
108
  },
109
109
  /**
110
- * What: uploads a file through `POST /data/v4/Files/UploadFileToLocalStorage`.
110
+ * What: creates a file/version and uploads its bytes to local storage.
111
111
  * Why: local-storage deployments need multipart upload through Blocks Data instead of a pre-signed cloud URL.
112
112
  * How: pass a `Blob`/`File` and metadata; the SDK builds `FormData` and does not add `projectKey`.
113
113
  */
114
- uploadToLocalStorage: (request) => this.http.request(`${DATA_API}/Files/UploadFileToLocalStorage`, {
114
+ uploadToLocalStorage: (request) => this.http.request(`${DATA_API}/files/upload-file-to-local-storage`, {
115
115
  body: toLocalStorageFormData(request),
116
116
  headers: {}
117
117
  }),
118
118
  /**
119
- * What: deletes a file through `POST /data/v4/Files/DeleteFile`.
119
+ * What: moves a file to trash or permanently deletes it.
120
120
  * Why: storage UIs need to remove files when permissions and Data rules allow it.
121
- * How: pass `fileId` and optional `configurationName`; the SDK sends no project key.
121
+ * How: pass `fileId` and an explicit `permanent` choice; false moves to trash.
122
122
  */
123
- delete: (request) => this.http.request(`${DATA_API}/Files/DeleteFile`, {
123
+ delete: (request) => this.http.request(`${DATA_API}/files/delete-file`, {
124
124
  body: withoutProjectKey(request)
125
125
  }),
126
126
  /**
127
- * What: updates file additional properties through `POST /data/v4/Files/UpdateFileAdditionalInfo`.
127
+ * What: updates file additional properties.
128
128
  * Why: apps often need to attach searchable metadata such as agent status or business references to a file.
129
129
  * How: pass `itemId` and `additionalProperties`; the SDK forwards the request as-is except for not adding project fields.
130
130
  */
131
- updateAdditionalInfo: (request) => this.http.request(`${DATA_API}/Files/UpdateFileAdditionalInfo`, {
131
+ updateAdditionalInfo: (request) => this.http.request(`${DATA_API}/files/update-file-additional-info`, {
132
132
  body: withoutProjectKey(request)
133
133
  }),
134
- /**
135
- * What: reads DMS file/folder entries through `POST /data/v4/Files/GetDmsFileAndFolder`.
136
- * Why: document-management views need combined folder and file listings.
137
- * How: pass Data's DMS listing payload exactly as your app builds it.
138
- */
139
- listFolder: (request) => this.http.request(`${DATA_API}/Files/GetDmsFileAndFolder`, {
140
- body: withoutProjectKey(request)
134
+ versions: (request) => this.http.request(`${DATA_API}/files/get-file-versions`, {
135
+ query: request
136
+ }),
137
+ createVersion: (request) => this.http.request(`${DATA_API}/files/create-file-version`, {
138
+ body: request
139
+ }),
140
+ copy: (request) => this.http.request(`${DATA_API}/files/copy-file`, {
141
+ body: request
142
+ }),
143
+ move: (request) => this.http.request(`${DATA_API}/files/move-file`, {
144
+ body: request
145
+ }),
146
+ rename: (request) => this.http.request(`${DATA_API}/files/rename-file`, {
147
+ body: request
141
148
  })
142
149
  };
143
- dms = {
144
- /**
145
- * What: lists DMS files and folders through `POST /data/v4/Files/GetDmsFileAndFolder`.
146
- * Why: document-management screens need folder contents, search, skip/take paging, and file entries together.
147
- * How: pass DMS listing fields such as `parentId`, `configurationName`, `searchKey`, `skip`, and `take`.
148
- */
149
- list: (request) => this.http.request(`${DATA_API}/Files/GetDmsFileAndFolder`, {
150
- body: withoutProjectKey(request)
150
+ directories = {
151
+ create: (request) => this.http.request(`${DATA_API}/directory/create-directory`, {
152
+ body: request
151
153
  }),
152
- /**
153
- * What: registers uploaded files in DMS through `POST /data/v4/Files/UploadFile`.
154
- * Why: after binary upload, DMS needs artifact metadata so files appear in document folders.
155
- * How: pass the `upload` array with file storage ids and metadata returned from the upload flow.
156
- */
157
- uploadFiles: (request) => this.http.request(`${DATA_API}/Files/UploadFile`, {
158
- body: withoutProjectKey(request)
154
+ get: (directoryId) => this.http.request(`${DATA_API}/directory/get-directory`, {
155
+ query: { directoryId }
159
156
  }),
160
- /**
161
- * What: creates a DMS folder through `POST /data/v4/Files/CreateFolder`.
162
- * Why: document-management UIs need to create folder hierarchy for uploaded files.
163
- * How: pass folder metadata such as `artifactName`, `parentId`, and optional `configurationName`.
164
- */
165
- createFolder: (request) => this.http.request(`${DATA_API}/Files/CreateFolder`, {
166
- body: withoutProjectKey(request)
157
+ update: (request) => this.http.request(`${DATA_API}/directory/update-directory`, {
158
+ body: request
167
159
  }),
168
- /**
169
- * What: deletes a DMS folder through `POST /data/v4/Files/DeleteFolder`.
170
- * Why: document-management UIs need to remove empty or allowed folders.
171
- * How: pass `folderId` and optional `configurationName`; the SDK sends no project key.
172
- */
173
- deleteFolder: (request) => this.http.request(`${DATA_API}/Files/DeleteFolder`, {
174
- body: withoutProjectKey(request)
160
+ delete: (request) => this.http.request(`${DATA_API}/directory/delete-directory`, {
161
+ body: request
162
+ }),
163
+ move: (request) => this.http.request(`${DATA_API}/directory/move-directory`, {
164
+ body: request
165
+ })
166
+ };
167
+ objects = {
168
+ list: (request = {}) => this.http.request(`${DATA_API}/objects/get-objects`, {
169
+ query: request
170
+ }),
171
+ search: (request) => this.http.request(`${DATA_API}/objects/search-objects`, {
172
+ query: request
173
+ }),
174
+ trash: (request = {}) => this.http.request(`${DATA_API}/objects/get-trash`, {
175
+ query: request
176
+ }),
177
+ shared: (request = {}) => this.http.request(`${DATA_API}/objects/get-shared-objects`, {
178
+ query: request
179
+ }),
180
+ restore: (request) => this.http.request(`${DATA_API}/objects/restore-from-trash`, {
181
+ body: request
182
+ }),
183
+ deleteFromTrash: (request) => this.http.request(`${DATA_API}/objects/delete-from-trash`, {
184
+ body: request
185
+ }),
186
+ accessPolicies: (resourceId) => this.http.request(`${DATA_API}/objects/get-access-policies`, {
187
+ query: { resourceId }
188
+ }),
189
+ grantAccess: (request) => this.http.request(`${DATA_API}/objects/grant-access`, {
190
+ body: request
191
+ }),
192
+ updateAccess: (request) => this.http.request(`${DATA_API}/objects/update-access-policy`, {
193
+ body: request
194
+ }),
195
+ revokeAccess: (request) => this.http.request(`${DATA_API}/objects/revoke-access-policy`, {
196
+ body: request
197
+ }),
198
+ resolveAccess: (resourceId) => this.http.request(`${DATA_API}/objects/resolve-access`, {
199
+ query: { resourceId }
200
+ }),
201
+ toggleInheritance: (request) => this.http.request(`${DATA_API}/objects/toggle-inheritance`, {
202
+ body: request
203
+ }),
204
+ share: (request) => this.http.request(`${DATA_API}/objects/share-object`, {
205
+ body: request
175
206
  })
176
207
  };
177
208
  validations = {
@@ -101,10 +101,7 @@ export type BlocksFileDeleteRequest = Record<string, unknown> & {
101
101
  configurationName?: string;
102
102
  eventQueueName?: string;
103
103
  fileId: string;
104
- };
105
- export type BlocksFolderDeleteRequest = Record<string, unknown> & {
106
- configurationName?: string;
107
- folderId: string;
104
+ permanent: boolean;
108
105
  };
109
106
  export type BlocksFileUpdateAdditionalInfoRequest = Record<string, unknown> & {
110
107
  additionalProperties?: Record<string, string>;
@@ -127,38 +124,132 @@ export type BlocksUploadToUrlRequest = {
127
124
  headers?: HeadersInit;
128
125
  url: string;
129
126
  };
130
- export type BlocksDmsListRequest = Record<string, unknown> & {
131
- configurationName?: string;
132
- moduleName?: string;
133
- parentId?: string;
134
- searchKey?: string;
135
- skip?: number;
136
- take?: number;
137
- };
138
- export type BlocksDmsMetaDataValue = {
139
- type: string;
140
- value: string;
141
- };
142
- export type BlocksDmsUploadItem = Record<string, unknown> & {
143
- artifactName?: string;
127
+ export type BlocksStorageObjectType = "directory" | "file";
128
+ export type BlocksStorageResourceType = "Directory" | "File";
129
+ export type BlocksStoragePrincipalType = "User" | "Role" | "Everyone" | "Organization";
130
+ export type BlocksStoragePermission = "View" | "Download" | "Edit" | "Delete" | "Manage" | "Owner";
131
+ export type BlocksStorageEffect = "Allow" | "Deny";
132
+ export type BlocksStoragePermissionFlags = {
133
+ canDelete: boolean;
134
+ canDownload: boolean;
135
+ canEdit: boolean;
136
+ canManage: boolean;
137
+ canOwner: boolean;
138
+ canView: boolean;
139
+ };
140
+ export type BlocksStorageObject = {
141
+ childDirectoryCount?: number;
142
+ childFileCount?: number;
143
+ contentType?: string;
144
+ createdBy?: string;
145
+ createdDate: string;
146
+ currentVersion?: number;
147
+ extension?: string;
148
+ isDefault: boolean;
149
+ itemId: string;
150
+ lastUpdatedDate: string;
151
+ name: string;
152
+ parentDirectoryId?: string;
153
+ permissions: BlocksStoragePermissionFlags;
154
+ sizeInBytes: number;
155
+ type: BlocksStorageObjectType;
156
+ };
157
+ export type BlocksStorageObjectsResponse = {
158
+ hasMore: boolean;
159
+ items: BlocksStorageObject[];
160
+ nextCursor?: string;
161
+ totalChildCount: number;
162
+ };
163
+ export type BlocksStorageObjectListRequest = {
164
+ cursor?: string;
165
+ limit?: number;
166
+ moduleName?: number;
167
+ parentDirectoryId?: string;
168
+ search?: string;
169
+ type?: BlocksStorageObjectType;
170
+ };
171
+ export type BlocksStorageObjectSearchRequest = {
172
+ cursor?: string;
173
+ directoryId?: string;
174
+ limit?: number;
175
+ query: string;
176
+ type?: BlocksStorageObjectType;
177
+ };
178
+ export type BlocksStorageObjectPageRequest = {
179
+ cursor?: string;
180
+ limit?: number;
181
+ type?: BlocksStorageObjectType;
182
+ };
183
+ export type BlocksDirectoryCreateRequest = {
184
+ allowedFileExtensions?: string[];
144
185
  configurationName?: string;
145
186
  description?: string;
146
- fileStorageId: string;
147
- metaData?: Record<string, BlocksDmsMetaDataValue>;
148
- organizationId?: string;
149
- parentId?: string;
150
- tags?: string[];
187
+ moduleName?: number;
188
+ name: string;
189
+ parentDirectoryId?: string;
190
+ };
191
+ export type BlocksDirectoryUpdateRequest = {
192
+ description?: string;
193
+ directoryId: string;
194
+ name?: string;
195
+ };
196
+ export type BlocksDirectoryDeleteRequest = {
197
+ directoryId: string;
198
+ permanent: boolean;
199
+ };
200
+ export type BlocksDirectoryMoveRequest = {
201
+ directoryId: string;
202
+ targetDirectoryId?: string;
151
203
  };
152
- export type BlocksDmsUploadRequest = Record<string, unknown> & {
153
- upload: BlocksDmsUploadItem[];
204
+ export type BlocksFileVersionsRequest = {
205
+ cursor?: string;
206
+ fileId: string;
207
+ limit?: number;
154
208
  };
155
- export type BlocksDmsCreateFolderRequest = Record<string, unknown> & {
156
- artifactName: string;
209
+ export type BlocksFileCreateVersionRequest = {
157
210
  configurationName?: string;
158
- description?: string;
159
- fileStorageId?: string;
160
- metaData?: Record<string, BlocksDmsMetaDataValue>;
161
- organizationId?: string;
162
- parentId?: string;
163
- tags?: string[];
211
+ fileId: string;
212
+ };
213
+ export type BlocksFileCopyRequest = {
214
+ copyAccessPolicies?: boolean;
215
+ fileId: string;
216
+ targetDirectoryId: string;
217
+ };
218
+ export type BlocksFileMoveRequest = {
219
+ fileId: string;
220
+ targetDirectoryId: string;
221
+ };
222
+ export type BlocksFileRenameRequest = {
223
+ fileId: string;
224
+ name: string;
225
+ };
226
+ export type BlocksStorageResourceRequest = {
227
+ resourceId: string;
228
+ };
229
+ export type BlocksStorageAccessPolicyRequest = {
230
+ effect?: BlocksStorageEffect;
231
+ expiresAt?: string;
232
+ permission: BlocksStoragePermission;
233
+ policyItemId?: string;
234
+ principalId?: string;
235
+ principalType: BlocksStoragePrincipalType;
236
+ priority?: number;
237
+ resourceId: string;
238
+ resourceType: BlocksStorageResourceType;
239
+ };
240
+ export type BlocksStorageRevokeAccessRequest = {
241
+ policyItemId: string;
242
+ resourceId: string;
243
+ };
244
+ export type BlocksStorageToggleInheritanceRequest = {
245
+ inheritsParentAccess: boolean;
246
+ resourceId: string;
247
+ };
248
+ export type BlocksStorageShareRequest = {
249
+ expiresAt?: string;
250
+ permission: BlocksStoragePermission;
251
+ principalId?: string;
252
+ principalType: BlocksStoragePrincipalType;
253
+ resourceId: string;
254
+ resourceType: BlocksStorageResourceType;
164
255
  };
@@ -12,26 +12,38 @@ export class BlocksHttpClient {
12
12
  }
13
13
  async request(path, options = {}) {
14
14
  const url = buildUrl(this.config.apiUrl, path, options.query);
15
- const headers = new Headers(options.headers);
16
15
  const rawBody = isBodyInit(options.body) ? options.body : undefined;
17
- headers.set("Accept", "application/json");
18
- headers.set("x-blocks-key", this.config.xBlocksKey);
19
- if (options.body !== undefined && !rawBody && !headers.has("Content-Type")) {
20
- headers.set("Content-Type", "application/json");
16
+ const send = async (accessTokenOverride) => {
17
+ const headers = new Headers(options.headers);
18
+ headers.set("Accept", "application/json");
19
+ headers.set("x-blocks-key", this.config.xBlocksKey);
20
+ if (options.body !== undefined && !rawBody && !headers.has("Content-Type")) {
21
+ headers.set("Content-Type", "application/json");
22
+ }
23
+ if (options.auth !== false) {
24
+ const token = accessTokenOverride ?? options.accessToken ?? await this.auth.accessToken();
25
+ if (token)
26
+ headers.set("Authorization", `Bearer ${token}`);
27
+ }
28
+ return this.fetchImpl(url, {
29
+ body: rawBody ?? (options.body === undefined ? undefined : JSON.stringify(options.body)),
30
+ // IAM's hosted IdP flow sets the session as a Secure, httpOnly cookie by default;
31
+ // without this the browser never sends it back on subsequent Blocks API calls.
32
+ credentials: "include",
33
+ headers,
34
+ method: options.method ?? (options.body === undefined ? "GET" : "POST")
35
+ });
36
+ };
37
+ let response = await send();
38
+ // A 401 on a token the caller supplied directly (options.accessToken) is the
39
+ // caller's problem to resolve, not ours. Otherwise, give the app one chance to
40
+ // recover through its own onUnauthorized hook (expected to dedupe concurrent
41
+ // callers behind a single refresh) and retry exactly once with what it returns.
42
+ if (response.status === 401 && options.auth !== false && options.accessToken === undefined && this.config.onUnauthorized) {
43
+ const freshToken = await this.config.onUnauthorized();
44
+ if (freshToken)
45
+ response = await send(freshToken);
21
46
  }
22
- if (options.auth !== false) {
23
- const token = options.accessToken ?? await this.auth.accessToken();
24
- if (token)
25
- headers.set("Authorization", `Bearer ${token}`);
26
- }
27
- const response = await this.fetchImpl(url, {
28
- body: rawBody ?? (options.body === undefined ? undefined : JSON.stringify(options.body)),
29
- // IAM's hosted IdP flow sets the session as a Secure, httpOnly cookie by default;
30
- // without this the browser never sends it back on subsequent Blocks API calls.
31
- credentials: "include",
32
- headers,
33
- method: options.method ?? (options.body === undefined ? "GET" : "POST")
34
- });
35
47
  const body = await parseBody(response);
36
48
  if (!response.ok)
37
49
  throw new BlocksApiError(response.status, response.statusText, body);
package/dist/index.d.ts CHANGED
@@ -11,7 +11,7 @@ export { BlocksNotifierClient } from "./notifier/notifier-client.js";
11
11
  export type { BlocksAuthPassThroughResponse, BlocksAuthResponse, BlocksClientCredentialsRequest, BlocksAuthLoginRequest, BlocksIdpCallbackRequest, BlocksIdpInitiateRequest, BlocksIdpInitiateResponse, BlocksLoginOption, BlocksLogoutRequest, BlocksOidcRefreshRequest, BlocksOidcUserInfo, BlocksRefreshRequest, BlocksSocialLoginRequest, BlocksSwitchOrganizationRequest } from "./auth/auth-client.js";
12
12
  export type { BlocksRequestOptions } from "./types.js";
13
13
  export type { BlocksBaseResponse, BlocksGetMyOrganizationsResponse, BlocksGetOrganizationResponse, BlocksGetOrganizationsResponse, BlocksGetPermissionResponse, BlocksGetPermissionsResponse, BlocksGetRoleResponse, BlocksGetRolesResponse, BlocksGetUserResponse, BlocksGetUsersResponse, BlocksIamListRequest, BlocksMeResponse, BlocksOrganization, BlocksPermission, BlocksQueryListResponse, BlocksQueryResponse, BlocksRole, BlocksUser } from "./iam/types.js";
14
- 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";
14
+ export type { BlocksDataCollection, BlocksDataListOptions, BlocksDirectoryCreateRequest, BlocksDirectoryDeleteRequest, BlocksDirectoryMoveRequest, BlocksDirectoryUpdateRequest, BlocksFileCopyRequest, BlocksFileCreateVersionRequest, BlocksFileDeleteRequest, BlocksFileGetOptions, BlocksFileInfoListRequest, BlocksFileListRequest, BlocksFileMoveRequest, BlocksFileRenameRequest, BlocksFileUpdateAdditionalInfoRequest, BlocksFileUploadRequest, BlocksFileVersionsRequest, BlocksGraphqlRequest, BlocksLocalStorageUploadRequest, BlocksPagedResult, BlocksRegexGenerateRequest, BlocksSchemaFieldValidationOptions, BlocksSchemaListOptions, BlocksSchemaValidationListOptions, BlocksStorageAccessPolicyRequest, BlocksStorageEffect, BlocksStorageObject, BlocksStorageObjectListRequest, BlocksStorageObjectPageRequest, BlocksStorageObjectSearchRequest, BlocksStorageObjectsResponse, BlocksStorageObjectType, BlocksStoragePermission, BlocksStoragePermissionFlags, BlocksStoragePrincipalType, BlocksStorageResourceRequest, BlocksStorageResourceType, BlocksStorageRevokeAccessRequest, BlocksStorageShareRequest, BlocksStorageToggleInheritanceRequest, BlocksUploadToUrlRequest } from "./data/types.js";
15
15
  export type { BlocksLocalizationDictionary, BlocksLocalizationKey, BlocksLocalizationKeyResource, BlocksLocalizationKeysByNamesRequest, BlocksLocalizationKeysByNamesResponse, BlocksLocalizationLanguage, BlocksLocalizationModule, BlocksLocalizationTranslationOptions } from "./localization/types.js";
16
16
  export type { BlocksMfaBackupCodeUseRequest, BlocksMfaConfig, BlocksMfaConfigSaveRequest, BlocksMfaGenerateRequest, BlocksMfaPassThroughResponse, BlocksMfaResendRequest, BlocksMfaSetMethodRequest, BlocksMfaVerifyRequest, BlocksMfaVerifyTotpSetupRequest } from "./mfa/types.js";
17
17
  export type { BlocksMailPassThroughResponse, BlocksSendMailRequest, BlocksSendMailToAnyRequest } from "./mail/types.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seliseblocks/client",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Framework-neutral TypeScript client SDK for SELISE Blocks frontend applications.",
5
5
  "license": "MIT",
6
6
  "type": "module",