diff --git a/types/forge-apis/forge-apis-tests.ts b/types/forge-apis/forge-apis-tests.ts
index 91037adfc94464..15d23cfe5b9c13 100644
--- a/types/forge-apis/forge-apis-tests.ts
+++ b/types/forge-apis/forge-apis-tests.ts
@@ -11,10 +11,14 @@ import {
ItemsApi,
ObjectsApi,
ProjectsApi,
+ setDebug,
UserProfileApi,
VersionsApi,
} from "forge-apis";
+// $ExpectType void
+setDebug(true);
+
const authToken: AuthToken = {
access_token: "",
expires_in: 0,
diff --git a/types/forge-apis/index.d.ts b/types/forge-apis/index.d.ts
index e8c65973be57fb..191b06f5083808 100644
--- a/types/forge-apis/index.d.ts
+++ b/types/forge-apis/index.d.ts
@@ -15,6 +15,11 @@
///
+/**
+ * Optionally enable debugging, which sets `isDebugMode` on the shared `ApiClient` instance.
+ */
+export function setDebug(isDebug: boolean): void;
+
/**
* https://forge.autodesk.com/en/docs/oauth/v2/developers_guide/scopes
*/
diff --git a/types/sharetribe-flex-integration-sdk/index.d.ts b/types/sharetribe-flex-integration-sdk/index.d.ts
index 39bc42df7d789d..4d1e7814c28973 100644
--- a/types/sharetribe-flex-integration-sdk/index.d.ts
+++ b/types/sharetribe-flex-integration-sdk/index.d.ts
@@ -240,6 +240,80 @@ export interface Message {
relationships: MessageRelationships;
}
+/**
+ * Lifecycle state of a file resource
+ */
+export type FileState = "pendingUpload" | "pendingVerification" | "available" | "verificationFailed";
+
+/**
+ * A single automatic verification check performed on a file (e.g. `{ type: "malwareScan", result: "success" }`)
+ */
+export interface FileVerificationCheck {
+ type: string;
+ result: string;
+}
+
+/**
+ * File attributes
+ */
+export interface FileAttributes {
+ name: string;
+ size: number;
+ state: FileState;
+ verificationChecks: FileVerificationCheck[];
+ requiredVerificationChecks: string[];
+ createdAt: string;
+ stateUpdatedAt: string;
+ deleted: boolean;
+}
+
+/**
+ * File relationships
+ */
+export interface FileRelationships {
+ owner: {
+ data: ResourceReference;
+ };
+ marketplace: {
+ data: ResourceReference;
+ };
+}
+
+/**
+ * File resource
+ */
+export interface File {
+ id: UUID;
+ type: "file";
+ attributes: FileAttributes;
+ relationships: FileRelationships;
+}
+
+/**
+ * File attachment relationships. The `message` relationship is only present when the file is attached to a message.
+ */
+export interface FileAttachmentRelationships {
+ file: {
+ data: ResourceReference;
+ };
+ message?: {
+ data: ResourceReference;
+ };
+}
+
+/**
+ * File attachment resource (links a file to a transaction message)
+ */
+export interface FileAttachment {
+ id: UUID;
+ type: "fileAttachment";
+ attributes: {
+ scope: "public";
+ deleted: boolean;
+ };
+ relationships: FileAttachmentRelationships;
+}
+
/**
* Event attributes
*/
@@ -527,6 +601,13 @@ export interface IntegrationSdk {
},
options?: PerRequestOptions,
) => Promise>;
+ /**
+ * Mark a user's email as verified. The email must match the user's primary email or pending email.
+ */
+ verifyEmail: (
+ params: { id: UUID | string; email: string },
+ options?: PerRequestOptions,
+ ) => Promise>;
};
listings: {
@@ -742,6 +823,55 @@ export interface IntegrationSdk {
show: (params: { id: UUID | string } & BaseQueryParams) => Promise>;
};
+ messages: {
+ /**
+ * Query messages. Either `transactionId` or `ids` must be provided.
+ */
+ query: (
+ params:
+ & (
+ | { transactionId: UUID | string; ids?: Array }
+ | { transactionId?: UUID | string; ids: Array }
+ )
+ & PaginationParams
+ & BaseQueryParams,
+ ) => Promise>;
+ };
+
+ files: {
+ /**
+ * Query files
+ */
+ query: (
+ params?:
+ & {
+ ids?: Array;
+ messageId?: UUID | string;
+ ownerId?: UUID | string;
+ createdAtStart?: Date | string;
+ createdAtEnd?: Date | string;
+ }
+ & PaginationParams
+ & BaseQueryParams,
+ ) => Promise>;
+ };
+
+ fileAttachments: {
+ /**
+ * Query file attachments
+ */
+ query: (
+ params?:
+ & {
+ ids?: Array;
+ fileIds?: Array;
+ messageId?: UUID | string;
+ }
+ & PaginationParams
+ & BaseQueryParams,
+ ) => Promise>;
+ };
+
/**
* Revoke authentication token
*/
diff --git a/types/sharetribe-flex-integration-sdk/package.json b/types/sharetribe-flex-integration-sdk/package.json
index 90be71f1ea2376..c740f577329982 100644
--- a/types/sharetribe-flex-integration-sdk/package.json
+++ b/types/sharetribe-flex-integration-sdk/package.json
@@ -1,7 +1,7 @@
{
"private": true,
"name": "@types/sharetribe-flex-integration-sdk",
- "version": "1.11.9999",
+ "version": "1.13.9999",
"projects": [
"https://github.com/sharetribe/flex-integration-sdk-js"
],
diff --git a/types/sharetribe-flex-integration-sdk/sharetribe-flex-integration-sdk-tests.ts b/types/sharetribe-flex-integration-sdk/sharetribe-flex-integration-sdk-tests.ts
index 97ad6c98a6d747..c2b00c9012596e 100644
--- a/types/sharetribe-flex-integration-sdk/sharetribe-flex-integration-sdk-tests.ts
+++ b/types/sharetribe-flex-integration-sdk/sharetribe-flex-integration-sdk-tests.ts
@@ -110,5 +110,48 @@ sdk.stockAdjustments.create({
const adjustmentId: string = response.data.data.id.uuid;
});
+// Mark a user's email as verified (added in integration-sdk 1.12)
+sdk.users.verifyEmail({
+ id: "user-id",
+ email: "test@example.com",
+}).then((response) => {
+ const userId: string = response.data.data.id.uuid;
+});
+
+// Query messages by transaction or by ids (added in integration-sdk 1.13)
+sdk.messages.query({ transactionId: "transaction-id" }).then((response) => {
+ const firstMessage = response.data.data[0];
+ if (firstMessage) {
+ const content: string = firstMessage.attributes.content;
+ }
+});
+sdk.messages.query({ ids: ["message-id"], include: ["sender"] }).then((response) => {
+ const totalPages: number = response.data.meta.totalPages;
+});
+
+// Query files with the supported filters (added in integration-sdk 1.13)
+sdk.files.query({
+ ownerId: "user-id",
+ messageId: "message-id",
+ ids: ["file-id"],
+ createdAtStart: new Date("2024-01-01T00:00:00.000Z"),
+ createdAtEnd: "2024-12-31T23:59:59.000Z",
+ include: ["owner"],
+}).then((response) => {
+ const firstFile = response.data.data[0];
+ if (firstFile) {
+ const state: string = firstFile.attributes.state;
+ const ownerRef: string = firstFile.relationships.owner.data.id.uuid;
+ }
+});
+
+// Query file attachments by message or file ids (added in integration-sdk 1.13)
+sdk.fileAttachments.query({ messageId: "message-id", fileIds: ["file-id"], include: ["file"] }).then((response) => {
+ const firstAttachment = response.data.data[0];
+ if (firstAttachment) {
+ const scope: "public" = firstAttachment.attributes.scope;
+ }
+});
+
const rateLimiterConfig = util.prodQueryLimiterConfig;
const rateLimiter = util.createRateLimiter(rateLimiterConfig);
diff --git a/types/sharetribe-flex-sdk/index.d.ts b/types/sharetribe-flex-sdk/index.d.ts
index aa0cef162657e6..d2514c8ba23b10 100644
--- a/types/sharetribe-flex-sdk/index.d.ts
+++ b/types/sharetribe-flex-sdk/index.d.ts
@@ -544,6 +544,100 @@ export interface StripeCustomer {
attributes: StripeCustomerAttributes;
}
+/**
+ * Lifecycle state of a file resource
+ */
+export type FileState = "pendingUpload" | "pendingVerification" | "available" | "verificationFailed";
+
+/**
+ * Attributes of a file owned by the current user
+ */
+export interface OwnFileAttributes {
+ name: string;
+ size: number;
+ state: FileState;
+ createdAt: string;
+ stateUpdatedAt: string;
+}
+
+/**
+ * A file owned by the current user
+ */
+export interface OwnFile {
+ id: UUID;
+ type: "ownFile";
+ attributes: OwnFileAttributes;
+}
+
+/**
+ * Attributes of a file accessible to the current user (e.g. attached to a transaction)
+ */
+export interface FileAttributes {
+ name: string;
+ size: number;
+ state: FileState;
+ deleted: boolean;
+}
+
+/**
+ * A file accessible to the current user (e.g. attached to a transaction)
+ */
+export interface File {
+ id: UUID;
+ type: "file";
+ attributes: FileAttributes;
+}
+
+/**
+ * A presigned upload target returned by `sdk.fileUploads.create()`
+ */
+export interface FileUpload {
+ id: UUID;
+ type: "fileUpload";
+ attributes: {
+ fileId: UUID;
+ url: string;
+ method: string;
+ headers: Record;
+ expiresAt: string;
+ };
+}
+
+/**
+ * A short-lived download URL for a file owned by the current user
+ */
+export interface OwnFileDownload {
+ id: UUID;
+ type: "ownFileDownload";
+ attributes: {
+ fileId: UUID;
+ url: string;
+ expiresAt: string;
+ };
+}
+
+/**
+ * A short-lived download URL for a file accessible to the current user
+ */
+export interface FileDownload {
+ id: UUID;
+ type: "fileDownload";
+ attributes: {
+ fileId: UUID;
+ url: string;
+ expiresAt: string;
+ };
+}
+
+/**
+ * File metadata extracted by `file.metadata()`, suitable for `sdk.ownFiles.create()`
+ */
+export interface FileMetadata {
+ name: string;
+ mimeType: string;
+ size: number;
+}
+
/**
* Common query parameters for GET requests
*/
@@ -1182,6 +1276,61 @@ export interface MarketplaceSdk {
queryAssets: (params?: PaginationParams) => Promise;
};
+ ownFiles: {
+ /**
+ * Register a file with the Marketplace API (first step of the upload flow)
+ */
+ create: (
+ params: { name: string; mimeType: string; size: number },
+ queryParams?: { expand?: boolean },
+ opts?: PerRequestOptions,
+ ) => Promise>;
+ /**
+ * Show a file owned by the current user
+ */
+ show: (params: { id: UUID | string } & BaseQueryParams) => Promise>;
+ };
+
+ files: {
+ /**
+ * Show a file accessible to the current user
+ */
+ show: (params: { id: UUID | string } & BaseQueryParams) => Promise>;
+ };
+
+ fileUploads: {
+ /**
+ * Request a presigned upload URL for a registered file
+ */
+ create: (
+ params: { fileId: UUID | string },
+ queryParams?: { expand?: boolean },
+ opts?: PerRequestOptions,
+ ) => Promise>;
+ };
+
+ ownFileDownloads: {
+ /**
+ * Request a short-lived download URL for a file owned by the current user
+ */
+ create: (
+ params: { fileId: UUID | string },
+ queryParams?: { expand?: boolean },
+ opts?: PerRequestOptions,
+ ) => Promise>;
+ };
+
+ fileDownloads: {
+ /**
+ * Request a short-lived download URL for a file accessible to the current user
+ */
+ create: (
+ params: { fileId: UUID | string },
+ queryParams?: { expand?: boolean },
+ opts?: PerRequestOptions,
+ ) => Promise>;
+ };
+
/**
* Authentication methods
*/
@@ -1222,3 +1371,44 @@ export interface SdkConfig {
* @returns Configured SDK instance
*/
export function createInstance(config: SdkConfig): MarketplaceSdk;
+
+/**
+ * Query string utilities
+ */
+export namespace util {
+ /**
+ * Serialize an object into a Sharetribe query string fragment, e.g. `{ a: "foo", b: 150 }` => `"a:foo;b:150"`.
+ * Used for parameters such as `meta_*` query filters.
+ */
+ function objectQueryString(obj: Record): string;
+ /**
+ * Serialize query parameters into a URL query string, handling Sharetribe types such as `UUID` and `LatLng`.
+ * Parameters may be passed as a string, an object, or an array combining the two.
+ */
+ function queryString(
+ params: string | Record | Array>,
+ ): string;
+}
+
+/**
+ * Helpers for the file upload flow
+ */
+export namespace file {
+ /**
+ * Extract the metadata needed for `sdk.ownFiles.create()` from a browser `File` object.
+ * @param file - A browser `File` object, e.g. from an `` element
+ */
+ function metadata(file: unknown): FileMetadata;
+ /**
+ * Upload a file directly to cloud storage using a presigned URL obtained from
+ * `sdk.fileUploads.create()`. This bypasses the SDK interceptor pipeline.
+ * @returns A promise that resolves when the upload is complete
+ */
+ function upload(params: {
+ url: string;
+ file: unknown;
+ method?: string;
+ headers?: Record;
+ onUploadProgress?: (progressEvent: unknown) => void;
+ }): Promise;
+}
diff --git a/types/sharetribe-flex-sdk/package.json b/types/sharetribe-flex-sdk/package.json
index 628a81767a35b4..64a82346dfd49c 100644
--- a/types/sharetribe-flex-sdk/package.json
+++ b/types/sharetribe-flex-sdk/package.json
@@ -1,7 +1,7 @@
{
"private": true,
"name": "@types/sharetribe-flex-sdk",
- "version": "1.22.9999",
+ "version": "1.24.9999",
"projects": [
"https://github.com/sharetribe/flex-sdk-js"
],
diff --git a/types/sharetribe-flex-sdk/sharetribe-flex-sdk-tests.ts b/types/sharetribe-flex-sdk/sharetribe-flex-sdk-tests.ts
index 1fb9a73a25fd19..294e0f2b12838f 100644
--- a/types/sharetribe-flex-sdk/sharetribe-flex-sdk-tests.ts
+++ b/types/sharetribe-flex-sdk/sharetribe-flex-sdk-tests.ts
@@ -1,4 +1,13 @@
-import { createInstance, Marketplace, ShowResponse } from "sharetribe-flex-sdk";
+import {
+ createInstance,
+ file,
+ FileUpload,
+ Marketplace,
+ MutationResponse,
+ OwnFile,
+ ShowResponse,
+ util,
+} from "sharetribe-flex-sdk";
const sdk = createInstance({ clientId: "client-id" });
@@ -11,3 +20,25 @@ sdk.assetByAlias({ path: "/assets", alias: "logo" }).then((result: { status?: nu
const status: number | undefined = result.status;
const data: unknown = result.data;
});
+
+// File upload flow (added in flex-sdk 1.24)
+const meta = file.metadata("file-like-object");
+const fileName: string = meta.name;
+
+sdk.ownFiles.create({ name: meta.name, mimeType: meta.mimeType, size: meta.size }).then(
+ (response: MutationResponse) => {
+ const fileId = response.data.data.id;
+ return sdk.fileUploads.create({ fileId }).then((uploadResponse: MutationResponse) => {
+ const { method, url, headers } = uploadResponse.data.data.attributes;
+ return file.upload({ method, url, headers, file: "file-like-object" });
+ });
+ },
+);
+
+sdk.fileDownloads.create({ fileId: "a5d04285-07da-4fa0-b80b-ebabb8bac9e5" }).then(response => {
+ const downloadUrl: string = response.data.data.attributes.url;
+});
+
+// Query string utilities (added in flex-sdk 1.23)
+const qs: string = util.queryString({ ok: true });
+const oqs: string = util.objectQueryString({ a: "foo", b: 150 });