npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

full-stack-pattern

v3.0.0-alpha.17

Published

A set of useful constructs, stacks, applications and patterns to help ease your journey with cdk

Downloads

218

Readme

full-stack-pattern

note: v3 of this library uses v2 aws-cdk-lib not v1 @aws-cdk

Full Documentation at full-stack-pattern.matthewkeil.com

Check out our docs site (hosted using this library). It has in-depth info on all the constructs in the library. There are use case examples for each of them and a list of what resources each deploys. There are also some tips and tricks in there for aws, and specifically how to get the most efficiency out of aws while building with these constructs.

The full-stack-pattern library contains two primary, high-level constructs FullStack and FullNestedStack. Both essentially do the same thing however FullStack is built from individual stack where FullNestedStack is built with one stack that has nested stacks. The interface you build with is identical so switching between the two is seamless.

Both build 5 primary components. The CoreConstruct which handles dns and tls/ssl. The CognitoConstruct which handles the auth. The CDNConstruct that hosts the front end, and other static assets, via a globally edge-cached cdn. Finally compute is handled by a fully ServerlessConstruct that optimizes on cost and maximizes the developer experience. The 5th is a ConfigFile CustomResource, for post deploy uploading of the environment configuration to the bucket hosting the ui.

You will be running on optimally configured S3, CloudFront, ApiGateway, Lambda, DynamoDb, and Cognito. All without knowing anything about aws. If you, or your company, would like help reach out to me on LinkedIn or on github.

  • Dead simple
  • Nearly all free (AWS free tier)
  • World-Class performance
  • All you need to focus on is writing your application code

There is a built-in, hot-reloading, dev server for running your lambda code locally. It's built right into the Construct and you can spin up an express server, built to mimic directly the apiGateway and lambda configurations. It will look and feel just like hitting the apiGateway but 100% locally. No-need to modify any code either.

Check out the docs for more information.

Constructs within full-stack-pattern

More information about what each does can be found by following the links below:

Usage Example

import { App } from '@aws-cdk/core';
import { FullStack, FullStackProps } from 'full-stack-construct';

(async function() {
  const app = new App();
  const stage = 'prod';

  const fs = await FullNestedStack.create(app, 'YourApp', {
    stage,
    prefix: `bc-full-stack-${stage}`,
    env: {
      region: 'us-east-1',
      account: '123456789012'
    },
    rootDomain: 'example.com',
    subDomain: 'micro-frontend',
    uiDevPort: 3012,
    core: {
      // See CoreConstruct on our docs, for more information
      includeSubdomains: true
    },
    cdn: {
      // See CDNConstruct on our docs, for more information
      codePaths: [resolve(__dirname, '..', 'frontend', 'build')],
      buildWwwSubdomain: false
    },
    cognito: {
      // See CognitoConstruct on our docs, for more information
      groups: [
        {
          groupName: 'admin',
          userEmails: ['[email protected]']
        }
      ]
    },
    serverless: {
      // See ServerlessConstruct on our docs, for more information
      code: Code.fromAsset(resolve(__dirname, '..', 'backend', 'src')),
      runtime: Runtime.NODEJS_14_X,
      billingMode: BillingMode.PAY_PER_REQUEST,
      tables: [
        {
          name: 'your-table',
          partitionKey: {
            id: 'string'
          }
        }
      ],
      lambdas: [
        {
          handler: 'fancyHandler/index.handler',
          name: 'fancy-handler',
          table: 'your-table',
          events: [
            {
              method: 'GET',
              path: '/fancy-path'
            }
          ]
        }
      ]
    }
  });

  fs.addConfigFile({
    fileName: 'config.json',
    config: {
      userPoolId: fs.cognito.userPool.userPoolId,
      userPoolClientId: fs.cognito.userPoolClient.userPoolClientId,
      userPoolDomain: fs.cognito.userPoolDomain?.domain,
      apiUrl:
        fs.domain && fs.serverless?.domain ? fs.serverless.domain : fs.serverless?.api?.api.url,
      webAppUrl: fs.domain ? fs.domain : fs.cdn?.distribution.distributionDomainName
    }
  });

  app.synth();
})();

FullStackConstructProps

export interface FullStackConstructProps {
  /**
   * The env for the stacks
   */
  readonly env?: Environment;

  /**
   * The prefix to use with resource names. If `prefix` and `name`
   * are provided then the apiName will be `${prefix}-${name}`.
   * If no name is provided then the apiName will be `prefix`. For
   * more info, see [Naming.](https://full-stack-pattern.matthewkeil.com/docs/naming)
   */
  prefix: string;

