open-index/open-npm huggingface dataset:
npm package: @strategies/color-utils
Description: Color utilities
Author: Ken Goulding
Latest version: 0.0.6

# Color Utilities

Currently only a single `ColorProvider` class is provided here, but we may add additional utilities for working with color - particularly related to data visualization.

## Install
```
pnpm install @strategies/color-utils
```

## Example

 
Use with default palettes:
```js
import {ColorProvider} from '@strategies/color-utils';

const colorProvider = new ColorProvider();
const newColor = colorProvider.next();
```
OR
```js
const newColor = colorProvider.random();
```

Specify custom palettes:
```js
import {colorbrewerPalettes, ColorProvider} from '@strategies/color-utils';

const palette1 = colorbrewerPalettes.Pastel1['9'];
const palette2 = colorbrewerPalettes.Accent['8'];

const colorProvider = new ColorProvider([palette1, palette2]);
const newColor = colorProvider.next();
```


## Publish

There is no build step - only TS environments are supported.

Commit to Git, then: 

```
pnpm publish
```
npm package: @strategies/excelerator
Description: We have Excel, but we want JSON
Author: Eric Youngberg
Latest version: 1.1.0

# Sasaki's Excelerator
### We have Excel, but we want JSON or CSV

## Install
```
yarn add @strategies/excelerator
```

## Example
```
(new Excelerator())
    .load('data.xlsx')
    .sheet('DashiData')
    .row(2)
    .columns({
        'A:id': [required, trim],
        'B:name': [required, trim, replace('unnamed Rhino ', '')],
        'D:gfa': [setDefault(30000)],
        'F:cost': [required],
        'E:costPerSF': [alias('cost')],
        'G:program': [required, trim],
        'H:scenario': [replace('all scenarios', ''), nullable],
        'I:phase': [(value, source, target) => `Phase ${value}-${target['scenario']}`],
    })
    .writeJSON('../assets/projects.json', 4);
```
npm package: @strategies/firebase-files
Description: Utilities for uploading, unzipping and serving files via firebase storage. Includes the upload form and client-side code for unzipping and uploading.
Author: Ken Goulding
Latest version: 0.0.15

# @strategies/firebase-files

A simple, but robust solution for file management on firebase.

## Firestore files

Store metadata and snapshot references in Firestore records. These are what get listed when the user brings up a list of snapshots, but they don't contain any file data - only references to snapshots - including an 'activeSnapshot' tag that represents the current state of the file. Every time user presses save they generate a new snapshot and the 'active' pointer in the Firestore record is updated.

## Snapshots
Direct serializations of mobx-keystone persist stores. Can support large data if needed.


## Uploads
Upload and unzip files into cloud storage. Then return a unique path in order to access those files.
npm package: @strategies/login
Description: Our Sasaki login component
Author: Raj Adi Raman
Latest version: 1.0.10

# Sasaki's React Login
### Standardized Firebase login pattern for Sasaki products


## Install
```
yarn add @strategies/login
```

## Publish
```
pnpm esbuild
pnpm publish --no-git-checks
```

## Example

```js
<Login
    // Firebase config
    config={config}

    // Image src path
    logo={DashiLogo}

    // Content for the user guide panel
    guide={<>
        <header>User Guide</header>
        <iframe title="User Guide" src="https://docs.google.com/document/d/e/2PACX-1vSxkp7VeI26uJyDZ7Pz_eV7ZKghZaQDDcbizP0YT0VthZmJ5iSwV3P8DzyA1KxA3DPO22xKVLeOK9bV/pub?embedded=true"></iframe>
    </>}

    // A list of screen grabs to display
    screens={[
        { src: TimelineScreen, alt: '', },
        { src: DataScreen, alt: '', },
        { src: ProjectDataScreen, alt: '', },
    ]}
/>

```


## Required Props

##### config: FirebaseConfig
Your app's Firebase config.


## Optional Props

##### contactEmail: string = 'strategies@sasaki.com'
Appears during certain phases of the login process when help might need to be
requested directly.

##### contactLink: string
The destination of the "Contact" icon link. If nothing is supplied, the icon
will not appear.

