From 66da9e0fb99a24784a82409cfba4860183a4f701 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sat, 31 May 2025 08:46:40 +0200 Subject: [PATCH] feat: deploy asset for proposal with approriate endpoints --- src/commands/deploy.ts | 79 +++++++++++++++-- .../deploy/deploy.execute.services.ts | 86 +++++++++++++------ 2 files changed, 131 insertions(+), 34 deletions(-) diff --git a/src/commands/deploy.ts b/src/commands/deploy.ts index 42307a85..0022dd49 100644 --- a/src/commands/deploy.ts +++ b/src/commands/deploy.ts @@ -1,13 +1,22 @@ +import {uploadAssetWithProposal} from '@junobuild/cdn'; import { deploy as cliDeploy, deployWithProposal as cliDeployWithProposal, type DeployResult, type DeployResultWithProposal, - hasArgs + hasArgs, + type UploadFileWithProposal } from '@junobuild/cli-tools'; +import {uploadBlob} from '@junobuild/core'; import {junoConfigExist} from '../configs/juno.config'; import {clear} from '../services/clear.services'; -import {type DeployFnParams, executeDeploy} from '../services/deploy/deploy.execute.services'; +import { + type DeployFnParams, + executeDeployImmediate, + executeDeployWithProposal, + type UploadFileFnParams, + type UploadFileFnParamsWithProposal +} from '../services/deploy/deploy.execute.services'; import {links} from '../services/links.services'; import {init} from './init'; @@ -30,7 +39,10 @@ export const deploy = async (args?: string[]) => { const deployWithProposal = async ({args, clearOption}: {args?: string[]; clearOption: boolean}) => { const noCommit = hasArgs({args, options: ['-n', '--no-commit']}); - const deployFn = async ({deploy, satellite}: DeployFnParams): Promise => + const deployFn = async ({ + deploy, + satellite + }: DeployFnParams): Promise => await cliDeployWithProposal({ deploy, proposal: { @@ -42,9 +54,40 @@ const deployWithProposal = async ({args, clearOption}: {args?: string[]; clearOp } }); - const {result} = await executeDeploy({ + const uploadFileFn = async ({ + filename: storageFilename, + fullPath: storagePath, + data, + collection, + headers = [], + encoding, + satellite, + proposalId + }: UploadFileFnParamsWithProposal) => { + // Similar as in Juno Core SDK + // The IC certification does not currently support encoding + const filename = decodeURI(storageFilename); + const fullPath = storagePath ?? `/${collection}/${filename}`; + + await uploadAssetWithProposal({ + cdn: {satellite}, + proposalId, + asset: { + filename, + fullPath, + // @ts-expect-error type incompatibility NodeJS vs bundle + data, + collection, + headers, + encoding + } + }); + }; + + const {result} = await executeDeployWithProposal({ args, - deployFn + deployFn, + uploadFileFn }); if (result !== 'deployed') { @@ -62,9 +105,31 @@ const deployImmediate = async ({args, clearOption}: {args?: string[]; clearOptio const deployFn = async ({deploy}: DeployFnParams): Promise => await cliDeploy(deploy); - await executeDeploy({ + const uploadFileFn = async ({ + filename, + fullPath, + data, + collection, + headers, + encoding, + satellite + }: UploadFileFnParams) => { + await uploadBlob({ + satellite, + filename, + fullPath, + // @ts-expect-error type incompatibility NodeJS vs bundle + data, + collection, + headers, + encoding + }); + }; + + await executeDeployImmediate({ args, - deployFn + deployFn, + uploadFileFn }); await links(args); diff --git a/src/services/deploy/deploy.execute.services.ts b/src/services/deploy/deploy.execute.services.ts index 11e88a25..02033ffb 100644 --- a/src/services/deploy/deploy.execute.services.ts +++ b/src/services/deploy/deploy.execute.services.ts @@ -2,29 +2,72 @@ import type { DeployParams, DeployResult, DeployResultWithProposal, - UploadFileStorage + UploadFile, + UploadFileStorage, + UploadFileStorageWithProposal, + UploadFileWithProposal } from '@junobuild/cli-tools'; import {postDeploy as cliPostDeploy, preDeploy as cliPreDeploy} from '@junobuild/cli-tools'; -import {type Asset, uploadBlob} from '@junobuild/core'; +import {type Asset} from '@junobuild/core'; import {red} from 'kleur'; import {lstatSync} from 'node:fs'; -import {type SatelliteParametersWithId} from '../../types/satellite'; +import type {SatelliteParametersWithId} from '../../types/satellite'; import {assertConfigAndLoadSatelliteContext} from '../../utils/satellite.utils'; import {assertSatelliteMemorySize} from './deploy.assert.services'; import {listAssets} from './deploy.list.services'; -export interface DeployFnParams { - deploy: DeployParams; +export interface DeployFnParams { + deploy: DeployParams; satellite: SatelliteParametersWithId; } -export const executeDeploy = async ({ +export type UploadFileFnParams = UploadFileStorage & {satellite: SatelliteParametersWithId}; +export type UploadFileFnParamsWithProposal = UploadFileFnParams & {proposalId: bigint}; + +export const executeDeployWithProposal = async ({ + args, + deployFn, + uploadFileFn +}: { + args?: string[]; + deployFn: (params: DeployFnParams) => Promise; + uploadFileFn: (params: UploadFileFnParamsWithProposal) => Promise; +}): Promise => { + return await executeDeploy({ + args, + deployFn, + uploadFileFn + }); +}; + +export const executeDeployImmediate = async ({ + args, + deployFn, + uploadFileFn +}: { + args?: string[]; + deployFn: (params: DeployFnParams) => Promise; + uploadFileFn: (params: UploadFileFnParams) => Promise; +}): Promise => { + return await executeDeploy({ + args, + deployFn, + uploadFileFn + }); +}; + +const executeDeploy = async < + P extends UploadFileStorage, + R extends DeployResult | DeployResultWithProposal +>({ args, - deployFn + deployFn, + uploadFileFn }: { args?: string[]; - deployFn: (params: DeployFnParams) => Promise; -}): Promise => { + deployFn: (params: DeployFnParams<(params: P) => Promise>) => Promise; + uploadFileFn: (params: P & {satellite: SatelliteParametersWithId}) => Promise; +}): Promise => { const assertMemory = async () => { await assertSatelliteMemorySize(args); }; @@ -37,24 +80,13 @@ export const executeDeploy = async ({ satellite }); - const uploadFile = async ({ - filename, - fullPath, - data, - collection, - headers, - encoding - }: UploadFileStorage) => { - await uploadBlob({ - satellite, - filename, - fullPath, - // @ts-expect-error type incompatibility NodeJS vs bundle - data, - collection, - headers, - encoding - }); + const uploadFile = async (params: P) => { + const paramsWithSatellite: P & {satellite: SatelliteParametersWithId} = { + ...params, + satellite + }; + + await uploadFileFn(paramsWithSatellite); }; await cliPreDeploy({config: satelliteConfig});