@pod-os/core 0.21.1-rc.762dee0.0 → 0.21.1-rc.b558373.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/dist/index.js CHANGED
@@ -3721,22 +3721,26 @@ var FileFetcher = class {
3721
3721
  });
3722
3722
  }
3723
3723
  createNewFile(container2, name9) {
3724
- const encodedName = encodeURIComponent(name9);
3724
+ const isFile = name9 instanceof File;
3725
+ const fileName = isFile ? name9.name : name9;
3726
+ const encodedName = encodeURIComponent(fileName);
3725
3727
  const url7 = container2.uri + encodedName;
3726
- const contentTypeHeader = index_lite_default.getType(encodedName) ?? "text/turtle";
3728
+ const contentTypeHeader = isFile ? name9.type : index_lite_default.getType(encodedName) ?? "text/turtle";
3729
+ const body = isFile ? name9 : void 0;
3727
3730
  return ResultAsync.fromPromise(
3728
3731
  this.session.authenticatedFetch(url7, {
3729
3732
  method: "PUT",
3730
3733
  headers: {
3731
3734
  "Content-Type": contentTypeHeader,
3732
3735
  "If-None-Match": "*"
3733
- }
3736
+ },
3737
+ body
3734
3738
  }),
3735
3739
  (e) => networkProblem("The file could not be created", e)
3736
3740
  ).andThen(
3737
3741
  (response6) => response6.ok ? ok({
3738
3742
  url: url7,
3739
- name: name9,
3743
+ name: fileName,
3740
3744
  contentType: contentTypeHeader
3741
3745
  }) : err(httpProblem("The file could not be created", response6))
3742
3746
  );
@@ -3994,6 +3998,89 @@ var Thing = class {
3994
3998
  assume(SpecificThing) {
3995
3999
  return new SpecificThing(this.uri, this.store, this.editable);
3996
4000
  }
4001
+ /**
4002
+ * Returns the container that contains this thing's document
4003
+ * The container URI is derived from the thing's URI.
4004
+ */
4005
+ container() {
4006
+ const doc = namedNode(this.uri).doc();
4007
+ const baseUri = doc.value.endsWith("/") ? doc.value.slice(0, -1) : doc.value;
4008
+ const uri6 = new URL(".", baseUri).toString();
4009
+ return { uri: uri6 };
4010
+ }
4011
+ };
4012
+
4013
+ // src/ldp-container/LdpContainer.ts
4014
+ var LdpContainer = class extends Thing {
4015
+ constructor(uri6, store, editable = false) {
4016
+ super(uri6, store, editable);
4017
+ this.uri = uri6;
4018
+ this.store = store;
4019
+ this.editable = editable;
4020
+ }
4021
+ contains() {
4022
+ const contains3 = this.store.statementsMatching(
4023
+ namedNode(this.uri),
4024
+ namedNode("http://www.w3.org/ns/ldp#contains"),
4025
+ null,
4026
+ namedNode(this.uri)
4027
+ );
4028
+ return contains3.map((content5) => ({
4029
+ uri: content5.object.value,
4030
+ name: labelFromUri(content5.object.value)
4031
+ }));
4032
+ }
4033
+ };
4034
+
4035
+ // src/picture/createPictureLinkOperation.ts
4036
+ var SCHEMA_IMAGE = "http://schema.org/image";
4037
+ function createPictureLinkOperation(thing, file2) {
4038
+ return {
4039
+ deletions: [],
4040
+ filesToCreate: [],
4041
+ insertions: [
4042
+ st(
4043
+ namedNode(thing.uri),
4044
+ namedNode(SCHEMA_IMAGE),
4045
+ namedNode(file2.url),
4046
+ namedNode(thing.uri).doc()
4047
+ )
4048
+ ]
4049
+ };
4050
+ }
4051
+
4052
+ // src/picture/PictureGateway.ts
4053
+ var PictureGateway = class {
4054
+ constructor(store, fileFetcher) {
4055
+ this.store = store;
4056
+ this.fileFetcher = fileFetcher;
4057
+ }
4058
+ /**
4059
+ * Uploads a picture file and associates it with a thing.
4060
+ * The container is automatically derived from the thing's URI.
4061
+ * Uses schema:image as the predicate.
4062
+ *
4063
+ * @param thing - The thing to add the picture to
4064
+ * @param pictureFile - The picture file to upload
4065
+ * @returns Result with the uploaded picture metadata (url, name, contentType) or error
4066
+ */
4067
+ uploadAndAddPicture(thing, pictureFile) {
4068
+ const container2 = this.getContainerFromThing(thing);
4069
+ return this.fileFetcher.createNewFile(container2, pictureFile).andThen((file2) => this.linkPictureToThing(thing, file2));
4070
+ }
4071
+ linkPictureToThing(thing, file2) {
4072
+ const operation3 = createPictureLinkOperation(thing, file2);
4073
+ return ResultAsync.fromPromise(
4074
+ this.store.executeUpdate(operation3).then(() => file2),
4075
+ () => ({
4076
+ type: "network",
4077
+ title: "Failed to link picture to thing"
4078
+ })
4079
+ );
4080
+ }
4081
+ getContainerFromThing(thing) {
4082
+ return this.store.get(thing.container().uri).assume(LdpContainer);
4083
+ }
3997
4084
  };