##### emailEnabled: boolean = true
If this is set to `false`, then the only option available is logging in with a
Sasaki account.

##### guide: ReactElement
What is rendered when a user clicks the "User Guide" icon. If nothing is supplied,
then the icon will not appear.

##### logo: string
Populates the `src` attribute of the image element that sits above the forms.

##### onChange: (user: User|null) => any
An event that is emitted whenever the auth state changes.

##### screens: { src: string, alt: string }[]
The images that fade in when the login component mounts.

##### title: string|ReactElement
Text for beneath the logo image.

##### whitelist: string[]
If supplied, will prevent users from creating accounts if the supplied email
does not match any in the whitelist. If nothing is supplied, then all emails
are valid for new account creation.
npm package: @strategies/maplibsasakidev
Description: To install dependencies:
Author: Armin Akhavan
Latest version: 1.6.0

# maplibsasaki

To install dependencies:

```bash
bun install
```

To run:

```bash
bun run watch
```

This project was created using `bun init` in bun v1.0.14. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
npm package: @strategies/notification
Description: Pure JS notifications
Author: Eric Youngberg
Latest version: 1.0.2

# Sasaki's Notification
### Pure JS notifications; popups and push enabled.

# Documentation

## Install
```
yarn add @strategies/notification
```


## Usage

```
new Notification('hello');
new Notification({ message: 'hello' });
```

### Lifecycle
There are two lifecycle methods: `.play()` and `.finish()`. All notifications can 
be replayed instead of having to create a new Notification each time you want to display
that notification.

```
const notification = new Notification('Repeat me');
notification.play();
notification.play();
```

### Attach a click event to a notification
```
let notification: Notification;
notification = new Notification({
    message: 'A will stay open until clicked',
    duration: Infinity,
    onClick: () => notification.finish(),
});
```

### Deferred notifications
If you want to create notifications to be used later, you can always defer them.

```
const notification = new Notification({ message: 'Hello', defer: true });

// notification won't play until you tell it to play
notification.play();
```

### Push notifications
If you desire to use the push notification feature of this package, you must supply
an empty JS file in your public folder to be used as a Service Worker. By default, 
this file is `./notification.js`.


## Configuration
#### Environment
You can configure the Notification environment statically on the Notification class. 
_Note: these configuration settings are the default values._

```
Notification.configure({
    mount: document.querySelector('body'),
    serviceWorker: './notification.js',
});
```

#### Notifications
You can configure the default settings for all notifications or pass the same
configuration options into each Notification instance.

```
Notification.configure({
    duration: 3000,  // amount of time in milliseconds that a notification will show.
    defer: false,    // if true, notifications will not play upon instantiantion.
    flash: false,    // if true, the latest notification will repeatedly flash in the tab title.
    push: false,     // if true, the notification will appear as a push notification if the tab is not in focus.
});

new Notification({
    message: 'Save Successful',
    duration: 2000,
});
```
npm package: @strategies/portals
Description: We need to render components elsewhere declaritively
Author: Eric Youngberg
Latest version: 0.1.4

# Sasaki's Stores
### Register stores in a flat structure to be referenced anywhere in your React app.


## Install
```
yarn add @strategies/stores react mobx
```

## Example


#### App Code
```js
import { computed } from 'mobx';
import { register, Store, stores } from '@strategies/stores';

class AppStore extends Store {

    /**
    * onRegister is a "secondary constructor" that fires when you register
    * this store, as seen below.
    */
    onRegister() {
        const { ui } = stores;
        console.log(ui.id); // -> 5
    }

    /**
    * onUpdateRegistration runs if `register` is called again after this 
    * store has already been registered.
    */
    onUpdateRegistration(stores: {[key: string]: Store}) {
        if (stores.layout) {
            console.log('We now have the layout store');
        }
    }

    /**
    * `stores` is a MobX observable meaning that we can observe
    * changes made to the store registry.
    */
    @computed
    get width() {
        return stores.layout.width;
    }

}

class UiStore extends Store {

    id: string;

    constructor(id: string) {
        super();
        this.id = id;
    }

}

class LayoutStore extends Store {

    readonly width: number = 500;

}


register({
    app: new AppStore(),
    ui: new UiStore('5'),
});

// We can register new stores at any point. Useful for enforcing load order.
register({
    layout: new LayoutStore()
});
```

