storyblok 4.3.3 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +109 -37
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -62,6 +62,13 @@ const regionsDomain = {
|
|
|
62
62
|
ca: "api-ca.storyblok.com",
|
|
63
63
|
ap: "api-ap.storyblok.com"
|
|
64
64
|
};
|
|
65
|
+
const managementApiRegions = {
|
|
66
|
+
eu: "mapi.storyblok.com",
|
|
67
|
+
us: "api-us.storyblok.com",
|
|
68
|
+
cn: "app.storyblokchina.cn",
|
|
69
|
+
ca: "api-ca.storyblok.com",
|
|
70
|
+
ap: "api-ap.storyblok.com"
|
|
71
|
+
};
|
|
65
72
|
const appDomains = {
|
|
66
73
|
eu: "app.storyblok.com",
|
|
67
74
|
us: "app-us.storyblok.com",
|
|
@@ -532,7 +539,7 @@ function getProgram() {
|
|
|
532
539
|
|
|
533
540
|
const API_VERSION = "v1";
|
|
534
541
|
const getStoryblokUrl = (region = "eu") => {
|
|
535
|
-
return `https://${
|
|
542
|
+
return `https://${managementApiRegions[region]}/${API_VERSION}`;
|
|
536
543
|
};
|
|
537
544
|
|
|
538
545
|
const loginWithToken = async (token, region) => {
|
|
@@ -723,7 +730,7 @@ function createSession() {
|
|
|
723
730
|
async function persistCredentials(region) {
|
|
724
731
|
if (state.isLoggedIn && state.login && state.password && state.region) {
|
|
725
732
|
await addCredentials({
|
|
726
|
-
machineName: regionsDomain[region] || "
|
|
733
|
+
machineName: regionsDomain[region] || "mapi.storyblok.com",
|
|
727
734
|
login: state.login,
|
|
728
735
|
password: state.password,
|
|
729
736
|
region: state.region
|
|
@@ -1003,6 +1010,7 @@ const getUser = async (token, region) => {
|
|
|
1003
1010
|
const program$f = getProgram();
|
|
1004
1011
|
program$f.command(commands.USER).description("Get the current user").action(async () => {
|
|
1005
1012
|
konsola.title(`${commands.USER}`, colorPalette.USER);
|
|
1013
|
+
const verbose = program$f.opts().verbose;
|
|
1006
1014
|
const { state, initializeSession } = session();
|
|
1007
1015
|
await initializeSession();
|
|
1008
1016
|
if (!requireAuthentication(state)) {
|
|
@@ -1018,6 +1026,9 @@ program$f.command(commands.USER).description("Get the current user").action(asyn
|
|
|
1018
1026
|
}
|
|
1019
1027
|
const { user } = await getUser(password, region);
|
|
1020
1028
|
spinner.succeed();
|
|
1029
|
+
if (verbose) {
|
|
1030
|
+
konsola.info(JSON.stringify(user, null, 2));
|
|
1031
|
+
}
|
|
1021
1032
|
konsola.ok(`Hi ${chalk.bold(user.friendly_name)}, you are currently logged in with ${chalk.hex(colorPalette.PRIMARY)(user.email)} on ${chalk.bold(region)} region`, true);
|
|
1022
1033
|
} catch (error) {
|
|
1023
1034
|
spinner.failed();
|
|
@@ -2838,18 +2849,21 @@ const fetchStories = async (space, params) => {
|
|
|
2838
2849
|
const allStories = [];
|
|
2839
2850
|
let currentPage = 1;
|
|
2840
2851
|
let hasMorePages = true;
|
|
2852
|
+
const perPage = 100;
|
|
2841
2853
|
while (hasMorePages) {
|
|
2842
2854
|
const { filter_query, ...restParams } = params || {};
|
|
2843
2855
|
const regularParams = new URLSearchParams({
|
|
2844
|
-
...objectToStringParams({ ...restParams, per_page:
|
|
2856
|
+
...objectToStringParams({ ...restParams, per_page: perPage }),
|
|
2845
2857
|
...currentPage > 1 && { page: currentPage.toString() }
|
|
2846
2858
|
}).toString();
|
|
2847
2859
|
const queryString = filter_query ? `${regularParams ? `${regularParams}&` : ""}${filter_query}` : regularParams;
|
|
2848
2860
|
const endpoint = `spaces/${space}/stories${queryString ? `?${queryString}` : ""}`;
|
|
2849
2861
|
const { data } = await client.get(endpoint, {});
|
|
2850
2862
|
allStories.push(...data.stories);
|
|
2851
|
-
|
|
2852
|
-
|
|
2863
|
+
hasMorePages = data.stories.length === perPage && data.stories.length > 0;
|
|
2864
|
+
if (data.stories.length < perPage) {
|
|
2865
|
+
break;
|
|
2866
|
+
}
|
|
2853
2867
|
currentPage++;
|
|
2854
2868
|
}
|
|
2855
2869
|
return allStories;
|
|
@@ -4668,7 +4682,12 @@ STORYBLOK_DELIVERY_API_TOKEN=${accessToken}
|
|
|
4668
4682
|
};
|
|
4669
4683
|
const generateSpaceUrl = (spaceId, region) => {
|
|
4670
4684
|
const domain = appDomains[region];
|
|
4671
|
-
|
|
4685
|
+
const utmParams = new URLSearchParams({
|
|
4686
|
+
utm_source: "storyblok-cli",
|
|
4687
|
+
utm_medium: "cli",
|
|
4688
|
+
utm_campaign: "create"
|
|
4689
|
+
});
|
|
4690
|
+
return `https://${domain}/#/me/spaces/${spaceId}/dashboard?${utmParams.toString()}`;
|
|
4672
4691
|
};
|
|
4673
4692
|
const openSpaceInBrowser = async (spaceId, region) => {
|
|
4674
4693
|
try {
|
|
@@ -4688,7 +4707,7 @@ const extractPortFromTopics = (topics) => {
|
|
|
4688
4707
|
}
|
|
4689
4708
|
return "3000";
|
|
4690
4709
|
};
|
|
4691
|
-
const
|
|
4710
|
+
const repositoryToTemplate = (repo) => {
|
|
4692
4711
|
const technology = repo.name.replace("blueprint-core-", "");
|
|
4693
4712
|
const port = extractPortFromTopics(repo.topics || []);
|
|
4694
4713
|
return {
|
|
@@ -4709,7 +4728,7 @@ const fetchBlueprintRepositories = async () => {
|
|
|
4709
4728
|
order: "desc",
|
|
4710
4729
|
per_page: 100
|
|
4711
4730
|
});
|
|
4712
|
-
const blueprints = data.items.filter((repo) => repo.name.startsWith("blueprint-core-")).map(
|
|
4731
|
+
const blueprints = data.items.filter((repo) => repo.name.startsWith("blueprint-core-")).map(repositoryToTemplate).sort((a, b) => a.name.localeCompare(b.name));
|
|
4713
4732
|
return blueprints;
|
|
4714
4733
|
} catch (error) {
|
|
4715
4734
|
handleAPIError("fetch_blueprints", error, "Failed to fetch blueprints from GitHub");
|
|
@@ -4729,10 +4748,17 @@ const createSpace = async (space) => {
|
|
|
4729
4748
|
};
|
|
4730
4749
|
|
|
4731
4750
|
const program$1 = getProgram();
|
|
4732
|
-
program$1.command(`${commands.CREATE} [project-path]`).alias("c").description(`Scaffold a new project using Storyblok`).option("-
|
|
4751
|
+
program$1.command(`${commands.CREATE} [project-path]`).alias("c").description(`Scaffold a new project using Storyblok`).option("-t, --template <template>", "technology starter template").option("-b, --blueprint <blueprint>", "[DEPRECATED] use --template instead").option("--skip-space", "skip space creation").action(async (projectPath, options) => {
|
|
4733
4752
|
konsola.title(`${commands.CREATE}`, colorPalette.CREATE);
|
|
4734
4753
|
const verbose = program$1.opts().verbose;
|
|
4735
|
-
const { blueprint } = options;
|
|
4754
|
+
const { template, blueprint } = options;
|
|
4755
|
+
let selectedTemplate = template;
|
|
4756
|
+
if (blueprint && !template) {
|
|
4757
|
+
konsola.warn(`The --blueprint flag is deprecated. Please use --template instead.`);
|
|
4758
|
+
selectedTemplate = blueprint;
|
|
4759
|
+
} else if (blueprint && template) {
|
|
4760
|
+
konsola.warn(`Both --blueprint and --template provided. Using --template and ignoring --blueprint.`);
|
|
4761
|
+
}
|
|
4736
4762
|
const { state, initializeSession } = session();
|
|
4737
4763
|
await initializeSession();
|
|
4738
4764
|
if (!requireAuthentication(state, verbose)) {
|
|
@@ -4749,33 +4775,42 @@ program$1.command(`${commands.CREATE} [project-path]`).alias("c").description(`S
|
|
|
4749
4775
|
const spinnerSpace = new Spinner({
|
|
4750
4776
|
verbose: !isVitest
|
|
4751
4777
|
});
|
|
4778
|
+
let userData;
|
|
4752
4779
|
try {
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4780
|
+
const { user } = await getUser(password, region);
|
|
4781
|
+
userData = user;
|
|
4782
|
+
} catch (error) {
|
|
4783
|
+
konsola.error("Failed to fetch user info. Please login again.", error);
|
|
4784
|
+
konsola.br();
|
|
4785
|
+
return;
|
|
4786
|
+
}
|
|
4787
|
+
try {
|
|
4788
|
+
spinnerBlueprints.start("Fetching starter templates...");
|
|
4789
|
+
const templates = await fetchBlueprintRepositories();
|
|
4790
|
+
spinnerBlueprints.succeed("Starter templates fetched successfully");
|
|
4791
|
+
if (!templates) {
|
|
4757
4792
|
spinnerBlueprints.failed();
|
|
4758
|
-
konsola.warn("No starter
|
|
4793
|
+
konsola.warn("No starter templates found. Please contact support@storyblok.com");
|
|
4759
4794
|
konsola.br();
|
|
4760
4795
|
return;
|
|
4761
4796
|
}
|
|
4762
|
-
let
|
|
4763
|
-
if (
|
|
4764
|
-
const
|
|
4765
|
-
const
|
|
4766
|
-
if (!
|
|
4767
|
-
const validOptions =
|
|
4768
|
-
konsola.warn(`Invalid
|
|
4797
|
+
let technologyTemplate = selectedTemplate;
|
|
4798
|
+
if (selectedTemplate) {
|
|
4799
|
+
const validTemplates = templates;
|
|
4800
|
+
const isValidTemplate = validTemplates.find((bp) => bp.value === selectedTemplate);
|
|
4801
|
+
if (!isValidTemplate) {
|
|
4802
|
+
const validOptions = validTemplates.map((bp) => bp.value).join(", ");
|
|
4803
|
+
konsola.warn(`Invalid template "${chalk.hex(colorPalette.CREATE)(selectedTemplate)}". Valid options are: ${chalk.hex(colorPalette.CREATE)(validOptions)}`);
|
|
4769
4804
|
konsola.br();
|
|
4770
|
-
|
|
4805
|
+
technologyTemplate = void 0;
|
|
4771
4806
|
}
|
|
4772
4807
|
}
|
|
4773
|
-
if (!
|
|
4774
|
-
|
|
4808
|
+
if (!technologyTemplate) {
|
|
4809
|
+
technologyTemplate = await select({
|
|
4775
4810
|
message: "Please select the technology you would like to use:",
|
|
4776
|
-
choices:
|
|
4777
|
-
name:
|
|
4778
|
-
value:
|
|
4811
|
+
choices: templates.map((template2) => ({
|
|
4812
|
+
name: template2.name,
|
|
4813
|
+
value: template2.value
|
|
4779
4814
|
}))
|
|
4780
4815
|
});
|
|
4781
4816
|
}
|
|
@@ -4783,7 +4818,7 @@ program$1.command(`${commands.CREATE} [project-path]`).alias("c").description(`S
|
|
|
4783
4818
|
if (!projectPath) {
|
|
4784
4819
|
finalProjectPath = await input({
|
|
4785
4820
|
message: "What is the path for your project?",
|
|
4786
|
-
default: `./my-${
|
|
4821
|
+
default: `./my-${technologyTemplate}-project`,
|
|
4787
4822
|
validate: (value) => {
|
|
4788
4823
|
if (!value.trim()) {
|
|
4789
4824
|
return "Project path is required";
|
|
@@ -4800,19 +4835,50 @@ program$1.command(`${commands.CREATE} [project-path]`).alias("c").description(`S
|
|
|
4800
4835
|
const targetDirectory = path.dirname(resolvedPath);
|
|
4801
4836
|
const projectName = path.basename(resolvedPath);
|
|
4802
4837
|
konsola.br();
|
|
4803
|
-
konsola.info(`Scaffolding your project using the ${chalk.hex(colorPalette.CREATE)(
|
|
4804
|
-
await generateProject(
|
|
4838
|
+
konsola.info(`Scaffolding your project using the ${chalk.hex(colorPalette.CREATE)(technologyTemplate)} template...`);
|
|
4839
|
+
await generateProject(technologyTemplate, projectName, targetDirectory);
|
|
4805
4840
|
konsola.ok(`Project ${chalk.hex(colorPalette.PRIMARY)(projectName)} created successfully in ${chalk.hex(colorPalette.PRIMARY)(finalProjectPath)}`, true);
|
|
4806
4841
|
let createdSpace;
|
|
4842
|
+
const choices = [
|
|
4843
|
+
{ name: "My personal account", value: "personal" }
|
|
4844
|
+
];
|
|
4845
|
+
if (userData.has_org) {
|
|
4846
|
+
choices.push({ name: `Organization (${userData.org.name})`, value: "org" });
|
|
4847
|
+
}
|
|
4848
|
+
if (userData.has_partner) {
|
|
4849
|
+
choices.push({ name: "Partner Portal", value: "partner" });
|
|
4850
|
+
}
|
|
4851
|
+
let whereToCreateSpace = "personal";
|
|
4852
|
+
if (region === "eu" && (userData.has_partner || userData.has_org)) {
|
|
4853
|
+
whereToCreateSpace = await select({
|
|
4854
|
+
message: `Where would you like to create this space?`,
|
|
4855
|
+
choices
|
|
4856
|
+
});
|
|
4857
|
+
}
|
|
4858
|
+
if (region !== "eu" && userData.has_org) {
|
|
4859
|
+
whereToCreateSpace = "org";
|
|
4860
|
+
}
|
|
4861
|
+
if (region !== "eu" && !userData.has_org) {
|
|
4862
|
+
konsola.warn(`Space creation in this region is limited to Enterprise accounts. If you're part of an organization, please ensure you have the required permissions. For more information about Enterprise access, contact our Sales Team.`);
|
|
4863
|
+
konsola.br();
|
|
4864
|
+
return;
|
|
4865
|
+
}
|
|
4807
4866
|
if (!options.skipSpace) {
|
|
4808
4867
|
try {
|
|
4809
4868
|
spinnerSpace.start(`Creating space "${toHumanReadable(projectName)}"`);
|
|
4810
|
-
const selectedBlueprint =
|
|
4869
|
+
const selectedBlueprint = templates.find((bp) => bp.value === technologyTemplate);
|
|
4811
4870
|
const blueprintDomain = selectedBlueprint?.location || "https://localhost:3000/";
|
|
4812
|
-
|
|
4871
|
+
const spaceToCreate = {
|
|
4813
4872
|
name: toHumanReadable(projectName),
|
|
4814
4873
|
domain: blueprintDomain
|
|
4815
|
-
}
|
|
4874
|
+
};
|
|
4875
|
+
if (whereToCreateSpace === "org") {
|
|
4876
|
+
spaceToCreate.org = userData.org;
|
|
4877
|
+
spaceToCreate.in_org = true;
|
|
4878
|
+
} else if (whereToCreateSpace === "partner") {
|
|
4879
|
+
spaceToCreate.assign_partner = true;
|
|
4880
|
+
}
|
|
4881
|
+
createdSpace = await createSpace(spaceToCreate);
|
|
4816
4882
|
spinnerSpace.succeed(`Space "${chalk.hex(colorPalette.PRIMARY)(toHumanReadable(projectName))}" created successfully`);
|
|
4817
4883
|
} catch (error) {
|
|
4818
4884
|
spinnerSpace.failed();
|
|
@@ -4841,9 +4907,15 @@ program$1.command(`${commands.CREATE} [project-path]`).alias("c").description(`S
|
|
|
4841
4907
|
}
|
|
4842
4908
|
}
|
|
4843
4909
|
konsola.br();
|
|
4844
|
-
konsola.ok(`Your ${chalk.hex(colorPalette.PRIMARY)(
|
|
4910
|
+
konsola.ok(`Your ${chalk.hex(colorPalette.PRIMARY)(technologyTemplate)} project is ready \u{1F389} !`);
|
|
4845
4911
|
if (createdSpace?.first_token) {
|
|
4846
|
-
|
|
4912
|
+
if (whereToCreateSpace === "org") {
|
|
4913
|
+
konsola.ok(`Storyblok space created in organization ${chalk.hex(colorPalette.PRIMARY)(userData.org.name)}, preview url and .env configured automatically. You can now open your space in the browser at ${chalk.hex(colorPalette.PRIMARY)(generateSpaceUrl(createdSpace.id, region))}`);
|
|
4914
|
+
} else if (whereToCreateSpace === "partner") {
|
|
4915
|
+
konsola.ok(`Storyblok space created in partner portal, preview url and .env configured automatically. You can now open your space in the browser at ${chalk.hex(colorPalette.PRIMARY)(generateSpaceUrl(createdSpace.id, region))}`);
|
|
4916
|
+
} else {
|
|
4917
|
+
konsola.ok(`Storyblok space created, preview url and .env configured automatically. You can now open your space in the browser at ${chalk.hex(colorPalette.PRIMARY)(generateSpaceUrl(createdSpace.id, region))}`);
|
|
4918
|
+
}
|
|
4847
4919
|
}
|
|
4848
4920
|
konsola.br();
|
|
4849
4921
|
konsola.info(`Next steps:
|
|
@@ -4860,7 +4932,7 @@ program$1.command(`${commands.CREATE} [project-path]`).alias("c").description(`S
|
|
|
4860
4932
|
konsola.br();
|
|
4861
4933
|
});
|
|
4862
4934
|
|
|
4863
|
-
const version = "4.
|
|
4935
|
+
const version = "4.4.0";
|
|
4864
4936
|
const pkg = {
|
|
4865
4937
|
version: version};
|
|
4866
4938
|
|