diff --git a/apps/admin/src/App.auth0.tsx b/apps/admin/src/App.auth0.tsx index 94470e11142..15b9bded727 100644 --- a/apps/admin/src/App.auth0.tsx +++ b/apps/admin/src/App.auth0.tsx @@ -1,6 +1,7 @@ import React from "react"; import { Admin } from "@webiny/app-serverless-cms"; import { Auth0 } from "@webiny/app-admin-auth0"; +import { Extensions } from "./Extensions"; import "./App.scss"; export const App = () => { @@ -13,6 +14,7 @@ export const App = () => { }} rootAppClientId={String(process.env.REACT_APP_AUTH0_CLIENT_ID)} /> + ); }; diff --git a/apps/admin/src/App.editor.tsx b/apps/admin/src/App.editor.tsx index d5ad5a4007b..81e29c37ce2 100644 --- a/apps/admin/src/App.editor.tsx +++ b/apps/admin/src/App.editor.tsx @@ -1,6 +1,7 @@ import React from "react"; import { Admin } from "@webiny/app-serverless-cms"; import { Cognito } from "@webiny/app-admin-users-cognito"; +import { Extensions } from "./Extensions"; import { Editor } from "@webiny/app-page-builder-editor"; import "./App.scss"; @@ -9,6 +10,7 @@ export const App = () => { + ); }; diff --git a/apps/admin/src/App.fm.tsx b/apps/admin/src/App.fm.tsx index b9b2522a83e..c3a53d9c10e 100644 --- a/apps/admin/src/App.fm.tsx +++ b/apps/admin/src/App.fm.tsx @@ -2,6 +2,7 @@ import React, { useCallback } from "react"; import { Admin, createComponentPlugin } from "@webiny/app-serverless-cms"; import { FileManagerFileItem, FileManagerRenderer, OverlayLayout } from "@webiny/app-admin"; import { Cognito } from "@webiny/app-admin-users-cognito"; +import { Extensions } from "./Extensions"; import "./App.scss"; const CustomFileManager = createComponentPlugin(FileManagerRenderer, () => { @@ -36,6 +37,7 @@ export const App = () => { + ); }; diff --git a/apps/admin/src/App.okta.tsx b/apps/admin/src/App.okta.tsx index 2ec41173259..7ffc0f568f6 100644 --- a/apps/admin/src/App.okta.tsx +++ b/apps/admin/src/App.okta.tsx @@ -1,6 +1,7 @@ import React from "react"; import { Admin } from "@webiny/app-serverless-cms"; import { Okta } from "@webiny/app-admin-okta"; +import { Extensions } from "./Extensions"; import "./App.scss"; import { oktaFactory, rootAppClientId } from "./okta"; @@ -9,6 +10,7 @@ export const App = () => { return ( + ); }; diff --git a/apps/admin/src/App.tsx b/apps/admin/src/App.tsx index 2773f643e51..ac6cee40cd1 100644 --- a/apps/admin/src/App.tsx +++ b/apps/admin/src/App.tsx @@ -1,12 +1,14 @@ import React from "react"; import { Admin } from "@webiny/app-serverless-cms"; import { Cognito } from "@webiny/app-admin-users-cognito"; +import { Extensions } from "./Extensions"; import "./App.scss"; export const App = () => { return ( + ); }; diff --git a/apps/admin/src/Extensions.tsx b/apps/admin/src/Extensions.tsx new file mode 100644 index 00000000000..00cd662531a --- /dev/null +++ b/apps/admin/src/Extensions.tsx @@ -0,0 +1,6 @@ +// This file is automatically updated via scaffolding utilities. +import React from "react"; + +export const Extensions = () => { + return <>; +}; diff --git a/apps/api/graphql/src/extensions.ts b/apps/api/graphql/src/extensions.ts new file mode 100644 index 00000000000..658b605320b --- /dev/null +++ b/apps/api/graphql/src/extensions.ts @@ -0,0 +1,4 @@ +// This file is automatically updated via scaffolding utilities. +export const extensions = () => { + return []; +}; diff --git a/apps/api/graphql/src/index.ts b/apps/api/graphql/src/index.ts index 5afef095ae9..a957791fc2b 100644 --- a/apps/api/graphql/src/index.ts +++ b/apps/api/graphql/src/index.ts @@ -38,13 +38,15 @@ import { createAco } from "@webiny/api-aco"; import { createAcoPageBuilderContext } from "@webiny/api-page-builder-aco"; import { createAuditLogs } from "@webiny/api-audit-logs"; import { createBackgroundTasks } from "@webiny/api-background-tasks-ddb"; -import scaffoldsPlugins from "./plugins/scaffolds"; import { createBenchmarkEnablePlugin } from "~/plugins/benchmarkEnable"; import { createCountDynamoDbTask } from "~/plugins/countDynamoDbTask"; import { createContinuingTask } from "~/plugins/continuingTask"; import { createWebsockets } from "@webiny/api-websockets"; import { createRecordLocking } from "@webiny/api-record-locking"; +import scaffoldsPlugins from "./plugins/scaffolds"; +import { extensions } from "./extensions"; + const debug = process.env.DEBUG === "true"; const documentClient = getDocumentClient(); @@ -107,7 +109,6 @@ export const handler = createHandler({ createAcoPageBuilderContext(), createAcoHcmsContext(), createHcmsTasks(), - scaffoldsPlugins(), createFileModelModifier(({ modifier }) => { modifier.addField({ id: "customField1", @@ -134,7 +135,11 @@ export const handler = createHandler({ }), createAuditLogs(), createCountDynamoDbTask(), - createContinuingTask() + createContinuingTask(), + + // Leave this at the end. + scaffoldsPlugins(), + extensions() ], debug }); diff --git a/apps/theme/global.scss b/extensions/theme/global.scss similarity index 100% rename from apps/theme/global.scss rename to extensions/theme/global.scss diff --git a/apps/theme/index.ts b/extensions/theme/index.ts similarity index 100% rename from apps/theme/index.ts rename to extensions/theme/index.ts diff --git a/apps/theme/layouts/forms/DefaultFormLayout.tsx b/extensions/theme/layouts/forms/DefaultFormLayout.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/Cell.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/Cell.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/Cell.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/Cell.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/Field.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/Field.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/Field.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/Field.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/ReCaptchaSection.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/ReCaptchaSection.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/ReCaptchaSection.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/ReCaptchaSection.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/Row.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/Row.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/Row.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/Row.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/SuccessMessage.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/SuccessMessage.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/SuccessMessage.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/SuccessMessage.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/TermsOfServiceSection.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/TermsOfServiceSection.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/TermsOfServiceSection.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/TermsOfServiceSection.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/buttons/Button.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/buttons/Button.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/buttons/Button.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/buttons/Button.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/fields/Checkbox.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/fields/Checkbox.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/fields/Checkbox.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/fields/Checkbox.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/fields/DateTime.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/fields/DateTime.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/fields/DateTime.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/fields/DateTime.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/fields/Hidden.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/fields/Hidden.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/fields/Hidden.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/fields/Hidden.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/fields/Input.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/fields/Input.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/fields/Input.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/fields/Input.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/fields/Radio.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/fields/Radio.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/fields/Radio.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/fields/Radio.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/fields/Select.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/fields/Select.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/fields/Select.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/fields/Select.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/fields/Textarea.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/fields/Textarea.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/fields/Textarea.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/fields/Textarea.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/fields/components/Field.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/fields/components/Field.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/fields/components/Field.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/fields/components/Field.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/fields/components/FieldErrorMessage.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/fields/components/FieldErrorMessage.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/fields/components/FieldErrorMessage.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/fields/components/FieldErrorMessage.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/fields/components/FieldHelperMessage.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/fields/components/FieldHelperMessage.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/fields/components/FieldHelperMessage.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/fields/components/FieldHelperMessage.tsx diff --git a/apps/theme/layouts/forms/DefaultFormLayout/fields/components/FieldLabel.tsx b/extensions/theme/layouts/forms/DefaultFormLayout/fields/components/FieldLabel.tsx similarity index 100% rename from apps/theme/layouts/forms/DefaultFormLayout/fields/components/FieldLabel.tsx rename to extensions/theme/layouts/forms/DefaultFormLayout/fields/components/FieldLabel.tsx diff --git a/apps/theme/layouts/pages/Static.tsx b/extensions/theme/layouts/pages/Static.tsx similarity index 100% rename from apps/theme/layouts/pages/Static.tsx rename to extensions/theme/layouts/pages/Static.tsx diff --git a/apps/theme/layouts/pages/Static/Footer.tsx b/extensions/theme/layouts/pages/Static/Footer.tsx similarity index 100% rename from apps/theme/layouts/pages/Static/Footer.tsx rename to extensions/theme/layouts/pages/Static/Footer.tsx diff --git a/apps/theme/layouts/pages/Static/Header.tsx b/extensions/theme/layouts/pages/Static/Header.tsx similarity index 100% rename from apps/theme/layouts/pages/Static/Header.tsx rename to extensions/theme/layouts/pages/Static/Header.tsx diff --git a/apps/theme/layouts/pages/Static/HeaderDesktop.tsx b/extensions/theme/layouts/pages/Static/HeaderDesktop.tsx similarity index 100% rename from apps/theme/layouts/pages/Static/HeaderDesktop.tsx rename to extensions/theme/layouts/pages/Static/HeaderDesktop.tsx diff --git a/apps/theme/layouts/pages/Static/HeaderMobile.tsx b/extensions/theme/layouts/pages/Static/HeaderMobile.tsx similarity index 100% rename from apps/theme/layouts/pages/Static/HeaderMobile.tsx rename to extensions/theme/layouts/pages/Static/HeaderMobile.tsx diff --git a/apps/theme/layouts/pages/Static/Navigation.tsx b/extensions/theme/layouts/pages/Static/Navigation.tsx similarity index 100% rename from apps/theme/layouts/pages/Static/Navigation.tsx rename to extensions/theme/layouts/pages/Static/Navigation.tsx diff --git a/apps/theme/layouts/pages/Static/assets/facebook-square-brands.svg b/extensions/theme/layouts/pages/Static/assets/facebook-square-brands.svg similarity index 100% rename from apps/theme/layouts/pages/Static/assets/facebook-square-brands.svg rename to extensions/theme/layouts/pages/Static/assets/facebook-square-brands.svg diff --git a/apps/theme/layouts/pages/Static/assets/instagram-brands.svg b/extensions/theme/layouts/pages/Static/assets/instagram-brands.svg similarity index 100% rename from apps/theme/layouts/pages/Static/assets/instagram-brands.svg rename to extensions/theme/layouts/pages/Static/assets/instagram-brands.svg diff --git a/apps/theme/layouts/pages/Static/assets/linkedin-brands.svg b/extensions/theme/layouts/pages/Static/assets/linkedin-brands.svg similarity index 100% rename from apps/theme/layouts/pages/Static/assets/linkedin-brands.svg rename to extensions/theme/layouts/pages/Static/assets/linkedin-brands.svg diff --git a/apps/theme/layouts/pages/Static/assets/twitter-square-brands.svg b/extensions/theme/layouts/pages/Static/assets/twitter-square-brands.svg similarity index 100% rename from apps/theme/layouts/pages/Static/assets/twitter-square-brands.svg rename to extensions/theme/layouts/pages/Static/assets/twitter-square-brands.svg diff --git a/apps/theme/package.json b/extensions/theme/package.json similarity index 100% rename from apps/theme/package.json rename to extensions/theme/package.json diff --git a/apps/theme/theme.ts b/extensions/theme/theme.ts similarity index 100% rename from apps/theme/theme.ts rename to extensions/theme/theme.ts diff --git a/apps/theme/tsconfig.json b/extensions/theme/tsconfig.json similarity index 100% rename from apps/theme/tsconfig.json rename to extensions/theme/tsconfig.json diff --git a/package.json b/package.json index 635cb3b66e8..131a871443f 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,6 @@ "apps/custom", "apps/website", "apps/website/prerendering/*", - "apps/theme", "apps/core/dynamoToElastic", "apps/api/apw/*", "apps/api/fileManager/*", @@ -18,6 +17,7 @@ "apps/api/pageBuilder/updateSettings", "apps/api/pageBuilder/import/*", "apps/api/pageBuilder/export/*", + "extensions/theme", "scripts/buildPackages", "scripts/prepublishOnly" ] diff --git a/packages/api-serverless-cms/.babelrc.js b/packages/api-serverless-cms/.babelrc.js new file mode 100644 index 00000000000..9da7674cb52 --- /dev/null +++ b/packages/api-serverless-cms/.babelrc.js @@ -0,0 +1 @@ +module.exports = require("@webiny/project-utils").createBabelConfigForNode({ path: __dirname }); diff --git a/packages/api-serverless-cms/LICENSE b/packages/api-serverless-cms/LICENSE new file mode 100644 index 00000000000..f772d04d4db --- /dev/null +++ b/packages/api-serverless-cms/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Webiny + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/api-serverless-cms/README.md b/packages/api-serverless-cms/README.md new file mode 100644 index 00000000000..fc99886f597 --- /dev/null +++ b/packages/api-serverless-cms/README.md @@ -0,0 +1,15 @@ +# @webiny/api-serverless-cms +[![](https://img.shields.io/npm/dw/@webiny/api-serverless-cms.svg)](https://www.npmjs.com/package/@webiny/api-serverless-cms) +[![](https://img.shields.io/npm/v/@webiny/api-serverless-cms.svg)](https://www.npmjs.com/package/@webiny/api-serverless-cms) +[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) +[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) + +## Install +``` +npm install --save @webiny/api-serverless-cms +``` + +Or if you prefer yarn: +``` +yarn add @webiny/api-serverless-cms +``` diff --git a/packages/api-serverless-cms/package.json b/packages/api-serverless-cms/package.json new file mode 100644 index 00000000000..4efd16ef13f --- /dev/null +++ b/packages/api-serverless-cms/package.json @@ -0,0 +1,47 @@ +{ + "name": "@webiny/api-serverless-cms", + "version": "0.0.0", + "main": "index.js", + "repository": { + "type": "git", + "url": "https://github.com/webiny/webiny-js.git" + }, + "description": "Core package for all of our API packages.", + "license": "MIT", + "dependencies": { + "@webiny/api": "0.0.0", + "@webiny/api-aco": "0.0.0", + "@webiny/api-file-manager": "0.0.0", + "@webiny/api-form-builder": "0.0.0", + "@webiny/api-headless-cms": "0.0.0", + "@webiny/api-i18n": "0.0.0", + "@webiny/api-i18n-content": "0.0.0", + "@webiny/api-page-builder": "0.0.0", + "@webiny/api-page-builder-aco": "0.0.0", + "@webiny/api-prerendering-service": "0.0.0", + "@webiny/api-security": "0.0.0", + "@webiny/api-tenancy": "0.0.0", + "@webiny/handler-client": "0.0.0", + "@webiny/handler-graphql": "0.0.0" + }, + "devDependencies": { + "@babel/cli": "^7.23.9", + "@babel/core": "^7.24.0", + "@babel/preset-env": "^7.24.0", + "@babel/preset-typescript": "^7.23.3", + "@webiny/cli": "0.0.0", + "@webiny/project-utils": "0.0.0", + "rimraf": "^5.0.5", + "ttypescript": "^1.5.13", + "typescript": "4.7.4" + }, + "publishConfig": { + "access": "public", + "directory": "dist" + }, + "scripts": { + "build": "yarn webiny run build", + "watch": "yarn webiny run watch" + }, + "gitHead": "8476da73b653c89cc1474d968baf55c1b0ae0e5f" +} diff --git a/packages/api-serverless-cms/src/index.ts b/packages/api-serverless-cms/src/index.ts new file mode 100644 index 00000000000..5e87938046f --- /dev/null +++ b/packages/api-serverless-cms/src/index.ts @@ -0,0 +1,43 @@ +import { ClientContext } from "@webiny/handler-client/types"; +import { TenancyContext } from "@webiny/api-tenancy/types"; +import { SecurityContext } from "@webiny/api-security/types"; +import { I18NContext } from "@webiny/api-i18n/types"; +import { I18NContentContext } from "@webiny/api-i18n-content/types"; +import { PbContext } from "@webiny/api-page-builder/graphql/types"; +import { PrerenderingServiceClientContext } from "@webiny/api-prerendering-service/client/types"; +import { FileManagerContext } from "@webiny/api-file-manager/types"; +import { FormBuilderContext } from "@webiny/api-form-builder/types"; +import { CmsContext } from "@webiny/api-headless-cms/types"; +import { AcoContext } from "@webiny/api-aco/types"; +import { PbAcoContext } from "@webiny/api-page-builder-aco/types"; +import { createContextPlugin as baseCreateContextPlugin, ContextPluginCallable } from "@webiny/api"; +import { + createGraphQLSchemaPlugin as baseCreateGraphQLSchemaPlugin, + GraphQLSchemaPluginConfig +} from "@webiny/handler-graphql"; + +export interface Context + extends ClientContext, + TenancyContext, + SecurityContext, + I18NContext, + I18NContentContext, + PbContext, + PrerenderingServiceClientContext, + FileManagerContext, + FormBuilderContext, + AcoContext, + PbAcoContext, + CmsContext {} + +export const createContextPlugin = ( + callable: ContextPluginCallable +) => { + return baseCreateContextPlugin(callable); +}; + +export const createGraphQLSchemaPlugin = ( + config: GraphQLSchemaPluginConfig +) => { + return baseCreateGraphQLSchemaPlugin(config); +}; diff --git a/packages/api-serverless-cms/tsconfig.build.json b/packages/api-serverless-cms/tsconfig.build.json new file mode 100644 index 00000000000..1f153853c01 --- /dev/null +++ b/packages/api-serverless-cms/tsconfig.build.json @@ -0,0 +1,27 @@ +{ + "extends": "../../tsconfig.build.json", + "include": ["src"], + "references": [ + { "path": "../api/tsconfig.build.json" }, + { "path": "../api-aco/tsconfig.build.json" }, + { "path": "../api-file-manager/tsconfig.build.json" }, + { "path": "../api-form-builder/tsconfig.build.json" }, + { "path": "../handler-graphql/tsconfig.build.json" }, + { "path": "../api-headless-cms/tsconfig.build.json" }, + { "path": "../api-i18n/tsconfig.build.json" }, + { "path": "../api-i18n-content/tsconfig.build.json" }, + { "path": "../api-page-builder/tsconfig.build.json" }, + { "path": "../api-page-builder-aco/tsconfig.build.json" }, + { "path": "../api-prerendering-service/tsconfig.build.json" }, + { "path": "../api-security/tsconfig.build.json" }, + { "path": "../api-tenancy/tsconfig.build.json" }, + { "path": "../handler-client/tsconfig.build.json" } + ], + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "declarationDir": "./dist", + "paths": { "~/*": ["./src/*"], "~tests/*": ["./__tests__/*"] }, + "baseUrl": "." + } +} diff --git a/packages/api-serverless-cms/tsconfig.json b/packages/api-serverless-cms/tsconfig.json new file mode 100644 index 00000000000..07dcf392adf --- /dev/null +++ b/packages/api-serverless-cms/tsconfig.json @@ -0,0 +1,58 @@ +{ + "extends": "../../tsconfig.json", + "include": ["src", "__tests__"], + "references": [ + { "path": "../api" }, + { "path": "../api-aco" }, + { "path": "../api-file-manager" }, + { "path": "../api-form-builder" }, + { "path": "../handler-graphql" }, + { "path": "../api-headless-cms" }, + { "path": "../api-i18n" }, + { "path": "../api-i18n-content" }, + { "path": "../api-page-builder" }, + { "path": "../api-page-builder-aco" }, + { "path": "../api-prerendering-service" }, + { "path": "../api-security" }, + { "path": "../api-tenancy" }, + { "path": "../handler-client" } + ], + "compilerOptions": { + "rootDirs": ["./src", "./__tests__"], + "outDir": "./dist", + "declarationDir": "./dist", + "paths": { + "~/*": ["./src/*"], + "~tests/*": ["./__tests__/*"], + "@webiny/api/*": ["../api/src/*"], + "@webiny/api": ["../api/src"], + "@webiny/api-aco/*": ["../api-aco/src/*"], + "@webiny/api-aco": ["../api-aco/src"], + "@webiny/api-file-manager/*": ["../api-file-manager/src/*"], + "@webiny/api-file-manager": ["../api-file-manager/src"], + "@webiny/api-form-builder/*": ["../api-form-builder/src/*"], + "@webiny/api-form-builder": ["../api-form-builder/src"], + "@webiny/handler-graphql/*": ["../handler-graphql/src/*"], + "@webiny/handler-graphql": ["../handler-graphql/src"], + "@webiny/api-headless-cms/*": ["../api-headless-cms/src/*"], + "@webiny/api-headless-cms": ["../api-headless-cms/src"], + "@webiny/api-i18n/*": ["../api-i18n/src/*"], + "@webiny/api-i18n": ["../api-i18n/src"], + "@webiny/api-i18n-content/*": ["../api-i18n-content/src/*"], + "@webiny/api-i18n-content": ["../api-i18n-content/src"], + "@webiny/api-page-builder/*": ["../api-page-builder/src/*"], + "@webiny/api-page-builder": ["../api-page-builder/src"], + "@webiny/api-page-builder-aco/*": ["../api-page-builder-aco/src/*"], + "@webiny/api-page-builder-aco": ["../api-page-builder-aco/src"], + "@webiny/api-prerendering-service/*": ["../api-prerendering-service/src/*"], + "@webiny/api-prerendering-service": ["../api-prerendering-service/src"], + "@webiny/api-security/*": ["../api-security/src/*"], + "@webiny/api-security": ["../api-security/src"], + "@webiny/api-tenancy/*": ["../api-tenancy/src/*"], + "@webiny/api-tenancy": ["../api-tenancy/src"], + "@webiny/handler-client/*": ["../handler-client/src/*"], + "@webiny/handler-client": ["../handler-client/src"] + }, + "baseUrl": "." + } +} diff --git a/packages/api-serverless-cms/webiny.config.js b/packages/api-serverless-cms/webiny.config.js new file mode 100644 index 00000000000..6dff86766c9 --- /dev/null +++ b/packages/api-serverless-cms/webiny.config.js @@ -0,0 +1,8 @@ +const { createWatchPackage, createBuildPackage } = require("@webiny/project-utils"); + +module.exports = { + commands: { + build: createBuildPackage({ cwd: __dirname }), + watch: createWatchPackage({ cwd: __dirname }) + } +}; diff --git a/packages/cli-plugin-scaffold-extensions/.babelrc.js b/packages/cli-plugin-scaffold-extensions/.babelrc.js new file mode 100644 index 00000000000..9da7674cb52 --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/.babelrc.js @@ -0,0 +1 @@ +module.exports = require("@webiny/project-utils").createBabelConfigForNode({ path: __dirname }); diff --git a/packages/cli-plugin-scaffold-extensions/LICENSE b/packages/cli-plugin-scaffold-extensions/LICENSE new file mode 100644 index 00000000000..f772d04d4db --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Webiny + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/cli-plugin-scaffold-extensions/README.md b/packages/cli-plugin-scaffold-extensions/README.md new file mode 100644 index 00000000000..df02f6c9ecd --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/README.md @@ -0,0 +1,15 @@ +# @webiny/cli-plugin-scaffold-extensions +[![](https://img.shields.io/npm/dw/@webiny/cli-plugin-scaffold-extensions.svg)](https://www.npmjs.com/package/@webiny/cli-plugin-scaffold-extensions) +[![](https://img.shields.io/npm/v/@webiny/cli-plugin-scaffold-extensions.svg)](https://www.npmjs.com/package/@webiny/cli-plugin-scaffold-extensions) +[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) +[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) + +## Install +``` +npm install --save @webiny/cli-plugin-scaffold-extensions +``` + +Or if you prefer yarn: +``` +yarn add @webiny/cli-plugin-scaffold-extensions +``` diff --git a/packages/cli-plugin-scaffold-extensions/package.json b/packages/cli-plugin-scaffold-extensions/package.json new file mode 100644 index 00000000000..01caf1d8874 --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/package.json @@ -0,0 +1,59 @@ +{ + "name": "@webiny/cli-plugin-scaffold-extensions", + "version": "0.0.0", + "description": "Scaffolds essential files for creating a new plugin.", + "main": "index.js", + "types": "index.d.ts", + "repository": { + "type": "git", + "url": "git+https://github.com/webiny/webiny-js.git", + "directory": "packages/cli-plugin-scaffold-extensions" + }, + "author": { + "name": "Webiny", + "url": "https://www.webiny.com" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/webiny/webiny-js/issues" + }, + "homepage": "https://github.com/webiny/webiny-js#readme", + "dependencies": { + "@webiny/cli": "0.0.0", + "@webiny/cli-plugin-scaffold": "0.0.0", + "@webiny/error": "0.0.0", + "case": "^1.6.3", + "execa": "^5.0.0", + "load-json-file": "^6.2.0", + "ncp": "^2.0.0", + "replace-in-path": "^1.1.0", + "ts-morph": "^11.0.0", + "validate-npm-package-name": "^3.0.0", + "write-json-file": "^4.3.0" + }, + "devDependencies": { + "@babel/cli": "^7.23.9", + "@babel/core": "^7.24.0", + "@babel/preset-env": "^7.24.0", + "@types/inquirer": "^7.3.1", + "@types/ncp": "^2.0.4", + "@types/pluralize": "^0.0.29", + "@types/validate-npm-package-name": "^3.0.3", + "@webiny/project-utils": "0.0.0", + "rimraf": "^5.0.5", + "typescript": "4.7.4" + }, + "scripts": { + "build": "yarn webiny run build", + "watch": "yarn webiny run watch" + }, + "publishConfig": { + "access": "public", + "directory": "dist" + }, + "adio": { + "ignoreDirs": [ + "template" + ] + } +} diff --git a/packages/cli-plugin-scaffold-extensions/src/generators/admin.ts b/packages/cli-plugin-scaffold-extensions/src/generators/admin.ts new file mode 100644 index 00000000000..940d00c05c5 --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/src/generators/admin.ts @@ -0,0 +1,6 @@ +import { addPluginToReactApp } from "./utils/addPluginToReactApp"; +import { PluginGenerator } from "~/types"; + +export const adminGenerator: PluginGenerator = async ({ input }) => { + await addPluginToReactApp(input); +}; diff --git a/packages/cli-plugin-scaffold-extensions/src/generators/api.ts b/packages/cli-plugin-scaffold-extensions/src/generators/api.ts new file mode 100644 index 00000000000..bfd8a55f7cc --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/src/generators/api.ts @@ -0,0 +1,6 @@ +import { addPluginToApiApp } from "./utils/addPluginToApiApp"; +import { PluginGenerator } from "~/types"; + +export const apiGenerator: PluginGenerator = async ({ input }) => { + await addPluginToApiApp(input); +}; diff --git a/packages/cli-plugin-scaffold-extensions/src/generators/index.ts b/packages/cli-plugin-scaffold-extensions/src/generators/index.ts new file mode 100644 index 00000000000..66743d5a83e --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/src/generators/index.ts @@ -0,0 +1,8 @@ +import { apiGenerator } from "./api"; +import { adminGenerator } from "./admin"; +import { PluginGenerator } from "~/types"; + +export const generators: Record = { + api: apiGenerator, + admin: adminGenerator +}; diff --git a/packages/cli-plugin-scaffold-extensions/src/generators/utils/addPluginToApiApp.tsx b/packages/cli-plugin-scaffold-extensions/src/generators/utils/addPluginToApiApp.tsx new file mode 100644 index 00000000000..bbcaa75b252 --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/src/generators/utils/addPluginToApiApp.tsx @@ -0,0 +1,53 @@ +import { Project, ArrayLiteralExpression, Node } from "ts-morph"; +import path from "path"; +import { formatCode } from "@webiny/cli-plugin-scaffold/utils"; + +interface Params { + name: string; + packageName: string; +} + +export const addPluginToApiApp = async (params: Params): Promise => { + const { name, packageName } = params; + + const extensionsFilePath = path.join("apps", "api", "graphql", "src", "extensions.ts"); + + const extensionFactory = name + "ExtensionFactory"; + const importName = "{ createExtension as " + extensionFactory + " }"; + const importPath = packageName; + + const project = new Project(); + project.addSourceFileAtPath(extensionsFilePath); + + const source = project.getSourceFileOrThrow(extensionsFilePath); + + const existingImportDeclaration = source.getImportDeclaration(importPath); + if (existingImportDeclaration) { + throw new Error( + `Could not import "${importPath}" in "${extensionsFilePath}" as it already exists.` + ); + } + + let index = 1; + + const importDeclarations = source.getImportDeclarations(); + if (importDeclarations.length) { + const last = importDeclarations[importDeclarations.length - 1]; + index = last.getChildIndex() + 1; + } + + source.insertImportDeclaration(index, { + defaultImport: importName, + moduleSpecifier: importPath + }); + + const pluginsArray = source.getFirstDescendant(node => + Node.isArrayLiteralExpression(node) + ) as ArrayLiteralExpression; + + pluginsArray.addElement(`${extensionFactory}()`); + + await source.save(); + + await formatCode(extensionsFilePath, {}); +}; diff --git a/packages/cli-plugin-scaffold-extensions/src/generators/utils/addPluginToReactApp.tsx b/packages/cli-plugin-scaffold-extensions/src/generators/utils/addPluginToReactApp.tsx new file mode 100644 index 00000000000..06c4891456d --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/src/generators/utils/addPluginToReactApp.tsx @@ -0,0 +1,84 @@ +import { Project, Node, JsxFragment } from "ts-morph"; +import path from "path"; +import { formatCode } from "@webiny/cli-plugin-scaffold/utils"; + +interface Params { + name: string; + packageName: string; +} + +export const addPluginToReactApp = async (params: Params): Promise => { + const { name, packageName } = params; + + const extensionsFilePath = path.join("apps", "admin", "src", "Extensions.tsx"); + + const extensionFactory = name + "ExtensionFactory"; + const importName = "{ createExtension as " + extensionFactory + " }"; + const importPath = packageName; + + const project = new Project(); + project.addSourceFileAtPath(extensionsFilePath); + + const source = project.getSourceFileOrThrow(extensionsFilePath); + + const existingImportDeclaration = source.getImportDeclaration(importPath); + if (existingImportDeclaration) { + throw new Error( + `Could not import "${importPath}" in "${extensionsFilePath}" as it already exists.` + ); + } + + let index = 1; + + const importDeclarations = source.getImportDeclarations(); + if (importDeclarations.length) { + const last = importDeclarations[importDeclarations.length - 1]; + index = last.getChildIndex() + 1; + } + + source.insertImportDeclaration(index, { + defaultImport: importName, + moduleSpecifier: importPath + }); + + const extensionsIdentifier = source.getFirstDescendant(node => { + if (!Node.isIdentifier(node)) { + return false; + } + + return node.getText() === "Extensions"; + }); + + if (!extensionsIdentifier) { + throw new Error( + `Could not find the "Extensions" React component in "${extensionsFilePath}". Did you maybe change the name of the component?` + ); + } + + const extensionsArrowFn = extensionsIdentifier.getNextSibling(node => + Node.isArrowFunction(node) + ); + if (!extensionsArrowFn) { + throw new Error( + `Could not find the "Extensions" React component in "${extensionsFilePath}". Did you maybe change its definition? It should be an arrow function.` + ); + } + + const extensionsArrowFnFragment = extensionsArrowFn.getFirstDescendant(node => { + return Node.isJsxFragment(node); + }) as JsxFragment; + + const extensionsArrowFnFragmentChildrenText = extensionsArrowFnFragment + .getFullText() + .replace("<>", "") + .replace("", "") + .trim(); + + extensionsArrowFnFragment.replaceWithText( + `<>{${name}ExtensionFactory()}${extensionsArrowFnFragmentChildrenText}` + ); + + await source.save(); + + await formatCode(extensionsFilePath, {}); +}; diff --git a/packages/cli-plugin-scaffold-extensions/src/index.ts b/packages/cli-plugin-scaffold-extensions/src/index.ts new file mode 100644 index 00000000000..eb812b22fce --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/src/index.ts @@ -0,0 +1,184 @@ +import { CliCommandScaffoldTemplate, PackageJson } from "@webiny/cli-plugin-scaffold/types"; +import fs from "fs"; +import path from "path"; +import util from "util"; +import ncpBase from "ncp"; +import readJson from "load-json-file"; +import writeJson from "write-json-file"; +import execa from "execa"; +import Case from "case"; +import { replaceInPath } from "replace-in-path"; +import WebinyError from "@webiny/error"; +import validateNpmPackageName from "validate-npm-package-name"; +/** + * TODO: rewrite cli into typescript + */ +// @ts-expect-error +import { getProject, log } from "@webiny/cli/utils"; +import { generators } from "./generators"; + +const ncp = util.promisify(ncpBase.ncp); + +interface Input { + type: string; + name: string; + packageName: string; + location: string; +} + +const EXTENSIONS_ROOT_FOLDER = "extensions"; + +export default (): CliCommandScaffoldTemplate => ({ + name: "cli-plugin-scaffold-template-extensions", + type: "cli-plugin-scaffold-template", + templateName: "new-extension", + scaffold: { + name: "New Extension", + description: "Scaffolds essential files for creating a new extension.", + questions: () => { + return [ + { + name: "type", + message: "What type of an extension do you want to create?", + type: "list", + choices: [ + { name: "Admin extension", value: "admin" }, + { name: "API extension", value: "api" } + ] + }, + { + name: "name", + message: "Enter the extension name:", + default: "myCustomExtension", + validate: name => { + if (!name) { + return "Missing extension name."; + } + + const isValidName = name === Case.camel(name); + if (!isValidName) { + return `Please use camel case when providing the name of the extension (for example "myCustomExtension").`; + } + + return true; + } + }, + { + name: "packageName", + message: "Enter the package name:", + default: (answers: Input) => { + return Case.kebab(answers.name); + }, + validate: pkgName => { + if (!pkgName) { + return "Missing package name."; + } + + const isValidName = validateNpmPackageName(pkgName); + if (!isValidName) { + return `Package name must look something like "my-custom-extension".`; + } + + return true; + } + }, + { + name: "location", + message: `Enter the extension location:`, + default: (answers: Input) => { + return `${EXTENSIONS_ROOT_FOLDER}/${answers.name}`; + }, + validate: location => { + if (!location) { + return "Please enter the package location."; + } + + if (!location.startsWith(`${EXTENSIONS_ROOT_FOLDER}/`)) { + return `Package location must start with "${EXTENSIONS_ROOT_FOLDER}/".`; + } + + const locationPath = path.resolve(location); + if (fs.existsSync(locationPath)) { + return `The target location already exists "${location}".`; + } + + return true; + } + } + ]; + }, + generate: async ({ input, ora }) => { + const { type, name } = input; + if (!type) { + throw new Error("Missing extension type."); + } + + const templatePath = path.join(__dirname, "templates", type); + const templateExists = fs.existsSync(templatePath); + if (!templateExists) { + throw new Error("Unknown extension type."); + } + + if (!name) { + throw new Error("Missing extension name."); + } + + let { packageName, location } = input; + if (!packageName) { + packageName = Case.kebab(name); + } + + if (!location) { + location = `${EXTENSIONS_ROOT_FOLDER}/${name}`; + } + + if (fs.existsSync(location)) { + throw new WebinyError(`The target location already exists "${location}"`); + } + + try { + ora.start(`Creating ${log.success.hl(name)} extension...`); + + // Copy template files + fs.mkdirSync(location, { recursive: true }); + await ncp(templatePath, location); + + const project = getProject(); + + const baseTsConfigFullPath = path.resolve(project.root, "tsconfig.json"); + const baseTsConfigRelativePath = path.relative(location, baseTsConfigFullPath); + + const codeReplacements = [ + { find: "PACKAGE_NAME", replaceWith: packageName }, + { + find: "BASE_TSCONFIG_PATH", + replaceWith: baseTsConfigRelativePath + } + ]; + + replaceInPath(path.join(location, "**/*.*"), codeReplacements); + + // Add package to workspaces + const rootPackageJsonPath = path.join(project.root, "package.json"); + const rootPackageJson = await readJson(rootPackageJsonPath); + if (!rootPackageJson.workspaces.packages.includes(location)) { + rootPackageJson.workspaces.packages.push(location); + await writeJson(rootPackageJsonPath, rootPackageJson); + } + + if (typeof generators[type] === "function") { + await generators[type]({ input: { name, packageName } }); + } + + // Once everything is done, run `yarn` so the new packages are automatically installed. + await execa("yarn"); + + ora.succeed(`New extension created in ${log.success.hl(location)}.`); + } catch (err) { + ora.fail("Could not create extension. Please check the logs below."); + console.log(); + console.log(err); + } + } + } +}); diff --git a/packages/cli-plugin-scaffold-extensions/src/types.ts b/packages/cli-plugin-scaffold-extensions/src/types.ts new file mode 100644 index 00000000000..034301c7096 --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/src/types.ts @@ -0,0 +1,8 @@ +interface PluginGeneratorParams { + input: { + name: string; + packageName: string; + }; +} + +export type PluginGenerator = (params: PluginGeneratorParams) => Promise; diff --git a/packages/cli-plugin-scaffold-extensions/templates/admin/package.json b/packages/cli-plugin-scaffold-extensions/templates/admin/package.json new file mode 100644 index 00000000000..6b600cd715b --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/templates/admin/package.json @@ -0,0 +1,5 @@ +{ + "name": "PACKAGE_NAME", + "main": "src/index.tsx", + "version": "1.0.0" +} diff --git a/packages/cli-plugin-scaffold-extensions/templates/admin/src/index.tsx b/packages/cli-plugin-scaffold-extensions/templates/admin/src/index.tsx new file mode 100644 index 00000000000..9aca87d931c --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/templates/admin/src/index.tsx @@ -0,0 +1,5 @@ +import React from "react"; + +export const createExtension = () => { + return <>{/* Your code here. */}; +}; diff --git a/packages/cli-plugin-scaffold-extensions/templates/admin/tsconfig.json b/packages/cli-plugin-scaffold-extensions/templates/admin/tsconfig.json new file mode 100644 index 00000000000..31464829d4e --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/templates/admin/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "BASE_TSCONFIG_PATH", + "include": ["src"] +} diff --git a/packages/cli-plugin-scaffold-extensions/templates/api/package.json b/packages/cli-plugin-scaffold-extensions/templates/api/package.json new file mode 100644 index 00000000000..4261ad1dad7 --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/templates/api/package.json @@ -0,0 +1,5 @@ +{ + "name": "PACKAGE_NAME", + "main": "src/index.ts", + "version": "1.0.0" +} diff --git a/packages/cli-plugin-scaffold-extensions/templates/api/src/index.ts b/packages/cli-plugin-scaffold-extensions/templates/api/src/index.ts new file mode 100644 index 00000000000..34b9cd491b3 --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/templates/api/src/index.ts @@ -0,0 +1,5 @@ +export const createExtension = () => { + return [ + // Your code here. + ]; +}; diff --git a/packages/cli-plugin-scaffold-extensions/templates/api/tsconfig.json b/packages/cli-plugin-scaffold-extensions/templates/api/tsconfig.json new file mode 100644 index 00000000000..31464829d4e --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/templates/api/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "BASE_TSCONFIG_PATH", + "include": ["src"] +} diff --git a/packages/cli-plugin-scaffold-extensions/tsconfig.build.json b/packages/cli-plugin-scaffold-extensions/tsconfig.build.json new file mode 100644 index 00000000000..b4b3446f615 --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/tsconfig.build.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.build.json", + "include": ["src"], + "references": [ + { "path": "../cli-plugin-scaffold/tsconfig.build.json" }, + { "path": "../error/tsconfig.build.json" } + ], + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "declarationDir": "./dist", + "paths": { "~/*": ["./src/*"], "~tests/*": ["./__tests__/*"] }, + "baseUrl": "." + } +} diff --git a/packages/cli-plugin-scaffold-extensions/tsconfig.json b/packages/cli-plugin-scaffold-extensions/tsconfig.json new file mode 100644 index 00000000000..442dd9125b9 --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../tsconfig.json", + "include": ["src", "__tests__"], + "references": [{ "path": "../cli-plugin-scaffold" }, { "path": "../error" }], + "compilerOptions": { + "rootDirs": ["./src", "./__tests__"], + "outDir": "./dist", + "declarationDir": "./dist", + "paths": { + "~/*": ["./src/*"], + "~tests/*": ["./__tests__/*"], + "@webiny/cli-plugin-scaffold/*": ["../cli-plugin-scaffold/src/*"], + "@webiny/cli-plugin-scaffold": ["../cli-plugin-scaffold/src"], + "@webiny/error/*": ["../error/src/*"], + "@webiny/error": ["../error/src"] + }, + "baseUrl": "." + } +} diff --git a/packages/cli-plugin-scaffold-extensions/webiny.config.js b/packages/cli-plugin-scaffold-extensions/webiny.config.js new file mode 100644 index 00000000000..240ce95d511 --- /dev/null +++ b/packages/cli-plugin-scaffold-extensions/webiny.config.js @@ -0,0 +1,18 @@ +const util = require("util"); +const path = require("path"); +const ncpBase = require("ncp"); +const ncp = util.promisify(ncpBase.ncp); + +const { createWatchPackage, createBuildPackage } = require("@webiny/project-utils"); + +module.exports = { + commands: { + build: async (options, context) => { + await createBuildPackage({ cwd: __dirname })(options, context); + const from = path.join(__dirname, "templates"); + const to = path.join(__dirname, "dist/templates"); + await ncp(from, to); + }, + watch: createWatchPackage({ cwd: __dirname }) + } +}; diff --git a/packages/cli-plugin-scaffold/src/index.ts b/packages/cli-plugin-scaffold/src/index.ts index 13a727e3a37..011b2c4a9b7 100644 --- a/packages/cli-plugin-scaffold/src/index.ts +++ b/packages/cli-plugin-scaffold/src/index.ts @@ -5,8 +5,20 @@ export default (): CliCommandPlugin => ({ type: "cli-command", name: "cli-command-scaffold", create({ yargs, context }) { - yargs.command("scaffold", "Generate boilerplate code", () => { - return scaffold({ context }); - }); + yargs.command( + "scaffold [template-name]", + "Generate boilerplate code", + (yargs: Record) => { + yargs.example("$0 scaffold"); + yargs.example("$0 scaffold new-extension --type admin --name customFilePreview"); + yargs.positional("templateName", { + describe: `Name of the scaffold to run (useful when running in non-interactive mode).`, + type: "string" + }); + }, + (argv: Record) => { + return scaffold(context, argv); + } + ); } }); diff --git a/packages/cli-plugin-scaffold/src/scaffold.ts b/packages/cli-plugin-scaffold/src/scaffold.ts index c04a8e9a1ca..615547cdd24 100644 --- a/packages/cli-plugin-scaffold/src/scaffold.ts +++ b/packages/cli-plugin-scaffold/src/scaffold.ts @@ -1,7 +1,7 @@ import ora from "ora"; import inquirer from "inquirer"; import chalk from "chalk"; -import { CliCommandScaffoldTemplate } from "./types"; +import { CliCommandScaffold, CliCommandScaffoldTemplate } from "./types"; import { CliContext } from "@webiny/cli/types"; const wait = (ms?: number): Promise => { @@ -10,13 +10,7 @@ const wait = (ms?: number): Promise => { }); }; -interface ScaffoldArgs { - context: CliContext; -} - -export const scaffold = async (args: ScaffoldArgs) => { - const { context } = args; - +export const scaffold = async (context: CliContext, args: Record) => { const scaffoldPlugins = context.plugins.byType( "cli-plugin-scaffold-template" ); @@ -27,50 +21,65 @@ export const scaffold = async (args: ScaffoldArgs) => { process.exit(1); } - const choices = scaffoldPlugins.map(plugin => { - const { name, description } = plugin.scaffold; + let scaffold: CliCommandScaffold>; + let input: any; - return { - name: `${chalk.bold(name)}\n ${description}\n`, - short: name, - value: plugin.name - }; - }); + if (args.templateName) { + const scaffoldPlugin = scaffoldPlugins.find(p => p.templateName === args.templateName); + if (!scaffoldPlugin) { + console.log(`🚨 We couldn't find the scaffold with the "${args.templateName}" alias.`); + process.exit(1); + } - const { selectedPluginName } = await inquirer.prompt({ - type: "list", - pageSize: 18, - name: "selectedPluginName", - message: "Choose a scaffold:", - choices - }); + scaffold = scaffoldPlugin!.scaffold; + input = args; + } else { + const choices = scaffoldPlugins.map(plugin => { + const { name, description } = plugin.scaffold; - const { scaffold } = context.plugins.byName(selectedPluginName); + return { + name: `${chalk.bold(name)}\n ${description}\n`, + short: name, + value: plugin.name + }; + }); - const questions = - typeof scaffold.questions === "function" - ? scaffold.questions({ context }) - : scaffold.questions; + const { selectedPluginName } = await inquirer.prompt({ + type: "list", + pageSize: 18, + name: "selectedPluginName", + message: "Choose a scaffold:", + choices + }); + + ({ scaffold } = context.plugins.byName(selectedPluginName)); + + const questions = + typeof scaffold.questions === "function" + ? scaffold.questions({ context }) + : scaffold.questions; + + input = await inquirer.prompt(questions); + } - const input = await inquirer.prompt(questions); const oraInstance = ora(); const callbackArgs = { input, context, wait, ora: oraInstance, inquirer }; try { - if (typeof scaffold.onGenerate === "function") { - await scaffold.onGenerate(callbackArgs); + if (typeof scaffold!.onGenerate === "function") { + await scaffold!.onGenerate(callbackArgs); } - await scaffold.generate(callbackArgs); + await scaffold!.generate(callbackArgs); - if (typeof scaffold.onSuccess === "function") { - await scaffold.onSuccess(callbackArgs); + if (typeof scaffold!.onSuccess === "function") { + await scaffold!.onSuccess(callbackArgs); } } catch (e) { oraInstance.stop(); - if (typeof scaffold.onError === "function") { - await scaffold.onError({ ...callbackArgs, error: e }); + if (typeof scaffold!.onError === "function") { + await scaffold!.onError({ ...callbackArgs, error: e }); } else { console.log(e); } diff --git a/packages/cli-plugin-scaffold/src/types.ts b/packages/cli-plugin-scaffold/src/types.ts index 4f279d8bc24..f4771101c97 100644 --- a/packages/cli-plugin-scaffold/src/types.ts +++ b/packages/cli-plugin-scaffold/src/types.ts @@ -79,7 +79,7 @@ export interface CliCommandScaffoldCallableWithErrorArgs> { +export interface CliCommandScaffold> { /** * Name of the scaffold to be picked from list of choices. */ @@ -123,6 +123,13 @@ export interface CliCommandScaffoldTemplate = Reco * A type of the plugin. */ type: "cli-plugin-scaffold-template"; + + /** + * Template name. Can be used when running the scaffold command in + * non-interactive mode (for example: `webiny scaffold new-template`). + */ + templateName?: string; + /** * The scaffold definition. */ diff --git a/packages/cli-plugin-scaffold/src/utils/updateScaffoldsIndexFile.ts b/packages/cli-plugin-scaffold/src/utils/updateScaffoldsIndexFile.ts index be0e4994e1f..9d6fe544bf6 100644 --- a/packages/cli-plugin-scaffold/src/utils/updateScaffoldsIndexFile.ts +++ b/packages/cli-plugin-scaffold/src/utils/updateScaffoldsIndexFile.ts @@ -4,9 +4,10 @@ interface Params { scaffoldsIndexPath: string; importName: string; importPath: string; + pluginsArrayElement?: string; } export default async (params: Params): Promise => { - const { scaffoldsIndexPath, importName, importPath } = params; + const { scaffoldsIndexPath, importName, importPath, pluginsArrayElement } = params; const project = new Project(); project.addSourceFileAtPath(scaffoldsIndexPath); @@ -34,7 +35,7 @@ export default async (params: Params): Promise => { Node.isArrayLiteralExpression(node) ) as ArrayLiteralExpression; - pluginsArray.addElement(importName); + pluginsArray.addElement(pluginsArrayElement || importName); await source.save(); }; diff --git a/packages/cwp-template-aws/template/common/apps/admin/src/App.tsx b/packages/cwp-template-aws/template/common/apps/admin/src/App.tsx index 2773f643e51..6526bd7faa8 100644 --- a/packages/cwp-template-aws/template/common/apps/admin/src/App.tsx +++ b/packages/cwp-template-aws/template/common/apps/admin/src/App.tsx @@ -1,12 +1,15 @@ import React from "react"; import { Admin } from "@webiny/app-serverless-cms"; import { Cognito } from "@webiny/app-admin-users-cognito"; +import { Extensions } from "./Extensions"; + import "./App.scss"; export const App = () => { return ( + ); }; diff --git a/packages/cwp-template-aws/template/common/apps/admin/src/Extensions.tsx b/packages/cwp-template-aws/template/common/apps/admin/src/Extensions.tsx new file mode 100644 index 00000000000..00cd662531a --- /dev/null +++ b/packages/cwp-template-aws/template/common/apps/admin/src/Extensions.tsx @@ -0,0 +1,6 @@ +// This file is automatically updated via scaffolding utilities. +import React from "react"; + +export const Extensions = () => { + return <>; +}; diff --git a/packages/cwp-template-aws/template/common/apps/theme/global.scss b/packages/cwp-template-aws/template/common/extensions/theme/global.scss similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/global.scss rename to packages/cwp-template-aws/template/common/extensions/theme/global.scss diff --git a/packages/cwp-template-aws/template/common/apps/theme/index.ts b/packages/cwp-template-aws/template/common/extensions/theme/index.ts similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/index.ts rename to packages/cwp-template-aws/template/common/extensions/theme/index.ts diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/Cell.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/Cell.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/Cell.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/Cell.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/Field.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/Field.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/Field.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/Field.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/ReCaptchaSection.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/ReCaptchaSection.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/ReCaptchaSection.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/ReCaptchaSection.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/Row.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/Row.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/Row.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/Row.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/SuccessMessage.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/SuccessMessage.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/SuccessMessage.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/SuccessMessage.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/TermsOfServiceSection.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/TermsOfServiceSection.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/TermsOfServiceSection.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/TermsOfServiceSection.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/buttons/Button.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/buttons/Button.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/buttons/Button.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/buttons/Button.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/Checkbox.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/Checkbox.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/Checkbox.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/Checkbox.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/DateTime.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/DateTime.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/DateTime.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/DateTime.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/Hidden.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/Hidden.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/Hidden.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/Hidden.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/Input.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/Input.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/Input.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/Input.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/Radio.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/Radio.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/Radio.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/Radio.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/Select.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/Select.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/Select.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/Select.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/Textarea.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/Textarea.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/Textarea.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/Textarea.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/components/Field.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/components/Field.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/components/Field.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/components/Field.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/components/FieldErrorMessage.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/components/FieldErrorMessage.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/components/FieldErrorMessage.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/components/FieldErrorMessage.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/components/FieldHelperMessage.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/components/FieldHelperMessage.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/components/FieldHelperMessage.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/components/FieldHelperMessage.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/components/FieldLabel.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/components/FieldLabel.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/forms/DefaultFormLayout/fields/components/FieldLabel.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/forms/DefaultFormLayout/fields/components/FieldLabel.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/Footer.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/Footer.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/Footer.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/Footer.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/Header.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/Header.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/Header.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/Header.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/HeaderDesktop.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/HeaderDesktop.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/HeaderDesktop.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/HeaderDesktop.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/HeaderMobile.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/HeaderMobile.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/HeaderMobile.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/HeaderMobile.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/Navigation.tsx b/packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/Navigation.tsx similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/Navigation.tsx rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/Navigation.tsx diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/assets/facebook-square-brands.svg b/packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/assets/facebook-square-brands.svg similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/assets/facebook-square-brands.svg rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/assets/facebook-square-brands.svg diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/assets/instagram-brands.svg b/packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/assets/instagram-brands.svg similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/assets/instagram-brands.svg rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/assets/instagram-brands.svg diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/assets/linkedin-brands.svg b/packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/assets/linkedin-brands.svg similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/assets/linkedin-brands.svg rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/assets/linkedin-brands.svg diff --git a/packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/assets/twitter-square-brands.svg b/packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/assets/twitter-square-brands.svg similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/layouts/pages/Static/assets/twitter-square-brands.svg rename to packages/cwp-template-aws/template/common/extensions/theme/layouts/pages/Static/assets/twitter-square-brands.svg diff --git a/packages/cwp-template-aws/template/common/apps/theme/package.json b/packages/cwp-template-aws/template/common/extensions/theme/package.json similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/package.json rename to packages/cwp-template-aws/template/common/extensions/theme/package.json diff --git a/packages/cwp-template-aws/template/common/apps/theme/theme.ts b/packages/cwp-template-aws/template/common/extensions/theme/theme.ts similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/theme.ts rename to packages/cwp-template-aws/template/common/extensions/theme/theme.ts diff --git a/packages/cwp-template-aws/template/common/apps/theme/tsconfig.json b/packages/cwp-template-aws/template/common/extensions/theme/tsconfig.json similarity index 100% rename from packages/cwp-template-aws/template/common/apps/theme/tsconfig.json rename to packages/cwp-template-aws/template/common/extensions/theme/tsconfig.json diff --git a/packages/cwp-template-aws/template/common/webiny.project.ts b/packages/cwp-template-aws/template/common/webiny.project.ts index 8de03c7a9f9..0e37a5ca086 100644 --- a/packages/cwp-template-aws/template/common/webiny.project.ts +++ b/packages/cwp-template-aws/template/common/webiny.project.ts @@ -6,6 +6,7 @@ import cliAwsTemplate from "@webiny/cwp-template-aws/cli"; import cliScaffold from "@webiny/cli-plugin-scaffold"; import cliScaffoldExtendGraphQlApi from "@webiny/cli-plugin-scaffold-graphql-service"; import cliScaffoldAdminModule from "@webiny/cli-plugin-scaffold-admin-app-module"; +import cliScaffoldExtensions from "@webiny/cli-plugin-scaffold-extensions"; import cliScaffoldCiCd from "@webiny/cli-plugin-scaffold-ci"; export default { @@ -21,6 +22,7 @@ export default { cliScaffold(), cliScaffoldExtendGraphQlApi(), cliScaffoldAdminModule(), + cliScaffoldExtensions(), cliScaffoldCiCd() ] }, diff --git a/packages/cwp-template-aws/template/ddb-es/apps/api/graphql/src/extensions.ts b/packages/cwp-template-aws/template/ddb-es/apps/api/graphql/src/extensions.ts new file mode 100644 index 00000000000..658b605320b --- /dev/null +++ b/packages/cwp-template-aws/template/ddb-es/apps/api/graphql/src/extensions.ts @@ -0,0 +1,4 @@ +// This file is automatically updated via scaffolding utilities. +export const extensions = () => { + return []; +}; diff --git a/packages/cwp-template-aws/template/ddb-es/apps/api/graphql/src/index.ts b/packages/cwp-template-aws/template/ddb-es/apps/api/graphql/src/index.ts index 690bc8e2b1a..2056a49a986 100644 --- a/packages/cwp-template-aws/template/ddb-es/apps/api/graphql/src/index.ts +++ b/packages/cwp-template-aws/template/ddb-es/apps/api/graphql/src/index.ts @@ -43,6 +43,7 @@ import { createRecordLocking } from "@webiny/api-record-locking"; // Imports plugins created via scaffolding utilities. import scaffoldsPlugins from "./plugins/scaffolds"; +import { extensions } from "./extensions"; const debug = process.env.DEBUG === "true"; @@ -118,7 +119,8 @@ export const handler = createHandler({ createAcoHcmsContext(), createHcmsTasks(), createAuditLogs(), - scaffoldsPlugins() + scaffoldsPlugins(), + extensions() ], debug }); diff --git a/packages/cwp-template-aws/template/ddb-es/dependencies.json b/packages/cwp-template-aws/template/ddb-es/dependencies.json index f7289c22c0f..26550e55dde 100644 --- a/packages/cwp-template-aws/template/ddb-es/dependencies.json +++ b/packages/cwp-template-aws/template/ddb-es/dependencies.json @@ -8,6 +8,7 @@ "@webiny/cli-plugin-scaffold-admin-app-module": "latest", "@webiny/cli-plugin-scaffold-graphql-service": "latest", "@webiny/cli-plugin-scaffold-ci": "latest", + "@webiny/cli-plugin-scaffold-extensions": "latest", "@webiny/cli-plugin-workspaces": "latest", "@webiny/cli-plugin-deploy-pulumi": "latest", "@webiny/project-utils": "latest", @@ -49,14 +50,7 @@ "typescript": "4.7.4" }, "workspaces": { - "packages": [ - "apps/admin", - "apps/website", - "apps/theme", - "apps/api/graphql", - "apps/api/headlessCMS", - "packages/*" - ] + "packages": ["apps/admin", "apps/website", "apps/api/graphql", "extensions/theme", "packages/*"] }, "scripts": { "test": "jest --config jest.config.js --passWithNoTests", diff --git a/packages/cwp-template-aws/template/ddb-os/apps/api/graphql/src/extensions.ts b/packages/cwp-template-aws/template/ddb-os/apps/api/graphql/src/extensions.ts new file mode 100644 index 00000000000..658b605320b --- /dev/null +++ b/packages/cwp-template-aws/template/ddb-os/apps/api/graphql/src/extensions.ts @@ -0,0 +1,4 @@ +// This file is automatically updated via scaffolding utilities. +export const extensions = () => { + return []; +}; diff --git a/packages/cwp-template-aws/template/ddb-os/apps/api/graphql/src/index.ts b/packages/cwp-template-aws/template/ddb-os/apps/api/graphql/src/index.ts index 1ae3afb7698..d1199759a1e 100644 --- a/packages/cwp-template-aws/template/ddb-os/apps/api/graphql/src/index.ts +++ b/packages/cwp-template-aws/template/ddb-os/apps/api/graphql/src/index.ts @@ -43,6 +43,7 @@ import { createRecordLocking } from "@webiny/api-record-locking"; // Imports plugins created via scaffolding utilities. import scaffoldsPlugins from "./plugins/scaffolds"; +import { extensions } from "./extensions"; const debug = process.env.DEBUG === "true"; @@ -118,7 +119,8 @@ export const handler = createHandler({ createAcoHcmsContext(), createHcmsTasks(), createAuditLogs(), - scaffoldsPlugins() + scaffoldsPlugins(), + extensions() ], debug }); diff --git a/packages/cwp-template-aws/template/ddb-os/dependencies.json b/packages/cwp-template-aws/template/ddb-os/dependencies.json index a3cfe9f2045..667ed0a2aa9 100644 --- a/packages/cwp-template-aws/template/ddb-os/dependencies.json +++ b/packages/cwp-template-aws/template/ddb-os/dependencies.json @@ -8,6 +8,7 @@ "@webiny/cli-plugin-scaffold-admin-app-module": "latest", "@webiny/cli-plugin-scaffold-graphql-service": "latest", "@webiny/cli-plugin-scaffold-ci": "latest", + "@webiny/cli-plugin-scaffold-extensions": "latest", "@webiny/cli-plugin-workspaces": "latest", "@webiny/cli-plugin-deploy-pulumi": "latest", "@webiny/project-utils": "latest", @@ -50,14 +51,7 @@ "typescript": "4.7.4" }, "workspaces": { - "packages": [ - "apps/admin", - "apps/website", - "apps/theme", - "apps/api/graphql", - "apps/api/headlessCMS", - "packages/*" - ] + "packages": ["apps/admin", "apps/website", "apps/api/graphql", "extensions/theme", "packages/*"] }, "scripts": { "test": "jest --config jest.config.js --passWithNoTests", diff --git a/packages/cwp-template-aws/template/ddb/apps/api/graphql/src/extensions.ts b/packages/cwp-template-aws/template/ddb/apps/api/graphql/src/extensions.ts new file mode 100644 index 00000000000..658b605320b --- /dev/null +++ b/packages/cwp-template-aws/template/ddb/apps/api/graphql/src/extensions.ts @@ -0,0 +1,4 @@ +// This file is automatically updated via scaffolding utilities. +export const extensions = () => { + return []; +}; diff --git a/packages/cwp-template-aws/template/ddb/apps/api/graphql/src/index.ts b/packages/cwp-template-aws/template/ddb/apps/api/graphql/src/index.ts index a146c148387..ac96cd22ddd 100644 --- a/packages/cwp-template-aws/template/ddb/apps/api/graphql/src/index.ts +++ b/packages/cwp-template-aws/template/ddb/apps/api/graphql/src/index.ts @@ -39,6 +39,7 @@ import { createRecordLocking } from "@webiny/api-record-locking"; // Imports plugins created via scaffolding utilities. import scaffoldsPlugins from "./plugins/scaffolds"; +import { extensions } from "./extensions"; const debug = process.env.DEBUG === "true"; @@ -103,7 +104,8 @@ export const handler = createHandler({ createAuditLogs(), createAcoHcmsContext(), createHcmsTasks(), - scaffoldsPlugins() + scaffoldsPlugins(), + extensions() ], debug }); diff --git a/packages/cwp-template-aws/template/ddb/dependencies.json b/packages/cwp-template-aws/template/ddb/dependencies.json index b4225c77b3f..2fd4a81b03a 100644 --- a/packages/cwp-template-aws/template/ddb/dependencies.json +++ b/packages/cwp-template-aws/template/ddb/dependencies.json @@ -8,6 +8,7 @@ "@webiny/cli-plugin-scaffold-admin-app-module": "latest", "@webiny/cli-plugin-scaffold-graphql-service": "latest", "@webiny/cli-plugin-scaffold-ci": "latest", + "@webiny/cli-plugin-scaffold-extensions": "latest", "@webiny/cli-plugin-workspaces": "latest", "@webiny/cli-plugin-deploy-pulumi": "latest", "@webiny/project-utils": "latest", @@ -49,14 +50,7 @@ "typescript": "4.7.4" }, "workspaces": { - "packages": [ - "apps/admin", - "apps/website", - "apps/theme", - "apps/api/graphql", - "apps/api/headlessCMS", - "packages/*" - ] + "packages": ["apps/admin", "apps/website", "apps/api/graphql", "extensions/theme", "packages/*"] }, "scripts": { "test": "jest --config jest.config.js --passWithNoTests", diff --git a/scripts/prepublishOnly/src/prepublishOnly.ts b/scripts/prepublishOnly/src/prepublishOnly.ts index d691f132242..29e3008b88e 100644 --- a/scripts/prepublishOnly/src/prepublishOnly.ts +++ b/scripts/prepublishOnly/src/prepublishOnly.ts @@ -135,7 +135,7 @@ const extraFiles: string[] = [ "packages/cwp-template-aws/template/ddb-es/apps/api/graphql/package.json", "packages/cwp-template-aws/template/ddb-os/apps/api/graphql/package.json", "packages/cwp-template-aws/template/common/apps/admin/package.json", - "packages/cwp-template-aws/template/common/apps/theme/package.json", + "packages/cwp-template-aws/template/common/extensions/theme/package.json", "packages/cwp-template-aws/template/common/apps/website/package.json" ]; diff --git a/webiny.project.ts b/webiny.project.ts index e4f4f1e02e5..74a64bd04c0 100644 --- a/webiny.project.ts +++ b/webiny.project.ts @@ -19,6 +19,7 @@ export default { import("@webiny/cli-plugin-scaffold"), import("@webiny/cli-plugin-scaffold-graphql-service"), import("@webiny/cli-plugin-scaffold-admin-app-module"), + import("@webiny/cli-plugin-scaffold-extensions"), import("@webiny/cli-plugin-scaffold-ci") ]); diff --git a/yarn.lock b/yarn.lock index e7ffdc3664d..ec57e8fda7b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14423,6 +14423,36 @@ __metadata: languageName: unknown linkType: soft +"@webiny/api-serverless-cms@workspace:packages/api-serverless-cms": + version: 0.0.0-use.local + resolution: "@webiny/api-serverless-cms@workspace:packages/api-serverless-cms" + dependencies: + "@babel/cli": ^7.23.9 + "@babel/core": ^7.24.0 + "@babel/preset-env": ^7.24.0 + "@babel/preset-typescript": ^7.23.3 + "@webiny/api": 0.0.0 + "@webiny/api-aco": 0.0.0 + "@webiny/api-file-manager": 0.0.0 + "@webiny/api-form-builder": 0.0.0 + "@webiny/api-headless-cms": 0.0.0 + "@webiny/api-i18n": 0.0.0 + "@webiny/api-i18n-content": 0.0.0 + "@webiny/api-page-builder": 0.0.0 + "@webiny/api-page-builder-aco": 0.0.0 + "@webiny/api-prerendering-service": 0.0.0 + "@webiny/api-security": 0.0.0 + "@webiny/api-tenancy": 0.0.0 + "@webiny/cli": 0.0.0 + "@webiny/handler-client": 0.0.0 + "@webiny/handler-graphql": 0.0.0 + "@webiny/project-utils": 0.0.0 + rimraf: ^5.0.5 + ttypescript: ^1.5.13 + typescript: 4.7.4 + languageName: unknown + linkType: soft + "@webiny/api-tenancy-so-ddb@0.0.0, @webiny/api-tenancy-so-ddb@workspace:packages/api-tenancy-so-ddb": version: 0.0.0-use.local resolution: "@webiny/api-tenancy-so-ddb@workspace:packages/api-tenancy-so-ddb" @@ -16257,6 +16287,34 @@ __metadata: languageName: unknown linkType: soft +"@webiny/cli-plugin-scaffold-extensions@workspace:packages/cli-plugin-scaffold-extensions": + version: 0.0.0-use.local + resolution: "@webiny/cli-plugin-scaffold-extensions@workspace:packages/cli-plugin-scaffold-extensions" + dependencies: + "@babel/cli": ^7.23.9 + "@babel/core": ^7.24.0 + "@babel/preset-env": ^7.24.0 + "@types/inquirer": ^7.3.1 + "@types/ncp": ^2.0.4 + "@types/pluralize": ^0.0.29 + "@types/validate-npm-package-name": ^3.0.3 + "@webiny/cli": 0.0.0 + "@webiny/cli-plugin-scaffold": 0.0.0 + "@webiny/error": 0.0.0 + "@webiny/project-utils": 0.0.0 + case: ^1.6.3 + execa: ^5.0.0 + load-json-file: ^6.2.0 + ncp: ^2.0.0 + replace-in-path: ^1.1.0 + rimraf: ^5.0.5 + ts-morph: ^11.0.0 + typescript: 4.7.4 + validate-npm-package-name: ^3.0.0 + write-json-file: ^4.3.0 + languageName: unknown + linkType: soft + "@webiny/cli-plugin-scaffold-full-stack-app@workspace:packages/cli-plugin-scaffold-full-stack-app": version: 0.0.0-use.local resolution: "@webiny/cli-plugin-scaffold-full-stack-app@workspace:packages/cli-plugin-scaffold-full-stack-app" @@ -37728,9 +37786,9 @@ __metadata: languageName: node linkType: hard -"theme@^0.1.0, theme@workspace:apps/theme": +"theme@^0.1.0, theme@workspace:extensions/theme": version: 0.0.0-use.local - resolution: "theme@workspace:apps/theme" + resolution: "theme@workspace:extensions/theme" dependencies: "@apollo/react-hooks": ^3.1.5 "@emotion/react": ^11.10.6