@exulu/backend 1.69.2 → 1.70.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.
@@ -892,6 +892,11 @@ function subtractDuration(date, duration) {
892
892
  }
893
893
  return new Date(date.getTime() - durationToDays(duration) * DAY_MS);
894
894
  }
895
+ function subtractOneCalendarMonth(date) {
896
+ const result = new Date(date);
897
+ result.setUTCMonth(result.getUTCMonth() - 1);
898
+ return result;
899
+ }
895
900
  function windowStartYmd(reset_at, duration) {
896
901
  const now = Date.now();
897
902
  const reset = reset_at ? new Date(reset_at) : null;
@@ -899,7 +904,7 @@ function windowStartYmd(reset_at, duration) {
899
904
  const trailingStart = subtractDuration(new Date(now), duration);
900
905
  if (resetMs !== null) {
901
906
  if (resetMs > now) {
902
- const periodStart = subtractDuration(reset, duration);
907
+ const periodStart = reset.getUTCDate() === 1 ? subtractOneCalendarMonth(reset) : subtractDuration(reset, duration);
903
908
  return ymd(periodStart > trailingStart ? periodStart : trailingStart);
904
909
  } else {
905
910
  return ymd(reset > trailingStart ? reset : trailingStart);
@@ -1630,7 +1635,7 @@ var ExuluTool = class _ExuluTool {
1630
1635
  });
1631
1636
  providerapikey = resolved.apiKey;
1632
1637
  }
1633
- const { convertExuluToolsToAiSdkTools: convertExuluToolsToAiSdkTools2 } = await import("./convert-exulu-tools-to-ai-sdk-tools-MXLGIOCT.js");
1638
+ const { convertExuluToolsToAiSdkTools: convertExuluToolsToAiSdkTools2 } = await import("./convert-exulu-tools-to-ai-sdk-tools-GQ3UIYP7.js");
1634
1639
  const tools = await convertExuluToolsToAiSdkTools2(
1635
1640
  [this],
1636
1641
  [],
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  convertExuluToolsToAiSdkTools
3
- } from "./chunk-PJSDLFXL.js";
3
+ } from "./chunk-WCP3WZM3.js";
4
4
  export {
5
5
  convertExuluToolsToAiSdkTools
6
6
  };
package/dist/index.cjs CHANGED
@@ -2758,6 +2758,11 @@ function subtractDuration(date, duration) {
2758
2758
  }
2759
2759
  return new Date(date.getTime() - durationToDays(duration) * DAY_MS);
2760
2760
  }