3998
4085
 
3999
4086
  // src/profile/WebIdProfile.ts
@@ -4041,7 +4128,7 @@ var WebIdProfile = class extends Thing {
4041
4128
  };
4042
4129
 
4043
4130
  // src/search/SearchIndex.ts
4044
- var import_lunr = __toESM(require_lunr());
4131
+ var import_lunr = __toESM(require_lunr(), 1);
4045
4132
  var SearchIndex = class {
4046
4133
  constructor(labelIndexes) {
4047
4134
  this.labelIndexes = labelIndexes;
@@ -4339,6 +4426,12 @@ var Store = class {
4339
4426
  isOnline: onlineStatus.isOnline
4340
4427
  });
4341
4428
  this.updater = new UpdateManager(this.internalStore);
4429
+ this.additions$ = new Subject();
4430
+ this.removals$ = new Subject();
4431
+ this.internalStore.addDataCallback((quad) => this.additions$.next(quad));
4432
+ this.internalStore.addDataRemovalCallback(
4433
+ (quad) => this.removals$.next(quad)
4434
+ );
4342
4435
  }
4343
4436
  /**
4344
4437
  * Fetch data for the given URI to the internalStore
@@ -25739,7 +25832,7 @@ function listKnownTerms() {
25739
25832
  }
25740
25833
 
25741
25834
  // src/uri/UriService.ts
25742
- var import_slugify = __toESM(require_slugify());
25835
+ var import_slugify = __toESM(require_slugify(), 1);
25743
25836
  var UriService = class {
25744
25837
  // We expect to use the store for calculating the uris for things
25745
25838
  // e.g. looking up locations in type index
@@ -25782,28 +25875,6 @@ var AnonymousSession = class {
25782
25875
  }
25783
25876
  };
25784
25877
 
25785
- // src/ldp-container/LdpContainer.ts
25786
- var LdpContainer = class extends Thing {
25787
- constructor(uri6, store, editable = false) {
25788
- super(uri6, store, editable);
25789
- this.uri = uri6;
25790
- this.store = store;
25791
- this.editable = editable;
25792
- }
25793
- contains() {
25794
- const contains3 = this.store.statementsMatching(
25795
- namedNode(this.uri),
25796
- namedNode("http://www.w3.org/ns/ldp#contains"),
25797
- null,
25798
- namedNode(this.uri)
25799
- );
25800
- return contains3.map((content5) => ({
25801
- uri: content5.object.value,
25802
- name: labelFromUri(content5.object.value)
25803
- }));
25804
- }
25805
- };
25806
-
25807
25878
  // src/index.ts
25808
25879
  var PodOS = class {
25809
25880
  constructor({
@@ -25821,9 +25892,10 @@ var PodOS = class {
25821
25892
  internalStore
25822
25893
  );
25823
25894
  this.searchGateway = new SearchGateway(this.store);
25895
+ this.fileFetcher = new FileFetcher(this.session);
25896
+ this.pictureGateway = new PictureGateway(this.store, this.fileFetcher);
25824
25897
  this.flagAuthorizationMetaDataOnSessionChange();
25825
25898
  this.uriService = new UriService(this.store);
25826
- this.fileFetcher = new FileFetcher(this.session);
25827
25899
  }
25828
25900
  /*
25829
25901
  Flagging authorization metadata is necessary every time the user
@@ -25925,6 +25997,17 @@ var PodOS = class {
25925
25997
  async createDefaultLabelIndex(profile2) {
25926
25998
  return await this.searchGateway.createDefaultLabelIndex(profile2);
25927
25999
  }
26000
+ /**
26001
+ * Uploads a picture file and associates it with a thing.
26002
+ * The container is automatically derived from the thing's URI.
26003
+ *
26004
+ * @param thing - The thing to add the picture to
26005
+ * @param pictureFile - The picture file to upload
26006
+ * @returns Result with the picture URL or error
26007
+ */
26008
+ uploadAndAddPicture(thing, pictureFile) {
26009
+ return this.pictureGateway.uploadAndAddPicture(thing, pictureFile);
26010
+ }
25928
26011
  };
