-
-
-
'
19 | filter_html_help: false
20 | filter_html_nofollow: false
21 | filter_align:
22 | id: filter_align
23 | provider: filter
24 | status: true
25 | weight: 7
26 | settings: { }
27 | filter_caption:
28 | id: filter_caption
29 | provider: filter
30 | status: true
31 | weight: 8
32 | settings: { }
33 | filter_html_image_secure:
34 | id: filter_html_image_secure
35 | provider: filter
36 | status: true
37 | weight: 9
38 | settings: { }
39 | editor_file_reference:
40 | id: editor_file_reference
41 | provider: editor
42 | status: true
43 | weight: 11
44 | settings: { }
45 |
--------------------------------------------------------------------------------
/backend/starters/development/web/profiles/custom/powerstack_profile/config/install/filter.format.full_html.yml:
--------------------------------------------------------------------------------
1 | langcode: en
2 | status: true
3 | dependencies:
4 | module:
5 | - editor
6 | name: 'Full HTML'
7 | format: full_html
8 | weight: 2
9 | roles:
10 | - administrator
11 | filters:
12 | filter_align:
13 | id: filter_align
14 | provider: filter
15 | status: true
16 | weight: 8
17 | settings: { }
18 | filter_caption:
19 | id: filter_caption
20 | provider: filter
21 | status: true
22 | weight: 9
23 | settings: { }
24 | filter_htmlcorrector:
25 | id: filter_htmlcorrector
26 | provider: filter
27 | status: true
28 | weight: 10
29 | settings: { }
30 | editor_file_reference:
31 | id: editor_file_reference
32 | provider: editor
33 | status: true
34 | weight: 11
35 | settings: { }
36 |
--------------------------------------------------------------------------------
/backend/starters/development/web/profiles/custom/powerstack_profile/config/install/gin.settings.yml:
--------------------------------------------------------------------------------
1 | favicon:
2 | mimetype: image/vnd.microsoft.icon
3 | path: profiles/custom/powerstack_profile/assets/images/favicon.ico
4 | use_default: false
5 | features:
6 | comment_user_picture: true
7 | comment_user_verification: true
8 | favicon: true
9 | node_user_picture: true
10 | logo:
11 | path: profiles/custom/powerstack_profile/assets/images/logo-nav-light.svg
12 | use_default: false
13 | third_party_settings:
14 | shortcut:
15 | module_link: true
16 | preset_accent_color: neutral
17 | preset_focus_color: gin
18 | enable_darkmode: '0'
19 | classic_toolbar: horizontal
20 | secondary_toolbar_frontend: true
21 | high_contrast_mode: false
22 | accent_color: '#f0b000'
23 | focus_color: ''
24 | layout_density: default
25 | show_description_toggle: false
26 | show_user_theme_settings: false
--------------------------------------------------------------------------------
/backend/starters/development/web/profiles/custom/powerstack_profile/config/install/system.theme.yml:
--------------------------------------------------------------------------------
1 | admin: gin
2 | default: gin
3 |
--------------------------------------------------------------------------------
/backend/starters/development/web/profiles/custom/powerstack_profile/powerstack_profile.info.yml:
--------------------------------------------------------------------------------
1 | name: Power Stack Profile
2 | type: profile
3 | description: Base installation profile for Power Stack
4 | package: profile
5 | core_version_requirement: ^8 || ^9 || ^10
6 | distribution:
7 | name: Power Stack
8 | install:
9 | theme: stark
10 | install:
11 | - node
12 | - dblog
13 | - ban
14 | - media
15 | - media_library
16 | - serialization
17 | - paragraphs
18 | - content_translation
19 | - language
20 | - datetime_range
21 | - telephone
22 | - field_group
23 | - locale
24 | - block
25 | - config
26 | - menu_link_content
27 | - datetime
28 | - block_content
29 | - editor
30 | - ckeditor5
31 | - menu_ui
32 | - options
33 | - path
34 | - path_alias
35 | - powerstack_api
36 | - powerstack_page_builder
37 | - big_pipe
38 | - dynamic_page_cache
39 | - taxonomy
40 | - field_ui
41 | - user
42 | - gin_toolbar
43 |
44 | themes:
45 | - gin
46 |
--------------------------------------------------------------------------------
/backend/starters/development/web/sites/README.txt:
--------------------------------------------------------------------------------
1 | This directory structure contains the settings and configuration files specific
2 | to your site or sites and is an integral part of multisite configurations.
3 |
4 | It is now recommended to place your custom and downloaded extensions in the
5 | /modules, /themes, and /profiles directories located in the Drupal root. The
6 | sites/all/ subdirectory structure, which was recommended in previous versions
7 | of Drupal, is still supported.
8 |
9 | See core/INSTALL.txt for information about single-site installation or
10 | multisite configuration.
11 |
--------------------------------------------------------------------------------
/backend/starters/development/web/sites/default/cors.services.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | cors.config:
3 | enabled: true
4 | # Specify allowed headers, like 'x-allowed-header'.
5 | allowedHeaders: [ 'x-csrf-token','authorization','content-type','accept','origin','x-requested-with', 'access-control-allow-origin','x-allowed-header','*' ]
6 | # Specify allowed request methods, specify ['*'] to allow all possible ones.
7 | allowedMethods: [ '*' ]
8 | # Configure requests allowed from specific origins.
9 | allowedOrigins: [ 'http://frontend.power-stack.docksal.site', '*' ]
10 | # Sets the Access-Control-Expose-Headers header.
11 | exposedHeaders: false
12 | # Sets the Access-Control-Max-Age header.
13 | maxAge: false
14 | # Sets the Access-Control-Allow-Credentials header.
15 | supportsCredentials: true
16 |
--------------------------------------------------------------------------------
/backend/starters/development/web/sites/default/files/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/backend/starters/development/web/sites/default/files/.gitkeep
--------------------------------------------------------------------------------
/backend/starters/development/web/sites/development.services.yml:
--------------------------------------------------------------------------------
1 | # Local development services.
2 | #
3 | # To activate this feature, follow the instructions at the top of the
4 | # 'example.settings.local.php' file, which sits next to this file.
5 | parameters:
6 | http.response.debug_cacheability_headers: true
7 | services:
8 | cache.backend.null:
9 | class: Drupal\Core\Cache\NullBackendFactory
10 |
--------------------------------------------------------------------------------
/backend/starters/development/web/themes/README.txt:
--------------------------------------------------------------------------------
1 | Themes allow you to change the look and feel of your Drupal site. You can use
2 | themes contributed by others or create your own.
3 |
4 | WHAT TO PLACE IN THIS DIRECTORY?
5 | --------------------------------
6 |
7 | Placing downloaded and custom themes in this directory separates downloaded and
8 | custom themes from Drupal core's themes. This allows Drupal core to be updated
9 | without overwriting these files.
10 |
11 | DOWNLOAD ADDITIONAL THEMES
12 | --------------------------
13 |
14 | Contributed themes from the Drupal community may be downloaded at
15 | https://www.drupal.org/project/project_theme.
16 |
17 | MULTISITE CONFIGURATION
18 | -----------------------
19 |
20 | In multisite configurations, themes found in this directory are available to
21 | all sites. You may also put themes in the sites/all/themes directory, and the
22 | versions in sites/all/themes will take precedence over versions of the same
23 | themes that are here. Alternatively, the sites/your_site_name/themes directory
24 | pattern may be used to restrict themes to a specific site instance.
25 |
26 | MORE INFORMATION
27 | -----------------
28 |
29 | Refer to the "Appearance" section of the README.md in the Drupal root directory
30 | for further information on customizing the appearance of Drupal with custom
31 | themes.
32 |
--------------------------------------------------------------------------------
/backend/starters/development/web/update.php:
--------------------------------------------------------------------------------
1 | handle($request);
28 | $response->send();
29 |
30 | $kernel->terminate($request, $response);
31 |
--------------------------------------------------------------------------------
/docs/.github/workflows/auto_close_prs.yml:
--------------------------------------------------------------------------------
1 | name: Auto Closer PR
2 |
3 | on:
4 | pull_request_target:
5 | types: [opened]
6 |
7 | jobs:
8 | run:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: superbrothers/close-pull-request@v3
12 | with:
13 | # Optional. Post a issue comment just before closing a pull request.
14 | comment: |
15 | Hi, thank you for your contribution.
16 | Unfortunately, this repository is read-only. It's a split from our main monorepo repository.
17 | We'd like to kindly ask you to move the contribution there - https://github.com/powerstackdev/power-stack.
18 | We'll check it, review it and give you feed back right way.
19 | Thank you.
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .cache/
3 | public
4 | *.env*
5 |
6 | .pnp.*
7 | .yarn/*
8 | !.yarn/patches
9 | !.yarn/plugins
10 | !.yarn/releases
11 | !.yarn/sdks
12 | !.yarn/versions
--------------------------------------------------------------------------------
/docs/.structurizr/eula.properties:
--------------------------------------------------------------------------------
1 | #
2 | #Mon Sep 05 11:39:07 UTC 2022
3 | eula-20210622=true
4 |
--------------------------------------------------------------------------------
/docs/.structurizr/images/Context-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/docs/.structurizr/images/Context-thumbnail.png
--------------------------------------------------------------------------------
/docs/.structurizr/images/softwareSystem-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/docs/.structurizr/images/softwareSystem-thumbnail.png
--------------------------------------------------------------------------------
/docs/.structurizr/images/thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/docs/.structurizr/images/thumbnail.png
--------------------------------------------------------------------------------
/docs/.structurizr/index/_0.cfe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/docs/.structurizr/index/_0.cfe
--------------------------------------------------------------------------------
/docs/.structurizr/index/_0.cfs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/docs/.structurizr/index/_0.cfs
--------------------------------------------------------------------------------
/docs/.structurizr/index/_0.si:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/docs/.structurizr/index/_0.si
--------------------------------------------------------------------------------
/docs/.structurizr/index/segments_1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/docs/.structurizr/index/segments_1
--------------------------------------------------------------------------------
/docs/.structurizr/index/write.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/docs/.structurizr/index/write.lock
--------------------------------------------------------------------------------
/docs/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
3 | yarnPath: .yarn/releases/yarn-sources.cjs
4 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # smooth-doc-starter
2 |
3 | ## [Docs](https://smooth-doc.com)
4 |
5 | **See the documentation at [smooth-doc.com](https://smooth-doc.com)** for more information about using Smooth DOC!
6 |
7 | ## License
8 |
9 | Licensed under the MIT License, Copyright © 2020-present Greg Bergé.
10 |
11 | See [LICENSE](./LICENSE) for more information.
12 |
--------------------------------------------------------------------------------
/docs/gatsby-config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [
3 | {
4 | resolve: "smooth-doc",
5 | options: {
6 | name: "Power Stack",
7 | description: "Supercharging digital experiences for the modern web",
8 | siteUrl: "https://powerstack.dev",
9 | author: 'Xavier Mirabelli-Montan',
10 | sections: [ 'Introduction', 'Core concepts', 'Development', 'Components', 'Guides', 'Reference' ],
11 | navItems: [{ title: 'Docs', url: '/docs/intro/overview' }, { title: 'Roadmap', url: '/roadmap' }, { title: 'Get Involved', url: '/contributing' }],
12 | githubRepositoryURL: 'https://github.com/power-stack-dev/power-stack/',
13 | },
14 | },
15 | {
16 | resolve: `gatsby-plugin-webfonts`,
17 | options: {
18 | fonts: {
19 | google: [
20 | {
21 | family: "Mulish",
22 | variants: ["600", "900"]
23 | },
24 | ],
25 | },
26 | },
27 | }
28 | ],
29 | };
30 |
--------------------------------------------------------------------------------
/docs/gatsby-node.js:
--------------------------------------------------------------------------------
1 | exports.onCreateWebpackConfig = ({ actions }) => {
2 | actions.setWebpackConfig({
3 | watchOptions: {
4 | aggregateTimeout: 200,
5 | poll: 1000,
6 | ignored: '**/node_modules',
7 | },
8 | })
9 | }
--------------------------------------------------------------------------------
/docs/images/hero-demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/docs/images/hero-demo.gif
--------------------------------------------------------------------------------
/docs/images/logo-manifest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/docs/images/logo-manifest.png
--------------------------------------------------------------------------------
/docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "smooth-doc-starter",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "develop": "gatsby develop",
7 | "build": "gatsby build",
8 | "serve": "gatsby serve"
9 | },
10 | "dependencies": {
11 | "@babel/core": "^7.16.12",
12 | "@xstyled/styled-components": "^3.5.1",
13 | "gatsby": "^4.23.1",
14 | "gatsby-plugin-google-analytics": "^4.6.0",
15 | "gatsby-plugin-webfonts": "^2.2.2",
16 | "gatsby-transformer-documentationjs": "^6.17.0",
17 | "react": "^17.0.2",
18 | "react-dom": "^17.0.2",
19 | "react-helmet": "^6.1.0",
20 | "react-icons": "^4.3.1",
21 | "react-is": "^17.0.2",
22 | "react-lite-youtube-embed": "^2.3.1",
23 | "react-vertical-timeline-component": "^3.5.2",
24 | "reakit": "^1.3.11",
25 | "smooth-doc": "^9.0.0",
26 | "styled-components": "^5.3.3"
27 | },
28 | "devDependencies": {
29 | "gatsby-cli": "^4.12.1"
30 | },
31 | "resolutions": {
32 | "babel-plugin-styled-components": "2.0.2"
33 | },
34 | "packageManager": "yarn@3.2.0"
35 | }
36 |
--------------------------------------------------------------------------------
/docs/pages/code-of-conduct.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ScreenContainer,
3 | HeroSection,
4 | Hero,
5 | HeroBody,
6 | HeroTitle,
7 | Article
8 | } from "smooth-doc/components"
9 | import CodeOfConduct from '../partials/code-of-conduct.mdx'
10 |
11 |
12 |
13 |
14 | Contributor Covenant Code of Conduct
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/docs/pages/contributing.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ScreenContainer,
3 | HeroSection,
4 | Hero,
5 | HeroBody,
6 | HeroTitle,
7 | Article
8 | } from "smooth-doc/components"
9 | import Contributing from '../partials/contributing.mdx'
10 |
11 |
12 |
13 |
14 | Contributing and Community
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/docs/pages/docs/1-Introduction/getting-started.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Getting Started
3 | section: Introduction
4 | slug: /docs/intro/getting-started/
5 | order: 2
6 | ---
7 |
8 | # Getting Started
9 |
10 | Getting started with Power Stack's 1-step setup.
11 |
12 | ## Install Power Stack
13 |
14 | To get started with Power Stack, run the following command:
15 |
16 | ```
17 | fin project create --name=power-stack --repo=https://github.com/powerstackdev/power-stack.git
18 | ```
19 |
20 | Once that is setup, you will see something along the lines of the following in your terminal screen.
21 |
22 | ### Dependencies
23 |
24 | This setup is utilises Docksal for creating and interacting with the necessary docker container so you will have
25 | configured.
26 |
27 | If you haven't setup Docksal yet you can do so by following the instructions on the
28 | [Docksal website](https://docs.docksal.io/getting-started/setup/).
29 |
30 | ## System requirements
31 |
32 | In theory, this setup should support all Docksal supported environments, we simply haven't tested them all yet.
33 |
34 | Currently, we've tested using:
35 |
36 | ```
37 | Docksal version: v1.17.0
38 | MacOS Monterey (12.3)
39 | 2.9 GHz Quad-Core Intel Core i7
40 | 16GB RAM
41 | ```
42 |
43 | If you run into an issue on a different OS/configuration please raise an issue and we'll happily look into it.
44 |
--------------------------------------------------------------------------------
/docs/pages/docs/1-Introduction/images/overview/Power-Stack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/docs/pages/docs/1-Introduction/images/overview/Power-Stack.png
--------------------------------------------------------------------------------
/docs/pages/docs/2-Core_concepts/apps.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Applications
3 | section: Core concepts
4 | slug: /docs/core-concepts/apps
5 | order: 3
6 | ---
7 |
8 | # Applications
9 |
10 | Applications provide core features and integrations
11 |
12 | ## What is an application?
13 |
14 | For each section of the stack, known as "applications," there are individual are top-level standalone components that may
15 | include packages.
16 |
17 | As a general rule of thumb, applications should contain a `packages` directory that contains application specific packages and a
18 | `starters` directory that provides ready to be provision instances of that application.
19 |
20 | Currently, the applications are as follows:
21 |
22 | ## Backend
23 |
24 | This application contains the content management and data storage functionality. It's built using a headless instance of Drupal.
25 |
26 | ## Frontend
27 |
28 | This application contains all the presentation and drag and drop editing logic. It's build using TinaCMS and Gatsby.
29 |
30 | ## Possible future applications
31 |
32 | ### Search
33 |
34 | Our current intentions are to implement Meilisearch for a dynamic realtime search experience across the Presentation
35 | Layer and Experience Layer.
36 |
37 | ### DAM
38 |
39 | Drupal has robust media management capabilities out-of-the-box. The plan is to incorporate this functionality with a
40 | React library such as [Toast UI Image Editor](https://www.npmjs.com/package/@toast-ui/react-image-editor) on the
41 | Experience Layer and use the automatic image optimization capabilities of Gatsby on the Presentation Layer.
42 |
43 | ### Events
44 |
45 | TBD
--------------------------------------------------------------------------------
/docs/pages/docs/2-Core_concepts/components.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Components
3 | section: Core concepts
4 | slug: /docs/core-concepts/components
5 | ---
6 |
7 | # Components
8 |
9 | Components provide a cluster of fields and field groups from Drupal to be edited in the React environment. In Drupal,
10 | we are using the Paragraphs module to provide the following information (grouped using "field groups") to instruct the
11 | React TinaCMS environment on what fields to use when building out the editorial experience.
12 |
13 | ## Inline Entity Reference Revisions (Paragraphs)
14 |
15 | Tina will look for Inline Entity Reference Revisions (Paragraphs) fields to initialise the Page building experience when
16 | creating or editing a new instance of a content type.
17 |
18 | ### Inline fields
19 |
20 | This is the information that should be edited inline in the WYSIWYG page builder.
21 |
22 | ### Form fields
23 |
24 | Fields relevant to creating a component that shouldn't live within the Inline experience that will show via a settings
25 | modal.
26 |
27 | ### Styling options
28 |
29 | A group within the Tina settings modal for all styling specific fields.
30 |
31 | ## Page fields
32 |
33 | All page specific fields that aren't to be added to the inline experience will appear in the sidebar form.
--------------------------------------------------------------------------------
/docs/pages/docs/2-Core_concepts/design.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Design
3 | section: Core concepts
4 | slug: /docs/core-concepts/design
5 | order: 5
6 | ---
7 |
8 | # Design
9 |
10 | We're developers not designers but in the pre-alpha stage, we want the design to still be simple and cohesive.
11 |
12 | Until we have a UX guru, the design cues can all be found on Figma:
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/pages/docs/2-Core_concepts/layers.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Layers
3 | section: Core concepts
4 | slug: /docs/core-concepts/layers
5 | order: 2
6 | ---
7 |
8 | # Layers
9 |
10 | Top-level groupings that cluster functionality together.
11 |
12 | ## What is a layer?
13 |
14 | Layers are a top-level clustering in Power Stack. They are an integrated clustering of services used to provide a
15 | specific function to a user. These layers refer to functionality within Power Stack and not networking layers.
16 |
17 | There are currently three layers that exist Power Stack.
18 |
19 | ## What are the layers
20 |
21 | - Presentation layer
22 | - Experience layer
23 | - Content layer
24 |
25 | ### Presentation Layer
26 |
27 | This is what a website user will see and interact with and how your website is presented.
28 |
29 | ### Experience Layer
30 |
31 | This is responsible for the editing experience and management of your content.
32 |
33 | ### Content layer
34 |
35 | The underlying content source and reporting system.
--------------------------------------------------------------------------------
/docs/pages/docs/2-Core_concepts/services.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Services
3 | section: Core concepts
4 | slug: /docs/core-concepts/services
5 | order: 4
6 | ---
7 |
8 | # Services
9 |
10 | Services provide the key backing processes to Applications. The Local development environment uses Docksal to provision
11 | and orchestrate the following backing services on Docker.
12 |
13 | ## Database
14 |
15 | This service contains the content data storage.
16 |
17 | ## PHP
18 |
19 | This service is a PHP proxy that executes PHP scripts before sending the data to the relevant Apache2 web services.
20 |
21 | ## Backend Web
22 |
23 | This is the Apache2 web services for the Drupal backend and API.
24 |
25 | ## Frontend Web
26 |
27 | This is the NodeJS service that initialises the Gatsby development environment to preview presentation and editing
28 | frontend.
29 |
30 | ## Docs Web
31 |
32 | This is the NodeJS service that initialises the Gatsby development environment for the documentation site preview.
33 |
34 | ## Start Page Web
35 |
36 | This is the Apache2 service for the Dashboard landing page.
37 |
38 |
--------------------------------------------------------------------------------
/docs/pages/docs/2-Core_concepts/themes.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Themes
3 | section: Core concepts
4 | slug: /docs/themes
5 | order: 6
6 | ---
7 |
8 | # Themes
9 |
10 | Getting started with Gatsby Themes and Theme UI.
11 |
12 | ## About themes
13 |
14 | Gatsby has the ability to shadow code. It's awesome! To do this, you can overwrite any module/package file's that live
15 | inside the `src/` directory.
16 |
17 | ## Overriding
18 |
19 | To override a specific file, copy the file you wish to change to `src/my-module/file.js` (obviously changing the module
20 | and filename to match the override) and then restart your server.
--------------------------------------------------------------------------------
/docs/pages/docs/2-Core_concepts/utilities.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Utilities
3 | section: Core concepts
4 | slug: /docs/core-concepts/utilities
5 | order: 5
6 | ---
7 |
8 | # Utilities
9 |
10 | In addition to the applications, Power Stack comes with some additional utilities to facilitate development.
11 |
12 | ## Docs
13 |
14 | Located at `/docs` this is the code for this website. It contains documentation and tips to develop, use, and get
15 | started with Power Stack. It also contains the necessary files for Structurizr to provide solutions architecture
16 | diagrams using the C4 model.
17 |
18 | ## Local Development
19 |
20 | Local development is setup using Docksal and Docker. All the files for this are located at `/.docksal`.
21 |
22 | ## Scripts
23 |
24 | To provision, setup, run, and develop with Power Stack, there are a series of bash scripts that have been created to
25 | provide these functionalities. These scripts are located at `/scripts`, and have been created in modular way.
26 |
--------------------------------------------------------------------------------
/docs/pages/docs/3-Development/config-variables.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Configuration Variables
3 | section: Development
4 | slug: /docs/developing/config-variables
5 | order: 1
6 | ---
7 |
8 | # Configuration Variables
9 |
10 | Where to find the two types of configuration variables and how they interact with Power Stack.
11 |
12 | ## Docksal config files
13 |
14 | Docksal comes with two configuration files `docksal.env` and `docksal-local.env`.
15 |
16 | ### The base `docksal.env`
17 |
18 | This file ships with all instances of Power Stack.
19 |
20 | ```bash
21 | # Where the backend docroot is located. Docksal defaults to "docroot"
22 | DOCROOT=web
23 |
24 | # MySQL settings.
25 | DB_IMAGE='docksal/mysql:5.7-1.4'
26 | # MySQL will be exposed on a random port. By default. This sets it to 3306
27 | MYSQL_PORT_MAPPING='0:3306'
28 |
29 | # Disable debugging by default
30 | XDEBUG_ENABLED=0
31 |
32 | # Define which starters to use
33 | BACKEND_STARTER="development"
34 | FRONTEND_STARTER="development"
35 | ```
36 |
37 | ### Overriding with `docksal-local.env`
38 |
39 | Any Docksal environment variables can be overridden by including theme in the `docksal-local.env` file.
40 |
41 | ## Power Stack config files
42 |
--------------------------------------------------------------------------------
/docs/pages/docs/3-Development/packages.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Packages
3 | section: Development
4 | slug: /docs/developing/packages
5 | order: 3
6 | ---
7 |
8 | # Packages
9 |
10 | ## About packages
11 |
12 | Power Stack is using a monorepo to create and manage packages.
13 |
14 | ## Packages
15 |
16 | One of the key goals for our packages is to be centrally managed but then distributed to their respective open-source
17 | project (e.g. a Drupal module or Gatsby Theme/Plugin).
18 |
19 | A new package should contain the following in addition to any specific code.
20 |
21 | ```
22 | .github/workflows/auto_close_prs.yml
23 | README.md
24 | LICENSE.md
25 | ```
26 |
27 | In the `.github/workflows/auto_close_prs.yml` there should be a workflow definition to close package PRs automatically
28 | and advise to go to the main project
29 |
30 | ```yaml
31 | name: Auto Closer PR
32 |
33 | on:
34 | pull_request_target:
35 | types: [opened]
36 |
37 | jobs:
38 | run:
39 | runs-on: ubuntu-latest
40 | steps:
41 | - uses: superbrothers/close-pull-request@v3
42 | with:
43 | # Optional. Post a issue comment just before closing a pull request.
44 | comment: |
45 | Hi, thank you for your contribution.
46 | Unfortunately, this repository is read-only. It's a split from our main monorepo repository.
47 | We'd like to kindly ask you to move the contribution there - https://github.com/powerstackdev/power-stack.
48 | We'll check it, review it and give you feed back right way.
49 | Thank you.
50 | ```
51 |
52 |
53 | ## Creating a new package
54 |
55 | The naming convention for the package repos is `{service}-{package}`.
56 |
57 | ## Creating a new starter
58 |
59 | The naming convention for the starter repos is `{service}-starter-{package}`.
60 |
--------------------------------------------------------------------------------
/docs/pages/docs/3-Development/scripts.mdx:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Create ASCII art
4 |
5 | https://patorjk.com/software/taag/#p=display&f=Slant&t=
6 |
--------------------------------------------------------------------------------
/docs/pages/docs/5-Guides/dashboard.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Using the dashboard
3 | section: Guides
4 | slug: /docs/guides/using-the-dashboard/
5 | order: 2
6 | ---
7 |
8 | # Using the Dashboard
9 |
10 | Getting started with Power Stack Dashboard
11 |
12 | ## Accessing your dashboard
13 |
14 | Once Docksal has been initialised, you will be able to access http://power-stack.docksal.site/.
15 |
16 |
17 |
18 | ### Login
19 |
20 | When prompted to login, use the credentials provided in the terminal from your install.
21 |
--------------------------------------------------------------------------------
/docs/pages/docs/5-Guides/images/dashboard/Dashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/docs/pages/docs/5-Guides/images/dashboard/Dashboard.png
--------------------------------------------------------------------------------
/docs/pages/docs/5-Guides/local-development.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Developing locally
3 | section: Guides
4 | slug: /docs/local-development/
5 | order: 3
6 | ---
7 |
8 | # Local development
9 |
10 | Our local development setup is built using Docksal.
11 |
12 |
--------------------------------------------------------------------------------
/docs/pages/docs/6-Reference/known-issues.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Known issues
3 | section: Reference
4 | slug: /docs/reference/known-issues
5 | order: 100
6 | ---
7 |
8 | # Known issues
9 |
10 | A list to reference if you run into issues
11 |
12 | ## Paragraphs structure requires manual configuration
13 |
14 | Currently, when creating a new component by making a new Paragraph using the Drupal backend, it requires that you setup
15 | the field groups manually. At a later date, we will provide a module in Drupal to create these groupings automatically.
16 |
17 | ## Running a Gatsby site within a Docker container
18 |
19 | When running Gatsby within a Docker container there are few specific settings that you will need to configure
20 | otherwise you may run into unexpected behaviours. For more information refer to the
21 |
22 | ## Pubkey issue with clone on install
23 |
24 | While this repo is private, there maybe some issues cloning. If your ssh-agent for Docksal isn't loaded into the
25 | current terminal window, you'll need to initialise it first. This will sync the `id_rsa` key for you.
26 |
27 | ```
28 | fin system reset ssh-agent
29 | ```
30 |
--------------------------------------------------------------------------------
/docs/pages/docs/6-Reference/useful-links.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Useful links
3 | section: Reference
4 | slug: /docs/reference/useful-links
5 | order: 1
6 | ---
7 |
8 | # Useful links
9 |
10 | Some handy links to reference if you run into issues
11 |
12 | ## Drupal
13 |
14 | - https://www.drupal.org/
15 | - https://www.drupal.org/documentation
16 |
17 | ## Tina
18 |
19 | - https://tina.io/
20 | - https://tina.io/docs/
21 |
22 | ## Gatsby
23 |
24 | - https://www.gatsbyjs.com/
25 | - https://www.gatsbyjs.com/docs
26 |
27 | ## Smooth Doc
28 | https://smooth-doc.com/
29 | https://smooth-doc.com/docs/getting-started/
30 |
31 | ## Theme UI
32 |
33 | - https://theme-ui.com/
34 | - https://theme-ui.com/getting-started
35 |
36 | ## Monorepos
37 |
38 | - https://classic.yarnpkg.com/lang/en/docs/workspaces/
39 | - https://github.com/splitsh/lite
40 |
41 | ## Other
42 |
43 | https://12factor.net/
--------------------------------------------------------------------------------
/docs/pages/drafts/4-Components/column.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Column
3 | section: Components
4 | slug: /docs/components/column
5 | order: 2
6 | ---
7 |
8 | # Column
9 |
--------------------------------------------------------------------------------
/docs/pages/drafts/4-Components/image.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Image
3 | section: Components
4 | slug: /docs/components/image
5 | order: 3
6 | ---
7 |
8 | # Image
9 |
--------------------------------------------------------------------------------
/docs/pages/drafts/4-Components/section.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Section
3 | section: Components
4 | slug: /docs/components/section
5 | order: 1
6 | ---
7 |
8 | # Section
9 |
--------------------------------------------------------------------------------
/docs/pages/drafts/4-Components/text.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Text
3 | section: Components
4 | slug: /docs/components/text
5 | order: 3
6 | ---
7 |
8 | # Text
9 |
--------------------------------------------------------------------------------
/docs/pages/drafts/4-Components/title.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Title
3 | section: Components
4 | slug: /docs/components/title
5 | order: 3
6 | ---
7 |
8 | # Title
9 |
10 |
11 |
--------------------------------------------------------------------------------
/docs/pages/drafts/field-groups.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Field groups
3 | section: Core concepts
4 | slug: /docs/core-concepts/fields-groups
5 | ---
6 |
7 | ## Drupal groups to Tina groups
8 |
9 |
--------------------------------------------------------------------------------
/docs/pages/drafts/fields.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Fields
3 | section: Core concepts
4 | slug: /docs/core-concepts/fields
5 | ---
6 |
7 | # Fields
8 |
9 | ## Data type mappings
10 | ### Drupal core fields to Tina Fields
11 |
12 | | Name | Current Support | Drupal | Tina | Tina Inline |
13 | | ---- | --------------- | ------ | ---- | ----------- |
14 | | `Text` | 🟢 | text | Text | InlineText |
15 | | `Long Text` | 🟢 | text_long | Textarea | InlineTextarea |
16 | | `Long Text with Summary` | 🔴 | text_with_summary | ❌ | ❌ |
17 | | `WYSIWYG` | 🟢 | text_long (with HTML formatter) | HTML | InlineWysiwyg |
18 | | `Boolean` | 🟡 | list_boolean | [Toggle](https://tina.io/docs/reference/toolkit/fields/toggle/) | ❌ |
19 | | `List (Text)` | 🟡 | list_text | [Select](https://tina.io/docs/reference/toolkit/fields/select/) | ❌ |
20 | | `List (Integer)` | 🔵 | list_integer | ❌ | ❌ |
21 | | `List (Float)` | 🔴 | list_float | ❌ | ❌ |
22 | | `Integer` | 🟡 | number_integer | [Number](https://tina.io/docs/reference/toolkit/fields/number/) | ❌ |
23 | | `Float` | 🔴 | number_float | ❌ | ❌ |
24 | | `Decimal` | 🔴 | number_decimal | ❌ | ❌ |
25 | | `Image` | 🟢 | image | HTML | Image |
26 | | `File` | 🔵 | file | ❌ | ❌ |
27 | | `Term Reference` | 🔵 | taxonomy_term_reference | ❌ | ❌ |
28 |
29 | 🟢 Full support 🟡 Partial support 🔴 No support 🔵 Future support planned
30 |
31 | ### Drupal contrib fields to Tina Fields
32 |
33 | | Name | Current Support | Drupal | Tina | Tina Inline |
34 | | ---- | --------------- | ------ | ---- | ----------- |
35 | | `Color` | 🟢 | text | Color | ❌ |
36 |
37 | 🟢 Full support 🟡 Partial support 🔴 No support 🔵 Future support planned
--------------------------------------------------------------------------------
/docs/partials/getting-started.mdx:
--------------------------------------------------------------------------------
1 | ## What is Power Stack?
2 |
3 | Power Stack is an open-source digital experience platform (DXP) project.
4 |
5 | Built on open data and modern web technologies, Power Stack revolutionizes tools for marketing and development teams giving flexibility to put customers at the heart of their digital portfolio.
6 |
7 | ## Try the pre-alpha today!
8 |
9 | Hopefully, if you've read this far, you're convinced and want to try Power Stack. We've tried to make development and setup as easy as possible using Docksal.
10 |
11 | Our 1-command install generates a preconfigured ready-to-use project with all the needed dependencies.
12 |
--------------------------------------------------------------------------------
/docs/src/smooth-doc/components/ColorModeSwitcher.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { x, useColorMode } from '@xstyled/styled-components'
3 | import { RiMoonClearLine, RiSunLine } from 'react-icons/ri'
4 |
5 | const modeIcons = {
6 | light: RiMoonClearLine,
7 | dark: RiSunLine,
8 | }
9 |
10 | function getInverseMode(mode) {
11 | return mode === 'light' ? 'dark' : 'light'
12 | }
13 |
14 | export const ColorModeSwitcher = React.forwardRef((props, ref) => {
15 | const [mode, setMode] = useColorMode()
16 | const Icon = modeIcons[mode]
17 | return (
18 | setMode(getInverseMode)}
22 | {...props}
23 | >
24 |
25 |
26 | )
27 | })
28 |
--------------------------------------------------------------------------------
/docs/src/smooth-doc/components/Feature.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable jsx-a11y/accessible-emoji */
2 | /* eslint-disable import/no-extraneous-dependencies */
3 | import React from 'react'
4 | import styled, { th, x } from '@xstyled/styled-components'
5 | import { IconContext } from 'react-icons'
6 | import { ScreenContainer } from './ScreenContainer'
7 |
8 | const InnerFeature = styled.box`
9 | background: white;
10 | border-radius: 0.5rem;
11 | border: 1px solid #EAECF0;
12 | box-shadow: 0px 1px 3px rgb(16 24 40 / 10%), 0px 1px 2px rgb(16 24 40 / 6%);
13 | padding: 1.6rem;
14 | text-align: center;
15 | `
16 |
17 | export const Feature = React.forwardRef((props, ref) => (
18 |
22 | ))
23 |
24 | export const FeatureTitle = styled.h2`
25 | margin: 3 0;
26 | font-size: 18;
27 | font-weight: bold;
28 | text-align: center;
29 | `
30 |
31 | export const FeatureText = styled.p`
32 | color: on-background-light;
33 | font-size: 18;
34 | text-align: center;
35 | margin: 4 0;
36 | `
37 |
38 | const InnerFeatureImage = styled.img`
39 | margin-top: 3;
40 | `
41 |
42 | export const FeatureImage = React.forwardRef((props, ref) => (
43 |
44 | ))
45 |
46 | export const FeatureList = React.forwardRef((props, ref) => (
47 |
48 |
49 |
50 | ))
51 |
52 | export const FeatureSection = React.forwardRef((props, ref) => (
53 |
59 | ))
60 |
--------------------------------------------------------------------------------
/docs/src/smooth-doc/components/Head.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { graphql, useStaticQuery } from 'gatsby'
3 | import { SEO } from './SEO'
4 |
5 | const HeadQuery = graphql`
6 | query HeadQueryShadow {
7 | site {
8 | siteMetadata {
9 | title
10 | }
11 | }
12 | }
13 | `
14 |
15 | export function Head({ title }) {
16 | const data = useStaticQuery(HeadQuery)
17 | return (
18 |
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/docs/src/smooth-doc/components/Input.js:
--------------------------------------------------------------------------------
1 | import styled from '@xstyled/styled-components'
2 |
3 | export const Input = styled.input`
4 | appearance: none;
5 | background-color: control-background;
6 | border-radius: control;
7 | border-style: solid;
8 | border-width: control;
9 | border-color: control-border;
10 | line-height: control;
11 | padding: 1 2;
12 | color: control-on;
13 | transition: control;
14 |
15 | &::placeholder {
16 | color: control-placeholder;
17 | }
18 |
19 | &:hover {
20 | border-color: control-border-hover;
21 | }
22 |
23 | &:focus {
24 | outline: none;
25 | box-shadow: control-focus;
26 | border-color: control-border-active;
27 | }
28 | `
29 |
30 | export const InputGroup = styled.div`
31 | display: inline-flex;
32 | color: control-placeholder;
33 | transition: control;
34 | position: relative;
35 |
36 | &:focus-within {
37 | color: control-on;
38 | }
39 |
40 | > ${Input} {
41 | flex: 1 1 auto;
42 | width: 1%;
43 | min-width: 0;
44 | padding-left: 32;
45 | }
46 |
47 | > .algolia-autocomplete {
48 | flex: 1 1 auto;
49 | width: 1%;
50 | min-width: 0;
51 |
52 | > ${Input} {
53 | padding-left: 32;
54 | }
55 | }
56 | `
57 |
58 | export const InputGroupIcon = styled.div`
59 | display: flex;
60 | position: absolute;
61 | padding: 1 2;
62 | height: 100%;
63 | align-items: center;
64 | user-select: none;
65 | pointer-events: none;
66 | z-index: 1;
67 | `
68 |
--------------------------------------------------------------------------------
/docs/src/smooth-doc/components/MDX.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { MDXProvider as BaseMDXProvider } from '@mdx-js/react'
3 | import { Code } from './Code'
4 | import { CarbonAd } from './CarbonAd'
5 | import { Table, TableContainer } from './Table'
6 |
7 | function transformCode({ children, className, ...props }) {
8 | const lang = className && className.split('-')[1]
9 | return (
10 |
11 | {children}
12 |
13 | )
14 | }
15 |
16 | function getCodeChild(children) {
17 | const childrenArray = React.Children.toArray(children)
18 | if (childrenArray.length !== 1) return null
19 | const [firstChild] = childrenArray
20 | if (firstChild.props.mdxType !== 'code') return null
21 | return firstChild
22 | }
23 |
24 | export const mdxComponents = {
25 | 'carbon-ad': () => ,
26 | pre: ({ children }) => {
27 | const codeChild = getCodeChild(children)
28 | return codeChild ? transformCode(codeChild.props) : {children}
29 | },
30 | table: ({ children }) => {
31 | return (
32 |
33 | {children}
34 |
35 | )
36 | },
37 | }
38 |
39 | export function MDXProvider({ children, components }) {
40 | return (
41 |
42 | {children}
43 |
44 | )
45 | }
46 |
--------------------------------------------------------------------------------
/docs/src/smooth-doc/components/Nav.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Link } from 'gatsby'
3 | import styled, { x, th, down, css } from '@xstyled/styled-components'
4 |
5 | export const Nav = styled.navBox`
6 | ${down(
7 | 'md',
8 | css`
9 | overflow-x: auto;
10 | max-width: calc(100vw - ${th.px(72)}) !important;
11 | `,
12 | )}
13 | `
14 |
15 | const InnerNavLink = styled.aBox`
16 | display: inline-flex;
17 | color: on-link;
18 | font-weight: 800;
19 | transition: base;
20 | transition-property: color;
21 | text-decoration: none;
22 | cursor: pointer;
23 |
24 | &:hover,
25 | &:focus {
26 | color: on-background-light;
27 | }
28 |
29 | /* Reset button */
30 | appearance: none;
31 | border: 0;
32 | background: transparent;
33 | padding: 0;
34 | `
35 |
36 | export const NavLink = React.forwardRef((props, ref) => {
37 | return
38 | })
39 |
40 | export const NavListItem = styled.liBox`
41 | list-style-type: none;
42 | white-space: nowrap;
43 | margin: 0;
44 | padding: 0;
45 | padding-right: 3;
46 | display: flex;
47 | align-items: center;
48 | `
49 |
50 | export const NavList = React.forwardRef((props, ref) => {
51 | return (
52 |
61 | )
62 | })
63 |
--------------------------------------------------------------------------------
/docs/src/smooth-doc/components/NotFound.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { ScreenContainer } from './ScreenContainer'
3 | import { Article } from './Article'
4 |
5 | export function NotFound() {
6 | return (
7 |
8 |
9 | 404
10 |
11 | We couldn’t find what you were looking for.
12 |
13 |
14 |
19 |
20 |
21 | Please contact the owner of the site that linked you to the original
22 | URL and let them know their link is broken.
23 |
24 |
25 |
26 | )
27 | }
28 |
--------------------------------------------------------------------------------
/docs/src/smooth-doc/components/PageWrapper.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { PageLayout } from './PageLayout'
3 | import { DocLayout } from './DocLayout'
4 |
5 | export function PageWrapper({
6 | children,
7 | props: {
8 | data: { mdx },
9 | },
10 | }) {
11 | if (!mdx?.fields?.pageType) return children
12 | switch (mdx.fields.pageType) {
13 | case 'doc':
14 | return (
15 |
20 | {children}
21 |
22 | )
23 | case 'page':
24 | return {children}
25 | default:
26 | return children
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/docs/src/smooth-doc/components/RootWrapper.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { ColorModeProvider, Preflight } from '@xstyled/styled-components'
3 | import { MDXProvider } from './MDX'
4 | import { GlobalStyle, ThemeProvider } from './Theme'
5 |
6 | export function RootWrapper({ children }) {
7 | return (
8 |
9 |
10 |
11 |
12 | {children}
13 |
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/docs/src/smooth-doc/components/ScreenContainer.js:
--------------------------------------------------------------------------------
1 | import styled from '@xstyled/styled-components'
2 |
3 | export const ScreenContainer = styled.box`
4 | width: 100%;
5 | max-width: screen;
6 | margin: 0 auto;
7 | padding-left: 3;
8 | padding-right: 3;
9 | `
10 |
--------------------------------------------------------------------------------
/docs/src/smooth-doc/components/SiblingNav.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Link } from 'gatsby'
3 | import styled from '@xstyled/styled-components'
4 |
5 | export const InnerSiblingNavLink = styled.aBox`
6 | font-size: 18;
7 | transition: fast;
8 | text-decoration: none;
9 | color: on-link;
10 |
11 | &:hover {
12 | color: on-background-primary-dark;
13 | }
14 | `
15 |
16 | export const SiblingNavLink = React.forwardRef(
17 | ({ type, children, ...props }, ref) => {
18 | return (
19 |
26 | {type === 'previous' && '← '}
27 | {children}
28 | {type === 'next' && ' →'}
29 |
30 | )
31 | },
32 | )
33 |
34 | export const SiblingNav = styled.navBox`
35 | display: grid;
36 | grid-template-areas: 'previous next';
37 | justify-content: space-between;
38 | margin: 5 0;
39 | `
40 |
--------------------------------------------------------------------------------
/docs/src/smooth-doc/components/Table.js:
--------------------------------------------------------------------------------
1 | import styled, { up, css } from '@xstyled/styled-components'
2 |
3 | export const TableContainer = styled.div`
4 | overflow-y: auto;
5 | margin: 3 0 2;
6 |
7 | ${up(
8 | 'lg',
9 | css`
10 | max-height: 100%;
11 | `,
12 | )}
13 | `
14 |
15 | export const Table = styled.table`
16 | width: 100%;
17 | text-align: left;
18 | border-collapse: collapse;
19 | font-size: 90%;
20 |
21 | tr {
22 | background-color: transparent;
23 | }
24 |
25 | td,
26 | th {
27 | padding: 2 3;
28 | }
29 |
30 | th {
31 | color: on-background-light;
32 | background-color: background-light;
33 | font-weight: 600;
34 | z-index: 20;
35 | position: sticky;
36 | top: 0;
37 | }
38 |
39 | td {
40 | font-size: 85%;
41 | border-top: 1;
42 | border-bottom: 1;
43 | border-color: layout-border;
44 | }
45 | `
46 |
--------------------------------------------------------------------------------
/docs/src/smooth-doc/components/Theme.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | createGlobalStyle,
4 | ThemeProvider as SCThemeProvider,
5 | th,
6 | } from '@xstyled/styled-components'
7 | import { theme } from '../theme'
8 |
9 | export const GlobalStyle = createGlobalStyle`
10 | ${th('global')}
11 | `
12 |
13 | export function ThemeProvider({ children }) {
14 | return {children}
15 | }
16 |
--------------------------------------------------------------------------------
/docs/src/smooth-doc/components/index.js:
--------------------------------------------------------------------------------
1 | export * from './Article'
2 | export * from './Button'
3 | export * from './Code'
4 | export * from './ColorModeSwitcher'
5 | export * from './Feature'
6 | export * from './Hero'
7 | export * from './Nav'
8 | export * from './ScreenContainer'
9 | export * from './SiblingNav'
10 |
--------------------------------------------------------------------------------
/docs/src/smooth-doc/theme.js:
--------------------------------------------------------------------------------
1 | // src/smooth-doc/theme.js
2 | import { theme as baseTheme } from 'smooth-doc/src/theme'
3 | import { th } from '@xstyled/styled-components'
4 |
5 |
6 | export const theme = {
7 | ...baseTheme,
8 | fonts: {
9 | ...baseTheme.fonts,
10 | base: 'Mulish',
11 | },
12 | colors: {
13 | ...baseTheme.colors,
14 | 'primary-50': '#FFF0B8',
15 | 'primary-100': '#FFEBA3',
16 | 'primary-200': '#FFE27A',
17 | 'primary-300': '#FFDA52',
18 | 'primary-400': '#FFD129',
19 | 'primary-500': '#FFC800',
20 | 'primary-600': '#C79C00',
21 | 'primary-700': '#8F7000',
22 | 'primary-800': '#574400',
23 | 'primary-900': '#1F1800',
24 | primary: '#ffc800', // primary-500
25 | background: '#FCFCFD',
26 | white: '#FFF',
27 | 'on-background': '#000',
28 | 'on-link': 'rgb(52, 64, 84)',
29 | modes: {
30 | dark: {
31 | ...baseTheme.colors.modes.dark,
32 | white: th.color('gray-900'),
33 | 'on-background': '#FFF',
34 | 'on-link': '#FFF'
35 | }
36 | }
37 | },
38 | }
--------------------------------------------------------------------------------
/frontend/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | globals: {
3 | __PATH_PREFIX__: true,
4 | },
5 | extends: `react-app`,
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .cache/
3 | public
4 | *.env*
5 |
6 | coverage*
7 | .pnp.*
8 | .yarn/*
9 | !.yarn/patches
10 | !.yarn/plugins
11 | !.yarn/releases
12 | !.yarn/sdks
13 | !.yarn/versions
--------------------------------------------------------------------------------
/frontend/.prettierignore:
--------------------------------------------------------------------------------
1 | .cache
2 | .next
3 | .yarn
4 | tailwind.config.ts
5 | package.json
6 | package-lock.json
7 | public
8 |
--------------------------------------------------------------------------------
/frontend/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "endOfLine": "lf",
3 | "semi": false,
4 | "singleQuote": false,
5 | "tabWidth": 2,
6 | "trailingComma": "es5"
7 | }
8 |
--------------------------------------------------------------------------------
/frontend/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
3 | plugins:
4 | - path: .yarn/plugins/@yarnpkg/plugin-version.cjs
5 | spec: "@yarnpkg/plugin-version"
6 |
7 | yarnPath: .yarn/releases/yarn-3.2.2.cjs
8 |
--------------------------------------------------------------------------------
/frontend/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = { presets: ["@babel/preset-env"] }
2 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/@powerstack/docker-webpack-polling/.github/workflows/auto_close_prs.yml:
--------------------------------------------------------------------------------
1 | name: Auto Closer PR
2 |
3 | on:
4 | pull_request_target:
5 | types: [opened]
6 |
7 | jobs:
8 | run:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: superbrothers/close-pull-request@v3
12 | with:
13 | # Optional. Post a issue comment just before closing a pull request.
14 | comment: |
15 | Hi, thank you for your contribution.
16 | Unfortunately, this repository is read-only. It's a split from our main monorepo repository.
17 | We'd like to kindly ask you to move the contribution there - https://github.com/powerstackdev/power-stack.
18 | We'll check it, review it and give you feed back right way.
19 | Thank you.
20 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/@powerstack/docker-webpack-polling/gatsby-node.js:
--------------------------------------------------------------------------------
1 | exports.onCreateWebpackConfig = ({ actions, getConfig }) => {
2 | actions.setWebpackConfig({
3 | watchOptions: {
4 | aggregateTimeout: 200,
5 | poll: 1000,
6 | ignored: "**/node_modules",
7 | },
8 | })
9 | }
10 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/@powerstack/docker-webpack-polling/index.js:
--------------------------------------------------------------------------------
1 | // noop
2 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/@powerstack/docker-webpack-polling/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@powerstack/docker-webpack-polling",
3 | "main": "index.js",
4 | "version": "1.0.1"
5 | }
6 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/@powerstack/drupal-oauth-connector/.github/workflows/auto_close_prs.yml:
--------------------------------------------------------------------------------
1 | name: Auto Closer PR
2 |
3 | on:
4 | pull_request_target:
5 | types: [opened]
6 |
7 | jobs:
8 | run:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: superbrothers/close-pull-request@v3
12 | with:
13 | # Optional. Post a issue comment just before closing a pull request.
14 | comment: |
15 | Hi, thank you for your contribution.
16 | Unfortunately, this repository is read-only. It's a split from our main monorepo repository.
17 | We'd like to kindly ask you to move the contribution there - https://github.com/powerstackdev/power-stack.
18 | We'll check it, review it and give you feed back right way.
19 | Thank you.
20 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/@powerstack/drupal-oauth-connector/index.js:
--------------------------------------------------------------------------------
1 | export * from "./src/Auth"
2 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/@powerstack/drupal-oauth-connector/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@powerstack/drupal-oauth-connector",
3 | "main": "index.js",
4 | "version": "1.0.1",
5 | "dependencies": {
6 | "@powerstack/utils": "workspace:*",
7 | "js-cookie": "^3.0.1",
8 | "set-cookie-parser": "^2.4.8"
9 | },
10 | "peerDependencies": {
11 | "form-data": "^4.0.0",
12 | "gatsby": "^4.5"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-craftjs/.github/workflows/auto_close_prs.yml:
--------------------------------------------------------------------------------
1 | name: Auto Closer PR
2 |
3 | on:
4 | pull_request_target:
5 | types: [opened]
6 |
7 | jobs:
8 | run:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: superbrothers/close-pull-request@v3
12 | with:
13 | # Optional. Post a issue comment just before closing a pull request.
14 | comment: |
15 | Hi, thank you for your contribution.
16 | Unfortunately, this repository is read-only. It's a split from our main monorepo repository.
17 | We'd like to kindly ask you to move the contribution there - https://github.com/powerstackdev/power-stack.
18 | We'll check it, review it and give you feed back right way.
19 | Thank you.
20 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-craftjs/index.js:
--------------------------------------------------------------------------------
1 | // noop
2 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-craftjs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gatsby-plugin-craftjs",
3 | "version": "1.0.1",
4 | "main": "index.js",
5 | "dependencies": {
6 | "@craftjs/core": "^0.2.0-beta.6",
7 | "@craftjs/utils": "^0.2.0-beta.6",
8 | "gatsby-theme-drupal-admin": "workspace:*",
9 | "react-tabs": "^5.1.0"
10 | },
11 | "peerDependencies": {
12 | "gatsby": "^4.0.0",
13 | "react": "^17.0.0 || ^18.0.0",
14 | "react-dom": "^17.0.0 || ^18.0.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-tinacms-pagebuilder/.github/workflows/auto_close_prs.yml:
--------------------------------------------------------------------------------
1 | name: Auto Closer PR
2 |
3 | on:
4 | pull_request_target:
5 | types: [opened]
6 |
7 | jobs:
8 | run:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: superbrothers/close-pull-request@v3
12 | with:
13 | # Optional. Post a issue comment just before closing a pull request.
14 | comment: |
15 | Hi, thank you for your contribution.
16 | Unfortunately, this repository is read-only. It's a split from our main monorepo repository.
17 | We'd like to kindly ask you to move the contribution there - https://github.com/powerstackdev/power-stack.
18 | We'll check it, review it and give you feed back right way.
19 | Thank you.
20 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-tinacms-pagebuilder/README.md:
--------------------------------------------------------------------------------
1 | # Gatsby Plugin TinaCMS Pagebuilder
2 |
3 | This plugin provides the integration between Drupal, TinaCMS and Gatsby.
4 |
5 | ```
6 | .
7 | ├── __tests__
8 | └── src
9 | ├── api
10 | │ └── fetch
11 | ├── contexts
12 | ├── pages
13 | │ └── edit
14 | │ ├── new
15 | │ └── page
16 | └── utils
17 | ```
18 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-tinacms-pagebuilder/__tests__/fieldUtils.test.js:
--------------------------------------------------------------------------------
1 | import {
2 | drupalFieldTypeToTinaFieldType,
3 | defaultField,
4 | } from "../src/utils/fieldUtils"
5 |
6 | it("Drupal fields convert to Tina fields", () => {
7 | expect(drupalFieldTypeToTinaFieldType("string_textfield")).toEqual("text")
8 | expect(drupalFieldTypeToTinaFieldType("boolean_checkbox")).toEqual("toggle")
9 | expect(drupalFieldTypeToTinaFieldType("boolean")).toEqual("toggle")
10 | expect(drupalFieldTypeToTinaFieldType("language_select")).toEqual("select")
11 | expect(drupalFieldTypeToTinaFieldType("list_string")).toEqual("select")
12 | expect(
13 | drupalFieldTypeToTinaFieldType("entity_reference_autocomplete")
14 | ).toEqual("select")
15 | expect(drupalFieldTypeToTinaFieldType("datetime_timestamp")).toEqual("date")
16 | expect(drupalFieldTypeToTinaFieldType("something_else")).toEqual("text")
17 | })
18 |
19 | it("Default field to format data for Tina format", () => {
20 | expect(defaultField("name", { name: "test", label: "test" })).toEqual({
21 | component: "text",
22 | label: "test",
23 | name: "name",
24 | })
25 | expect(defaultField("name", { name: "test", label: "test" }))
26 | })
27 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-tinacms-pagebuilder/gatsby-config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [
3 | "gatsby-theme-core-design-system",
4 | {
5 | resolve: "gatsby-plugin-tinacms",
6 | options: {
7 | editPath: `/edit/`,
8 | enabled: true,
9 | toolbar: true,
10 | sidebar: {
11 | position: `displace`,
12 | },
13 | },
14 | },
15 | ],
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-tinacms-pagebuilder/gatsby-node.js:
--------------------------------------------------------------------------------
1 | var webpack = require("webpack")
2 |
3 | exports.onCreateWebpackConfig = ({ actions }) => {
4 | actions.setWebpackConfig({
5 | experiments: {
6 | topLevelAwait: true,
7 | },
8 | plugins: [
9 | new webpack.ProvidePlugin({
10 | process: "process",
11 | util: "util",
12 | }),
13 | ],
14 | resolve: {
15 | fallback: {
16 | process: "process",
17 | util: "util",
18 | },
19 | },
20 | })
21 | }
22 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-tinacms-pagebuilder/index.js:
--------------------------------------------------------------------------------
1 | // noop
2 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-tinacms-pagebuilder/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gatsby-plugin-tinacms-pagebuilder",
3 | "main": "index.js",
4 | "version": "1.0.1",
5 | "dependencies": {
6 | "@loadable/component": "^5.15.2",
7 | "@tinacms/icons": "^0.42.1",
8 | "@tinacms/react-forms": "^0.43.3",
9 | "@tinacms/toolkit": "0.56.4",
10 | "gatsby-plugin-tinacms": "workspace:^",
11 | "gatsby-theme-core-design-system": "workspace:^",
12 | "lodash.set": "^4.3.2",
13 | "process": "^0.11.10",
14 | "qs": "^6.10.2",
15 | "react-tinacms-editor": "^0.52.10",
16 | "react-tinacms-inline": "0.52.3",
17 | "styled-components": "^5.1.3",
18 | "treeify-js": "^1.0.8",
19 | "util": "^0.12.4"
20 | },
21 | "peerDependencies": {
22 | "gatsby": "^4.0.0",
23 | "react": "^17.0.0 || ^18.0.0",
24 | "react-dom": "^17.0.0 || ^18.0.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-tinacms-pagebuilder/src/api/fetch/postRequestUtils.js:
--------------------------------------------------------------------------------
1 | import axios from "axios"
2 | import qs from "qs"
3 | import { isTinaWindow } from "../../utils/tinaUtils"
4 |
5 | export const submitTinaDataToDrupal = (data) => {
6 | axios
7 | .post(
8 | process.env.GATSBY_DRUPAL_HOST + `/api/tinacms/page/create`,
9 | qs.stringify({
10 | json_data: data,
11 | })
12 | )
13 | .then(
14 | (response) => {
15 | isTinaWindow && window.tinacms.alerts.success("Saved!")
16 | },
17 | (error) => {
18 | isTinaWindow && window.tinacms.alerts.error("Error saving")
19 | }
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-tinacms-pagebuilder/src/contexts/PageBuilderContext.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 |
3 | export const PageBuilderContext = React.createContext()
4 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-tinacms-pagebuilder/src/utils/fieldUtils.js:
--------------------------------------------------------------------------------
1 | import {
2 | languageSelectField,
3 | userSelectField,
4 | publishStatusToggleField,
5 | } from "./listUtils"
6 | import { capitalize } from "@powerstack/utils"
7 |
8 | export const drupalFieldTypeToTinaFieldType = (type) => {
9 | switch (type) {
10 | case "string_textfield":
11 | return "text"
12 | case "boolean_checkbox":
13 | case "boolean":
14 | return "toggle"
15 | case "language_select":
16 | case "list_string":
17 | return "select"
18 | case "entity_reference_autocomplete":
19 | return "select"
20 | case "datetime_timestamp":
21 | return "date"
22 | default:
23 | return "text"
24 | }
25 | }
26 |
27 | export const defaultField = (name, fieldData) => {
28 | const type = fieldData.type || fieldData.field_type
29 | const label = fieldData.label || capitalize(name)
30 |
31 | return {
32 | label,
33 | name: name,
34 | component: drupalFieldTypeToTinaFieldType(type),
35 | }
36 | }
37 |
38 | export const createTinaField = (name, fieldData, serverData) => {
39 | if (name === "status") {
40 | return publishStatusToggleField(name, fieldData)
41 | }
42 |
43 | if (name === "uid") {
44 | return userSelectField(name, fieldData, serverData)
45 | }
46 |
47 | if (fieldData.type === "language_select") {
48 | return languageSelectField(name, fieldData, serverData)
49 | }
50 |
51 | return defaultField(name, fieldData)
52 | }
53 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-tinacms-pagebuilder/src/utils/inits.js:
--------------------------------------------------------------------------------
1 | import { useForm, usePlugin, useScreenPlugin } from "tinacms"
2 |
3 | // These init functions are a bit of a hack to get around the conditional rules of hooks error
4 |
5 | export const InitForm = (formConfig) => {
6 | return useForm(formConfig)
7 | }
8 |
9 | export const InitPlugin = (form) => {
10 | usePlugin(form)
11 |
12 | return null
13 | }
14 |
15 | export const InitScreenPlugin = (screenPlugin) => {
16 | useScreenPlugin(screenPlugin)
17 |
18 | return null
19 | }
20 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-tinacms/.github/workflows/auto_close_prs.yml:
--------------------------------------------------------------------------------
1 | name: Auto Closer PR
2 |
3 | on:
4 | pull_request_target:
5 | types: [opened]
6 |
7 | jobs:
8 | run:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: superbrothers/close-pull-request@v3
12 | with:
13 | # Optional. Post a issue comment just before closing a pull request.
14 | comment: |
15 | Hi, thank you for your contribution.
16 | Unfortunately, this repository is read-only. It's a split from our main monorepo repository.
17 | We'd like to kindly ask you to move the contribution there - https://github.com/powerstackdev/power-stack.
18 | We'll check it, review it and give you feed back right way.
19 | Thank you.
20 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-tinacms/gatsby-browser.js:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { TinaProvider, TinaCMS } from "tinacms"
3 | import DrupalMediaStore from "./src/DrupalMediaStore"
4 |
5 | export const wrapRootElement = (
6 | { element },
7 | { editPath, enabled, toolbar, sidebar }
8 | ) => {
9 | if (window.location.pathname.startsWith(editPath)) {
10 | window.tinacms = new TinaCMS({
11 | enabled,
12 | toolbar,
13 | sidebar,
14 | media: new DrupalMediaStore(),
15 | })
16 | return {element}
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-tinacms/index.js:
--------------------------------------------------------------------------------
1 | // noop
2 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-plugin-tinacms/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gatsby-plugin-tinacms",
3 | "version": "1.0.1",
4 | "main": "index.js",
5 | "dependencies": {
6 | "axios": "^0.26.1",
7 | "tinacms": "^0.60.3"
8 | },
9 | "peerDependencies": {
10 | "gatsby": "^4.0.0",
11 | "react": "^17.0.0 || ^18.0.0",
12 | "react-dom": "^17.0.0 || ^18.0.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/.github/workflows/auto_close_prs.yml:
--------------------------------------------------------------------------------
1 | name: Auto Closer PR
2 |
3 | on:
4 | pull_request_target:
5 | types: [opened]
6 |
7 | jobs:
8 | run:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: superbrothers/close-pull-request@v3
12 | with:
13 | # Optional. Post a issue comment just before closing a pull request.
14 | comment: |
15 | Hi, thank you for your contribution.
16 | Unfortunately, this repository is read-only. It's a split from our main monorepo repository.
17 | We'd like to kindly ask you to move the contribution there - https://github.com/powerstackdev/power-stack.
18 | We'll check it, review it and give you feed back right way.
19 | Thank you.
20 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/gatsby-config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [],
3 | }
4 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/index.js:
--------------------------------------------------------------------------------
1 | // noop
2 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gatsby-theme-core-design-system",
3 | "main": "index.js",
4 | "version": "1.0.1",
5 | "dependencies": {
6 | "@powerstack/drupal-oauth-connector": "workspace:*",
7 | "react-accessible-accordion": "^4.0.0",
8 | "react-icons": "^4.3.1",
9 | "react-reveal": "^1.2.2",
10 | "recharts": "^2.1.8",
11 | "rerousel": "^0.1.9"
12 | },
13 | "peerDependencies": {
14 | "gatsby": "^4.0.0",
15 | "react": "^17.0.0 || ^18.0.0",
16 | "react-dom": "^17.0.0 || ^18.0.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/src/components/Accordions/Accordion.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import {
3 | AccordionItem,
4 | AccordionItemButton,
5 | AccordionItemHeading,
6 | AccordionItemPanel,
7 | } from "react-accessible-accordion"
8 |
9 | export const Accordion = ({ data, index }) => {
10 | return (
11 |
12 |
13 | {data.heading}
14 |
15 | {data.supporting_copy}
16 |
17 | )
18 | }
19 |
20 | export const accordionBlock = {
21 | label: "Accordion Tab",
22 | key: "accordion",
23 | defaultItem: {
24 | _template: "accordion",
25 | heading: "Marie Skłodowska Curie",
26 | supporting_copy:
27 | "Rich in mystery muse about vastness is bearable only through love Ut enim ad minima veniam at the edge of forever are creatures of the cosmos. ",
28 | },
29 | itemProps: (item) => ({
30 | key: item.id,
31 | label: item.heading,
32 | }),
33 | fields: [
34 | {
35 | name: "heading",
36 | component: "text",
37 | label: "Heading",
38 | },
39 | {
40 | name: "supporting_copy",
41 | component: "textarea",
42 | label: "Description",
43 | },
44 | ],
45 | }
46 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/src/components/Blocks/Column.js:
--------------------------------------------------------------------------------
1 | import { Box } from "theme-ui"
2 | import { BlocksControls, InlineBlocks } from "react-tinacms-inline"
3 | import React from "react"
4 |
5 | export const EditColumn = ({ blockKey, availableBlocks, data, index }) => {
6 | console.log("triggered")
7 | return (
8 |
9 |
10 | test column
11 |
16 |
17 |
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/src/components/Blocks/Section.js:
--------------------------------------------------------------------------------
1 | import { Box } from "theme-ui"
2 | import { BlocksControls, InlineBlocks } from "react-tinacms-inline"
3 | import React from "react"
4 |
5 | export const EditSection = ({ blockKey, availableBlocks, data, index }) => {
6 | return (
7 |
15 |
16 |
21 |
22 |
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/src/components/Features/Feature.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { BlocksControls, InlineTextarea } from "react-tinacms-inline"
3 | import { Card, Text } from "theme-ui"
4 | import Zoom from "react-reveal/Zoom"
5 |
6 | function Feature({ index, data }) {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | )
21 | }
22 |
23 | export const featureBlock = {
24 | Component: Feature,
25 | template: {
26 | label: "Feature",
27 | defaultItem: {
28 | _template: "feature",
29 | heading: "Marie Skłodowska Curie",
30 | supporting_copy:
31 | "Rich in mystery muse about vastness is bearable only through love Ut enim ad minima veniam at the edge of forever are creatures of the cosmos. ",
32 | },
33 | fields: [],
34 | },
35 | }
36 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/src/components/Footers/Footer.js:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx, Link } from "theme-ui"
3 |
4 | export const Footer = () => (
5 |
37 | )
38 |
39 | export default Footer
40 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/src/components/Images/Image.js:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx } from "theme-ui"
3 | import React from "react"
4 | import { BlocksControls, InlineImage } from "react-tinacms-inline"
5 | import Zoom from "react-reveal/Zoom"
6 |
7 | function Image({ data, index }) {
8 | return (
9 |
10 |
18 |
19 | `${media.src}?id=${media.id}&vid=${media.vid}`}
22 | previewSrc={(src) => src}
23 | focusRing={false}
24 | />
25 |
26 |
27 |
28 | )
29 | }
30 |
31 | export const imageBlock = {
32 | Component: Image,
33 | template: {
34 | label: "Image",
35 | defaultItem: {
36 | _template: "image",
37 | image: {
38 | src: "/martin-sanchez-unsplash-square.jpg",
39 | },
40 | },
41 | fields: [
42 | {
43 | name: "image.src",
44 | label: "Image",
45 | component: "image",
46 | parse: (media) => `${media.src}?id=${media.id}&vid=${media.vid}`,
47 | previewSrc: (src) => src,
48 | focusRing: false,
49 | },
50 | {
51 | name: "image.alt",
52 | label: "Alt Text",
53 | component: "text",
54 | },
55 | ],
56 | },
57 | }
58 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/src/components/Layout/Layout.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Layout component that queries for data
3 | * with Gatsby's useStaticQuery component
4 | *
5 | * See: https://www.gatsbyjs.com/docs/use-static-query/
6 | */
7 |
8 | import * as React from "react"
9 | import PropTypes from "prop-types"
10 | import { graphql, useStaticQuery } from "gatsby"
11 |
12 | import Header, { AdminHeader } from "../Headers/Header"
13 |
14 | const Layout = ({ isAdmin, children, serverData }) => {
15 | const data = useStaticQuery(graphql`
16 | query SiteTitleQuery {
17 | site {
18 | siteMetadata {
19 | title
20 | }
21 | }
22 | }
23 | `)
24 |
25 | return (
26 | <>
27 | {isAdmin ? (
28 |
32 | ) : (
33 |
37 | )}
38 |
39 |
45 | {children}
46 |
47 | >
48 | )
49 | }
50 |
51 | Layout.propTypes = {
52 | children: PropTypes.node.isRequired,
53 | }
54 |
55 | export default Layout
56 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/src/components/Signposts/SignpostEmailSignup.js:
--------------------------------------------------------------------------------
1 | import Zoom from "react-reveal/Zoom"
2 | import { BlocksControls, InlineTextarea } from "react-tinacms-inline"
3 | import { Badge, Box, Button, Card, Input } from "theme-ui"
4 | import React from "react"
5 | import { MdEmail } from "react-icons/md"
6 |
7 | const SignpostEmailSignup = ({ index, data }) => {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | e.preventDefault()} sx={{ mt: 3 }}>
24 |
29 |
30 |
31 |
32 |
33 |
34 | )
35 | }
36 |
37 | export const signpostEmailSignupBlock = {
38 | Component: SignpostEmailSignup,
39 | template: {
40 | label: "Email Signup",
41 | defaultItem: {
42 | _template: "signpostEmailSignup",
43 | heading: "Sign up to our newsletter",
44 | supporting_copy:
45 | "We won't spam you or share your details with anyone else",
46 | },
47 | fields: [],
48 | },
49 | }
50 |
51 | export default signpostEmailSignupBlock
52 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/src/components/Text/Paragraph.js:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx } from "theme-ui"
3 | import Zoom from "react-reveal/Zoom"
4 |
5 | import { BlocksControls, InlineWysiwyg } from "react-tinacms-inline"
6 |
7 | export const Paragraph = ({ text }) => (
8 |
9 |
15 |
16 | )
17 |
18 | export const EditParagraph = ({ index, data }) => {
19 | return (
20 |
21 |
22 |
23 |
24 |
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/src/components/Text/Title.js:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx } from "theme-ui"
3 |
4 | import { InlineText } from "react-tinacms-inline"
5 | import Zoom from "react-reveal/Zoom"
6 | import { darken } from "@theme-ui/color"
7 |
8 | export const Title = ({ title }) => {
9 | return (
10 |
15 | `linear-gradient(45deg, ${theme.colors.secondary}, ${darken(
16 | "secondary",
17 | 0.15
18 | )(theme)})`,
19 | textAlign: `center`,
20 | }}
21 | >
22 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | )
38 | }
39 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/src/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/frontend/deprecated-packages/gatsby-theme-core-design-system/src/images/icon.png
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-core-design-system/src/images/quantum.svg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/frontend/deprecated-packages/gatsby-theme-core-design-system/src/images/quantum.svg
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-drupal-admin/.github/workflows/auto_close_prs.yml:
--------------------------------------------------------------------------------
1 | name: Auto Closer PR
2 |
3 | on:
4 | pull_request_target:
5 | types: [opened]
6 |
7 | jobs:
8 | run:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: superbrothers/close-pull-request@v3
12 | with:
13 | # Optional. Post a issue comment just before closing a pull request.
14 | comment: |
15 | Hi, thank you for your contribution.
16 | Unfortunately, this repository is read-only. It's a split from our main monorepo repository.
17 | We'd like to kindly ask you to move the contribution there - https://github.com/powerstackdev/power-stack.
18 | We'll check it, review it and give you feed back right way.
19 | Thank you.
20 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-drupal-admin/gatsby-config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [
3 | "gatsby-theme-core-design-system",
4 | {
5 | resolve: `gatsby-plugin-google-fonts`,
6 | options: {
7 | fonts: [
8 | `inter\:300,400,400i,500,600,700`, // you can also specify font weights and styles
9 | ],
10 | display: "swap",
11 | },
12 | },
13 | ],
14 | }
15 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-drupal-admin/gatsby-node.js:
--------------------------------------------------------------------------------
1 | var webpack = require("webpack")
2 |
3 | exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
4 | if (stage === "build-html" || stage === "develop-html") {
5 | actions.setWebpackConfig({
6 | module: {
7 | rules: [
8 | {
9 | test: /\@nosferatu500/,
10 | use: loaders.null(),
11 | },
12 | ],
13 | },
14 | plugins: [
15 | new webpack.ProvidePlugin({
16 | stream: "stream-browserify",
17 | url: "url",
18 | }),
19 | ],
20 | resolve: {
21 | fallback: {
22 | stream: "stream",
23 | url: "url",
24 | },
25 | },
26 | })
27 | } else {
28 | actions.setWebpackConfig({
29 | plugins: [
30 | new webpack.ProvidePlugin({
31 | stream: "stream-browserify",
32 | url: "url",
33 | }),
34 | ],
35 | resolve: {
36 | fallback: {
37 | stream: "stream-browserify",
38 | url: "url",
39 | },
40 | },
41 | })
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-drupal-admin/index.js:
--------------------------------------------------------------------------------
1 | // noop
2 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-drupal-admin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gatsby-theme-drupal-admin",
3 | "version": "1.0.1",
4 | "main": "index.js",
5 | "dependencies": {
6 | "@nosferatu500/theme-file-explorer": "^3.0.11",
7 | "@powerstack/docker-webpack-polling": "workspace:^",
8 | "absolution": "^1.0.2",
9 | "gatsby-plugin-google-fonts": "^1.0.1",
10 | "gatsby-theme-core-design-system": "workspace:^",
11 | "javascript-time-ago": "^2.3.10",
12 | "react-icons": "^4.4.0",
13 | "react-sortable-tree": "^2.8.0",
14 | "react-time-ago": "^7.1.4",
15 | "split-html": "^1.1.0",
16 | "stream-browserify": "^3.0.0",
17 | "url": "^0.11.0"
18 | },
19 | "peerDependencies": {
20 | "gatsby": "^4.0.0",
21 | "gatsby-plugin-theme-ui": "^0.12.0",
22 | "react": "^17.0.0 || ^18.0.0",
23 | "react-dom": "^17.0.0 || ^18.0.0"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-drupal-admin/src/components/Buttons/LoginLogoutButton.js:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx } from "theme-ui"
3 | import { Button } from "theme-ui"
4 | import React, { useEffect, useState } from "react"
5 | import { isLoggedIn } from "@powerstack/drupal-oauth-connector"
6 |
7 | export const LoginLogoutButton = () => {
8 | const [loggedIn, setLoggedIn] = useState(false)
9 |
10 | useEffect(() => {
11 | isLoggedIn().then((result) => {
12 | setLoggedIn(result)
13 | })
14 | }, [])
15 | return (
16 | -
23 | {loggedIn ? (
24 |
28 | ) : (
29 |
30 | )}
31 |
32 | )
33 | }
34 |
35 | export default LoginLogoutButton
36 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-drupal-admin/src/components/Buttons/NotificationsButton.js:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import React from "react"
3 | import { jsx, Button, Badge } from "theme-ui"
4 | import { FiBell } from "react-icons/fi"
5 |
6 | export const NotificationsButton = () => (
7 | <>
8 |
14 | >
15 | )
16 |
17 | export default NotificationsButton
18 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-drupal-admin/src/components/Buttons/SearchButton.js:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx, Button } from "theme-ui"
3 | import { FiSearch } from "react-icons/fi"
4 |
5 | export const SearchButton = () => (
6 |
9 | )
10 |
11 | export default SearchButton
12 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-drupal-admin/src/components/Buttons/SettingsButton.js:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx, Button } from "theme-ui"
3 | import { FiSettings } from "react-icons/fi"
4 |
5 | export const SettingsButton = () => (
6 |
9 | )
10 |
11 | export default SettingsButton
12 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-drupal-admin/src/components/Buttons/ToggleColorModeButton.js:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx, Button, useColorMode } from "theme-ui"
3 | import { FiSun, FiMoon } from "react-icons/fi"
4 |
5 | export const ToggleColorModeButton = (props) => {
6 | const [mode, setMode] = useColorMode()
7 |
8 | return (
9 |
19 | )
20 | }
21 |
22 | export default ToggleColorModeButton
23 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-drupal-admin/src/components/Layout/Layout.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Layout component that queries for data
3 | * with Gatsby's useStaticQuery component
4 | *
5 | * See: https://www.gatsbyjs.com/docs/use-static-query/
6 | */
7 |
8 | /** @jsx jsx */
9 | import { jsx } from "theme-ui"
10 |
11 | import * as React from "react"
12 | import PropTypes from "prop-types"
13 | import { graphql, useStaticQuery } from "gatsby"
14 |
15 | import Header, { AdminHeader } from "../Headers/Header"
16 |
17 | const Layout = ({ isFull, children, serverData }) => {
18 | const data = useStaticQuery(graphql`
19 | query AdminSiteTitleQuery {
20 | site {
21 | siteMetadata {
22 | title
23 | }
24 | }
25 | }
26 | `)
27 |
28 | return (
29 | <>
30 |
34 |
35 |
40 | {children}
41 |
42 | >
43 | )
44 | }
45 |
46 | Layout.propTypes = {
47 | children: PropTypes.node.isRequired,
48 | }
49 |
50 | export default Layout
51 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-tina-edit/.github/workflows/auto_close_prs.yml:
--------------------------------------------------------------------------------
1 | name: Auto Closer PR
2 |
3 | on:
4 | pull_request_target:
5 | types: [opened]
6 |
7 | jobs:
8 | run:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: superbrothers/close-pull-request@v3
12 | with:
13 | # Optional. Post a issue comment just before closing a pull request.
14 | comment: |
15 | Hi, thank you for your contribution.
16 | Unfortunately, this repository is read-only. It's a split from our main monorepo repository.
17 | We'd like to kindly ask you to move the contribution there - https://github.com/powerstackdev/power-stack.
18 | We'll check it, review it and give you feed back right way.
19 | Thank you.
20 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-tina-edit/gatsby-config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [
3 | "gatsby-theme-core-design-system",
4 | {
5 | resolve: "gatsby-plugin-tinacms",
6 | options: {
7 | editPath: `/edit/page`,
8 | enabled: true,
9 | toolbar: true,
10 | sidebar: {
11 | position: `overlay`,
12 | },
13 | },
14 | },
15 | ],
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-tina-edit/gatsby-node.js:
--------------------------------------------------------------------------------
1 | var webpack = require("webpack")
2 |
3 | exports.onCreateWebpackConfig = ({ actions }) => {
4 | actions.setWebpackConfig({
5 | experiments: {
6 | topLevelAwait: true,
7 | },
8 | plugins: [
9 | new webpack.ProvidePlugin({
10 | process: "process",
11 | util: "util",
12 | }),
13 | ],
14 | resolve: {
15 | fallback: {
16 | process: "process",
17 | util: "util",
18 | },
19 | },
20 | })
21 | }
22 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-tina-edit/index.js:
--------------------------------------------------------------------------------
1 | // noop
2 |
--------------------------------------------------------------------------------
/frontend/deprecated-packages/gatsby-theme-tina-edit/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gatsby-theme-tina-edit",
3 | "main": "index.js",
4 | "version": "1.0.1",
5 | "dependencies": {
6 | "@tinacms/icons": "^0.42.1",
7 | "@tinacms/react-forms": "^0.43.3",
8 | "@tinacms/toolkit": "^0.56.4",
9 | "gatsby-plugin-tinacms": "workspace:^",
10 | "gatsby-theme-core-design-system": "workspace:^",
11 | "process": "^0.11.10",
12 | "qs": "^6.10.2",
13 | "react-tinacms-editor": "^0.52.10",
14 | "react-tinacms-inline": "0.52.3",
15 | "styled-components": "^5.1.3",
16 | "util": "^0.12.4"
17 | },
18 | "peerDependencies": {
19 | "gatsby": "^4.0.0",
20 | "react": "^17.0.0 || ^18.0.0",
21 | "react-dom": "^17.0.0 || ^18.0.0"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend-layer",
3 | "private": true,
4 | "workspaces": [
5 | "starters/*",
6 | "packages/*"
7 | ],
8 | "packageManager": "yarn@3.2.2",
9 | "devDependencies": {
10 | "@babel/preset-env": "^7.18.10",
11 | "eslint": "8.21.0",
12 | "eslint-config-prettier": "^8.5.0",
13 | "eslint-config-react-app": "7.0.1",
14 | "eslint-plugin-prettier": "^4.2.1",
15 | "jest": "^28.1.3",
16 | "prettier": "2.7.1"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/.npmignore:
--------------------------------------------------------------------------------
1 | /coverage
2 | /CHANGELOG.md
3 | /tests
4 | /tsconfig.json
5 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/jest.config.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import('ts-jest').JestConfigWithTsJest} */
2 | module.exports = {
3 | preset: "ts-jest",
4 | testEnvironment: "node",
5 | setupFiles: ["dotenv/config"],
6 | setupFilesAfterEnv: ["/jest.setup.ts"],
7 | testMatch: ["**/tests/**/*.test.{ts,tsx}"],
8 | transform: {
9 | "^.+\\.tsx?$": [
10 | "ts-jest",
11 | {
12 | isolatedModules: true,
13 | },
14 | ],
15 | },
16 | testLocationInResults: true,
17 | coverageProvider: "v8",
18 | collectCoverage: true,
19 | collectCoverageFrom: ["./src/**"],
20 | coveragePathIgnorePatterns: [
21 | "./src/deprecated/*",
22 | "./src/deprecated.ts",
23 | "./src/navigation.ts",
24 | "./src/types/*",
25 | ],
26 | coverageReporters: ["lcov", "text", "text-summary"],
27 | coverageThreshold: {
28 | global: {
29 | statements: 100,
30 | branches: 100,
31 | functions: 100,
32 | lines: 100,
33 | },
34 | },
35 | }
36 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/jest.setup.ts:
--------------------------------------------------------------------------------
1 | import "isomorphic-fetch"
2 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/src/deprecated.ts:
--------------------------------------------------------------------------------
1 | export * from "./deprecated/get-menu"
2 | export * from "./deprecated/get-paths"
3 | export * from "./deprecated/get-resource-collection"
4 | export * from "./deprecated/preview"
5 | export * from "./deprecated/get-resource-type"
6 | export * from "./deprecated/get-resource"
7 | export * from "./deprecated/get-search-index"
8 | export * from "./deprecated/get-view"
9 | export * from "./deprecated/translate-path"
10 | export {
11 | deserialize,
12 | buildUrl,
13 | getJsonApiIndex,
14 | getJsonApiPathForResourceType,
15 | syncDrupalPreviewRoutes,
16 | } from "./deprecated/utils"
17 |
18 | export type * from "./types/deprecated"
19 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/src/draft-constants.ts:
--------------------------------------------------------------------------------
1 | export const DRAFT_DATA_COOKIE_NAME = "next_drupal_draft_data"
2 |
3 | // See https://vercel.com/docs/workflow-collaboration/draft-mode
4 | export const DRAFT_MODE_COOKIE_NAME = "__prerender_bypass"
5 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./draft-constants"
2 | export * from "./drupal-client"
3 | export * from "./next-drupal-fetch"
4 | export * from "./jsonapi-errors"
5 | export * from "./next-drupal"
6 |
7 | export type * from "./types"
8 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/src/jsonapi-errors.ts:
--------------------------------------------------------------------------------
1 | // https://jsonapi.org/format/#error-objects
2 | export interface JsonApiError {
3 | id?: string
4 | status?: string
5 | code?: string
6 | title?: string
7 | detail?: string
8 | links?: JsonApiLinks
9 | }
10 |
11 | // https://jsonapi.org/format/#document-links
12 | export interface JsonApiLinks {
13 | [key: string]: string | Record
14 | }
15 |
16 | export class JsonApiErrors extends Error {
17 | errors: JsonApiError[] | string
18 | statusCode: number
19 |
20 | constructor(errors: JsonApiError[] | string, statusCode: number) {
21 | super()
22 |
23 | this.errors = errors
24 | this.statusCode = statusCode
25 | this.message = JsonApiErrors.formatMessage(errors)
26 | }
27 |
28 | static formatMessage(errors: JsonApiError[] | string) {
29 | if (typeof errors === "string") {
30 | return errors
31 | }
32 |
33 | const [error] = errors
34 |
35 | let message = `${error.status} ${error.title}`
36 |
37 | if (error.detail) {
38 | message += `\n${error.detail}`
39 | }
40 |
41 | return message
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/src/logger.ts:
--------------------------------------------------------------------------------
1 | import type { Logger } from "./types"
2 |
3 | export const LOG_MESSAGE_PREFIX = "[next-drupal][log]:"
4 | export const DEBUG_MESSAGE_PREFIX = "[next-drupal][debug]:"
5 | export const WARN_MESSAGE_PREFIX = "[next-drupal][warn]:"
6 | export const ERROR_MESSAGE_PREFIX = "[next-drupal][error]:"
7 |
8 | // Default logger. Uses console.
9 | export const logger: Logger = {
10 | log(message) {
11 | console.log(LOG_MESSAGE_PREFIX, message)
12 | },
13 | debug(message) {
14 | console.debug(DEBUG_MESSAGE_PREFIX, message)
15 | },
16 | warn(message) {
17 | console.warn(WARN_MESSAGE_PREFIX, message)
18 | },
19 | error(message) {
20 | console.error(ERROR_MESSAGE_PREFIX, message)
21 | },
22 | }
23 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/src/navigation.ts:
--------------------------------------------------------------------------------
1 | export { useMenu } from "./deprecated/use-menu"
2 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/src/types/deprecated.ts:
--------------------------------------------------------------------------------
1 | import type { JsonApiOptions } from "./options"
2 |
3 | export type JsonApiWithLocaleOptions = Omit
4 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/src/types/drupal-client.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | NextDrupalAuth,
3 | NextDrupalAuthClientIdSecret,
4 | NextDrupalAuthUsernamePassword,
5 | NextDrupalAuthAccessToken,
6 | } from "./next-drupal-fetch"
7 | import type { JsonDeserializer, NextDrupalOptions } from "./next-drupal"
8 |
9 | export type DrupalClientOptions = NextDrupalOptions & {
10 | /**
11 | * Override the default data serializer. You can use this to add your own JSON:API data deserializer.
12 | *
13 | * * **Default value**: `jsona`
14 | * * **Required**: *No*
15 | *
16 | * [Documentation](https://next-drupal.org/docs/client/configuration#serializer)
17 | */
18 | serializer?: Serializer
19 | }
20 |
21 | export type DrupalClientAuth = NextDrupalAuth
22 |
23 | export type DrupalClientAuthUsernamePassword = NextDrupalAuthUsernamePassword
24 |
25 | export type DrupalClientAuthClientIdSecret = NextDrupalAuthClientIdSecret
26 |
27 | export type DrupalClientAuthAccessToken = NextDrupalAuthAccessToken
28 |
29 | export interface Serializer {
30 | deserialize: JsonDeserializer
31 | }
32 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/src/types/index.ts:
--------------------------------------------------------------------------------
1 | export type * from "./drupal-client"
2 | export type * from "./drupal"
3 | export type * from "./next-drupal-fetch"
4 | export type * from "./next-drupal"
5 | export type * from "./options"
6 | export type * from "./resource"
7 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/src/types/options.ts:
--------------------------------------------------------------------------------
1 | import type { NextDrupalAuth } from "./next-drupal-fetch"
2 | import type { RequestInit } from "next/dist/server/web/spec-extension/request"
3 |
4 | export type BaseUrl = string
5 |
6 | export type Locale = string
7 |
8 | export type PathPrefix = string
9 |
10 | export interface FetchOptions extends RequestInit {
11 | withAuth?: boolean | NextDrupalAuth
12 | }
13 |
14 | export type JsonApiOptions = {
15 | deserialize?: boolean
16 | params?: JsonApiParams
17 | credentials?: string
18 | } & JsonApiWithAuthOption &
19 | (
20 | | {
21 | locale: Locale
22 | defaultLocale: Locale
23 | }
24 | | {
25 | locale?: undefined
26 | defaultLocale?: never
27 | }
28 | )
29 |
30 | export type JsonApiWithAuthOption = {
31 | withAuth?: boolean | NextDrupalAuth
32 | }
33 |
34 | export type JsonApiWithCacheOptions = {
35 | withCache?: boolean
36 | cacheKey?: string
37 | }
38 |
39 | // TODO: Properly type this.
40 | /* eslint-disable @typescript-eslint/no-explicit-any */
41 | export type JsonApiParams = Record
42 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/tests/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../.eslintrc.json"],
3 | "overrides": [
4 | {
5 | "files": ["*.test.ts"],
6 | "rules": {
7 | "@typescript-eslint/ban-ts-comment": "off"
8 | }
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/tests/DrupalClient/constructor.test.ts:
--------------------------------------------------------------------------------
1 | import { afterEach, describe, expect, jest, test } from "@jest/globals"
2 | import { Jsona } from "jsona"
3 | import { DrupalClient, NextDrupal, NextDrupalFetch } from "../../src"
4 | import { BASE_URL } from "../utils"
5 |
6 | afterEach(() => {
7 | jest.restoreAllMocks()
8 | })
9 |
10 | describe("baseUrl parameter", () => {
11 | test("returns a DrupalClient", () => {
12 | expect(new DrupalClient(BASE_URL)).toBeInstanceOf(DrupalClient)
13 | expect(new DrupalClient(BASE_URL)).toBeInstanceOf(NextDrupal)
14 | expect(new DrupalClient(BASE_URL)).toBeInstanceOf(NextDrupalFetch)
15 | })
16 | })
17 |
18 | describe("options parameter", () => {
19 | describe("serializer", () => {
20 | test("defaults to `new Jsona()`", () => {
21 | const drupal = new DrupalClient(BASE_URL)
22 | expect(drupal.serializer).toBeInstanceOf(Jsona)
23 | })
24 |
25 | test("sets up a custom serializer", () => {
26 | const customSerializer: DrupalClient["serializer"] = {
27 | deserialize(
28 | body: Record,
29 | options?: Record
30 | ): unknown {
31 | return {
32 | deserialized: true,
33 | }
34 | },
35 | }
36 |
37 | const drupal = new DrupalClient(BASE_URL, {
38 | serializer: customSerializer,
39 | })
40 | expect(drupal.serializer).toBe(customSerializer)
41 | })
42 | })
43 | })
44 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/tests/__mocks__/next.ts:
--------------------------------------------------------------------------------
1 | export const NextApiRequest = jest.fn(function () {
2 | this.query = {
3 | path: "/example",
4 | resourceVersion: "id:1",
5 | plugin: "simple_oauth",
6 | secret: "very-secret-key",
7 | }
8 | this.url = `https://example.com/?${new URLSearchParams(this.query)}`
9 | this.headers = {
10 | host: "https://example.com",
11 | }
12 | })
13 |
14 | export const NextApiResponse = jest.fn(function () {
15 | const headers = {
16 | "Set-Cookie": ["mock-cookie-value"],
17 | }
18 | const response = {
19 | statusCode: 200,
20 | status: jest.fn((statusCode) => {
21 | response.statusCode = statusCode
22 | return response
23 | }),
24 | clearPreviewData: jest.fn(() => response),
25 | setPreviewData: jest.fn(() => response),
26 | setDraftMode: jest.fn(() => response),
27 | getHeader: jest.fn((name) => headers[name]),
28 | setHeader: jest.fn((name, value) => {
29 | headers[name] = value
30 | return response
31 | }),
32 | writeHead: jest.fn(() => response),
33 | end: jest.fn(),
34 | json: jest.fn(),
35 | }
36 | return response
37 | })
38 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/tests/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./mocks"
2 | export * from "./rpc"
3 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/tests/utils/mocks/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./data"
2 | export * from "./fetch"
3 | export * from "./logger"
4 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/tests/utils/mocks/logger.ts:
--------------------------------------------------------------------------------
1 | import { Logger } from "../../../src"
2 |
3 | export function mockLogger(): Logger {
4 | return {
5 | log: jest.fn(),
6 | debug: jest.fn(),
7 | warn: jest.fn(),
8 | error: jest.fn(),
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/tests/utils/rpc.ts:
--------------------------------------------------------------------------------
1 | import { DrupalClient } from "../../src"
2 | import { BASE_URL } from "./index"
3 |
4 | const client = new DrupalClient(BASE_URL, {
5 | auth: {
6 | clientId: process.env["DRUPAL_CLIENT_ID"] as string,
7 | clientSecret: process.env["DRUPAL_CLIENT_SECRET"] as string,
8 | },
9 | })
10 |
11 | export async function executeRPC(body) {
12 | const url = client.buildUrl("/jsonrpc")
13 |
14 | const response = await client.fetch(url.toString(), {
15 | method: "POST",
16 | body: JSON.stringify(body),
17 | withAuth: true,
18 | })
19 |
20 | return response.ok
21 | }
22 |
23 | export async function toggleDrupalModule(name: string, status = true) {
24 | await executeRPC({
25 | jsonrpc: "2.0",
26 | method: "module.toggle",
27 | params: {
28 | name,
29 | status,
30 | },
31 | id: "toggle-drupal-module",
32 | })
33 | }
34 |
35 | export async function deleteTestNodes() {
36 | await executeRPC({
37 | jsonrpc: "2.0",
38 | method: "test_content.clean",
39 | id: "clean-test-content",
40 | })
41 | }
42 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2020",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": false,
8 | "forceConsistentCasingInFileNames": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "node",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve"
15 | },
16 | "exclude": ["node_modules", "**/*.test.ts"],
17 | "include": ["src/**/*.ts"]
18 | }
19 |
--------------------------------------------------------------------------------
/frontend/packages/next-drupal/tsup.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "tsup"
2 |
3 | export const tsup = defineConfig({
4 | entry: ["src/index.ts", "src/draft.ts", "src/navigation.ts"],
5 | // Enable experimental code splitting support in CommonJS.
6 | // splitting: true,
7 | // Use Rollup for tree shaking.
8 | // treeshake: true,
9 | sourcemap: true,
10 | clean: true,
11 | format: ["esm", "cjs"],
12 | dts: true,
13 | cjsInterop: true,
14 | })
15 |
--------------------------------------------------------------------------------
/frontend/packages/utils/.github/workflows/auto_close_prs.yml:
--------------------------------------------------------------------------------
1 | name: Auto Closer PR
2 |
3 | on:
4 | pull_request_target:
5 | types: [opened]
6 |
7 | jobs:
8 | run:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: superbrothers/close-pull-request@v3
12 | with:
13 | # Optional. Post a issue comment just before closing a pull request.
14 | comment: |
15 | Hi, thank you for your contribution.
16 | Unfortunately, this repository is read-only. It's a split from our main monorepo repository.
17 | We'd like to kindly ask you to move the contribution there - https://github.com/powerstackdev/power-stack.
18 | We'll check it, review it and give you feed back right way.
19 | Thank you.
20 |
--------------------------------------------------------------------------------
/frontend/packages/utils/__tests__/Utils.test.js:
--------------------------------------------------------------------------------
1 | import { formatDrupalType, snakeToCamel, capitalize } from "../src/Utils"
2 |
3 | it("Format paragraph to type", () => {
4 | expect(formatDrupalType("paragraph--type")).toBe("type")
5 | })
6 |
7 | it("Snakecase changes to camelcase", () => {
8 | expect(snakeToCamel("snake_case")).toEqual("snakeCase")
9 | expect(snakeToCamel("snake_case_test_more_chars")).toEqual(
10 | "snakeCaseTestMoreChars"
11 | )
12 | })
13 |
14 | it("Capitalize letters changes to uppercase on first letter", () => {
15 | expect(capitalize("word")).toEqual("Word")
16 | expect(capitalize("Word")).toEqual("Word")
17 | expect(capitalize("word1 word2")).toEqual("Word1 word2")
18 | })
19 |
--------------------------------------------------------------------------------
/frontend/packages/utils/index.js:
--------------------------------------------------------------------------------
1 | export * from "./src/Utils"
2 |
--------------------------------------------------------------------------------
/frontend/packages/utils/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@powerstack/utils",
3 | "main": "index.js",
4 | "version": "1.0.1"
5 | }
6 |
--------------------------------------------------------------------------------
/frontend/packages/utils/src/Utils.js:
--------------------------------------------------------------------------------
1 | export const drupalFieldPrefix = "field_"
2 |
3 | export const formatDrupalField = (type) => type.replace(drupalFieldPrefix, "")
4 |
5 | export const formatDrupalType = (type) => type.replace("paragraph--", "")
6 |
7 | export const snakeToCamel = (text) =>
8 | text
9 | .toLowerCase()
10 | .replace(/([-_][a-z])/g, (group) =>
11 | group.toUpperCase().replace("-", "").replace("_", "")
12 | )
13 |
14 | export const capitalize = (text) =>
15 | text.charAt(0).toUpperCase() + text.slice(1).toLowerCase()
16 |
17 | export const isBrowser = () => typeof window !== "undefined"
18 |
19 | export const formatDate = (dateString) => {
20 | const date = new Date(dateString)
21 | return date.toLocaleString("en-US", {
22 | year: "numeric", // 2021, 2022, ...
23 | month: "long", // January, February, ...
24 | day: "numeric", // 1, 2, 3, ...
25 | hour: "numeric", // 12 AM, 1 PM, ...
26 | minute: "numeric", // 00, 01, 02, ...
27 | second: "numeric", // 00, 01, 02, ...
28 | })
29 | }
30 |
--------------------------------------------------------------------------------
/frontend/starters/development/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals",
3 | "root": true
4 | }
5 |
--------------------------------------------------------------------------------
/frontend/starters/development/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # IDE files
24 | /.idea
25 | /.vscode
26 |
27 | # debug
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 |
32 | # local env files
33 | .env*.local
34 |
35 | # vercel
36 | .vercel
37 |
38 | # typescript
39 | *.tsbuildinfo
40 | next-env.d.ts
41 |
--------------------------------------------------------------------------------
/frontend/starters/development/.nvmrc:
--------------------------------------------------------------------------------
1 | v20
2 |
--------------------------------------------------------------------------------
/frontend/starters/development/.prettierignore:
--------------------------------------------------------------------------------
1 | # Ignore everything.
2 | /*
3 |
4 | # Format most files in the root directory.
5 | !/*.js
6 | !/*.ts
7 | !/*.md
8 | !/*.json
9 | # But ignore some.
10 | /package.json
11 | /package-lock.json
12 | /CHANGELOG.md
13 |
14 | # Don't ignore these nested directories.
15 | !/app
16 | !/components
17 | !/lib
18 | !/pages
19 |
--------------------------------------------------------------------------------
/frontend/starters/development/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "trailingComma": "es5"
4 | }
5 |
--------------------------------------------------------------------------------
/frontend/starters/development/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
--------------------------------------------------------------------------------
/frontend/starters/development/README.md:
--------------------------------------------------------------------------------
1 | # Basic Starter
2 |
3 | A simple starter for building your site with Next.js and Drupal.
4 |
5 | ## How to use
6 |
7 | `npx create-next-app -e https://github.com/chapter-three/next-drupal-basic-starter`
8 |
9 | ## Deploy to Vercel
10 |
11 | [](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fchapter-three%2Fnext-drupal-basic-starter&env=NEXT_PUBLIC_DRUPAL_BASE_URL,NEXT_IMAGE_DOMAIN,DRUPAL_CLIENT_ID,DRUPAL_CLIENT_SECRET&envDescription=Learn%20more%20about%20environment%20variables&envLink=https%3A%2F%2Fnext-drupal.org%2Fdocs%2Fenvironment-variables&project-name=next-drupal&demo-title=Next.js%20for%20Drupal&demo-description=A%20next-generation%20front-end%20for%20your%20Drupal%20site.&demo-url=https%3A%2F%2Fdemo.next-drupal.org&demo-image=https%3A%2F%2Fnext-drupal.org%2Fimages%2Fdemo-screenshot.jpg)
12 |
13 | ## Documentation
14 |
15 | See https://next-drupal.org
16 |
--------------------------------------------------------------------------------
/frontend/starters/development/app/api/revalidate/route.ts:
--------------------------------------------------------------------------------
1 | import { revalidatePath } from "next/cache"
2 | import type { NextRequest } from "next/server"
3 |
4 | async function handler(request: NextRequest) {
5 | const searchParams = request.nextUrl.searchParams
6 | const path = searchParams.get("path")
7 | const secret = searchParams.get("secret")
8 |
9 | // Validate secret.
10 | if (secret !== process.env.NEXT_REVALIDATE_SECRET) {
11 | return new Response("Invalid secret.", { status: 401 })
12 | }
13 |
14 | // Validate path.
15 | if (!path) {
16 | return new Response("Invalid path.", { status: 400 })
17 | }
18 |
19 | try {
20 | revalidatePath(path)
21 |
22 | return new Response("Revalidated.")
23 | } catch (error) {
24 | return new Response((error as Error).message, { status: 500 })
25 | }
26 | }
27 |
28 | export { handler as GET, handler as POST }
29 |
--------------------------------------------------------------------------------
/frontend/starters/development/app/blocks/Hero/Hero.tsx:
--------------------------------------------------------------------------------
1 | import { Title, Text, Button, Container } from "@mantine/core"
2 | import { Dots } from "./Dots"
3 | import classes from "./Hero.module.css"
4 |
5 | export function HeroBlock({ title, subtitle, description }) {
6 | return (
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | {title}
17 |
18 |
19 |
20 | {subtitle}
21 |
22 |
23 |
24 |
25 | {description}
26 |
27 |
28 |
29 |
30 |
33 |
36 |
37 |
38 |
39 | )
40 | }
41 |
--------------------------------------------------------------------------------
/frontend/starters/development/app/blocks/Stats/Stats.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | margin: calc(var(--mantine-spacing-xl) * 1.5) 0;
3 | display: flex;
4 | background-image: linear-gradient(
5 | -60deg,
6 | var(--mantine-color-blue-4) 0%,
7 | var(--mantine-color-blue-7) 100%
8 | );
9 | padding: calc(var(--mantine-spacing-xl) * 1.5);
10 | border-radius: var(--mantine-radius-md);
11 |
12 | @media (max-width: $mantine-breakpoint-sm) {
13 | flex-direction: column;
14 | }
15 | }
16 |
17 | .title {
18 | color: var(--mantine-color-white);
19 | text-transform: uppercase;
20 | font-weight: 700;
21 | font-size: var(--mantine-font-size-sm);
22 | }
23 |
24 | .count {
25 | color: var(--mantine-color-white);
26 | font-size: rem(32px);
27 | line-height: 1;
28 | font-weight: 700;
29 | margin-bottom: var(--mantine-spacing-md);
30 | font-family: Greycliff CF, var(--mantine-font-family);
31 | }
32 |
33 | .description {
34 | color: var(--mantine-color-blue-0);
35 | font-size: var(--mantine-font-size-sm);
36 | margin-top: rem(5px);
37 | }
38 |
39 | .stat {
40 | flex: 1;
41 |
42 | & + & {
43 | padding-left: var(--mantine-spacing-xl);
44 | margin-left: var(--mantine-spacing-xl);
45 | border-left: rem(1px) solid var(--mantine-color-blue-3);
46 |
47 | @media (max-width: $mantine-breakpoint-sm) {
48 | padding-left: 0;
49 | margin-left: 0;
50 | border-left: 0;
51 | padding-top: var(--mantine-spacing-xl);
52 | margin-top: var(--mantine-spacing-xl);
53 | border-top: rem(1px) solid var(--mantine-color-blue-3);
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/frontend/starters/development/app/blocks/Stats/Stats.tsx:
--------------------------------------------------------------------------------
1 | import { Text, Container } from "@mantine/core"
2 | import classes from "./Stats.module.css"
3 |
4 | export function StatsBlock({ data }) {
5 | const stats = data.map((stat) => (
6 |
7 | {stat.stats}
8 | {stat.title}
9 | {stat.description}
10 |
11 | ))
12 | return (
13 |
14 | {stats}
15 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/frontend/starters/development/app/blocks/Text/Text.module.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | position: relative;
3 | padding-top: rem(40px);
4 | padding-bottom: rem(40px);
5 |
6 | @media (max-width: $mantine-breakpoint-sm) {
7 | padding-top: rem(30px);
8 | padding-bottom: rem(30px);
9 | }
10 | }
11 |
12 | .inner {
13 | position: relative;
14 | z-index: 1;
15 | }
16 |
17 | .title {
18 | text-align: left;
19 | font-weight: 800;
20 | font-size: rem(40px);
21 | letter-spacing: -1px;
22 | color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
23 | margin-bottom: var(--mantine-spacing-xs);
24 | font-family: Greycliff CF, var(--mantine-font-family);
25 |
26 | @media (max-width: $mantine-breakpoint-xs) {
27 | font-size: rem(28px);
28 | }
29 | }
30 |
31 | .highlight {
32 | color: light-dark(var(--mantine-color-blue-6), var(--mantine-color-blue-4));
33 | }
34 |
35 | .description {
36 | text-align: left;
37 |
38 | @media (max-width: $mantine-breakpoint-xs) {
39 | font-size: var(--mantine-font-size-md);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/frontend/starters/development/app/blocks/Text/Text.tsx:
--------------------------------------------------------------------------------
1 | import { Title, Text, Button, Container } from "@mantine/core"
2 | import classes from "./Text.module.css"
3 |
4 | export function TextBlock({ title, text }) {
5 | return (
6 |
7 |
8 |
9 | {title}
10 |
11 | {text}
12 |
13 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/frontend/starters/development/app/edit/page.tsx:
--------------------------------------------------------------------------------
1 | export { default, generateMetadata } from "./[...puckPath]/page"
2 |
--------------------------------------------------------------------------------
/frontend/starters/development/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/powerstackdev/power-stack/d26150cb0a0afca4df08471bca96dc4714415986/frontend/starters/development/app/favicon.ico
--------------------------------------------------------------------------------
/frontend/starters/development/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next"
2 | import type { ReactNode } from "react"
3 | import "@mantine/core/styles.css"
4 | import { MantineProvider, ColorSchemeScript } from "@mantine/core"
5 | import { theme } from "../theme"
6 |
7 | import "@/styles/globals.css"
8 | import { Toaster } from "@/components/ui/sonner"
9 | import { Header } from "@/components/admin/Header/Header"
10 |
11 | import { getServerSession } from "next-auth/next"
12 |
13 | export const metadata: Metadata = {
14 | title: {
15 | default: "Power Stack Frontend",
16 | template: "%s | Power Stack Frontend",
17 | },
18 | description: "Power Stack Frontend",
19 | icons: {
20 | icon: "/favicon.ico",
21 | },
22 | }
23 |
24 | export default async function RootLayout({
25 | // Layouts must accept a children prop.
26 | // This will be populated with nested layouts or pages
27 | children,
28 | }: {
29 | children: ReactNode
30 | session: any
31 | }) {
32 | const session = await getServerSession()
33 | return (
34 |
35 |
36 |
37 |
41 |
42 |
43 |
44 | {session && }
45 | {children}
46 |
47 |
48 | )
49 | }
50 |
--------------------------------------------------------------------------------
/frontend/starters/development/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "default",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "styles/globals.css",
9 | "baseColor": "slate",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/frontend/starters/development/components/Header/Header.module.css:
--------------------------------------------------------------------------------
1 | .header {
2 | height: rem(72px);
3 | background-color: var(--mantine-color-body);
4 | border-bottom: rem(1px) solid
5 | light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
6 | }
7 |
8 | .inner {
9 | height: rem(72px);
10 | display: flex;
11 | justify-content: space-between;
12 | align-items: center;
13 | }
14 |
15 | .link {
16 | display: block;
17 | line-height: 1;
18 | padding: rem(8px) rem(12px);
19 | border-radius: var(--mantine-radius-sm);
20 | text-decoration: none;
21 | color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0));
22 | font-size: var(--mantine-font-size-sm);
23 | font-weight: 500;
24 |
25 | @mixin hover {
26 | background-color: light-dark(
27 | var(--mantine-color-gray-0),
28 | var(--mantine-color-dark-6)
29 | );
30 | }
31 | }
32 |
33 | .linkLabel {
34 | margin-right: rem(5px);
35 | }
36 |
--------------------------------------------------------------------------------
/frontend/starters/development/components/drupal/Article.tsx:
--------------------------------------------------------------------------------
1 | import Image from "next/image"
2 | import { absoluteUrl, formatDate } from "@/lib/utils"
3 | import type { DrupalNode } from "next-drupal"
4 |
5 | interface ArticleProps {
6 | node: DrupalNode
7 | }
8 |
9 | export function Article({ node, ...props }: ArticleProps) {
10 | return (
11 |
12 | {node.title}
13 |
14 | {node.uid?.display_name ? (
15 |
16 | Posted by{" "}
17 | {node.uid?.display_name}
18 |
19 | ) : null}
20 | - {formatDate(node.created)}
21 |
22 | {node.field_image && (
23 |
24 |
31 | {node.field_image.resourceIdObjMeta.title && (
32 |
33 | {node.field_image.resourceIdObjMeta.title}
34 |
35 | )}
36 |
37 | )}
38 | {node.body?.processed && (
39 |
43 | )}
44 |
45 | )
46 | }
47 |
--------------------------------------------------------------------------------
/frontend/starters/development/components/navigation/HeaderNav.tsx:
--------------------------------------------------------------------------------
1 | import { Link } from "@/components/navigation/Link"
2 |
3 | export function HeaderNav() {
4 | return (
5 |
6 |
7 |
8 | Next.js for Drupal
9 |
10 |
16 | Read the docs
17 |
18 |
19 |
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/frontend/starters/development/components/navigation/Link.tsx:
--------------------------------------------------------------------------------
1 | import { forwardRef } from "react"
2 | import NextLink from "next/link"
3 | import type { AnchorHTMLAttributes, ReactNode } from "react"
4 | import type { LinkProps as NextLinkProps } from "next/link"
5 |
6 | type LinkProps = NextLinkProps &
7 | Omit, keyof NextLinkProps> & {
8 | children?: ReactNode
9 | }
10 |
11 | export const Link = forwardRef(
12 | function LinkWithRef(
13 | {
14 | // Turn next/link prefetching off by default.
15 | // @see https://github.com/vercel/next.js/discussions/24009
16 | prefetch = false,
17 | ...rest
18 | },
19 | ref
20 | ) {
21 | return
22 | }
23 | )
24 |
--------------------------------------------------------------------------------
/frontend/starters/development/components/ui/badge.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { cva, type VariantProps } from "class-variance-authority"
3 |
4 | import { cn } from "@/lib/utils"
5 |
6 | const badgeVariants = cva(
7 | "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
8 | {
9 | variants: {
10 | variant: {
11 | default:
12 | "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
13 | secondary:
14 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
15 | destructive:
16 | "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
17 | outline: "text-foreground",
18 | },
19 | },
20 | defaultVariants: {
21 | variant: "default",
22 | },
23 | }
24 | )
25 |
26 | export interface BadgeProps
27 | extends React.HTMLAttributes,
28 | VariantProps {}
29 |
30 | function Badge({ className, variant, ...props }: BadgeProps) {
31 | return (
32 |
33 | )
34 | }
35 |
36 | export { Badge, badgeVariants }
37 |
--------------------------------------------------------------------------------
/frontend/starters/development/components/ui/checkbox.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
5 | import { Check } from "lucide-react"
6 |
7 | import { cn } from "@/lib/utils"
8 |
9 | const Checkbox = React.forwardRef<
10 | React.ElementRef,
11 | React.ComponentPropsWithoutRef
12 | >(({ className, ...props }, ref) => (
13 |
21 |
24 |
25 |
26 |
27 | ))
28 | Checkbox.displayName = CheckboxPrimitive.Root.displayName
29 |
30 | export { Checkbox }
31 |
--------------------------------------------------------------------------------
/frontend/starters/development/components/ui/input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 |
3 | import { cn } from "@/lib/utils"
4 |
5 | export interface InputProps
6 | extends React.InputHTMLAttributes {}
7 |
8 | const Input = React.forwardRef(
9 | ({ className, type, ...props }, ref) => {
10 | return (
11 |
20 | )
21 | }
22 | )
23 | Input.displayName = "Input"
24 |
25 | export { Input }
26 |
--------------------------------------------------------------------------------
/frontend/starters/development/components/ui/label.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as LabelPrimitive from "@radix-ui/react-label"
5 | import { cva, type VariantProps } from "class-variance-authority"
6 |
7 | import { cn } from "@/lib/utils"
8 |
9 | const labelVariants = cva(
10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
11 | )
12 |
13 | const Label = React.forwardRef<
14 | React.ElementRef,
15 | React.ComponentPropsWithoutRef &
16 | VariantProps
17 | >(({ className, ...props }, ref) => (
18 |
23 | ))
24 | Label.displayName = LabelPrimitive.Root.displayName
25 |
26 | export { Label }
27 |
--------------------------------------------------------------------------------
/frontend/starters/development/components/ui/sonner.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import { useTheme } from "next-themes"
4 | import { Toaster as Sonner } from "sonner"
5 |
6 | type ToasterProps = React.ComponentProps
7 |
8 | const Toaster = ({ ...props }: ToasterProps) => {
9 | const { theme = "system" } = useTheme()
10 |
11 | return (
12 |
28 | )
29 | }
30 |
31 | export { Toaster }
32 |
--------------------------------------------------------------------------------
/frontend/starters/development/lib/drupal.ts:
--------------------------------------------------------------------------------
1 | import { NextDrupal } from "next-drupal"
2 |
3 | const baseUrl = process.env.NEXT_PUBLIC_DRUPAL_HOST as string
4 | const clientId = process.env.NEXT_PUBLIC_DRUPAL_CLIENT_ID as string
5 | const clientSecret = process.env.NEXT_PUBLIC_DRUPAL_CLIENT_SECRET as string
6 |
7 | export const drupal = new NextDrupal(baseUrl, {
8 | auth: {
9 | clientId,
10 | clientSecret,
11 | },
12 | // debug: true,
13 | // useDefaultResourceTypeEntry: true,
14 | })
15 |
--------------------------------------------------------------------------------
/frontend/starters/development/lib/get-page.ts:
--------------------------------------------------------------------------------
1 | import { Data } from "@measured/puck"
2 | import fs from "fs"
3 |
4 | // Replace with call to your database
5 | export const getPage = (path: string) => {
6 | console.log(path)
7 |
8 | const allData: Record | null = fs.existsSync("database.json")
9 | ? JSON.parse(fs.readFileSync("database.json", "utf-8"))
10 | : null
11 |
12 | return allData ? allData[path] : null
13 | }
14 |
--------------------------------------------------------------------------------
/frontend/starters/development/lib/trigger-revalidation.ts:
--------------------------------------------------------------------------------
1 | "use server"
2 |
3 | import { revalidatePath } from 'next/cache';
4 |
5 | export const triggerRevalidation = async (path) => {
6 | const revalidateUrl = `/${path}`;
7 | const revalidateEditUrl = `/edit/[...puckPath]`;
8 |
9 | try {
10 | await revalidatePath(revalidateUrl, 'page'); // Assuming revalidatePath is an async operation
11 | console.log("Page revalidated");
12 |
13 | await revalidatePath(revalidateEditUrl, 'page');
14 | console.log("Edit page revalidated");
15 |
16 | return "Both pages revalidated successfully"; // Resolving the promise with a success message
17 | } catch (error) {
18 | console.error("Error triggering revalidation:", error);
19 | throw error; // Rejecting the promise with the caught error
20 | }
21 | };
--------------------------------------------------------------------------------
/frontend/starters/development/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { type ClassValue, clsx } from "clsx"
2 | import { twMerge } from "tailwind-merge"
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs))
6 | }
7 |
8 | export function absoluteUrl(input: string) {
9 | return `${process.env.NEXT_PUBLIC_DRUPAL_BASE_URL}${input}`
10 | }
11 |
12 | export function formatDate(input: string): string {
13 | const date = new Date(input)
14 | return date.toLocaleDateString("en-US", {
15 | month: "long",
16 | day: "numeric",
17 | year: "numeric",
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/frontend/starters/development/middleware.ts:
--------------------------------------------------------------------------------
1 | import { NextResponse } from "next/server"
2 |
3 | import type { NextRequest } from "next/server"
4 |
5 | export async function middleware(req: NextRequest) {
6 | const res = NextResponse.next()
7 |
8 | const { cookies } = req
9 | const sessionToken = cookies.get("next-auth.session-token")
10 |
11 | if (sessionToken) {
12 | res.headers.set("x-middleware-cache", "no-cache")
13 | }
14 |
15 | if (req.method === "GET") {
16 | // Rewrite routes that match "/[...puckPath]/edit" to "/puck/[...puckPath]"
17 | if (req.nextUrl.pathname.endsWith("/edit")) {
18 | const pathWithoutEdit = req.nextUrl.pathname.slice(
19 | 0,
20 | req.nextUrl.pathname.length - 5
21 | )
22 | const pathWithEditPrefix = `/edit${pathWithoutEdit}`
23 |
24 | if (!sessionToken) {
25 | return NextResponse.redirect(new URL("/api/auth/signin", req.url))
26 | }
27 | const response = NextResponse.rewrite(
28 | new URL(pathWithEditPrefix, req.url)
29 | )
30 | response.headers.set("x-middleware-cache", "no-cache")
31 |
32 | return response
33 | }
34 |
35 | if (req.nextUrl.pathname === "/") {
36 | return NextResponse.redirect(new URL("/welcome", req.url))
37 | }
38 |
39 | if (req.nextUrl.pathname.startsWith("/admin") && !sessionToken) {
40 | return NextResponse.redirect(new URL("/api/auth/signin", req.url))
41 | }
42 |
43 | // Disable "/puck/[...puckPath]"
44 | if (req.nextUrl.pathname.startsWith("/puck")) {
45 | return NextResponse.redirect(new URL("/", req.url))
46 | }
47 | }
48 |
49 | return res
50 | }
51 |
--------------------------------------------------------------------------------
/frontend/starters/development/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | reactStrictMode: true,
4 | images: {
5 | remotePatterns: [
6 | {
7 | // protocol: 'https',
8 | hostname: process.env.NEXT_IMAGE_DOMAIN,
9 | // port: '',
10 | // pathname: '/sites/default/files/**',
11 | },
12 | ],
13 | },
14 | webpack: (config) => {
15 | config.watchOptions = {
16 | aggregateTimeout: 200,
17 | poll: 1000,
18 | ignored: "**/node_modules",
19 | }
20 | return config
21 | },
22 | async headers() {
23 | return [
24 | {
25 | source: "/:path*",
26 | headers: [
27 | {
28 | key: "Access-Control-Allow-Origin",
29 | value: `http://${process.env.VIRTUAL_HOST}`, // Set your origin
30 | },
31 | ],
32 | },
33 | ]
34 | },
35 | }
36 |
37 | module.exports = nextConfig
38 |
--------------------------------------------------------------------------------
/frontend/starters/development/postcss.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | "postcss-preset-mantine": {},
5 | "postcss-simple-vars": {
6 | variables: {
7 | "mantine-breakpoint-xs": "36em",
8 | "mantine-breakpoint-sm": "48em",
9 | "mantine-breakpoint-md": "62em",
10 | "mantine-breakpoint-lg": "75em",
11 | "mantine-breakpoint-xl": "88em",
12 | },
13 | },
14 | },
15 | }
16 |
--------------------------------------------------------------------------------
/frontend/starters/development/theme.ts:
--------------------------------------------------------------------------------
1 | "use client"
2 | import { createTheme, MantineColorsTuple } from "@mantine/core"
3 |
4 | const powerstack: MantineColorsTuple = [
5 | "#fff8e1",
6 | "#ffefcc",
7 | "#ffdd9b",
8 | "#ffca64",
9 | "#ffba38",
10 | "#ffb01b",
11 | "#ffab09",
12 | "#e39500",
13 | "#ca8500",
14 | "#af7100",
15 | ]
16 |
17 | export const theme = createTheme({
18 | colors: {
19 | powerstack,
20 | },
21 | })
22 |
--------------------------------------------------------------------------------
/frontend/starters/development/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": false,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "incremental": true,
17 | "plugins": [
18 | {
19 | "name": "next"
20 | }
21 | ],
22 | "paths": {
23 | "@/*": ["./*"],
24 | "next-drupal": ["../../packages/next-drupal/src/"],
25 | "next-drupal/*": ["../../packages/next-drupal/src/*"],
26 | "@powerstack/utils": ["../../packages/utils/*"]
27 | }
28 | },
29 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
30 | "exclude": ["node_modules", "../../packages/next-drupal/src/*"]
31 | }
32 |
--------------------------------------------------------------------------------
/package-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "subtree-splits": [
3 |
4 | {
5 | "name": "powerstackdev/docs",
6 | "directory": "docs",
7 | "target": "git@github.com:powerstackdev/docs.git"
8 | },
9 |
10 | {
11 | "name": "powerstackdev/backend-starter-development",
12 | "directory": "backend/starters/development",
13 | "target": "git@github.com:powerstackdev/backend-starter-development.git"
14 | },
15 |
16 | {
17 | "name": "powerstackdev/frontend-powerstack-utils",
18 | "directory": "frontend/packages/@powerstack/utils",
19 | "target": "git@github.com:powerstackdev/frontend-powerstack-utils.git"
20 | },
21 |
22 | {
23 | "name": "powerstackdev/frontend-starter-development",
24 | "directory": "frontend/starters/development",
25 | "target": "git@github.com:powerstackdev/frontend-starter-development.git"
26 | },
27 |
28 | {
29 | "name": "powerstackdev/scripts",
30 | "directory": "scripts",
31 | "target": "git@github.com:powerstackdev/scripts.git"
32 | }
33 | ]
34 | }
35 |
--------------------------------------------------------------------------------
/scripts/.github/workflows/auto_close_prs.yml:
--------------------------------------------------------------------------------
1 | name: Auto Closer PR
2 |
3 | on:
4 | pull_request_target:
5 | types: [opened]
6 |
7 | jobs:
8 | run:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: superbrothers/close-pull-request@v3
12 | with:
13 | # Optional. Post a issue comment just before closing a pull request.
14 | comment: |
15 | Hi, thank you for your contribution.
16 | Unfortunately, this repository is read-only. It's a split from our main monorepo repository.
17 | We'd like to kindly ask you to move the contribution there - https://github.com/powerstackdev/power-stack.
18 | We'll check it, review it and give you feed back right way.
19 | Thank you.
--------------------------------------------------------------------------------
/scripts/development/backend/update_dependencies.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | #: exec_target = cli
4 |
5 | ## Initialize CMS codebase
6 | ##
7 | ## Usage: fin cms/code-init
8 |
9 | # Abort if anything fails
10 | set -e
11 |
12 | cd "$PROJECT_ROOT/backend/starters/$BACKEND_STARTER"
13 |
14 | # Install dependencies
15 | time composer install
16 | #time composer install --no-dev --ignore-platform-reqs --no-interaction --prefer-dist
17 | time composer update --ignore-platform-reqs --no-interaction --prefer-dist
18 |
--------------------------------------------------------------------------------
/scripts/development/backend/update_install_dependencies_and_reinstall_cms.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | . ./scripts/misc/globals.sh
3 | . ./scripts/misc/startup.sh
4 |
5 | subtitle "Reinstalling CMS"
6 |
7 | title "Step 1" "Updating and installing Composer dependencies"
8 |
9 | # Installing composer dependencies
10 | fin exec ./scripts/development/backend/update_dependencies.sh
11 | fin exec ./scripts/setup/backend/install_dependencies.sh
12 |
13 | title "Step 2" "Reinstalling codebase"
14 | fin exec ./scripts/setup/backend/install_cms.sh
--------------------------------------------------------------------------------
/scripts/misc/generate-tree.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | # Generate a tree for all directories and subdirectories of the current location 4 levels deep. This excludes
4 | # node_modules, vendor and public directories from the list.
5 |
6 | # Check that the command exists first before running as it's not included on MacOS by default. Mac users install with
7 | # `brew install tree`
8 | if ! command -v tree &> /dev/null
9 | then
10 | echo "The tree command could not be found. Please install tree and try again."
11 | exit
12 | fi
13 |
14 | tree -L 4 -d -I 'node_modules|vendor|public|coverage'
15 |
--------------------------------------------------------------------------------
/scripts/misc/globals.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | # Console colors
4 | red='\033[0;31m'
5 | green='\033[0;32m'
6 | green_bg='\033[1;97;42m'
7 | yellow='\033[1;33m'
8 | NC='\033[0m'
9 |
10 | echo_red () { echo -e "${red}$1${NC}"; }
11 | echo_green () { echo -e "${green}$1${NC}"; }
12 | echo_green_bg () { echo -e "${green_bg}$1${NC}"; }
13 | echo_yellow () { echo -e "${yellow}$1${NC}"; }
14 |
15 | br () { printf "\n"; }
16 |
17 | title () {
18 | local step="$1"
19 | local text="$2"
20 |
21 | br
22 | echo -e "${green_bg} ${step} ${NC}${green} ${text}... ${NC}"
23 | br
24 | }
25 |
26 | subtitle () {
27 | local text="$1"
28 |
29 | br
30 | echo_green "${text}..."
31 | br
32 | }
33 |
34 | # copy_env_file()
35 | # {
36 |
37 | # local source="${PROJECT_ROOT}/.docksal/settings/.env"
38 | # local dest="${PROJECT_ROOT}/.env"
39 |
40 | # echo "Copying ${source} to ${dest}..."
41 |
42 | # if [[ ! -f $dest ]]; then
43 | # cp $source $dest
44 | # else
45 | # echo "${dest} already in place. Creating backup first..."
46 | # mv $dest $dest.old
47 | # cp $source $dest
48 | # fi
49 | # }
50 |
51 | update_env_file() {
52 | local key="$1"
53 | local value="$2"
54 |
55 | fin config set --env=local "${key}=${value}"
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/scripts/misc/startup.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | . ./scripts/misc/globals.sh
4 |
5 | cat << "EOF"
6 |
7 | ____ _____ __ __
8 | / __ \____ _ _____ _____ / ___// /_____ ______/ /__
9 | / /_/ / __ \ | /| / / _ \/ ___/ \__ \/ __/ __ `/ ___/ //_/
10 | / ____/ /_/ / |/ |/ / __/ / ___/ / /_/ /_/ / /__/ ,<
11 | /_/ \____/|__/|__/\___/_/ /____/\__/\__,_/\___/_/|_|
12 |
13 |
14 | EOF
--------------------------------------------------------------------------------
/scripts/setup/backend/install_dependencies.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | #: exec_target = cli
4 |
5 | ## Initialize CMS codebase
6 | ##
7 | ## Usage: fin cms/code-init
8 |
9 | # Abort if anything fails
10 | set -e
11 |
12 | cd "${PROJECT_ROOT}/backend/starters/${BACKEND_STARTER}"
13 |
14 | time composer install --ignore-platform-reqs --no-interaction --prefer-dist
--------------------------------------------------------------------------------
/scripts/setup/docs/install_dependencies.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | #: exec_target = cli
4 |
5 | ## Initialize frontend codebase
6 | ##
7 | ## Usage: fin fe/code-init
8 | ## In case of any errors during this command execution try to stop gatsby
9 | ## container first:
10 | ## fin stop api
11 |
12 | # Abort if anything fails
13 | set -e
14 |
15 | cd "$PROJECT_ROOT/docs"
16 |
17 | # Install dependencies
18 | # Using "npm ci" instead of "npm install" here to avoid unintentional package-lock.json updates
19 | # time npm ci
20 | # With node_modules being a volume, npm ci will fail with "EBUSY: resource busy or locked, rmdir '/var/www/frontend/node_modules'"
21 | # Stick with npm install the time being...
22 | time yarn
23 |
--------------------------------------------------------------------------------
/scripts/setup/frontend/install_dependencies.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | #: exec_target = cli
4 |
5 | ## Initialize frontend codebase
6 | ##
7 | ## Usage: fin fe/code-init
8 | ## In case of any errors during this command execution try to stop gatsby
9 | ## container first:
10 | ## fin stop api
11 |
12 | # Abort if anything fails
13 | set -e
14 |
15 | cd "$PROJECT_ROOT/frontend"
16 |
17 | # Install dependencies
18 |
19 | # With node_modules being a volume, yarn will fail with "EBUSY: resource busy or locked, rmdir
20 | # '/var/www/frontend/node_modules'" until next version is released https://github.com/yarnpkg/berry/issues/4172
21 | # temporary fix is to set from sources rather than be pinned to 3.2.0
22 | # fin exec yarn set version from sources
23 |
24 |
25 | time yarn
26 |
--------------------------------------------------------------------------------
/scripts/setup/init_env_file.sh:
--------------------------------------------------------------------------------
1 | #-------------------------- Helper Functions --------------------------------
2 | . ./scripts/misc/globals.sh
3 |
4 | secret=$(openssl rand -hex 20)
5 | preview_secret=$(openssl rand -hex 20)
6 | revalidate_secret=$(openssl rand -hex 20)
7 | nextauth_secret=$(openssl rand -hex 20)
8 |
9 | update_env_file "NEXT_PUBLIC_DRUPAL_HOST" "http://backend.${VIRTUAL_HOST}"
10 | update_env_file "NEXT_IMAGE_DOMAIN" "http://backend.${VIRTUAL_HOST}"
11 | update_env_file "NEXT_HOST" "http://frontend.${VIRTUAL_HOST}"
12 | update_env_file "NEXT_PUBLIC_DRUPAL_CLIENT_SECRET" "${secret}"
13 | update_env_file "DRUPAL_PREVIEW_SECRET" "${prewview_secret}"
14 | update_env_file "NEXT_REVALIDATE_SECRET" "${revalidate_secret}"
15 | update_env_file "NEXT_PUBLIC_DRUPAL_CLIENT_ID" "next"
16 | update_env_file "NEXTAUTH_SECRET" "${nextauth_secret}"
17 | update_env_file "NEXTAUTH_URL" "http://frontend.${VIRTUAL_HOST}"
--------------------------------------------------------------------------------
/scripts/setup/setup.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | . ./scripts/misc/startup.sh
4 |
5 | cat << "EOF"
6 | _____ __
7 | / ___/___ / /___ ______
8 | \__ \/ _ \/ __/ / / / __ \
9 | ___/ / __/ /_/ /_/ / /_/ /
10 | /____/\___/\__/\__,_/ .___/
11 | /_/
12 | EOF
--------------------------------------------------------------------------------
/scripts/setup/startup.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | ##
3 | #source /var/www/.docksal/docksal.env
4 | #source /var/www/.docksal/docksal-local.env
5 | ##
6 | ### Docker volumes are mounted as root:root by default, so we have to fix permissions on them
7 | sudo chown $(id -u):$(id -g) "/var" || true
8 |
9 | sudo chown -R $(id -u):$(id -g) "/var/www/backend/starters/${BACKEND_STARTER}/vendor" || true
10 | sudo chown -R $(id -u):$(id -g) /var/www/frontend/node_modules || true
11 | sudo chown -R $(id -u):$(id -g) "/var/www/frontend/starters/${FRONTEND_STARTER}/.cache" || true
12 |
13 | sudo chown $(id -u):$(id -g) "/var/www/docs" || true
14 | sudo chown -R $(id -u):$(id -g) "/var/www/docs/.cache" || true
15 | sudo chown -R $(id -u):$(id -g) "/var/www/docs/node_modules" || true
16 |
--------------------------------------------------------------------------------
/scripts/testing/backend/code_formatting.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | phpcbf \
4 | --standard="Drupal,DrupalPractice" -n \
5 | --extensions="php,module,inc,install,test,profile,theme" \
6 | --ignore="*.features.*,*.pages*.inc,*vendor/*" \
7 | backend/packages
8 |
9 | phpcs \
10 | --standard="Drupal,DrupalPractice" -n \
11 | --extensions="php,module,inc,install,test,profile,theme" \
12 | --ignore="*.features.*,*.pages*.inc,*vendor/*" \
13 | backend/packages
14 |
--------------------------------------------------------------------------------
/scripts/testing/frontend/code_formatting.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | yarn --cwd frontend run prettier packages -w
4 | yarn --cwd frontend run eslint --fix packages
5 |
--------------------------------------------------------------------------------
/scripts/testing/frontend/tests.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | yarn --cwd frontend run jest --coverage
4 |
--------------------------------------------------------------------------------
/scripts/testing/init.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 | . ./scripts/misc/globals.sh
3 | . ./scripts/setup/setup.sh
4 |
5 | #-------------------------- Execution --------------------------------
6 |
7 | # Cleanup backend code formatting
8 | title "Step 1" "Cleaning backend code formatting"
9 | . ./scripts/testing/backend/code_formatting.sh
10 |
11 | # Cleanup frontend code formatting
12 | title "Step 2" "Cleaning frontend code formatting"
13 | . ./scripts/testing/frontend/code_formatting.sh
14 |
15 | # Cleanup frontend code formatting
16 | title "Step 3" "Testing frontend with Jest"
17 | . ./scripts/testing/frontend/tests.sh
--------------------------------------------------------------------------------
/scripts/testing/setup.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | . ./scripts/misc/startup.sh
4 |
5 | cat << "EOF"
6 | ______ __ _
7 | /_ __/__ _____/ /_(_)___ ____ _
8 | / / / _ \/ ___/ __/ / __ \/ __ `/
9 | / / / __(__ ) /_/ / / / / /_/ /
10 | /_/ \___/____/\__/_/_/ /_/\__, /
11 | /____/
12 | EOF
--------------------------------------------------------------------------------