#### React
```jsx
import { observer } from 'mobx-react';
import { useStores } from '@strategies/stores';

/**
* the `useStores` hook is used to inject the stores
* into our React components
*/
export default observer(function App() {
    const { app } = useStores();

    return (
        <div className="App" style={{ width: `${app.width}px` }}>
            {/* ... */}
        </div>
    )
});
```
npm package: @strategies/react-events
Description: `mobx` and other state management solutions allow state changes to be observed really effectively so that components can respond reactively. However some reactions need to happen in response to events rather than a state change.
Latest version: 1.0.1

# @strategies/react-events

## Motivation
`mobx` and other state management solutions allow state changes to be observed really effectively so that components can respond reactively. However some reactions need to happen in
response to events rather than a state change. 

For example a user clicking a button to zoom in to a map. Nothing about the state has changed, and external components don't know enough about the intended 
action to modify the state at the top level, so the component needs to receive an instruction to respond to.

One way of solving this in react is to pass a ref to the object (such as the Map instance) up the component hierarchy so that a method can be called in response to a user interaction. 
However passing refs up is more cumbersome than passing an object down as a prop - or accessing that object (such as a store) via context or imports.

This solution uses an object that implements a typed EventEmitter and then listens to that object on a react component using `useEventSubscription`

### mobx
This event emitter and `useEventSubscription` pattern works well with mobx stores and can be implemented on a mobx store.

### creating an event emitter with typed events
using a type automatically generates the accepted "keys" that can be used as strings.
```js
type MapStoreEvents = {
    zoomIn: number,
    zoomOut: number,
    zoomToSelected: void
}

export class MapStore extends EventEmitter<MapStoreEvents> {
    zoomToSelected() {
        this.emit("zoomToSelected")
    }
    zoomIn() {
        this.emit("zoomIn", 5)
    }
    zoomOut() {
        this.emit("zoomOut", 5)
    }
}
```

### useEventSubscription hook for EventEmitter
whenever the event emitter calls emit with a specific key, the function passed to the `useEventSubscription` is executed.
```js
useEventSubscription(myEmitter, "zoomToSelected", () => {
   mapRef.zoomToSelected('Zoomed');
});
```
npm package: @strategies/react-login
Description: Our Sasaki login component
Author: Eric Youngberg
Latest version: 2.0.7

# Sasaki's React Login 
### Standardized Firebase login pattern for Sasaki products


## Install
```
yarn add @sasaki-dev/react-login
```


## Example

```js
<ReactLogin
    // Firebase config
    config={config}

    // Image src path
    logo={DashiLogo}

    // Content for the user guide panel
    guide={<>
        <header>User Guide</header>
        <iframe title="User Guide" src="https://docs.google.com/document/d/e/2PACX-1vSxkp7VeI26uJyDZ7Pz_eV7ZKghZaQDDcbizP0YT0VthZmJ5iSwV3P8DzyA1KxA3DPO22xKVLeOK9bV/pub?embedded=true"></iframe>
    </>}

    // A list of screen grabs to display
    screens={[
        { src: TimelineScreen, alt: '', },
        { src: DataScreen, alt: '', },
        { src: ProjectDataScreen, alt: '', },
    ]}
/>

```


## Required Props

##### config: FirebaseConfig
Your app's Firebase config.


## Optional Props

##### contactEmail: string = 'strategies@sasaki.com'
Appears during certain phases of the login process when help might need to be 
requested directly.

##### contactLink: string
The destination of the "Contact" icon link. If nothing is supplied, the icon 
will not appear.

##### emailEnabled: boolean = true
If this is set to `false`, then the only option available is logging in with a 
Sasaki account.

##### guide: ReactElement
What is rendered when a user clicks the "User Guide" icon. If nothing is supplied, 
then the icon will not appear.

##### logo: string
Populates the `src` attribute of the image element that sits above the forms.

##### onChange: (user: User|null) => any
An event that is emitted whenever the auth state changes.