25929
26012
  export {
25930
26013
  AnonymousSession,
@@ -25937,6 +26020,7 @@ export {
25937
26020
  LdpContainer,
25938
26021
  NoOfflineCache,
25939
26022
  OfflineCapableFetcher,
26023
+ PictureGateway,
25940
26024
  PodOS,
25941
26025
  RdfDocument,
25942
26026
  SearchGateway,
@@ -25945,6 +26029,7 @@ export {
25945
26029
  Thing,
25946
26030
  UriService,
25947
26031
  WebIdProfile,
26032
+ createPictureLinkOperation,
25948
26033
  httpProblem,
25949
26034
  labelFromUri,
25950
26035
  listKnownTerms,
package/lib/index.js CHANGED
@@ -34751,6 +34751,7 @@ _:patch
34751
34751
  LdpContainer: () => LdpContainer,
34752
34752
  NoOfflineCache: () => NoOfflineCache,
34753
34753
  OfflineCapableFetcher: () => OfflineCapableFetcher,
34754
+ PictureGateway: () => PictureGateway,
34754
34755
  PodOS: () => PodOS,
34755
34756
  RdfDocument: () => RdfDocument,
34756
34757
  SearchGateway: () => SearchGateway,
@@ -34759,6 +34760,7 @@ _:patch
34759
34760
  Thing: () => Thing,
34760
34761
  UriService: () => UriService,
34761
34762
  WebIdProfile: () => WebIdProfile,
34763
+ createPictureLinkOperation: () => createPictureLinkOperation,
34762
34764
  httpProblem: () => httpProblem,
34763
34765
  labelFromUri: () => labelFromUri,
34764
34766
  listKnownTerms: () => listKnownTerms,
@@ -36685,22 +36687,26 @@ _:patch
36685
36687
  });
36686
36688
  }
36687
36689
  createNewFile(container2, name9) {
36688
- const encodedName = encodeURIComponent(name9);
36690
+ const isFile = name9 instanceof File;
36691
+ const fileName = isFile ? name9.name : name9;
36692
+ const encodedName = encodeURIComponent(fileName);
36689
36693
  const url7 = container2.uri + encodedName;
36690
- const contentTypeHeader = index_lite_default.getType(encodedName) ?? "text/turtle";
36694
+ const contentTypeHeader = isFile ? name9.type : index_lite_default.getType(encodedName) ?? "text/turtle";
36695
+ const body = isFile ? name9 : void 0;
36691
36696
  return ResultAsync.fromPromise(
36692
36697
  this.session.authenticatedFetch(url7, {
36693
36698
  method: "PUT",
36694
36699
  headers: {
36695
36700
  "Content-Type": contentTypeHeader,
36696
36701
  "If-None-Match": "*"
36697
- }
36702
+ },
36703
+ body
36698
36704
  }),
36699
36705
  (e) => networkProblem("The file could not be created", e)
36700
36706
  ).andThen(
36701
36707
  (response6) => response6.ok ? ok({
36702
36708
  url: url7,
36703
- name: name9,
36709
+ name: fileName,
36704
36710
  contentType: contentTypeHeader
36705
36711
  }) : err(httpProblem("The file could not be created", response6))
36706
36712
  );
