Skip to content

Commit c52ef1e

Browse files
authored
feat(website-builder): add Nuxt starter kit configuration (#5265)
1 parent e3c91d5 commit c52ef1e

19 files changed

Lines changed: 452 additions & 7 deletions

File tree

packages/admin-ui/src/Drawer/Drawer.stories.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ export const WithTabs: Story = {
188188
children: (
189189
<>
190190
<Tabs
191+
separator={true}
191192
spacing={"lg"}
192193
tabs={[
193194
<Tabs.Tab
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { NuxtConfig } from "~/features/nuxt/abstractions.js";

packages/api-website-builder/src/features/nextjs/NextjsConfig.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ class NextjsConfigImpl implements Abstraction.Interface {
3232
DESCRIPTION: `This is a configuration for <a href="{STARTER_KIT_LINK}" target="_blank">Webiny Next.js starter kit:</a>`,
3333
STARTER_KIT_LINK: `https://github.com/webiny/website-builder-nextjs`,
3434
API_TOKEN: apiKey ? apiKey.token : "{API_KEY_TOKEN}",
35-
API_HOST: domains.apiHost ?? "",
36-
ADMIN_HOST: domains.adminHost ?? "",
35+
API_HOST: domains.apiHost ?? "{API_HOST_URL}",
36+
ADMIN_HOST: domains.adminHost ?? "{ADMIN_HOST_URL}",
3737
TENANT_ID: tenant.id
3838
})
3939
.add("description", "{DESCRIPTION}")
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { NuxtConfig as Abstraction } from "~/features/nuxt/abstractions.js";
2+
import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
3+
import { MarkdownContentBuilder } from "~/features/nextjs/MarkdownContentBuilder.js";
4+
import { ServiceDiscovery } from "@webiny/api-core/features/serviceDiscovery/index.js";
5+
import { ApiKeysRepository } from "@webiny/api-core/features/security/apiKeys/shared/abstractions.js";
6+
7+
class NuxtConfigImpl implements Abstraction.Interface {
8+
constructor(
9+
private tenantContext: TenantContext.Interface,
10+
private apiKeyRepo: ApiKeysRepository.Interface
11+
) {}
12+
13+
async execute(): Abstraction.Return {
14+
const tenant = this.tenantContext.getTenant();
15+
const apiKeyResult = await this.apiKeyRepo.getBySlug("website-builder");
16+
const apiKey = apiKeyResult.isOk() ? apiKeyResult.value : null;
17+
const domains = await this.getDomains();
18+
19+
const envVars = [
20+
`WEBINY_API_KEY={API_TOKEN}`,
21+
`WEBINY_API_HOST={API_HOST}`,
22+
`WEBINY_API_TENANT={TENANT_ID}`
23+
];
24+
25+
if (domains.adminHost) {
26+
envVars.push(`WEBINY_ADMIN_HOST={ADMIN_HOST}`);
27+
}
28+
29+
const builder = new MarkdownContentBuilder();
30+
builder
31+
.setVariables({
32+
DESCRIPTION: `This is a configuration for <a href="{STARTER_KIT_LINK}" target="_blank">Webiny Nuxt starter kit:</a>`,
33+
STARTER_KIT_LINK: `https://github.com/webiny/website-builder-nuxt`,
34+
API_TOKEN: apiKey ? apiKey.token : "{API_KEY_TOKEN}",
35+
API_HOST: domains.apiHost ?? "{API_HOST_URL}",
36+
ADMIN_HOST: domains.adminHost ?? "{ADMIN_HOST_URL}",
37+
TENANT_ID: tenant.id
38+
})
39+
.add("description", "{DESCRIPTION}")
40+
.add("dotEnvStart", "```dotenv")
41+
.add("dotEnvBody", envVars.join("\n"))
42+
.add("dotEnvEnd", "```");
43+
44+
return builder;
45+
}
46+
47+
private async getDomains() {
48+
const manifest = await ServiceDiscovery.load();
49+
50+
const domains: Record<string, string | null> = {
51+
apiHost: null,
52+
adminHost: null
53+
};
54+
55+
if (!manifest) {
56+
return domains;
57+
}
58+
59+
const { api, admin } = manifest;
60+
61+
if (api?.cloudfront) {
62+
domains.apiHost = api.cloudfront.domain;
63+
}
64+
65+
if (admin?.cloudfront) {
66+
domains.adminHost = admin.cloudfront.domain;
67+
}
68+
69+
return domains;
70+
}
71+
}
72+
73+
export const NuxtConfig = Abstraction.createImplementation({
74+
implementation: NuxtConfigImpl,
75+
dependencies: [TenantContext, ApiKeysRepository]
76+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { createAbstraction } from "@webiny/feature/api";
2+
import type { IMarkdownContentBuilder } from "~/features/nextjs/MarkdownContentBuilder.js";
3+
4+
export interface INuxtConfig {
5+
execute(): Promise<IMarkdownContentBuilder>;
6+
}
7+
8+
/** Configuration for Nuxt website rendering. */
9+
export const NuxtConfig = createAbstraction<INuxtConfig>("Wb/NuxtConfig");
10+
export namespace NuxtConfig {
11+
export type Interface = INuxtConfig;
12+
export type Return = Promise<IMarkdownContentBuilder>;
13+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { createFeature } from "@webiny/feature/api";
2+
import { NuxtConfig } from "./NuxtConfig.js";
3+
4+
export const NuxtFeature = createFeature({
5+
name: "WebsiteBuilder/Nuxt",
6+
register(container) {
7+
container.register(NuxtConfig);
8+
}
9+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { NuxtConfig } from "./abstractions.js";
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
2+
import NotAuthorizedResponse from "@webiny/api-core/graphql/security/NotAuthorizedResponse.js";
3+
import { ErrorResponse, Response } from "@webiny/handler-graphql";
4+
import { CoreGraphQLSchemaFactory } from "@webiny/handler-graphql/graphql/abstractions.core.js";
5+
import { NuxtConfig } from "~/features/nuxt/index.js";
6+
import { GraphQLSchemaBuilder } from "@webiny/handler-graphql/features/GraphQLSchemaBuilder/abstractions.js";
7+
8+
class Schema implements CoreGraphQLSchemaFactory.Interface {
9+
public async execute(builder: GraphQLSchemaBuilder.Interface): CoreGraphQLSchemaFactory.Return {
10+
builder.addTypeDefs(/* GraphQL */ `
11+
type NuxtConfigResponse {
12+
data: String
13+
error: WbError
14+
}
15+
16+
extend type WbQuery {
17+
getNuxtConfig: NuxtConfigResponse
18+
}
19+
`);
20+
21+
builder.addResolver({
22+
dependencies: [IdentityContext, NuxtConfig],
23+
path: "WbQuery.getNuxtConfig",
24+
resolver(identityContext: IdentityContext.Interface, nuxtConfig: NuxtConfig.Interface) {
25+
return async () => {
26+
const identity = identityContext.getIdentity();
27+
if (!identity.isAdmin()) {
28+
return new NotAuthorizedResponse();
29+
}
30+
31+
const permission = await identityContext.getPermission("wb.settings");
32+
if (!permission) {
33+
return new ErrorResponse({
34+
code: "WebsiteBuilder/Settings/NotAuthorized",
35+
message: "Not authorized!"
36+
});
37+
}
38+
39+
const config = await nuxtConfig.execute();
40+
41+
return new Response(config.build());
42+
};
43+
}
44+
});
45+
46+
return builder;
47+
}
48+
}
49+
50+
export const NuxtGraphQLSchema = CoreGraphQLSchemaFactory.createImplementation({
51+
implementation: Schema,
52+
dependencies: []
53+
});

packages/api-website-builder/src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import { WbPermissionsFeature } from "~/features/permissions/feature.js";
3333
import { ApiKeyInstallerFeature } from "~/features/installer/feature.js";
3434
import { NextjsGraphQLSchema } from "~/graphql/nextjs/NextjsGraphQLSchema.js";
3535
import { NextjsFeature } from "~/features/nextjs/feature.js";
36+
import { NuxtGraphQLSchema } from "~/graphql/nuxt/NuxtGraphQLSchema.js";
37+
import { NuxtFeature } from "~/features/nuxt/feature.js";
3638
import { ListDeletedPagesFeature } from "~/features/pages/ListDeletedPages/feature.js";
3739
import { TrashPageFeature } from "~/features/pages/TrashPage/feature.js";
3840
import { RestorePageFeature } from "~/features/pages/RestorePage/feature.js";
@@ -98,11 +100,13 @@ const createContext = () => {
98100
MovePageFeature.register(container);
99101
ApiKeyInstallerFeature.register(container);
100102
NextjsFeature.register(container);
103+
NuxtFeature.register(container);
101104
WbWebhooksFeature.register(container);
102105
// TenantModelExtensionFeature.register(container);
103106

104107
// Register GraphQL
105108
container.register(NextjsGraphQLSchema);
109+
container.register(NuxtGraphQLSchema);
106110
},
107111
{ name: "wb.createContext" }
108112
);

packages/app-website-builder/src/Extension.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { Routes } from "~/routes.js";
1515
import { PagesWidget } from "~/modules/widgets/PagesWidget.js";
1616
import { Extension as NavigationExtension } from "./presentation/navigation/Extension.js";
1717
import { NextjsConfigFeature } from "~/presentation/navigation/NextjsConfig/feature.js";
18+
import { NuxtConfigFeature } from "~/presentation/navigation/NuxtConfig/feature.js";
1819
import { WB_PERMISSIONS_SCHEMA } from "~/constants.js";
1920
import { WbPermissionsFeature } from "~/features/permissions/feature.js";
2021
import { HasPermission } from "~/presentation/security/HasPermission.js";
@@ -46,6 +47,7 @@ export const Extension = () => {
4647
<>
4748
<RegisterFeature feature={SharedPageInfrastructureFeature} />
4849
<RegisterFeature feature={NextjsConfigFeature} />
50+
<RegisterFeature feature={NuxtConfigFeature} />
4951
<RegisterFeature feature={WbPermissionsFeature} />
5052
<RegisterFeature feature={TranslatePageFeature} />
5153
<RegisterFeature feature={DeletePageFeature} />

0 commit comments

Comments
 (0)