##### screens: { src: string, alt: string }[]
The images that fade in when the login component mounts. 

##### title: string|ReactElement
Text for beneath the the logo image.

##### whitelist: string[]
If supplied, will prevent users from creating accounts if the supplied email 
does not match any in the whitelist. If nothing is supplied, then all emails
are valid for new account creation.
npm package: @strategies/react-pinboard
Description: Pin components inside a component
Author: Eric Youngberg
Latest version: 1.2.2

# Sasaki's React Pinboard
### Pin components inside a fixed component with optional fixed aspect ratio


## Install
```
yarn add @strategies/react-pinboard
```

## Example

```js
import { Pinboard, Pin } from '@strategies/react-pinboard'
```

```js
<Pinboard aspect={4/3}>
    <img src={baseImage} alt="An unpinned element inside the pinboard" />

    <Pin x={.3} y={.25}>
        <YourComponent />
    </Pin>

    <Pin x={.5} y={1}>
        <YourComponent />
    </Pin>

    <Pin x={.65} y={.1}>
        <YourOtherComponent />
    </Pin>
</Pinboard>
```
npm package: @strategies/stores
Description: We need stores, and we need them MobX, and we need them in context
Author: Eric Youngberg
Latest version: 1.3.4

# Sasaki's Stores
### Register stores in a flat structure to be referenced anywhere in your React app.


## Install
```
yarn add @strategies/stores react mobx
```

## Example


#### App Code
```js
import { computed } from 'mobx';
import { register, Store, stores } from '@strategies/stores';

class AppStore extends Store {

    /**
    * onRegister is a "secondary constructor" that fires when you register
    * this store, as seen below.
    */
    onRegister() {
        const { ui } = stores;
        console.log(ui.id); // -> 5
    }

    /**
    * onUpdateRegistration runs if `register` is called again after this 
    * store has already been registered.
    */
    onUpdateRegistration(stores: {[key: string]: Store}) {
        if (stores.layout) {
            console.log('We now have the layout store');
        }
    }

    /**
    * `stores` is a MobX observable meaning that we can observe
    * changes made to the store registry.
    */
    @computed
    get width() {
        return stores.layout.width;
    }

}

class UiStore extends Store {

    id: string;

    constructor(id: string) {
        super();
        this.id = id;
    }

}

class LayoutStore extends Store {

    readonly width: number = 500;

}


register({
    app: new AppStore(),
    ui: new UiStore('5'),
});

// We can register new stores at any point. Useful for enforcing load order.
register({
    layout: new LayoutStore()
});
```

#### React
```jsx
import { observer } from 'mobx-react';
import { useStores } from '@strategies/stores';

/**
* the `useStores` hook is used to inject the stores
* into our React components
*/
export default observer(function App() {
    const { app } = useStores();

    return (
        <div className="App" style={{ width: `${app.width}px` }}>
            {/* ... */}
        </div>
    )
});
```
npm package: @strategies/target-animate
Description: Delayed state animation library for react
Latest version: 1.0.6


## Summary 

Extremely simple state-based animation

Using a TargetWrapper for any property's getter/setter, we can delay the resolution of the object to that display state. 

Because this is not true animation - objects always simply approach their target state - it is not only very simple, but it effortlessly handles situations where regular timing-based animation get tricky (state changing before animation is complete). 

Once set, objects can be updated based on stateful calculations.


## Implementation


This is implemented in two ways:

1.  This implementation is defining a react Hook: and exports `useTarget`, only depending on react for state management,
    
2.  The second implementation depends on `mobx` for state management, and is more tailored to our internal setup.


## installation 

```
yarn add @strategies/target-animate
```

## example usage

TBD


undocumented example usage:

https://bitbucket.org/sasaki_dev/react-fiddles/src/master/src/fiddles/delayed-state-animation/prioritizer/     

https://misc-tools.s3.amazonaws.com/testbed/prioritizer-3-poc/index.html    

http://misc-tools.s3-website-us-east-1.amazonaws.com/testbed/prioritizer-3-poc     

## License
MIT
npm package: @strategies/versions
Description: System for applying incremental updates to a data structure
Author: Eric Youngberg
Latest version: 1.1.5