@@ -36728,7 +36734,7 @@ _:patch
36728
36734
  return store.loadModule(module3);
36729
36735
  }
36730
36736
 
36731
- // src/profile/WebIdProfile.ts
36737
+ // src/ldp-container/LdpContainer.ts
36732
36738
  init_esm();
36733
36739
 
36734
36740
  // src/thing/Thing.ts
@@ -36965,9 +36971,94 @@ _:patch
36965
36971
  assume(SpecificThing) {
36966
36972
  return new SpecificThing(this.uri, this.store, this.editable);
36967
36973
  }
36974
+ /**
36975
+ * Returns the container that contains this thing's document
36976
+ * The container URI is derived from the thing's URI.
36977
+ */
36978
+ container() {
36979
+ const doc = namedNode(this.uri).doc();
36980
+ const baseUri = doc.value.endsWith("/") ? doc.value.slice(0, -1) : doc.value;
36981
+ const uri6 = new URL(".", baseUri).toString();
36982
+ return { uri: uri6 };
36983
+ }
36984
+ };
36985
+
36986
+ // src/ldp-container/LdpContainer.ts
36987
+ var LdpContainer = class extends Thing {
36988
+ constructor(uri6, store, editable = false) {
36989
+ super(uri6, store, editable);
36990
+ this.uri = uri6;
36991
+ this.store = store;
36992
+ this.editable = editable;
36993
+ }
36994
+ contains() {
36995
+ const contains3 = this.store.statementsMatching(
36996
+ namedNode(this.uri),
36997
+ namedNode("http://www.w3.org/ns/ldp#contains"),
36998
+ null,
36999
+ namedNode(this.uri)
37000
+ );
37001
+ return contains3.map((content5) => ({
37002
+ uri: content5.object.value,
37003
+ name: labelFromUri(content5.object.value)
37004
+ }));
37005
+ }
37006
+ };
37007
+
37008
+ // src/picture/createPictureLinkOperation.ts
37009
+ init_esm();
37010
+ var SCHEMA_IMAGE = "http://schema.org/image";
37011
+ function createPictureLinkOperation(thing, file2) {
37012
+ return {
37013
+ deletions: [],
37014
+ filesToCreate: [],
37015
+ insertions: [
37016
+ st(
37017
+ namedNode(thing.uri),
37018
+ namedNode(SCHEMA_IMAGE),
37019
+ namedNode(file2.url),
37020
+ namedNode(thing.uri).doc()
37021
+ )
37022
+ ]
37023
+ };
37024
+ }
37025
+
37026
+ // src/picture/PictureGateway.ts
37027
+ var PictureGateway = class {
37028
+ constructor(store, fileFetcher) {
37029
+ this.store = store;
37030
+ this.fileFetcher = fileFetcher;
37031
+ }
37032
+ /**
37033
+ * Uploads a picture file and associates it with a thing.
37034
+ * The container is automatically derived from the thing's URI.
37035
+ * Uses schema:image as the predicate.
37036
+ *
37037
+ * @param thing - The thing to add the picture to
37038
+ * @param pictureFile - The picture file to upload
37039
+ * @returns Result with the uploaded picture metadata (url, name, contentType) or error
37040
+ */
37041
+ uploadAndAddPicture(thing, pictureFile) {
37042
+ const container2 = this.getContainerFromThing(thing);
37043
+ return this.fileFetcher.createNewFile(container2, pictureFile).andThen((file2) => this.linkPictureToThing(thing, file2));
37044
+ }
37045
+ linkPictureToThing(thing, file2) {
37046
+ const operation3 = createPictureLinkOperation(thing, file2);
37047
+ return ResultAsync.fromPromise(
37048
+ this.store.executeUpdate(operation3).then(() => file2),
37049
+ () => ({
37050
+ type: "network",
37051
+ title: "Failed to link picture to thing"
37052
+ })
37053
+ );
37054
+ }
37055
+ getContainerFromThing(thing) {
37056
+ return this.store.get(thing.container().uri).assume(LdpContainer);
37057
+ }
36968
37058
  };