  /**
   * The deployment stage name.  This will be used to prefix all
   * resources.
   *
   * @default "prod"
   */
  stage: string;

  /**
   * The url/rootDomain for the HostedZone.  If you don not provide
   * a rootDomain a CoreConstruct will not be created.
   *
   * @example If you are hosting the ui at `www.example.com` and the
   * api at `api.example.com` the rootDomain would be `example.com`.
   * This is similar for branches, such as `dev.api.example.com` and
   * `dev.example.com`.  The rootDomain will still be `example.com`.
   */
  rootDomain: string;

  /**
   * Optional: A url subDomain to host the application at. Will
   * still use the HostedZone at rootDomain but all of this 
   * application will be hosted at the subDomain
   *
   * Assume your HostedZone is at `rootDomain: "example.com"` and
   * you want to host at `subDomain: "best-app"`
   *
   * This subDomain is the new "default" root of the application
   * - the UI will be at `best-app.example.com` and the
   *   dev branch will be at `dev.best-app.example.com`.
   *   Optionally you can build `www.best-app.example.com`
   *
   * - The Api will be at
   *   `api.best-app.example.com` and the dev api will be at
   *   `dev.api.best-app.example.com`
   */
  subDomain?: string;

  /**
   * Builds the component stacks as either Stack's or NestedStack's
   */
  nested?: boolean;

  /**
   * This is the NestedStack stack timeout that will be applied. For
   * non-nested stacks, this is ignored.
   */
  stackTimeout?: Duration;

  /**
   * RemovalPolicy to apply to all resources.  If a RemovalPolicy
   * prop is provided for a specific resource, ie the
   * `props.core.removalPolicy`, it will override this value
   */
  removalPolicy?: RemovalPolicy;

  /**
   * For standing the development server and configuring cors during
   * development. This is the localhost:PORT that serves your
   * frontend
   */
  uiDevPort?: number | string;

  /**
   * No CognitoConstruct will be built
   */
  noCognito?: boolean;

  /**
   * Settings for the [CoreConstruct](https://full-stack-pattern.matthewkeil.com/docs/core/coreConstruct)
   *
   * Optional: If you do not provide a `rootDomain` this will be
   * ignored and a CoreConstruct will not be built
   *
   * rootDomain is not available on core, it is passed in from
   * fullStackProp.rootDomain
   */
  core?: Omit<CoreConstructProps, 'rootDomain'>;

  /**
   * Settings for the [CDNConstruct](https://full-stack-pattern.matthewkeil.com/docs/cdn/cdnConstruct)
   *
   * Optional: If you do not provide this a CDNConstruct will not be
   * built
   *
   * prefix, stage and rootDomain are not available on 
   * fullStackProps.cdn They are passed in from fullStackProp.prefix
   * and fullStackProp.stage and fullStackProp.rootDomain
   */
  cdn?: Omit<CDNConstructProps, 'prefix' | 'stage' | 'rootDomain'>;

  /**
   * Settings for the [ServerlessConstruct](https://full-stack-pattern.matthewkeil.com/docs/serverless/serverlessConstruct)
   *
   * Optional: If you do not provide this a ServerlessConstruct will not be
   * built
   *
   * prefix, stage  are not available on fullStackProps.serverless,
   * they are passed in from fullStackProp.prefix and
   * fullStackProp.stage
   */
  serverless?: Omit<ServerlessConstructProps, 'prefix' | 'stage'>;

  /**
   * Settings for the [CognitoConstruct](https://full-stack-pattern.matthewkeil.com/docs/cognito/cognitoConstruct)
   *
   * rootDomain is not available on core, it is passed in from
   * fullStackProp.rootDomain
   */
  cognito?: Cognito;
}

type Cognito = Omit<CognitoConstructProps, 'prefix'> & {
  /**
   * The login path to append to all urls.
   *
   * ex. a value of '/auth/login' will result in a cognito callback url of
   * 'http://localhost:3000/auth/login' and the cloudfront cognito url will be
   * 'https://d1mkdh3z21t61o24eles.cloudfront.net/auth/login'
   */
  loginCallbackPath?: string;

  /**
   * The logout path to append to all urls.
   *
   * ex. a value of '/auth/logout' will result in a cognito callback url of
   * 'http://localhost:3000/auth/logout' and the cloudfront cognito url will be
   * 'https://d1mkdh3z21t61o24eles.cloudfront.net/auth/logout'
   */
  logoutCallbackPath?: string;
};