@igorchugurov/public-api-sdk 1.1.0 → 1.3.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/LICENSE +1 -0
- package/README.md +56 -1
- package/dist/{client-BV5AAKYo.d.mts → client-D3jtlTId.d.mts} +18 -0
- package/dist/{client-BV5AAKYo.d.ts → client-D3jtlTId.d.ts} +18 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +183 -26
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +183 -26
- package/dist/index.mjs.map +1 -1
- package/dist/server.d.mts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +198 -26
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +198 -26
- package/dist/server.mjs.map +1 -1
- package/package.json +3 -3
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -152,14 +152,68 @@ const { data, pagination } = await sdk.getInstances(entityDefinitionId, {
|
|
|
152
152
|
|
|
153
153
|
#### `getInstance(entityDefinitionId, id, params?)`
|
|
154
154
|
|
|
155
|
-
Получить один
|
|
155
|
+
Получить один экземпляр по ID.
|
|
156
156
|
|
|
157
157
|
```typescript
|
|
158
158
|
const instance = await sdk.getInstance(entityDefinitionId, id, {
|
|
159
159
|
relationsAsIds?: boolean; // default: false
|
|
160
|
+
loadFiles?: boolean; // default: false
|
|
160
161
|
});
|
|
161
162
|
```
|
|
162
163
|
|
|
164
|
+
**Пример:**
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
// Базовое использование - без файлов
|
|
168
|
+
const instance = await sdk.getInstance("entity-def-id", "instance-id");
|
|
169
|
+
|
|
170
|
+
// Для редактирования - нужны только ID связей
|
|
171
|
+
const instance = await sdk.getInstance("entity-def-id", "instance-id", {
|
|
172
|
+
relationsAsIds: true,
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Для отображения с файлами - полные объекты
|
|
176
|
+
const instance = await sdk.getInstance("entity-def-id", "instance-id", {
|
|
177
|
+
relationsAsIds: false,
|
|
178
|
+
loadFiles: true, // файлы и изображения будут загружены как полные объекты EntityFile
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
#### `getInstanceBySlug(entityDefinitionId, slug, params?)`
|
|
183
|
+
|
|
184
|
+
Получить один экземпляр по slug.
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
const instance = await sdk.getInstanceBySlug(entityDefinitionId, slug, {
|
|
188
|
+
relationsAsIds?: boolean; // default: false
|
|
189
|
+
loadFiles?: boolean; // default: false
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Пример:**
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
// Базовое использование - без файлов
|
|
197
|
+
const instance = await sdk.getInstanceBySlug("entity-def-id", "my-article-slug");
|
|
198
|
+
|
|
199
|
+
// Для отображения с файлами - полные объекты
|
|
200
|
+
const instance = await sdk.getInstanceBySlug("entity-def-id", "my-article-slug", {
|
|
201
|
+
relationsAsIds: false,
|
|
202
|
+
loadFiles: true, // файлы и изображения будут загружены как полные объекты EntityFile
|
|
203
|
+
});
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**Особенности:**
|
|
207
|
+
- Валидирует формат slug перед запросом (только строчные латинские буквы, цифры и дефисы)
|
|
208
|
+
- Работает аналогично `getInstance`, но ищет по slug вместо id
|
|
209
|
+
- Поддерживает те же параметры, что и `getInstance`
|
|
210
|
+
- Параметр `relationsAsIds`:
|
|
211
|
+
- `false` (по умолчанию) - возвращает полные объекты связанных сущностей
|
|
212
|
+
- `true` - возвращает только массивы ID связанных сущностей
|
|
213
|
+
- Параметр `loadFiles`:
|
|
214
|
+
- `false` (по умолчанию) - файлы и изображения не загружаются
|
|
215
|
+
- `true` - файлы и изображения загружаются как полные объекты `EntityFile` (с `fileUrl`, `fileName`, `fileSize` и т.д.)
|
|
216
|
+
|
|
163
217
|
#### `createInstance(entityDefinitionId, data)`
|
|
164
218
|
|
|
165
219
|
Создать новый экземпляр. Автоматически генерирует уникальный `slug` из поля `name`.
|
|
@@ -322,3 +376,4 @@ pnpm dev
|
|
|
322
376
|
|
|
323
377
|
MIT
|
|
324
378
|
|
|
379
|
+
|
|
@@ -1108,6 +1108,11 @@ declare abstract class BasePublicAPIClient {
|
|
|
1108
1108
|
}>;
|
|
1109
1109
|
abstract getInstance(entityDefinitionId: string, id: string, params?: {
|
|
1110
1110
|
relationsAsIds?: boolean;
|
|
1111
|
+
loadFiles?: boolean;
|
|
1112
|
+
}): Promise<EntityInstanceWithFields>;
|
|
1113
|
+
abstract getInstanceBySlug(entityDefinitionId: string, slug: string, params?: {
|
|
1114
|
+
relationsAsIds?: boolean;
|
|
1115
|
+
loadFiles?: boolean;
|
|
1111
1116
|
}): Promise<EntityInstanceWithFields>;
|
|
1112
1117
|
abstract createInstance(entityDefinitionId: string, data: CreateInstanceData): Promise<EntityInstanceWithFields>;
|
|
1113
1118
|
abstract updateInstance(entityDefinitionId: string, id: string, data: UpdateInstanceData): Promise<EntityInstanceWithFields>;
|
|
@@ -1146,11 +1151,24 @@ declare class PublicAPIClient extends BasePublicAPIClient {
|
|
|
1146
1151
|
* Получить режим работы клиента (для отладки)
|
|
1147
1152
|
*/
|
|
1148
1153
|
getMode(): "server" | "client";
|
|
1154
|
+
/**
|
|
1155
|
+
* Загружает файлы для экземпляра и возвращает их как полные объекты EntityFile,
|
|
1156
|
+
* сгруппированные по именам полей
|
|
1157
|
+
*/
|
|
1158
|
+
private loadFilesForInstance;
|
|
1149
1159
|
/**
|
|
1150
1160
|
* Получить один экземпляр
|
|
1151
1161
|
*/
|
|
1152
1162
|
getInstance(entityDefinitionId: string, id: string, params?: {
|
|
1153
1163
|
relationsAsIds?: boolean;
|
|
1164
|
+
loadFiles?: boolean;
|
|
1165
|
+
}): Promise<EntityInstanceWithFields>;
|
|
1166
|
+
/**
|
|
1167
|
+
* Получить один экземпляр по slug
|
|
1168
|
+
*/
|
|
1169
|
+
getInstanceBySlug(entityDefinitionId: string, slug: string, params?: {
|
|
1170
|
+
relationsAsIds?: boolean;
|
|
1171
|
+
loadFiles?: boolean;
|
|
1154
1172
|
}): Promise<EntityInstanceWithFields>;
|
|
1155
1173
|
/**
|
|
1156
1174
|
* Получить список экземпляров
|
|
@@ -1108,6 +1108,11 @@ declare abstract class BasePublicAPIClient {
|
|
|
1108
1108
|
}>;
|
|
1109
1109
|
abstract getInstance(entityDefinitionId: string, id: string, params?: {
|
|
1110
1110
|
relationsAsIds?: boolean;
|
|
1111
|
+
loadFiles?: boolean;
|
|
1112
|
+
}): Promise<EntityInstanceWithFields>;
|
|
1113
|
+
abstract getInstanceBySlug(entityDefinitionId: string, slug: string, params?: {
|
|
1114
|
+
relationsAsIds?: boolean;
|
|
1115
|
+
loadFiles?: boolean;
|
|
1111
1116
|
}): Promise<EntityInstanceWithFields>;
|
|
1112
1117
|
abstract createInstance(entityDefinitionId: string, data: CreateInstanceData): Promise<EntityInstanceWithFields>;
|
|
1113
1118
|
abstract updateInstance(entityDefinitionId: string, id: string, data: UpdateInstanceData): Promise<EntityInstanceWithFields>;
|
|
@@ -1146,11 +1151,24 @@ declare class PublicAPIClient extends BasePublicAPIClient {
|
|
|
1146
1151
|
* Получить режим работы клиента (для отладки)
|
|
1147
1152
|
*/
|
|
1148
1153
|
getMode(): "server" | "client";
|
|
1154
|
+
/**
|
|
1155
|
+
* Загружает файлы для экземпляра и возвращает их как полные объекты EntityFile,
|
|
1156
|
+
* сгруппированные по именам полей
|
|
1157
|
+
*/
|
|
1158
|
+
private loadFilesForInstance;
|
|
1149
1159
|
/**
|
|
1150
1160
|
* Получить один экземпляр
|
|
1151
1161
|
*/
|
|
1152
1162
|
getInstance(entityDefinitionId: string, id: string, params?: {
|
|
1153
1163
|
relationsAsIds?: boolean;
|
|
1164
|
+
loadFiles?: boolean;
|
|
1165
|
+
}): Promise<EntityInstanceWithFields>;
|
|
1166
|
+
/**
|
|
1167
|
+
* Получить один экземпляр по slug
|
|
1168
|
+
*/
|
|
1169
|
+
getInstanceBySlug(entityDefinitionId: string, slug: string, params?: {
|
|
1170
|
+
relationsAsIds?: boolean;
|
|
1171
|
+
loadFiles?: boolean;
|
|
1154
1172
|
}): Promise<EntityInstanceWithFields>;
|
|
1155
1173
|
/**
|
|
1156
1174
|
* Получить список экземпляров
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FieldConfig, a as FieldValue, E as EntityDefinition, b as Field, c as EntityUIConfig, C as ColumnConfig, S as SDKOptions, P as PublicAPIClient } from './client-
|
|
2
|
-
export { y as ActionConfig, A as AuthResult, g as CreateInstanceData, D as DbType, l as DbTypeToTSType, m as EntityData, e as EntityDefinitionConfig, x as EntityFile, n as EntityInstance, q as EntityInstanceWithFields, p as EntityRelation, k as FieldOption, j as FieldType, r as FilterValue, z as FormPageConfig, G as GetInstancesOptions, I as InstanceData, L as ListPageConfig, M as MessagesConfig, h as PaginationResult, w as PartialInstanceData, B as PartialUIConfig, d as ProjectConfig, Q as QueryParams, R as RelationFilterInfo, f as RelationFilterMode, o as RelationType, s as RelationsData, i as SignUpData, U as UpdateInstanceData, v as getFieldValue, u as isEntityData, t as isFieldValue } from './client-
|
|
1
|
+
import { F as FieldConfig, a as FieldValue, E as EntityDefinition, b as Field, c as EntityUIConfig, C as ColumnConfig, S as SDKOptions, P as PublicAPIClient } from './client-D3jtlTId.mjs';
|
|
2
|
+
export { y as ActionConfig, A as AuthResult, g as CreateInstanceData, D as DbType, l as DbTypeToTSType, m as EntityData, e as EntityDefinitionConfig, x as EntityFile, n as EntityInstance, q as EntityInstanceWithFields, p as EntityRelation, k as FieldOption, j as FieldType, r as FilterValue, z as FormPageConfig, G as GetInstancesOptions, I as InstanceData, L as ListPageConfig, M as MessagesConfig, h as PaginationResult, w as PartialInstanceData, B as PartialUIConfig, d as ProjectConfig, Q as QueryParams, R as RelationFilterInfo, f as RelationFilterMode, o as RelationType, s as RelationsData, i as SignUpData, U as UpdateInstanceData, v as getFieldValue, u as isEntityData, t as isFieldValue } from './client-D3jtlTId.mjs';
|
|
3
3
|
import '@supabase/supabase-js';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FieldConfig, a as FieldValue, E as EntityDefinition, b as Field, c as EntityUIConfig, C as ColumnConfig, S as SDKOptions, P as PublicAPIClient } from './client-
|
|
2
|
-
export { y as ActionConfig, A as AuthResult, g as CreateInstanceData, D as DbType, l as DbTypeToTSType, m as EntityData, e as EntityDefinitionConfig, x as EntityFile, n as EntityInstance, q as EntityInstanceWithFields, p as EntityRelation, k as FieldOption, j as FieldType, r as FilterValue, z as FormPageConfig, G as GetInstancesOptions, I as InstanceData, L as ListPageConfig, M as MessagesConfig, h as PaginationResult, w as PartialInstanceData, B as PartialUIConfig, d as ProjectConfig, Q as QueryParams, R as RelationFilterInfo, f as RelationFilterMode, o as RelationType, s as RelationsData, i as SignUpData, U as UpdateInstanceData, v as getFieldValue, u as isEntityData, t as isFieldValue } from './client-
|
|
1
|
+
import { F as FieldConfig, a as FieldValue, E as EntityDefinition, b as Field, c as EntityUIConfig, C as ColumnConfig, S as SDKOptions, P as PublicAPIClient } from './client-D3jtlTId.js';
|
|
2
|
+
export { y as ActionConfig, A as AuthResult, g as CreateInstanceData, D as DbType, l as DbTypeToTSType, m as EntityData, e as EntityDefinitionConfig, x as EntityFile, n as EntityInstance, q as EntityInstanceWithFields, p as EntityRelation, k as FieldOption, j as FieldType, r as FilterValue, z as FormPageConfig, G as GetInstancesOptions, I as InstanceData, L as ListPageConfig, M as MessagesConfig, h as PaginationResult, w as PartialInstanceData, B as PartialUIConfig, d as ProjectConfig, Q as QueryParams, R as RelationFilterInfo, f as RelationFilterMode, o as RelationType, s as RelationsData, i as SignUpData, U as UpdateInstanceData, v as getFieldValue, u as isEntityData, t as isFieldValue } from './client-D3jtlTId.js';
|
|
3
3
|
import '@supabase/supabase-js';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/index.js
CHANGED
|
@@ -34,7 +34,8 @@ var __export = (target, all) => {
|
|
|
34
34
|
var slug_exports = {};
|
|
35
35
|
__export(slug_exports, {
|
|
36
36
|
generateSlug: () => generateSlug,
|
|
37
|
-
generateUniqueSlugForInstance: () => generateUniqueSlugForInstance
|
|
37
|
+
generateUniqueSlugForInstance: () => generateUniqueSlugForInstance,
|
|
38
|
+
validateSlug: () => validateSlug
|
|
38
39
|
});
|
|
39
40
|
function generateSlug(name) {
|
|
40
41
|
if (!name || typeof name !== "string") {
|
|
@@ -42,6 +43,16 @@ function generateSlug(name) {
|
|
|
42
43
|
}
|
|
43
44
|
return name.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").substring(0, 100);
|
|
44
45
|
}
|
|
46
|
+
function validateSlug(slug) {
|
|
47
|
+
if (!slug || typeof slug !== "string") {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
if (slug.length === 0 || slug.length > 100) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
const slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
54
|
+
return slugRegex.test(slug);
|
|
55
|
+
}
|
|
45
56
|
function generateRandomSuffix() {
|
|
46
57
|
return Math.random().toString(36).substring(2, 6);
|
|
47
58
|
}
|
|
@@ -754,8 +765,25 @@ function flattenInstance(instance, fields, relationsAsIds = false) {
|
|
|
754
765
|
}
|
|
755
766
|
return result;
|
|
756
767
|
}
|
|
768
|
+
function transformEntityFile(row) {
|
|
769
|
+
return {
|
|
770
|
+
id: row.id,
|
|
771
|
+
entityInstanceId: row.entity_instance_id,
|
|
772
|
+
fieldId: row.field_id,
|
|
773
|
+
fileUrl: row.file_url,
|
|
774
|
+
filePath: row.file_path,
|
|
775
|
+
fileName: row.file_name,
|
|
776
|
+
fileSize: row.file_size,
|
|
777
|
+
fileType: row.file_type,
|
|
778
|
+
storageBucket: row.storage_bucket,
|
|
779
|
+
uploadedBy: row.uploaded_by,
|
|
780
|
+
createdAt: row.created_at,
|
|
781
|
+
updatedAt: row.updated_at
|
|
782
|
+
};
|
|
783
|
+
}
|
|
757
784
|
|
|
758
785
|
// src/client.ts
|
|
786
|
+
init_slug();
|
|
759
787
|
var _PublicAPIClient = class _PublicAPIClient extends BasePublicAPIClient {
|
|
760
788
|
constructor(supabase, projectId, mode, options = {}) {
|
|
761
789
|
super(supabase, projectId, options);
|
|
@@ -785,6 +813,42 @@ var _PublicAPIClient = class _PublicAPIClient extends BasePublicAPIClient {
|
|
|
785
813
|
getMode() {
|
|
786
814
|
return this.mode;
|
|
787
815
|
}
|
|
816
|
+
/**
|
|
817
|
+
* Загружает файлы для экземпляра и возвращает их как полные объекты EntityFile,
|
|
818
|
+
* сгруппированные по именам полей
|
|
819
|
+
*/
|
|
820
|
+
async loadFilesForInstance(instanceId, fileFields) {
|
|
821
|
+
if (fileFields.length === 0) {
|
|
822
|
+
return /* @__PURE__ */ new Map();
|
|
823
|
+
}
|
|
824
|
+
const { data: allFiles, error: filesError } = await this.supabase.from("entity_file").select("*").eq("entity_instance_id", instanceId);
|
|
825
|
+
if (filesError) {
|
|
826
|
+
throw new SDKError(
|
|
827
|
+
"FILES_LOAD_ERROR",
|
|
828
|
+
`Failed to load files for instance ${instanceId}: ${filesError.message}`,
|
|
829
|
+
500,
|
|
830
|
+
filesError
|
|
831
|
+
);
|
|
832
|
+
}
|
|
833
|
+
if (!allFiles || allFiles.length === 0) {
|
|
834
|
+
return /* @__PURE__ */ new Map();
|
|
835
|
+
}
|
|
836
|
+
const filesMap = /* @__PURE__ */ new Map();
|
|
837
|
+
const fieldIdToName = new Map(
|
|
838
|
+
fileFields.map((f) => [f.id, f.name])
|
|
839
|
+
);
|
|
840
|
+
allFiles.forEach((fileRow) => {
|
|
841
|
+
if (!fileRow.field_id) return;
|
|
842
|
+
const fieldName = fieldIdToName.get(fileRow.field_id);
|
|
843
|
+
if (!fieldName) return;
|
|
844
|
+
const entityFile = transformEntityFile(fileRow);
|
|
845
|
+
if (!filesMap.has(fieldName)) {
|
|
846
|
+
filesMap.set(fieldName, []);
|
|
847
|
+
}
|
|
848
|
+
filesMap.get(fieldName).push(entityFile);
|
|
849
|
+
});
|
|
850
|
+
return filesMap;
|
|
851
|
+
}
|
|
788
852
|
/**
|
|
789
853
|
* Получить один экземпляр
|
|
790
854
|
*/
|
|
@@ -861,34 +925,127 @@ var _PublicAPIClient = class _PublicAPIClient extends BasePublicAPIClient {
|
|
|
861
925
|
}
|
|
862
926
|
}
|
|
863
927
|
}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
filesError
|
|
875
|
-
);
|
|
928
|
+
if ((params == null ? void 0 : params.loadFiles) === true) {
|
|
929
|
+
const fileFields = fields.filter(
|
|
930
|
+
(f) => f.type === "files" || f.type === "images"
|
|
931
|
+
);
|
|
932
|
+
if (fileFields.length > 0) {
|
|
933
|
+
const filesMap = await this.loadFilesForInstance(id, fileFields);
|
|
934
|
+
fileFields.forEach((field) => {
|
|
935
|
+
const files = filesMap.get(field.name) || [];
|
|
936
|
+
transformedInstance.data[field.name] = files;
|
|
937
|
+
});
|
|
876
938
|
}
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
939
|
+
}
|
|
940
|
+
const instanceWithRelations = __spreadProps(__spreadValues({}, transformedInstance), {
|
|
941
|
+
relations: Object.keys(relations).length > 0 ? relations : void 0
|
|
942
|
+
});
|
|
943
|
+
return flattenInstance(
|
|
944
|
+
instanceWithRelations,
|
|
945
|
+
fields.map((f) => ({ name: f.name, dbType: f.dbType })),
|
|
946
|
+
(_a = params == null ? void 0 : params.relationsAsIds) != null ? _a : false
|
|
947
|
+
);
|
|
948
|
+
} catch (error) {
|
|
949
|
+
if (error instanceof NotFoundError || error instanceof PermissionDeniedError || error instanceof SDKError) {
|
|
950
|
+
throw error;
|
|
951
|
+
}
|
|
952
|
+
handleSupabaseError(error);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Получить один экземпляр по slug
|
|
957
|
+
*/
|
|
958
|
+
async getInstanceBySlug(entityDefinitionId, slug, params) {
|
|
959
|
+
var _a;
|
|
960
|
+
try {
|
|
961
|
+
if (!validateSlug(slug)) {
|
|
962
|
+
throw new ValidationError(
|
|
963
|
+
"slug",
|
|
964
|
+
"Slug must contain only lowercase letters, numbers, and hyphens, and cannot start or end with a hyphen"
|
|
965
|
+
);
|
|
966
|
+
}
|
|
967
|
+
const fields = await this.getFields(entityDefinitionId);
|
|
968
|
+
const { data: instance, error: instanceError } = await this.supabase.from("entity_instance").select("*").eq("slug", slug).eq("entity_definition_id", entityDefinitionId).eq("project_id", this.projectId).single();
|
|
969
|
+
if (instanceError || !instance) {
|
|
970
|
+
handleInstanceError(
|
|
971
|
+
instanceError || new Error("Instance not found"),
|
|
972
|
+
slug
|
|
973
|
+
);
|
|
974
|
+
}
|
|
975
|
+
const transformedInstance = transformEntityInstance(instance);
|
|
976
|
+
if (transformedInstance.entityDefinitionId !== entityDefinitionId) {
|
|
977
|
+
throw new NotFoundError("Entity instance", slug);
|
|
978
|
+
}
|
|
979
|
+
const relationFields = fields.filter(
|
|
980
|
+
(f) => f.dbType === "manyToMany" || f.dbType === "manyToOne" || f.dbType === "oneToMany" || f.dbType === "oneToOne"
|
|
981
|
+
);
|
|
982
|
+
const relations = {};
|
|
983
|
+
if (relationFields.length > 0) {
|
|
984
|
+
const relationFieldIds = relationFields.map((f) => f.id).filter((id) => Boolean(id));
|
|
985
|
+
if (relationFieldIds.length > 0) {
|
|
986
|
+
const { data: allRelations, error: relationsError } = await this.supabase.from("entity_relation").select("target_instance_id, relation_field_id").eq("source_instance_id", transformedInstance.id).in("relation_field_id", relationFieldIds);
|
|
987
|
+
if (relationsError) {
|
|
988
|
+
throw new SDKError(
|
|
989
|
+
"RELATIONS_LOAD_ERROR",
|
|
990
|
+
`Failed to load relations for instance with slug ${slug}: ${relationsError.message}`,
|
|
991
|
+
500,
|
|
992
|
+
relationsError
|
|
993
|
+
);
|
|
994
|
+
}
|
|
995
|
+
if (allRelations && allRelations.length > 0) {
|
|
996
|
+
const targetInstanceIds = [
|
|
997
|
+
...new Set(allRelations.map((r) => r.target_instance_id))
|
|
998
|
+
];
|
|
999
|
+
const { data: relatedInstances, error: instancesError } = await this.supabase.from("entity_instance").select("*").in("id", targetInstanceIds);
|
|
1000
|
+
if (instancesError) {
|
|
1001
|
+
throw new SDKError(
|
|
1002
|
+
"RELATED_INSTANCES_LOAD_ERROR",
|
|
1003
|
+
`Failed to load related instances for instance with slug ${slug}: ${instancesError.message}`,
|
|
1004
|
+
500,
|
|
1005
|
+
instancesError
|
|
1006
|
+
);
|
|
1007
|
+
}
|
|
1008
|
+
if (relatedInstances) {
|
|
1009
|
+
const relatedInstancesMap = new Map(
|
|
1010
|
+
relatedInstances.map((inst) => [
|
|
1011
|
+
inst.id,
|
|
1012
|
+
transformEntityInstance(inst)
|
|
1013
|
+
])
|
|
1014
|
+
);
|
|
1015
|
+
for (const relation of allRelations) {
|
|
1016
|
+
const relationField = relationFields.find(
|
|
1017
|
+
(f) => f.id === relation.relation_field_id
|
|
1018
|
+
);
|
|
1019
|
+
if (relationField) {
|
|
1020
|
+
const relatedInstance = relatedInstancesMap.get(
|
|
1021
|
+
relation.target_instance_id
|
|
1022
|
+
);
|
|
1023
|
+
if (relatedInstance) {
|
|
1024
|
+
if (!relations[relationField.name]) {
|
|
1025
|
+
relations[relationField.name] = [];
|
|
1026
|
+
}
|
|
1027
|
+
relations[relationField.name].push(
|
|
1028
|
+
relatedInstance
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
883
1032
|
}
|
|
884
|
-
filesByFieldId.get(file.field_id).push(file.id);
|
|
885
1033
|
}
|
|
886
|
-
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
if ((params == null ? void 0 : params.loadFiles) === true) {
|
|
1038
|
+
const fileFields = fields.filter(
|
|
1039
|
+
(f) => f.type === "files" || f.type === "images"
|
|
1040
|
+
);
|
|
1041
|
+
if (fileFields.length > 0) {
|
|
1042
|
+
const filesMap = await this.loadFilesForInstance(
|
|
1043
|
+
transformedInstance.id,
|
|
1044
|
+
fileFields
|
|
1045
|
+
);
|
|
887
1046
|
fileFields.forEach((field) => {
|
|
888
|
-
const
|
|
889
|
-
|
|
890
|
-
transformedInstance.data[field.name] = fileIds;
|
|
891
|
-
}
|
|
1047
|
+
const files = filesMap.get(field.name) || [];
|
|
1048
|
+
transformedInstance.data[field.name] = files;
|
|
892
1049
|
});
|
|
893
1050
|
}
|
|
894
1051
|
}
|
|
@@ -901,7 +1058,7 @@ var _PublicAPIClient = class _PublicAPIClient extends BasePublicAPIClient {
|
|
|
901
1058
|
(_a = params == null ? void 0 : params.relationsAsIds) != null ? _a : false
|
|
902
1059
|
);
|
|
903
1060
|
} catch (error) {
|
|
904
|
-
if (error instanceof NotFoundError || error instanceof PermissionDeniedError || error instanceof SDKError) {
|
|
1061
|
+
if (error instanceof NotFoundError || error instanceof PermissionDeniedError || error instanceof ValidationError || error instanceof SDKError) {
|
|
905
1062
|
throw error;
|
|
906
1063
|
}
|
|
907
1064
|
handleSupabaseError(error);
|