36969
37059
 
36970
37060
  // src/profile/WebIdProfile.ts
37061
+ init_esm();
36971
37062
  var WebIdProfile = class extends Thing {
36972
37063
  constructor(webId, store, editable = false) {
36973
37064
  super(webId, store, editable);
@@ -37012,7 +37103,7 @@ _:patch
37012
37103
  };
37013
37104
 
37014
37105
  // src/search/SearchIndex.ts
37015
- var import_lunr = __toESM(require_lunr());
37106
+ var import_lunr = __toESM(require_lunr(), 1);
37016
37107
  var SearchIndex = class {
37017
37108
  constructor(labelIndexes) {
37018
37109
  this.labelIndexes = labelIndexes;
@@ -37324,6 +37415,12 @@ _:patch
37324
37415
  isOnline: onlineStatus.isOnline
37325
37416
  });
37326
37417
  this.updater = new UpdateManager(this.internalStore);
37418
+ this.additions$ = new Subject();
37419
+ this.removals$ = new Subject();
37420
+ this.internalStore.addDataCallback((quad3) => this.additions$.next(quad3));
37421
+ this.internalStore.addDataRemovalCallback(
37422
+ (quad3) => this.removals$.next(quad3)
37423
+ );
37327
37424
  }
37328
37425
  /**
37329
37426
  * Fetch data for the given URI to the internalStore
@@ -58724,7 +58821,7 @@ _:patch
58724
58821
  }
58725
58822
 
58726
58823
  // src/uri/UriService.ts
58727
- var import_slugify = __toESM(require_slugify());
58824
+ var import_slugify = __toESM(require_slugify(), 1);
58728
58825
  var UriService = class {
58729
58826
  // We expect to use the store for calculating the uris for things
58730
58827
  // e.g. looking up locations in type index
@@ -58767,29 +58864,6 @@ _:patch
58767
58864
  }
58768
58865
  };
58769
58866
 
58770
- // src/ldp-container/LdpContainer.ts
58771
- init_esm();
58772
- var LdpContainer = class extends Thing {
58773
- constructor(uri6, store, editable = false) {
58774
- super(uri6, store, editable);
58775
- this.uri = uri6;
58776
- this.store = store;
58777
- this.editable = editable;
58778
- }
58779
- contains() {
58780
- const contains3 = this.store.statementsMatching(
58781
- namedNode(this.uri),
58782
- namedNode("http://www.w3.org/ns/ldp#contains"),
58783
- null,
58784
- namedNode(this.uri)
58785
- );
58786
- return contains3.map((content5) => ({
58787
- uri: content5.object.value,
58788
- name: labelFromUri(content5.object.value)
58789
- }));
58790
- }
58791
- };
58792
-
58793
58867
  // src/index.ts
58794
58868
  var PodOS = class {
58795
58869
  constructor({
@@ -58807,9 +58881,10 @@ _:patch
58807
58881
  internalStore
58808
58882
  );
58809
58883
  this.searchGateway = new SearchGateway(this.store);
58884
+ this.fileFetcher = new FileFetcher(this.session);
58885
+ this.pictureGateway = new PictureGateway(this.store, this.fileFetcher);
58810
58886
  this.flagAuthorizationMetaDataOnSessionChange();
58811
58887
  this.uriService = new UriService(this.store);
58812
- this.fileFetcher = new FileFetcher(this.session);
58813
58888
  }
58814
58889
  /*
58815
58890
  Flagging authorization metadata is necessary every time the user
@@ -58911,6 +58986,17 @@ _:patch
58911
58986
  async createDefaultLabelIndex(profile2) {
58912
58987
  return await this.searchGateway.createDefaultLabelIndex(profile2);
58913
58988
  }
58989
+ /**
58990
+ * Uploads a picture file and associates it with a thing.
58991
+ * The container is automatically derived from the thing's URI.
58992
+ *
58993
+ * @param thing - The thing to add the picture to
58994
+ * @param pictureFile - The picture file to upload
58995
+ * @returns Result with the picture URL or error
58996
+ */
58997
+ uploadAndAddPicture(thing, pictureFile) {
58998
+ return this.pictureGateway.uploadAndAddPicture(thing, pictureFile);
58999
+ }
58914
59000
  };
