Skip to content

Commit

Permalink
chore: remove axios dependency from CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
benmccann committed Feb 3, 2024
1 parent 329659b commit 349bc4e
Show file tree
Hide file tree
Showing 218 changed files with 22,789 additions and 122 deletions.
67 changes: 8 additions & 59 deletions cli/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
],
"dependencies": {
"@immich/sdk": "file:../open-api/typescript-sdk",
"axios": "^1.6.7",
"byte-size": "^8.1.1",
"cli-progress": "^3.12.0",
"commander": "^11.0.0",
Expand Down
6 changes: 3 additions & 3 deletions cli/src/commands/server-info.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { BaseCommand } from './base-command';
export class ServerInfoCommand extends BaseCommand {
public async run() {
await this.connect();
const { data: versionInfo } = await this.immichApi.serverInfoApi.getServerVersion();
const { data: mediaTypes } = await this.immichApi.serverInfoApi.getSupportedMediaTypes();
const { data: statistics } = await this.immichApi.assetApi.getAssetStatistics();
const versionInfo = await this.immichApi.serverInfoApi.getServerVersion();
const mediaTypes = await this.immichApi.serverInfoApi.getSupportedMediaTypes();
const statistics = await this.immichApi.assetApi.getAssetStatistics();

console.log(`Server Version: ${versionInfo.major}.${versionInfo.minor}.${versionInfo.patch}`);
console.log(`Image Types: ${mediaTypes.image.map((extension) => extension.replace('.', ''))}`);
Expand Down
39 changes: 19 additions & 20 deletions cli/src/commands/upload.command.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
import byteSize from 'byte-size';
import cliProgress from 'cli-progress';
import fs, { createReadStream } from 'node:fs';
Expand Down Expand Up @@ -114,7 +113,7 @@ export class UploadCommand extends BaseCommand {
await this.connect();

const formatResponse = await this.immichApi.serverInfoApi.getSupportedMediaTypes();
const crawlService = new CrawlService(formatResponse.data.image, formatResponse.data.video);
const crawlService = new CrawlService(formatResponse.image, formatResponse.video);

const inputFiles: string[] = [];
for (const pathArgument of paths) {
Expand Down Expand Up @@ -163,7 +162,7 @@ export class UploadCommand extends BaseCommand {
}
}

const { data: existingAlbums } = await this.immichApi.albumApi.getAllAlbums();
const existingAlbums = await this.immichApi.albumApi.getAllAlbums();

uploadProgress.start(totalSize, 0);
uploadProgress.update({ value_formatted: 0, total_formatted: byteSize(totalSize) });
Expand All @@ -186,11 +185,11 @@ export class UploadCommand extends BaseCommand {
assetBulkUploadCheckDto,
});

skipUpload = checkResponse.data.results[0].action === 'reject';
skipUpload = checkResponse.results[0].action === 'reject';

const isDuplicate = checkResponse.data.results[0].reason === 'duplicate';
const isDuplicate = checkResponse.results[0].reason === 'duplicate';
if (isDuplicate) {
existingAssetId = checkResponse.data.results[0].assetId;
existingAssetId = checkResponse.results[0].assetId;
}

skipAsset = skipUpload && !isDuplicate;
Expand All @@ -199,19 +198,20 @@ export class UploadCommand extends BaseCommand {
if (!skipAsset && !options.dryRun) {
if (!skipUpload) {
const formData = await asset.getUploadFormData();
const { data } = await this.uploadAsset(formData);
existingAssetId = data.id;
const response = await this.uploadAsset(formData);
const json = await response.json();
existingAssetId = json.id;
uploadCounter++;
totalSizeUploaded += asset.fileSize;
}

if ((options.album || options.albumName) && asset.albumName !== undefined) {
let album = existingAlbums.find((album) => album.albumName === asset.albumName);
if (!album) {
const { data } = await this.immichApi.albumApi.createAlbum({
const response = await this.immichApi.albumApi.createAlbum({
createAlbumDto: { albumName: asset.albumName },
});
album = data;
album = response;
existingAlbums.push(album);
}

Expand Down Expand Up @@ -259,21 +259,20 @@ export class UploadCommand extends BaseCommand {
}
}

private async uploadAsset(data: FormData): Promise<AxiosResponse> {
private async uploadAsset(data: FormData): Promise<Response> {
const url = this.immichApi.instanceUrl + '/asset/upload';

const config: AxiosRequestConfig = {
const response = await fetch(url, {
method: 'post',
maxRedirects: 0,
url,
redirect: 'error',
headers: {
'x-api-key': this.immichApi.apiKey,
},
maxContentLength: Number.POSITIVE_INFINITY,
maxBodyLength: Number.POSITIVE_INFINITY,
data,
};

return axios(config);
body: data,
});
if (response.status !== 200 && response.status !== 201) {
throw new Error(await response.text());
}
return response;
}
}
13 changes: 6 additions & 7 deletions cli/src/services/api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
SystemConfigApi,
UserApi,
} from '@immich/sdk';
import FormData from 'form-data';

export class ImmichApi {
public userApi: UserApi;
Expand All @@ -31,12 +30,9 @@ export class ImmichApi {
) {
this.config = new Configuration({
basePath: instanceUrl,
baseOptions: {
headers: {
'x-api-key': apiKey,
},
headers: {
'x-api-key': apiKey,
},
formDataCtor: FormData,
});

this.userApi = new UserApi(this.config);
Expand All @@ -52,6 +48,9 @@ export class ImmichApi {

setApiKey(apiKey: string) {
this.apiKey = apiKey;
this.config.baseOptions.headers['x-api-key'] = apiKey;
if (!this.config.headers) {
throw new Error('missing headers');
}
this.config.headers['x-api-key'] = apiKey;
}
}
4 changes: 2 additions & 2 deletions cli/src/services/session.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import {
spyOnConsole,
} from '../../test/cli-test-utils';

const mockPingServer = vi.fn(() => Promise.resolve({ data: { res: 'pong' } }));
const mockUserInfo = vi.fn(() => Promise.resolve({ data: { email: 'admin@example.com' } }));
const mockPingServer = vi.fn(() => Promise.resolve({ res: 'pong' }));
const mockUserInfo = vi.fn(() => Promise.resolve({ email: 'admin@example.com' }));

vi.mock('@immich/sdk', async () => ({
...(await vi.importActual('@immich/sdk')),
Expand Down
4 changes: 2 additions & 2 deletions cli/src/services/session.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class SessionService {

const api = new ImmichApi(instanceUrl, apiKey);

const { data: pingResponse } = await api.serverInfoApi.pingServer().catch((error) => {
const pingResponse = await api.serverInfoApi.pingServer().catch((error) => {
throw new Error(`Failed to connect to server ${api.instanceUrl}: ${error.message}`);
});

Expand All @@ -68,7 +68,7 @@ export class SessionService {
const api = new ImmichApi(instanceUrl, apiKey);

// Check if server and api key are valid
const { data: userInfo } = await api.userApi.getMyUserInfo().catch((error) => {
const userInfo = await api.userApi.getMyUserInfo().catch((error) => {
throw new LoginError(`Failed to connect to server ${instanceUrl}: ${error.message}`);
});

Expand Down
4 changes: 2 additions & 2 deletions cli/test/cli-test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ export const setup = async () => {
await api.authenticationApi.signUpAdmin({
signUpDto: { email: 'cli@immich.app', password: 'password', name: 'Administrator' },
});
const { data: admin } = await api.authenticationApi.login({
const admin = await api.authenticationApi.login({
loginCredentialDto: { email: 'cli@immich.app', password: 'password' },
});
const { data: apiKey } = await api.keyApi.createApiKey(
const apiKey = await api.keyApi.createApiKey(
{ aPIKeyCreateDto: { name: 'CLI Test' } },
{ headers: { Authorization: `Bearer ${admin.accessToken}` } },
);
Expand Down
2 changes: 1 addition & 1 deletion cli/test/e2e/login-key.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe(`login-key (e2e)`, () => {

it('should error when providing an invalid API key', async () => {
await expect(new LoginCommand(CLI_BASE_OPTIONS).run(instanceUrl, 'invalid')).rejects.toThrow(
`Failed to connect to server ${instanceUrl}: Request failed with status code 401`,
`Failed to connect to server ${instanceUrl}: Response returned an error code`,
);
});

Expand Down
10 changes: 5 additions & 5 deletions cli/test/e2e/upload.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ describe(`upload (e2e)`, () => {

it('should upload a folder recursively', async () => {
await new UploadCommand(CLI_BASE_OPTIONS).run([`${IMMICH_TEST_ASSET_PATH}/albums/nature/`], { recursive: true });
const { data: assets } = await api.assetApi.getAllAssets({}, { headers: { 'x-api-key': api.apiKey } });
const assets = await api.assetApi.getAllAssets({}, { headers: { 'x-api-key': api.apiKey } });
expect(assets.length).toBeGreaterThan(4);
});

it('should not create a new album', async () => {
await new UploadCommand(CLI_BASE_OPTIONS).run([`${IMMICH_TEST_ASSET_PATH}/albums/nature/`], { recursive: true });
const { data: albums } = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } });
const albums = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } });
expect(albums.length).toEqual(0);
});

Expand All @@ -42,7 +42,7 @@ describe(`upload (e2e)`, () => {
album: true,
});

const { data: albums } = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } });
const albums = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } });
expect(albums.length).toEqual(1);
const natureAlbum = albums[0];
expect(natureAlbum.albumName).toEqual('nature');
Expand All @@ -59,7 +59,7 @@ describe(`upload (e2e)`, () => {
album: true,
});

const { data: albums } = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } });
const albums = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } });
expect(albums.length).toEqual(1);
const natureAlbum = albums[0];
expect(natureAlbum.albumName).toEqual('nature');
Expand All @@ -71,7 +71,7 @@ describe(`upload (e2e)`, () => {
albumName: 'testAlbum',
});

const { data: albums } = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } });
const albums = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } });
expect(albums.length).toEqual(1);
const testAlbum = albums[0];
expect(testAlbum.albumName).toEqual('testAlbum');
Expand Down
3 changes: 2 additions & 1 deletion open-api/bin/generate-open-api.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ function dart {

function typescript {
rm -rf ./typescript-sdk/client
npx --yes @openapitools/openapi-generator-cli generate -g typescript-axios -i ./immich-openapi-specs.json -o ./typescript-sdk/client --additional-properties=useSingleRequestParameter=true
npx --yes @openapitools/openapi-generator-cli generate -g typescript-axios -i ./immich-openapi-specs.json -o ./typescript-sdk/axios-client --additional-properties=useSingleRequestParameter=true,supportsES6=true
npx --yes @openapitools/openapi-generator-cli generate -g typescript-fetch -i ./immich-openapi-specs.json -o ./typescript-sdk/fetch-client --additional-properties=useSingleRequestParameter=true,supportsES6=true
npm --prefix typescript-sdk ci && npm --prefix typescript-sdk run build
}

Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
.gitignore
.npmignore
.openapi-generator-ignore
api.ts
base.ts
common.ts
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 4 additions & 0 deletions open-api/typescript-sdk/axios.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './axios-client';
export * as base from './axios-client/base';
export * as configuration from './axios-client/configuration';
export * as common from './axios-client/common';

0 comments on commit 349bc4e

Please sign in to comment.