From 5e62fd9751390d01c22bf2804e92acca340f791f Mon Sep 17 00:00:00 2001 From: RobertPechaCZ Date: Sat, 30 Aug 2025 18:20:06 +0200 Subject: [PATCH] feat: remove functions commands, remove storage upload and delete commands --- .changeset/poor-wolves-ask.md | 5 + src/FleekSdk.ts | 18 --- src/clients/functions.test.ts | 163 -------------------- src/clients/functions.ts | 187 ----------------------- src/clients/ipfs.test.ts | 277 ---------------------------------- src/clients/ipfs.ts | 118 +-------------- 6 files changed, 7 insertions(+), 761 deletions(-) create mode 100644 .changeset/poor-wolves-ask.md delete mode 100644 src/clients/functions.test.ts delete mode 100644 src/clients/functions.ts delete mode 100644 src/clients/ipfs.test.ts diff --git a/.changeset/poor-wolves-ask.md b/.changeset/poor-wolves-ask.md new file mode 100644 index 0000000..c45300e --- /dev/null +++ b/.changeset/poor-wolves-ask.md @@ -0,0 +1,5 @@ +--- +"@fleek-platform/sdk": major +--- + +Remove Fleek functions SDK, remove Fleek storage SDK diff --git a/src/FleekSdk.ts b/src/FleekSdk.ts index 78bac5b..13cfead 100644 --- a/src/FleekSdk.ts +++ b/src/FleekSdk.ts @@ -8,7 +8,6 @@ import { EnvNotSetError } from '@fleek-platform/errors'; import { ApplicationsClient } from './clients/applications'; import { DomainsClient } from './clients/domains'; import { EnsClient } from './clients/ens'; -import { FunctionsClient } from './clients/functions'; import { IpfsClient } from './clients/ipfs'; import { IpnsClient } from './clients/ipns'; import { PrivateGatewayClient } from './clients/privateGateway'; @@ -51,18 +50,12 @@ export class FleekSdk { private graphqlServiceApiUrl: string; private ipfsClient?: IpfsClient; - private ipfsStorageApiUrl: string; - private functionsClient?: FunctionsClient; constructor({ graphqlServiceApiUrl = getDefined('SDK__GRAPHQL_API_URL'), - ipfsStorageApiUrl = getDefined('SDK__IPFS__STORAGE_API_URL'), uploadProxyApiUrl = getDefined('SDK__UPLOAD_PROXY_API_URL'), accessTokenService, }: FleekSdkOptions) { - if (!ipfsStorageApiUrl) { - throw new EnvNotSetError('SDK__IPFS__STORAGE_API_URL'); - } if (!uploadProxyApiUrl) { throw new EnvNotSetError('SDK__UPLOAD_PROXY_API_URL'); @@ -87,7 +80,6 @@ export class FleekSdk { }); this.graphqlServiceApiUrl = graphqlServiceApiUrl; - this.ipfsStorageApiUrl = ipfsStorageApiUrl; this.uploadProxyApiUrl = uploadProxyApiUrl; this.uploadProxyClient = new UploadProxyClient({ @@ -202,16 +194,6 @@ export class FleekSdk { return this.storageClient; }; - public functions = (): FunctionsClient => { - if (!this.functionsClient) { - this.functionsClient = new FunctionsClient({ - graphqlClient: this.graphqlClient, - }); - } - - return this.functionsClient; - }; - private getAuthenticationHeaders = async () => { try { const accessToken = await this.accessTokenService.getAccessToken(); diff --git a/src/clients/functions.test.ts b/src/clients/functions.test.ts deleted file mode 100644 index f3b7cd6..0000000 --- a/src/clients/functions.test.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from 'vitest'; - -import { FleekSdk } from '../FleekSdk'; -import { mockGraphqlServiceApiUrl as graphqlServiceApiUrl } from '../mocks/graphql/handlers'; -import { server } from '../mocks/graphql/node'; -import state from '../mocks/state'; - -vi.mock('@fleek-platform/utils-token', async (importOriginal) => { - const original = await importOriginal(); - - return { - ...original, - createApplicationClientId: vi.fn().mockReturnValue('client_testtesttest'), - }; -}); - -vi.mock('@fleek-platform/utils-text', () => ({ - generateSlug: vi.fn().mockReturnValue('crooked-bland-jackal'), -})); - -describe('FleekSDK', () => { - const sdk = new FleekSdk({ - graphqlServiceApiUrl, - accessTokenService: {} as any, - }); - - beforeAll(() => server.listen()); - afterEach(() => server.resetHandlers()); - afterAll(() => server.close()); - - it('should get function by its name', async (context) => { - const response = await sdk.functions().get({ - name: state.fleekFunctions.fleekFunction.electronicCoEshop.name, - }); - - expect(response).toMatchInlineSnapshot(` - Object { - "currentDeployment": Object { - "cid": "bafybeifyvm5aa2z35jnpehvg3hfflazesjfma53yekmhz7dckqn4buvr7q", - }, - "currentDeploymentId": "clgmajsoo000108moef7f1yt0", - "id": "clgma7ilu000008jzdlwhb76a", - "invokeUrl": "blue-green-yellow.functions.on-fleek.app", - "name": "electronic-co-shop", - "projectId": "clgkiwjd8000c08mefyco2eoo", - "siteId": null, - "slug": "blue-green-yellow", - "status": "ACTIVE", - } - `); - }); - - it('list functions', async () => { - const response = await sdk.functions().list(); - - expect(response).toMatchInlineSnapshot(` - Array [ - Object { - "currentDeployment": Object { - "cid": "bafybeifcesfwifuhcshuobdgw6kod4jzinu4u4v2lzjzdmps3ndaydrsri", - }, - "currentDeploymentId": "clmz7kxj60003mk08eg5wmtqh", - "id": "clmkp5nn50000mm08yq7hierx", - "invokeUrl": "red-green-blue.functions.on-fleek.app", - "name": "electronicCoLanding", - "projectId": "clgkiwjd8000c08mefyco2eoo", - "siteId": null, - "slug": "red-green-blue", - "status": "ACTIVE", - }, - Object { - "currentDeployment": null, - "currentDeploymentId": null, - "id": "clgma7mmh000108jzd13c50ol", - "invokeUrl": "white-black-silver.functions.on-fleek.app", - "name": "electronic-co-blog", - "projectId": "clgkiwjd8000c08mefyco2eoo", - "siteId": null, - "slug": "white-black-silver", - "status": "ACTIVE", - }, - Object { - "currentDeployment": null, - "currentDeploymentId": null, - "id": "clje32iwx000008js9rjb5uoo", - "invokeUrl": "green-gold-silver.functions.on-fleek.app", - "name": "electronic-co-videos", - "projectId": "clgkiwjd8000c08mefyco2eoo", - "siteId": null, - "slug": "green-gold-silver", - "status": "ACTIVE", - }, - Object { - "currentDeployment": Object { - "cid": "bafybeifyvm5aa2z35jnpehvg3hfflazesjfma53yekmhz7dckqn4buvr7q", - }, - "currentDeploymentId": "clgmajsoo000108moef7f1yt0", - "id": "clgma7ilu000008jzdlwhb76a", - "invokeUrl": "blue-green-yellow.functions.on-fleek.app", - "name": "electronic-co-shop", - "projectId": "clgkiwjd8000c08mefyco2eoo", - "siteId": null, - "slug": "blue-green-yellow", - "status": "ACTIVE", - }, - Object { - "currentDeployment": null, - "currentDeploymentId": null, - "id": "clm93utuz000108laem2a4pe4", - "invokeUrl": "blue-gold-yellow.functions.on-fleek.app", - "name": "electronic-co-deprecated", - "projectId": "clgkiwjd8000c08mefyco2eoo", - "siteId": null, - "slug": "blue-gold-yellow", - "status": "ACTIVE", - }, - ] - `); - }); - - it('should create function', async () => { - const response = await sdk.functions().create({ - name: 'new-function', - }); - - expect(response).toMatchInlineSnapshot( - { id: expect.any(String) }, - ` - Object { - "currentDeployment": null, - "currentDeploymentId": null, - "id": Any, - "invokeUrl": "https://crooked-bland-jackal.dev.on-fleek-functions.app", - "name": "new-function", - "projectId": "clgkiwjd8000c08mefyco2eoo", - "siteId": null, - "slug": "crooked-bland-jackal", - "status": "ACTIVE", - } - ` - ); - }); - - it('should delete function', async () => { - const response = await sdk.functions().delete({ - id: state.fleekFunctions.fleekFunction.electronicCoVideos.id, - }); - - expect(response).toMatchInlineSnapshot(` - Object { - "currentDeployment": null, - "currentDeploymentId": null, - "id": "clje32iwx000008js9rjb5uoo", - "invokeUrl": "green-gold-silver.functions.on-fleek.app", - "name": "electronic-co-videos", - "projectId": "clgkiwjd8000c08mefyco2eoo", - "siteId": null, - "slug": "green-gold-silver", - "status": "ACTIVE", - } - `); - }); -}); diff --git a/src/clients/functions.ts b/src/clients/functions.ts deleted file mode 100644 index 8213534..0000000 --- a/src/clients/functions.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { - Client, - FleekFunction as OriginalFleekFunction, - FleekFunctionDeployment, - FleekFunctionDeploymentGenqlSelection, - FleekFunctionGenqlSelection, - FleekFunctionStatus, -} from '@fleek-platform/utils-genql-client'; -type FunctionsClientOptions = { - graphqlClient: Client; -}; - -export type FleekFunction = Omit; - -export type GetFleekFunctionArgs = { - name: string; -}; -export type CreateFleekFunctionArgs = { - name: string; - siteId?: string; -}; -export type DeleteFleekFunctionArgs = { - id: string; -}; -export type UpdateFleekFunctionArgs = { - id: string; - name?: string; - slug?: string; - status?: FleekFunctionStatus; -}; -export type DeployFleekFunctionArgs = { - functionId: string; - cid: string; - sgx?: boolean; - blake3Hash?: string; - assetsCid?: string; -}; -export type ListFleekFunctionArgs = { - functionId: string; -}; - -export class FunctionsClient { - private graphqlClient: Client; - - private static Deployment_MAPPED_PROPERTIES: FleekFunctionDeploymentGenqlSelection = { - id: true, - fleekFunctionId: true, - cid: true, - updatedAt: true, - createdAt: true, - }; - - private static FleekFunction_MAPPED_PROPERTIES: FleekFunctionGenqlSelection = { - id: true, - name: true, - slug: true, - invokeUrl: true, - projectId: true, - currentDeploymentId: true, - currentDeployment: { - cid: true, - }, - siteId: true, - status: true, - }; - - constructor(options: FunctionsClientOptions) { - this.graphqlClient = options.graphqlClient; - } - - public get = async ({ name }: GetFleekFunctionArgs): Promise => { - const response = await this.graphqlClient.query({ - __name: 'GetFleekFunctionByName', - fleekFunctionByName: { - __args: { - where: { - name, - }, - }, - ...FunctionsClient.FleekFunction_MAPPED_PROPERTIES, - }, - }); - - return response.fleekFunctionByName; - }; - - public list = async (): Promise => { - const response = await this.graphqlClient.query({ - __name: 'GetFleekFunctions', - fleekFunctions: { - __args: {}, - data: { - ...FunctionsClient.FleekFunction_MAPPED_PROPERTIES, - }, - }, - }); - - return response.fleekFunctions.data; - }; - - public listDeployments = async ({ functionId }: ListFleekFunctionArgs): Promise => { - const response = await this.graphqlClient.query({ - fleekFunctionDeployments: { - __args: { - where: { - fleekFunctionId: functionId, - }, - }, - data: { - ...FunctionsClient.Deployment_MAPPED_PROPERTIES, - }, - }, - }); - - return response.fleekFunctionDeployments.data; - }; - - public create = async ({ name, siteId }: CreateFleekFunctionArgs) => { - const response = await this.graphqlClient.mutation({ - __name: 'CreateFleekFunction', - createFleekFunction: { - __args: { - data: { - name, - siteId, - }, - }, - ...FunctionsClient.FleekFunction_MAPPED_PROPERTIES, - }, - }); - - return response.createFleekFunction; - }; - - public deploy = async ({ functionId, cid, sgx, blake3Hash, assetsCid }: DeployFleekFunctionArgs): Promise => { - const response = await this.graphqlClient.mutation({ - triggerFleekFunctionDeployment: { - __args: { - where: { - functionId, - cid, - }, - data: { sgx, blake3Hash, assetsCid }, - }, - ...FunctionsClient.Deployment_MAPPED_PROPERTIES, - }, - }); - - return response.triggerFleekFunctionDeployment; - }; - - public delete = async ({ id }: DeleteFleekFunctionArgs) => { - const response = await this.graphqlClient.mutation({ - __name: 'DeleteFleekFunction', - deleteFleekFunction: { - __args: { - where: { - id, - }, - }, - ...FunctionsClient.FleekFunction_MAPPED_PROPERTIES, - }, - }); - - return response.deleteFleekFunction; - }; - - public update = async ({ id, slug, name, status }: UpdateFleekFunctionArgs) => { - const response = await this.graphqlClient.mutation({ - updateFleekFunction: { - __args: { - where: { - id, - }, - data: { - slug, - name, - status, - }, - }, - ...FunctionsClient.FleekFunction_MAPPED_PROPERTIES, - }, - }); - - return response.updateFleekFunction; - }; -} diff --git a/src/clients/ipfs.test.ts b/src/clients/ipfs.test.ts deleted file mode 100644 index 60796b3..0000000 --- a/src/clients/ipfs.test.ts +++ /dev/null @@ -1,277 +0,0 @@ -import { - describe, - expect, - it, - afterAll, - afterEach, - beforeAll, - vi, -} from 'vitest'; -import { server } from '../mocks/graphql/node'; -import { mockGraphqlServiceApiUrl as graphqlServiceApiUrl } from '../mocks/graphql/handlers'; -import { FleekSdk } from '../FleekSdk'; - -type MockFileNames = 'HelloWorld' | 'Lyrics'; -type MockFiles = Record< - MockFileNames, - { - path: string; - content: Buffer; - cid: string; - } ->; - -const mockFiles: MockFiles = { - HelloWorld: { - path: 'src/HelloWorld.txt', - content: Buffer.from('Hello World!'), - cid: 'QmWvQxTqbG2Z9HPJgG57jjwR154cKhbtJenbyYTWkjgF3e', - }, - Lyrics: { - path: 'Documents/random/Lyrics.txt', - content: Buffer.from('My favourite song lyrics'), - cid: 'QmQtQq4iofjT8vgD75G3UPF3v4caatuFw3YnU2mhn17BUf', - }, -}; - -const mockUploadContent = vi.fn().mockImplementation(async ({ basename }) => { - if (basename === 'HelloWorld.txt') { - return { - pin: { - cid: mockFiles.HelloWorld.cid, - size: 100, - }, - duplicate: false, - }; - } - - if (basename === 'Lyrics.txt') { - return { - pin: { - cid: mockFiles.HelloWorld.cid, - size: 100, - }, - duplicate: false, - }; - } - - if (basename === 'src') { - return { - pin: { - // TODO: Missing CID - cid: mockFiles.HelloWorld.cid, - size: 10000, - }, - duplicate: false, - }; - } -}); - -vi.mock('./uploadProxy', () => { - return { - UploadProxyClient: vi.fn().mockImplementation(() => ({ - uploadContent: mockUploadContent, - })), - }; -}); - -vi.mock('@web3-storage/upload-client', () => { - return { - UnixFS: { - createFileEncoderStream: vi.fn(), - createDirectoryEncoderStream: vi.fn(), - }, - }; -}); - -vi.mock('files-from-path', () => { - return { - filesFromPaths: vi.fn(), - }; -}); - -vi.mock('fs', async () => { - const actual = await vi.importActual('fs'); - return { - ...actual, - promises: { - ...actual.promises, - stat: vi.fn().mockResolvedValue({ - isDirectory: () => true, - size: 1024, - }), - }, - }; -}); - -describe('FleekSDK', () => { - const sdk = new FleekSdk({ - graphqlServiceApiUrl, - accessTokenService: {} as any, - }); - - beforeAll(() => server.listen()); - afterEach(() => server.resetHandlers()); - afterAll(() => server.close()); - - it('should add file to ipfs', async () => { - const { path, content } = mockFiles.HelloWorld; - - const response = await sdk.ipfs().add({ - path, - content, - }); - - expect(response).toMatchInlineSnapshot(` - Object { - "cid": Object { - "code": 112, - "hash": Uint8Array [ - 18, - 32, - 127, - 131, - 177, - 101, - 127, - 241, - 252, - 83, - 185, - 45, - 193, - 129, - 72, - 161, - 214, - 93, - 252, - 45, - 75, - 31, - 163, - 214, - 119, - 40, - 74, - 221, - 210, - 0, - 18, - 109, - 144, - 105, - ], - "version": 0, - }, - "path": "HelloWorld.txt", - "size": 100, - } - `); - }); - - it('should add all files to ipfs', async () => { - const { HelloWorld, Lyrics } = mockFiles; - - const response = await sdk.ipfs().addAll([HelloWorld, Lyrics]); - - expect(response).toMatchInlineSnapshot(` - Array [ - Object { - "cid": Object { - "code": 112, - "hash": Uint8Array [ - 18, - 32, - 127, - 131, - 177, - 101, - 127, - 241, - 252, - 83, - 185, - 45, - 193, - 129, - 72, - 161, - 214, - 93, - 252, - 45, - 75, - 31, - 163, - 214, - 119, - 40, - 74, - 221, - 210, - 0, - 18, - 109, - 144, - 105, - ], - "version": 0, - }, - "path": "HelloWorld.txt", - "size": 100, - }, - Object { - "cid": Object { - "code": 112, - "hash": Uint8Array [ - 18, - 32, - 127, - 131, - 177, - 101, - 127, - 241, - 252, - 83, - 185, - 45, - 193, - 129, - 72, - 161, - 214, - 93, - 252, - 45, - 75, - 31, - 163, - 214, - 119, - 40, - 74, - 221, - 210, - 0, - 18, - 109, - 144, - 105, - ], - "version": 0, - }, - "path": "Lyrics.txt", - "size": 100, - }, - ] - `); - }); - - it.todo('should add files by path', async () => { - const response = await sdk.ipfs().addFromPath('./src'); - - expect(response).toMatchInlineSnapshot(`{}`); - }); -}); diff --git a/src/clients/ipfs.ts b/src/clients/ipfs.ts index 4d838fb..ad11fa2 100644 --- a/src/clients/ipfs.ts +++ b/src/clients/ipfs.ts @@ -1,16 +1,7 @@ -import { - SdkRequiredNodeRuntimeError, - StorageIpfsUploadFailedError, -} from '@fleek-platform/errors'; +import { SdkRequiredNodeRuntimeError } from '@fleek-platform/errors'; import { filesFromPaths } from 'files-from-path'; -import type { ReadStream } from 'fs'; -import type { CID, globSource } from 'ipfs-http-client'; import { requireNodeEnv } from '../libs/requireNodeEnv'; -import { - WriteFilesArgs, - writeFilesFromStream, -} from '../libs/writeFilesFromStream'; import { isNode } from '../utils/node'; import { UploadPinResponse, UploadProxyClient } from './uploadProxy'; @@ -23,24 +14,12 @@ export type IpfsClientOptions = { uploadProxyClient: UploadProxyClient; }; -export type AddAllOptions = { - basename?: string; - wrapWithDirectory?: boolean; - searchParams?: URLSearchParams; - siteId?: string; -}; - export type AddFromPathOptions = { wrapWithDirectory?: boolean; searchParams?: URLSearchParams; siteId?: string; }; -export type UploadResult = { - cid: CID; - size: number; - path: string; -}; export class IpfsClient { private uploadProxyClient: UploadProxyClient; @@ -65,100 +44,7 @@ export class IpfsClient { }; }; - public add = async (file: IpfsFile): Promise => { - const nodePath = await import('path'); - const path = file.path ? nodePath.basename(file.path) : ''; - - const blob = new Blob([file.content]); - const { UnixFS } = await import('@web3-storage/upload-client'); - const getStream = () => - UnixFS.createFileEncoderStream({ stream: () => blob.stream() }); - - try { - const { pin } = await this.uploadProxyClient.uploadContent({ - getStream, - basename: path, - }); - - return this.pinToUploadResult(pin, path); - } catch { - throw new StorageIpfsUploadFailedError(); - } - }; - - public addAll = async ( - files: Array | ReturnType, - options: AddAllOptions = {}, - ): Promise => { - const added: UploadResult[] = []; - try { - if (Array.isArray(files)) { - const pins = await Promise.all( - files.map(async (file) => await this.add(file)), - ); - added.push(...pins); - } else { - requireNodeEnv(); - - const fileStreams: WriteFilesArgs[] = []; - const basename = options.basename ?? 'wrapped'; - const { randomBytes } = await import('crypto'); - const wrappedRandomDir = `wrapped_${randomBytes(10).toString('hex')}`; - const wrapped = `${wrappedRandomDir}/${basename}`; - const path = await import('path'); - - for await (const file of files) { - if (file.content === undefined) { - continue; - } - - fileStreams.push({ - readStream: file.content as ReadStream, - outputPath: path.join(wrapped, file.path.slice(1)), - }); - } - - await writeFilesFromStream(fileStreams); - const filesFromPath = await filesFromPaths([wrapped]); - const { UnixFS } = await import('@web3-storage/upload-client'); - - if (options.wrapWithDirectory) { - const getStream = () => - UnixFS.createDirectoryEncoderStream(filesFromPath); - const { pin } = await this.uploadProxyClient.uploadContent({ - getStream, - basename, - }); - const uploadResult = await this.pinToUploadResult(pin, basename); - added.push(uploadResult); - } else { - const pins = await Promise.all( - filesFromPath.map(async (path) => { - const getStream = () => - UnixFS.createDirectoryEncoderStream([path]); - const { pin } = await this.uploadProxyClient.uploadContent({ - getStream, - basename: path.name, - }); - - return this.pinToUploadResult(pin, path.name); - }), - ); - added.push(...pins); - } - - const { promises: fs } = await import('fs'); - await fs.rm(wrappedRandomDir, { recursive: true, force: true }); - } - - return added; - } catch (err) { - console.log(err); - throw new StorageIpfsUploadFailedError(); - } - }; - - public addFromPath = async ( + private addFromPath = async ( path: string, options: AddFromPathOptions = {}, ) => {