Skip to content
This repository was archived by the owner on Jan 19, 2026. It is now read-only.

Commit 6f86bd8

Browse files
committed
Merge remote-tracking branch 'origin/next' into bugfix/211-alt
2 parents c7ec9a5 + f360f6b commit 6f86bd8

31 files changed

Lines changed: 339 additions & 153 deletions

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<a href="https://npmjs.com/package/storyblok" rel="nofollow">
1515
<img src="https://img.shields.io/npm/dt/storyblok.svg?style=appveyor&color=8d60ff" alt="npm">
1616
</a>
17-
<a href="https://discord.gg/jKrbAMz">
17+
<a href="https://storyblok.com/join-discord">
1818
<img src="https://img.shields.io/discord/700316478792138842?label=Join%20Our%20Discord%20Community&style=appveyor&logo=discord&color=8d60ff">
1919
</a>
2020
<a href="https://twitter.com/intent/follow?screen_name=storyblok">
@@ -103,7 +103,7 @@ For help, discussion about best practices, or any other conversation that would
103103

104104
For community support, chatting with other users, please visit:
105105

106-
- [Discuss Storyblok on Discord](https://discord.gg/jKrbAMz)
106+
- [Discuss Storyblok on Discord](https://storyblok.com/join-discord)
107107

108108
## Support
109109

@@ -118,7 +118,7 @@ We understand that you might not be able to share your company's project code. P
118118

119119
### I only have a question
120120

121-
If you have a question, please ask in the [Discuss Storyblok on Discord](https://discord.gg/jKrbAMz) channel.
121+
If you have a question, please ask in the [Discuss Storyblok on Discord](https://storyblok.com/join-discord) channel.
122122

123123
## Contributing
124124

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "storyblok",
33
"type": "module",
4-
"version": "4.0.0-beta.4",
4+
"version": "4.0.0-beta.5",
55
"packageManager": "pnpm@10.10.0",
66
"description": "Storyblok CLI",
77
"author": "Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/)",
@@ -25,6 +25,7 @@
2525
],
2626
"scripts": {
2727
"build": "unbuild",
28+
"typecheck": "tsc --noEmit",
2829
"release": "release-it",
2930
"dev": "pnpm run build && node dist/index.mjs",
3031
"lint": "eslint .",

src/commands/components/pull/index.test.ts

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,7 @@ vi.mock('../../../session', () => {
3838
};
3939
});
4040

41-
vi.mock('../../../utils', async () => {
42-
const actualUtils = await vi.importActual('../../../utils');
43-
return {
44-
...actualUtils,
45-
isVitestRunning: true,
46-
konsola: {
47-
ok: vi.fn(),
48-
title: vi.fn(),
49-
warn: vi.fn(),
50-
error: vi.fn(),
51-
br: vi.fn(),
52-
},
53-
handleError: (error: unknown, header = false) => {
54-
konsola.error(error as string, header);
55-
// Optionally, prevent process.exit during tests
56-
},
57-
};
58-
});
41+
vi.mock('../../../utils/konsola');
5942

6043
describe('pull', () => {
6144
beforeEach(() => {
@@ -157,9 +140,10 @@ describe('pull', () => {
157140
session().state = {
158141
isLoggedIn: false,
159142
};
160-
const mockError = new CommandError(`You are currently not logged in. Please login first to get your user info.`);
161143
await componentsCommand.parseAsync(['node', 'test', 'pull', '--space', '12345']);
162-
expect(konsola.error).toHaveBeenCalledWith(mockError, false);
144+
expect(konsola.error).toHaveBeenCalledWith('You are currently not logged in. Please run storyblok login to authenticate, or storyblok signup to sign up.', null, {
145+
header: true,
146+
});
163147
});
164148

165149
it('should throw an error if the space is not provided', async () => {
@@ -172,7 +156,9 @@ describe('pull', () => {
172156
const mockError = new CommandError(`Please provide the space as argument --space YOUR_SPACE_ID.`);
173157

174158
await componentsCommand.parseAsync(['node', 'test', 'pull']);
175-
expect(konsola.error).toHaveBeenCalledWith(mockError, false);
159+
expect(konsola.error).toHaveBeenCalledWith(mockError.message, null, {
160+
header: true,
161+
});
176162
});
177163
});
178164

src/commands/components/pull/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { PullComponentsOptions } from './constants';
22

33
import { Spinner } from '@topcli/spinner';
44
import { colorPalette, commands } from '../../../constants';
5-
import { CommandError, handleError, isVitest, konsola } from '../../../utils';
5+
import { CommandError, handleError, isVitest, konsola, requireAuthentication } from '../../../utils';
66
import { session } from '../../../session';
77
import { fetchComponent, fetchComponentGroups, fetchComponentInternalTags, fetchComponentPresets, fetchComponents, saveComponentsToFiles } from '../actions';
88
import { componentsCommand } from '../command';
@@ -30,8 +30,7 @@ componentsCommand
3030
const { state, initializeSession } = session();
3131
await initializeSession();
3232

33-
if (!state.isLoggedIn || !state.password || !state.region) {
34-
handleError(new CommandError(`You are currently not logged in. Please login first to get your user info.`), verbose);
33+
if (!requireAuthentication(state, verbose)) {
3534
return;
3635
}
3736
if (!space) {

src/commands/components/push/actions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export const updateComponentGroup = async (space: string, groupId: number, compo
8585
body: JSON.stringify(componentGroup),
8686
});
8787
return data.component_group;
88+
return data.component_group;
8889
}
8990
catch (error) {
9091
handleAPIError('update_component_group', error as Error, `Failed to update component group ${componentGroup.name}`);

src/commands/components/push/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { PushComponentsOptions } from './constants';
22

33
import { colorPalette, commands } from '../../../constants';
44
import { getProgram } from '../../../program';
5-
import { CommandError, handleError, konsola } from '../../../utils';
5+
import { CommandError, handleError, konsola, requireAuthentication } from '../../../utils';
66
import { session } from '../../../session';
77
import { readComponentsFiles } from './actions';
88
import { componentsCommand } from '../command';
@@ -35,8 +35,7 @@ componentsCommand
3535
const { state, initializeSession } = session();
3636
await initializeSession();
3737

38-
if (!state.isLoggedIn || !state.password || !state.region) {
39-
handleError(new CommandError(`You are currently not logged in. Please login first to get your user info.`), verbose);
38+
if (!requireAuthentication(state, verbose)) {
4039
return;
4140
}
4241

src/commands/languages/index.test.ts

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,23 +39,7 @@ vi.mock('../../session', () => {
3939
};
4040
});
4141

42-
vi.mock('../../utils', async () => {
43-
const actualUtils = await vi.importActual('../../utils');
44-
return {
45-
...actualUtils,
46-
konsola: {
47-
ok: vi.fn(),
48-
title: vi.fn(),
49-
warn: vi.fn(),
50-
error: vi.fn(),
51-
br: vi.fn(),
52-
},
53-
handleError: (error: Error, header = false) => {
54-
konsola.error(error, header);
55-
// Optionally, prevent process.exit during tests
56-
},
57-
};
58-
});
42+
vi.mock('../../utils/konsola');
5943

6044
describe('languagesCommand', () => {
6145
describe('pull', () => {
@@ -102,9 +86,11 @@ describe('languagesCommand', () => {
10286
session().state = {
10387
isLoggedIn: false,
10488
};
105-
const mockError = new CommandError(`You are currently not logged in. Please login first to get your user info.`);
89+
const mockError = new CommandError(`You are currently not logged in. Please run storyblok login to authenticate, or storyblok signup to sign up.`);
10690
await languagesCommand.parseAsync(['node', 'test', 'pull', '--space', '12345']);
107-
expect(konsola.error).toHaveBeenCalledWith(mockError, false);
91+
expect(konsola.error).toHaveBeenCalledWith(mockError.message, null, {
92+
header: true,
93+
});
10894
});
10995

11096
it('should throw an error if the space is not provided', async () => {
@@ -121,7 +107,9 @@ describe('languagesCommand', () => {
121107
catch (error) {
122108
console.log('TEST languages', error);
123109
}
124-
expect(konsola.error).toHaveBeenCalledWith(mockError, false);
110+
expect(konsola.error).toHaveBeenCalledWith(mockError.message, null, {
111+
header: true,
112+
});
125113
});
126114

127115
it('should prompt a warning the user if no languages are found', async () => {

src/commands/languages/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { colorPalette, commands } from '../../constants';
2-
import { CommandError, handleError, isVitest, konsola } from '../../utils';
2+
import { CommandError, handleError, isVitest, konsola, requireAuthentication } from '../../utils';
33
import { getProgram } from '../../program';
44
import { session } from '../../session';
55
import { fetchLanguages, saveLanguagesToFile } from './actions';
@@ -34,22 +34,23 @@ languagesCommand
3434
const { state, initializeSession } = session();
3535
await initializeSession();
3636

37-
if (!state.isLoggedIn || !state.password || !state.region) {
38-
handleError(new CommandError(`You are currently not logged in. Please login first to get your user info.`), verbose);
37+
if (!requireAuthentication(state, verbose)) {
3938
return;
4039
}
4140
if (!space) {
4241
handleError(new CommandError(`Please provide the space as argument --space YOUR_SPACE_ID.`), verbose);
4342
return;
4443
}
4544

45+
const { password, region } = state;
46+
4647
const spinner = new Spinner({
4748
verbose: !isVitest,
4849
});
4950
try {
5051
spinner.start(`Fetching ${chalk.hex(colorPalette.LANGUAGES)('languages')}`);
5152

52-
const internationalization = await fetchLanguages(space, state.password, state.region);
53+
const internationalization = await fetchLanguages(space, password, region);
5354

5455
if (!internationalization || internationalization.languages?.length === 0) {
5556
spinner.failed();

src/commands/login/actions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const loginWithToken = async (token: string, region: RegionCode) => {
2828
throw new APIError('network_error', 'login_with_token', error);
2929
}
3030
}
31-
throw new APIError('generic', 'login_with_token', error, 'The provided credentials are invalid');
31+
throw new APIError('generic', 'login_with_token', error as FetchError, 'The provided credentials are invalid');
3232
}
3333
};
3434

src/commands/migrations/generate/index.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import chalk from 'chalk';
44
import type { MigrationsGenerateOptions } from './constants';
55
import { colorPalette, commands } from '../../../constants';
66
import { getProgram } from '../../../program';
7-
import { CommandError, handleError, isVitest, konsola } from '../../../utils';
7+
import { CommandError, handleError, isVitest, konsola, requireAuthentication } from '../../../utils';
88
import { session } from '../../../session';
99
import { fetchComponent } from '../../../commands/components';
1010
import { migrationsCommand } from '../command';
1111
import { generateMigration } from './actions';
12+
import { mapiClient } from '../../../api';
1213

1314
const program = getProgram();
1415

@@ -34,8 +35,7 @@ migrationsCommand
3435
const { state, initializeSession } = session();
3536
await initializeSession();
3637

37-
if (!state.isLoggedIn || !state.password || !state.region) {
38-
handleError(new CommandError(`You are currently not logged in. Please login first to get your user info.`), verbose);
38+
if (!requireAuthentication(state, verbose)) {
3939
return;
4040
}
4141
if (!space) {
@@ -45,11 +45,16 @@ migrationsCommand
4545

4646
const { password, region } = state;
4747

48+
mapiClient({
49+
token: password,
50+
region,
51+
});
52+
4853
const spinner = new Spinner({
4954
verbose: !isVitest,
5055
}).start(`Generating migration for component ${componentName}...`);
5156
try {
52-
const component = await fetchComponent(space, componentName, password, region);
57+
const component = await fetchComponent(space, componentName);
5358

5459
if (!component) {
5560
spinner.failed(`Failed to fetch component ${componentName}. Make sure the component exists in your space.`);

0 commit comments

Comments
 (0)