2761
+ function subtractOneCalendarMonth(date) {
2762
+ const result = new Date(date);
2763
+ result.setUTCMonth(result.getUTCMonth() - 1);
2764
+ return result;
2765
+ }
2761
2766
  function windowStartYmd(reset_at, duration) {
2762
2767
  const now = Date.now();
2763
2768
  const reset = reset_at ? new Date(reset_at) : null;
@@ -2765,7 +2770,7 @@ function windowStartYmd(reset_at, duration) {
2765
2770
  const trailingStart = subtractDuration(new Date(now), duration);
2766
2771
  if (resetMs !== null) {
2767
2772
  if (resetMs > now) {
2768
- const periodStart = subtractDuration(reset, duration);
2773
+ const periodStart = reset.getUTCDate() === 1 ? subtractOneCalendarMonth(reset) : subtractDuration(reset, duration);
2769
2774
  return ymd(periodStart > trailingStart ? periodStart : trailingStart);
2770
2775
  } else {
2771
2776
  return ymd(reset > trailingStart ? reset : trailingStart);
@@ -22945,6 +22950,48 @@ ${style.markdown}` : params.prompt;
22945
22950
  }
22946
22951
  res.status(204).send();
22947
22952
  });
22953
+ app.get("/shared-artifacts", async (req, res) => {
22954
+ const { db: db2 } = await postgresClient();
22955
+ const auth = await requestValidators.authenticate(req);
22956
+ if (!auth.user?.id) {
22957
+ res.status(401).json({ detail: "Authentication required." });
22958
+ return;
22959
+ }
22960
+ const s3keyRaw = req.query.s3key;
22961
+ if (!s3keyRaw || typeof s3keyRaw !== "string") {
22962
+ res.status(400).json({ detail: "s3key query parameter is required." });
22963
+ return;
22964
+ }
22965
+ const bucket = config.fileUploads?.s3Bucket ?? "";
22966
+ const normalizedKey = normalizeS3Key(s3keyRaw, bucket);
22967
+ const rows = await db2("shared_artifacts").where({ s3key: normalizedKey, created_by: auth.user.id }).orderBy("createdAt", "desc").select("name", "auth_mode", "expires_at", "rights_mode");
22968
+ res.json(rows.map((r) => ({
22969
+ name: r.name,
22970
+ auth_mode: r.auth_mode,
22971
+ expires_at: r.expires_at ?? null,
22972
+ rights_mode: r.rights_mode ?? null
22973
+ })));
22974
+ });
22975
+ app.delete("/shared-artifacts/:name", async (req, res) => {
22976
+ const { db: db2 } = await postgresClient();
22977
+ const auth = await requestValidators.authenticate(req);
22978
+ if (!auth.user?.id) {
22979
+ res.status(401).json({ detail: "Authentication required." });
22980
+ return;
22981
+ }
22982
+ const row = await getSharedArtifactByName(db2, req.params.name ?? "");
22983
+ if (!row) {
22984
+ res.status(404).json({ detail: "Not found." });
22985
+ return;
22986
+ }
22987
+ if (row.created_by !== auth.user.id) {
22988
+ res.status(403).json({ detail: "You can only delete your own share links." });
22989
+ return;
22990
+ }
22991
+ await db2("rbac").where({ entity: "shared_artifact", target_resource_id: row.id }).delete();
22992
+ await db2("shared_artifacts").where({ id: row.id }).delete();
22993
+ res.status(204).end();
22994
+ });
22948
22995
  app.post("/shared-artifacts", async (req, res) => {
22949
22996
  const { db: db2 } = await postgresClient();
22950
22997
  const auth = await requestValidators.authenticate(req);
package/dist/index.js CHANGED
@@ -88,7 +88,7 @@ import {
88
88
  vectorSearch,
89
89
  waitForLiteLLMReady,
90
90
  withRetry
91
- } from "./chunk-PJSDLFXL.js";
91
+ } from "./chunk-WCP3WZM3.js";
92
92
  import {
93
93
  findLiteLLMModel
94
94
  } from "./chunk-YCE44CMU.js";
@@ -11807,6 +11807,48 @@ ${style.markdown}` : params.prompt;
11807
11807
  }
11808
11808
  res.status(204).send();
11809
11809
  });
11810
+ app.get("/shared-artifacts", async (req, res) => {
11811
+ const { db } = await postgresClient();
11812
+ const auth = await requestValidators.authenticate(req);
11813
+ if (!auth.user?.id) {
11814
+ res.status(401).json({ detail: "Authentication required." });
11815
+ return;
11816
+ }
11817
+ const s3keyRaw = req.query.s3key;
11818
+ if (!s3keyRaw || typeof s3keyRaw !== "string") {
11819
+ res.status(400).json({ detail: "s3key query parameter is required." });
11820
+ return;
11821
+ }
11822
+ const bucket = config.fileUploads?.s3Bucket ?? "";
11823
+ const normalizedKey = normalizeS3Key(s3keyRaw, bucket);
11824
+ const rows = await db("shared_artifacts").where({ s3key: normalizedKey, created_by: auth.user.id }).orderBy("createdAt", "desc").select("name", "auth_mode", "expires_at", "rights_mode");
11825
+ res.json(rows.map((r) => ({
11826
+ name: r.name,
11827
+ auth_mode: r.auth_mode,
11828
+ expires_at: r.expires_at ?? null,
11829
+ rights_mode: r.rights_mode ?? null
11830
+ })));
11831
+ });
11832
+ app.delete("/shared-artifacts/:name", async (req, res) => {
11833
+ const { db } = await postgresClient();
11834
+ const auth = await requestValidators.authenticate(req);
11835
+ if (!auth.user?.id) {
11836
+ res.status(401).json({ detail: "Authentication required." });
11837
+ return;
11838
+ }
11839
+ const row = await getSharedArtifactByName(db, req.params.name ?? "");
11840
+ if (!row) {
11841
+ res.status(404).json({ detail: "Not found." });
11842
+ return;
11843
+ }
11844
+ if (row.created_by !== auth.user.id) {
11845
+ res.status(403).json({ detail: "You can only delete your own share links." });
11846
+ return;
11847
+ }
11848
+ await db("rbac").where({ entity: "shared_artifact", target_resource_id: row.id }).delete();
11849
+ await db("shared_artifacts").where({ id: row.id }).delete();
11850
+ res.status(204).end();
11851
+ });
11810
11852
  app.post("/shared-artifacts", async (req, res) => {
11811
11853
  const { db } = await postgresClient();
11812
11854
  const auth = await requestValidators.authenticate(req);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@exulu/backend",
3
3
  "author": "Qventu Bv.",
4
- "version": "1.69.2",
4
+ "version": "1.70.0",
5
5
  "main": "./dist/index.js",
6
6
  "private": false,
7
7
  "publishConfig": {