58915
59001
  return __toCommonJS(index_exports);
58916
59002
  })();
package/package.json CHANGED
@@ -1,13 +1,25 @@
1
1
  {
2
2
  "name": "@pod-os/core",
3
- "version": "0.21.1-rc.762dee0.0",
3
+ "description": "Core module of PodOS",
4
+ "version": "0.21.1-rc.b558373.0",
5
+ "type": "module",
4
6
  "main": "./dist/index.js",
5
7
  "types": "./types/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./types/index.d.ts",
12
+ "require": "./lib/index.js"
13
+ }
14
+ },
6
15
  "files": [
7
16
  "lib/",
8
17
  "dist/",
9
18
  "types/"
10
19
  ],
20
+ "engines": {
21
+ "node": ">=18.0.0"
22
+ },
11
23
  "scripts": {
12
24
  "test": "jest",
13
25
  "test:watch": "jest --watch",
@@ -60,9 +72,6 @@
60
72
  "slugify": "^1.6.6",
61
73
  "url": "^0.11.4"
62
74
  },
63
- "directories": {
64
- "lib": "lib"
65
- },
66
75
  "repository": {
67
76
  "type": "git",
68
77
  "url": "git+https://github.com/pod-os/pod-os.git"
@@ -70,6 +79,5 @@
70
79
  "bugs": {
71
80
  "url": "https://github.com/pod-os/pod-os/issues"
72
81
  },
73
- "homepage": "https://github.com/pod-os/pod-os#readme",
74
- "description": ""
82
+ "homepage": "https://github.com/pod-os/pod-os#readme"
75
83
  }
package/types/Store.d.ts CHANGED
@@ -3,14 +3,18 @@ import { PodOsSession } from "./authentication";
3
3
  import { Thing } from "./thing";
4
4
  import { ModuleConfig, UpdateOperation } from "@solid-data-modules/rdflib-utils";
5
5
  import { OfflineCache, OnlineStatus } from "./offline-cache";
6
+ import { Subject } from "rxjs";
7
+ import { Quad } from "rdflib/lib/tf-types";
6
8
  /**
7
- * The internalStore contains all data that is known locally.
9
+ * The Store contains all data that is known locally.
8
10
  * It can be used to fetch additional data from the web and also update data and sync it back to editable resources.
9
11
  */
10
12
  export declare class Store {
11
13
  private readonly internalStore;
12
14
  private readonly fetcher;
13
15
  private readonly updater;
16
+ additions$: Subject<Quad>;
17
+ removals$: Subject<Quad>;
14
18
  constructor(session: PodOsSession, offlineCache?: OfflineCache, onlineStatus?: OnlineStatus, internalStore?: IndexedFormula);
15
19
  /**
16
20
  * Fetch data for the given URI to the internalStore
@@ -19,14 +19,14 @@ export declare class FileFetcher {
19
19
  * @returns {Promise<Response>} The HTTP response
20
20
  */
21
21
  putFile(file: SolidFile, newContent: string): Promise<Response>;
22
- createNewFile(container: LdpContainer, name: string): ResultAsync<NewFile, NotCreated>;
22
+ createNewFile(container: LdpContainer, name: string | File): ResultAsync<NewFile, NotCreated>;
23
23
  createNewFolder(container: LdpContainer, name: string): ResultAsync<NewFolder, NotCreated>;
24
24
  }