# Sasaki's Versions
### System for applying incremental patches to a data structure.


## Install
```
yarn add @strategies/versions
```

## Example
#### Create your version patches
```js
const versions = new Versions({

	'1.0.0': file => {
		// perform work on file. Mutating file itsself is okay since we always
		// pass a fresh object into subsequent patches. 
		return file;
	},

	'2.0.0': file => {
		// ...
		return file;
	},

	// Patches can be declared out of order; that's okay. 
	'1.5.0': file => {
		// ...
		return file;
	},

});

console.log(versions.latest)   // -> '2.0.0'
console.log(versions.versions) // -> ['1.0.0', '1.5.0', '2.0.0']
```

#### Pass an object through
If the object does not contain a `version` key, then the data starts at `0.0.0`. 

```js
const fileWithLatestPatch = versions.upgrade(file);
// fileWithLatestPatch.version === '2.0.0'
```

If you don't want to apply patches to the latest version, you can optionally specify which version as a second argument.

```js
const fileAt1point5 = versions.upgrade(file, '1.5.0');
```
npm package: @strategies/visualizer.speckle-api
Description: Local copy of speckle api for dev and dependency conflict resolution
Author: Ken Goulding
Latest version: 0.0.2

# speckle-api

Local copy of speckle api for dev and dependency conflict resolution
https://github.com/sasakiassociates/speckle/

## the issue

There was an issue with core.js (https://github.com/zloirock/core-js/issues/1091)
It was using one with this path: `http://127.0.0.1:5174/node_modules/.pnpm/@strategies+speckle@1.0.1_f4ffqkgz5d3wev7su7t7l2rrua/node_modules/@strategies/speckle/node_modules/core-js/`
Different from the `poc` package that was using `http://127.0.0.1:5173/node_modules/.pnpm/core-js@3.27.1/node_modules/core-js/`
so we're adding here as a dependency even though we don't use it
npm package: @strategies/visualizer.viewers.colorizer
Description: Colorizer IViewer implementation using react-colorizer.
Author: Ken Goulding
Latest version: 0.1.7

# viewers.colorizer

A visualizer-compatible implementation of the colorizer.

The colorizer supports the properties of viewerStates elements (IViewerState). For each implementation, ColorizerStyles may be applied to determine how each state is represented. For example how "selection" is shown.

Other properties such as the folder name for the colorizer files, background images and other settings are also specified in ColorizerStyles.

## Publishing
This module is used from source, so no build step is required, but `pnpm` must be used in order to resolve workspace dependencies.

Update build number then:
`pnpm publish --no-git-checks`

## Dev Note
establish a simple folder link to local react-colorizer package:
e.g.
```
pnpm link "C:\Users\kgoulding\Documents\Development\JavaScript\lib\packages\react-colorizer"
```

## TODO
[ ] Support switching the colorizerDir property as a way to change the content of the Colorizer
npm package: @strategies/visualizer.viewers.speckle
Description: Speckle-based IViewer implementation.
Author: Ken Goulding
Latest version: 0.0.2

# viewers.speckle

A speckle-based 3D viewer that builds on Speckle's web viewer.

https://github.com/specklesystems/speckle-server/tree/main/packages/viewer

https://speckle.notion.site/Viewer-API-Documentation-11f7bcbf3d2547c2985b0c988fb9889e


TODO:

[ ] Add support for multiple viewers simultaneously
[ ] Allow component to be toggled on and off - currently doesn't show up after showing the second time...

Currently, there is an error being thrown in getRenderViewsForNode - I suspect because the data is referencing an older node or something...?
npm package: @strategies/visualizer.zoomable
Description: Visualizer support for zoomable components.
Author: Ken Goulding
Latest version: 0.0.3

# visualizer-zoomable

Some visualizer implementations will provide their own zooming and panning functionality. For example, the SpeckleViewer handles this with a 3D camera and map controls like MapboxGL provide this.

However, for other content such as Colorizer canvases or SVG imagery, we want a standard solution to provide that functionality.

This code builds on the TransformComponent and TransformWrapper components from "react-zoom-pan-pinch", but simplifies and standardizes the implementation within the Visualizer.

## Single vs Multiple

The Visualizer allows numerous configurations for layouts on screen. 

### One at a time
One viewer may be shown at a time; with the option to switch to a different viewer;

```
<div className={'stage'}>
    {activeView === 'colorizer' && <Zoomable ...zoomBindings()><ColorizerViewer ...bindings() /></Zoomable>}
    {activeView === 'html' && <HtmlViewer ...bindings() />}
</div>
```

### Multiple, Independent Controls
Multiple viewers may be shown side by side, and controlled independently.

```
<div className={'stage'}>
    <Zoomable ...zoomBindings()><ColorizerViewer ...bindings() /></Zoomable>
</div>
<div className={'stage'}>
    <HtmlViewer ...bindings() />
</div>
```

### Multiple, Shared Controls
Multiple viewers may share space on the same larger 'canvas' and be controlled by a single zoom/pan controller. 

```
<div className={'stage'}>
    <Zoomable ...zoomBindings()>
        <div className={'zoomies'}>
            <div className={'positioned'} style={getPosition(0)}>
                <ColorizerViewer ...bindings() />        
            </div>
            <div className={'positioned'} style={getPosition(1)}>
                <HtmlViewer ...bindings() />        
            </div>
        </div>
    </Zoomable>
</div>
```

The current implementation returns a viewer object that each app can maintain that exposes functions like zoomIn etc
However, this does not support the use case where viewers are combined on the same canvas.

Perhaps we can return and manage a series of iZoomables instead. these would be returned for each zoomable element.

How do we connect these to the zoom actions within the TransformWrapper?
npm package: @strategy/react-hooks
Description: React Apollo Hooks.
Author: liuhuan@ihealthlabs.com.cn
Latest version: 4.0.0

# <a href="https://www.apollographql.com/"><img src="https://user-images.githubusercontent.com/841294/53402609-b97a2180-39ba-11e9-8100-812bab86357c.png" height="100" alt="React Apollo"></a>

## React Apollo - Hooks

[![npm version](https://badge.fury.io/js/%40apollo%2Freact-hooks.svg)](https://badge.fury.io/js/%40apollo%2Freact-hooks)
[![Build Status](https://circleci.com/gh/apollographql/react-apollo.svg?style=svg)](https://circleci.com/gh/apollographql/react-apollo)
[![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/apollo)

React Apollo `useQuery`, `useLazyQuery`, `useMutation`, `useSubscription` and `useApolloClient` hooks.

### Installation

```
npm install @apollo/react-hooks
```

### Documentation

All Apollo Client documentation, including React Apollo usage articles and helpful recipes, lives on [https://www.apollographql.com/docs/react/](https://www.apollographql.com/docs/react/)

For the React Apollo API reference, visit [https://www.apollographql.com/docs/react/api/react-apollo.html](https://www.apollographql.com/docs/react/api/react-apollo.html)
npm package: @strathberry/klaviyo-client
Description: (Fork) Klaviyo API client for Node.js and browser
Author: Matthew Erskine
Latest version: 1.0.3-hydrogen

# Klaviyo API client for Node.js and browser

This is a Klaviyo API client for Node.js and browser written in Typescript.

## Installation

```shell
npm i klaviyo-client
```

or

```shell
yarn add klaviyo-client
```

## Usage

The package contains two separate classes:

- `KlaviyoClient` to identify profiles and track events. Klaviyo Token is needed to use it
- `KlaviyoApi` to work with Klaviyo API. Klaviyo Token and API key are needed to use it. Currently it supports following operations:
  - Lists - get profiles from list and segments
  - Lists - create list
  - Lists - get all lists
  - Lists - get list details
  - Lists - update list
  - Lists - delete list
  - Profiles - get complete profile data
  - Profiles - create or update profile data
  - Profiles - get a list of profile events
  - Profiles - get a list of profile events by metric ID

The package supports providing generic event or profile properties types in order to work in well-known types manner.

## Configuration

You can get **API key** and **token** in your Klaviyo account <a href="https://www.klaviyo.com/account#api-keys-tab/" target="_blank">here</a>.

_Token is also known as Site ID or public API key._

Please read <a href="https://www.klaviyo.com/docs/http-api/" target="_blank">Klaviyo API documentation</a>.

## Need Help or Feature?

Drop me an email to [Mikhail Monchak](mailto:mikhail.monchak.work@gmail.com)
npm package: @stratiformdigital/serverless-s3-security-helper
Description: Serverless plugin to set security related settings on s3 buckets.
Author: Mike Dial
Latest version: 4.0.0

<h1 align="center" style="border-bottom: none;"> serverless-s3-security-helper</h1>
<h3 align="center">Sets security related settings on s3 buckets.</h3>
<p align="center">
  <a href="https://github.com/stratiformdigital/serverless-s3-security-helper/releases/latest">
    <img alt="latest release" src="https://img.shields.io/github/release/stratiformdigital/serverless-s3-security-helper.svg">
  </a>
  <a href="https://www.npmjs.com/package/@stratiformdigital/serverless-s3-security-helper">
    <img alt="npm latest version" src="https://img.shields.io/npm/v/@stratiformdigital/serverless-s3-security-helper/latest.svg">
  </a>
  <a href="https://codeclimate.com/github/stratiformdigital/serverless-s3-security-helper/maintainability">
    <img alt="Maintainability" src="https://api.codeclimate.com/v1/badges/3a3eb55e2dc93c7e0174/maintainability">
  </a>
  <a href="https://github.com/semantic-release/semantic-release">
    <img alt="semantic-release: angular" src="https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release">
  </a>
  <a href="https://dependabot.com/">
    <img alt="Dependabot" src="https://badgen.net/badge/Dependabot/enabled/green?icon=dependabot">
  </a>
  <a href="https://github.com/prettier/prettier">
    <img alt="code style: prettier" src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square">
  </a>
</p>

## Usage

```
...

plugins:
  - serverless-s3-security-helper

...

```

## Background

This plugin set settings on all S3 buckets. These are settings that are commonly required for security compliance. It handles severless deployment buckets as well as buckets created by a service.

Currently, the plugin:

- enables versioning for objects
- blocks all public access on the bucket, by default

This plugin has two hooks:

- package:createDeploymentArtifacts
- package:compileEvents

At each step, the buckets are set to be configured properly. This ensures the serverless deployment bucket is configured properly throughout its entire lifecycle.

## License

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

See [LICENSE](LICENSE) for full details.
npm package: @stratify/cli
Description: Command-line tool for [Stratify](https://www.npmjs.com/package/@stratify/core), a modular Fastify framework with DI and TypeScript support. It scaffolds a ready-to-use Stratify project with TypeScript, ESLint, and Prettier.
Latest version: 0.2.4


# Stratify CLI

Command-line tool for [Stratify](https://www.npmjs.com/package/@stratify/core), a modular Fastify framework with DI and TypeScript support.
It scaffolds a ready-to-use Stratify project with TypeScript, ESLint, and Prettier.

## Installation

```bash
npm install -g @stratify/cli
```

## Usage

With `npx` (no global install required):

```bash
npx @stratify/cli new <app-name>
```

Or, after a global install:

```bash
stratify-cli new <app-name>
```

Creates a new project with:

* TypeScript + ESM
* ESLint and Prettier setup
* Example module under `/src/tasks` (controllers, providers, hooks, installers, adapters)

Then:

```bash
cd <app-name>
npm install
npm run dev
```
npm package: @stratify/core
Description: Dependency Injection package for the Fastify framework
Author: jean.antoine.michelet@gmail.com
Latest version: 0.2.2

# Stratify

**Stratify** is an architectural framework built on [**Fastify**](https://fastify.dev/) that introduces clear structural boundaries and a robust **Dependency Injection** system.
Applications are defined through **modules, providers, controllers, hooks, installers, and adapters**, while maintaining Fastify’s performance and encapsulation model.

The suffix _-ify_ acknowledges its Fastify heritage, and _strata_ expresses its guiding principle of modular layering and clear separation of concerns.

Stratify remains fully compatible with the Fastify ecosystem.

> Early stage: open to community feedback as the API matures toward stability by late 2025.

Read the documentation here: https://stratifyjs.github.io/