25
- interface NewFolder {
25
+ export interface NewFolder {
26
26
  url: string;
27
27
  name: string;
28
28
  }
29
- interface NewFile {
29
+ export interface NewFile {
30
30
  url: string;
31
31
  name: string;
32
32
  contentType: string;
package/types/index.d.ts CHANGED
@@ -11,11 +11,14 @@ import { Thing } from "./thing";
11
11
  import { UriService } from "./uri/UriService";
12
12
  import { OfflineCache, OnlineStatus } from "./offline-cache";
13
13
  import { IndexedFormula } from "rdflib";
14
+ import { ResultAsync } from "neverthrow";
15
+ import { HttpProblem, NetworkProblem } from "./problems";
14
16
  export * from "./authentication";
15
17
  export * from "./files";
16
18
  export * from "./thing";
17
19
  export * from "./rdf-document";
18
20
  export * from "./ldp-container";
21
+ export * from "./picture";
19
22
  export * from "./profile";
20
23
  export * from "./search";
21
24
  export * from "./offline-cache";
@@ -35,6 +38,7 @@ export declare class PodOS {
35
38
  readonly uriService: UriService;
36
39
  private readonly fileFetcher;
37
40
  private readonly searchGateway;
41
+ private readonly pictureGateway;
38
42
  private readonly offlineCache;
39
43
  constructor({ session, offlineCache, onlineStatus, internalStore, }?: PodOsConfiguration);
40
44
  private flagAuthorizationMetaDataOnSessionChange;
@@ -85,4 +89,15 @@ export declare class PodOS {
85
89
  * @returns the newly created label index
86
90
  */
87
91
  createDefaultLabelIndex(profile: WebIdProfile): Promise<LabelIndex>;
92
+ /**
93
+ * Uploads a picture file and associates it with a thing.
94
+ * The container is automatically derived from the thing's URI.
95
+ *
96
+ * @param thing - The thing to add the picture to
97
+ * @param pictureFile - The picture file to upload
98
+ * @returns Result with the picture URL or error
99
+ */
100
+ uploadAndAddPicture(thing: Thing, pictureFile: File): ResultAsync<{
101
+ url: string;
102
+ }, HttpProblem | NetworkProblem>;
88
103
  }
@@ -0,0 +1,24 @@
1
+ import { ResultAsync } from "neverthrow";
2
+ import { Thing } from "../thing";
3
+ import { Store } from "../Store";
4
+ import { FileFetcher, NewFile } from "../files";
5
+ import { HttpProblem, NetworkProblem } from "../problems";
6
+ export declare class PictureGateway {
7
+ private readonly store;
8
+ private readonly fileFetcher;
9
+ constructor(store: Store, fileFetcher: FileFetcher);
10
+ /**
11
+ * Uploads a picture file and associates it with a thing.
12
+ * The container is automatically derived from the thing's URI.
13
+ * Uses schema:image as the predicate.
14
+ *
15
+ * @param thing - The thing to add the picture to
16
+ * @param pictureFile - The picture file to upload
17
+ * @returns Result with the uploaded picture metadata (url, name, contentType) or error
18
+ */
19
+ uploadAndAddPicture(thing: Thing, pictureFile: File): ResultAsync<UploadedPicture, HttpProblem | NetworkProblem>;
20
+ private linkPictureToThing;
21
+ private getContainerFromThing;
22
+ }
23
+ type UploadedPicture = NewFile;
24
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ import { UpdateOperation } from "@solid-data-modules/rdflib-utils";
2
+ import { Thing } from "../thing";
3
+ import { NewFile } from "../files";
4
+ /**
5
+ * Creates an update operation to link a picture file to a thing.
6
+ * Uses schema:image as the predicate to establish the relationship.
7
+ *
8
+ * @param thing - The thing to link the picture to
9
+ * @param file - The uploaded picture file metadata
10
+ * @returns UpdateOperation that adds the picture link to the thing's document
11
+ */
12
+ export declare function createPictureLinkOperation(thing: Thing, file: NewFile): UpdateOperation;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from "./PictureGateway";
2
+ export * from "./createPictureLinkOperation";
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -75,4 +75,11 @@ export declare class Thing {
75
75
  * @param SpecificThing - a subclass of Thing to assume
76
76
  */
77
77
  assume<T>(SpecificThing: new (uri: string, store: IndexedFormula, editable: boolean) => T): T;
78
+ /**
79
+ * Returns the container that contains this thing's document
80
+ * The container URI is derived from the thing's URI.
81
+ */
82
+ container(): {
83
+ uri: string;
84
+ };
78
85
  }