diff --git a/API.md b/API.md
index 5b14174..75c4ae0 100644
--- a/API.md
+++ b/API.md
@@ -379,35 +379,117 @@ public readonly cidr: string;
---
+## Classes
-## Protocols
+### Shard
-### IShard
+- *Implements:* IShard
+
+#### Initializers
+
+```typescript
+import { Shard } from '@time-loop/cdk-named-environments'
+
+new Shard(props: IShardProps)
+```
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| props | IShardProps | *No description.* |
+
+---
+
+##### `props`Required
+
+- *Type:* IShardProps
+
+---
+
+
+
+#### Properties
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| cidr | string | The cidr for a shard's vpc. |
+| name | string | There are numerous different ways to name a shard. |
+| number | number | The shard-number within the region. |
+| region | string | The AWS region for a shard. |
+
+---
+
+##### `cidr`Required
+
+```typescript
+public readonly cidr: string;
+```
+
+- *Type:* string
+
+The cidr for a shard's vpc.
+
+Regions typically receive a 10.?.0.0/12 address space,
+within which there are 16 /16 subnets for shards.
+
+---
-- *Implemented By:* IShard
+##### `name`Required
-#### Methods
+```typescript
+public readonly name: string;
+```
+
+- *Type:* string
+
+There are numerous different ways to name a shard.
-| **Name** | **Description** |
-| --- | --- |
-| toString | *No description.* |
+Pick one and stick with
+it.
---
-##### `toString`
+##### `number`Required
```typescript
-public toString(): string
+public readonly number: number;
```
+- *Type:* number
+
+The shard-number within the region.
+
+---
+
+##### `region`Required
+
+```typescript
+public readonly region: string;
+```
+
+- *Type:* string
+
+The AWS region for a shard.
+
+---
+
+
+## Protocols
+
+### IShard
+
+- *Extends:* IShardProps
+
+- *Implemented By:* Shard, IShard
+
+
#### Properties
| **Name** | **Type** | **Description** |
| --- | --- | --- |
| cidr | string | The cidr for a shard's vpc. |
-| name | string | The proper name for a shard (without numeric suffix). |
| number | number | The shard-number within the region. |
| region | string | The AWS region for a shard. |
+| name | string | The proper name for a shard (without numeric suffix). |
---
@@ -426,6 +508,30 @@ within which there are 16 /16 subnets for shards.
---
+##### `number`Required
+
+```typescript
+public readonly number: number;
+```
+
+- *Type:* number
+
+The shard-number within the region.
+
+---
+
+##### `region`Required
+
+```typescript
+public readonly region: string;
+```
+
+- *Type:* string
+
+The AWS region for a shard.
+
+---
+
##### `name`Required
```typescript
@@ -438,7 +544,37 @@ The proper name for a shard (without numeric suffix).
---
-##### `number`Required
+### IShardProps
+
+- *Implemented By:* Shard, IShard, IShardProps
+
+
+#### Properties
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| cidr | string | The cidr for a shard's vpc. |
+| number | number | The shard-number within the region. |
+| region | string | The AWS region for a shard. |
+
+---
+
+##### `cidr`Required
+
+```typescript
+public readonly cidr: string;
+```
+
+- *Type:* string
+
+The cidr for a shard's vpc.
+
+Regions typically receive a 10.?.0.0/12 address space,
+within which there are 16 /16 subnets for shards.
+
+---
+
+##### `number`Required
```typescript
public readonly number: number;
@@ -450,7 +586,7 @@ The shard-number within the region.
---
-##### `region`Required
+##### `region`Required
```typescript
public readonly region: string;
diff --git a/src/Shard.ts b/src/Shard.ts
index 07d28c5..2928460 100644
--- a/src/Shard.ts
+++ b/src/Shard.ts
@@ -1,4 +1,4 @@
-export interface IShard {
+export interface IShardProps {
/**
* The cidr for a shard's vpc.
* Regions typically receive a 10.?.0.0/12 address space,
@@ -10,13 +10,32 @@ export interface IShard {
*/
readonly region: string;
/**
- * The proper name for a shard (without numeric suffix).
+ * The shard-number within the region.
*/
- readonly name: string;
+ readonly number: number;
+}
+
+export interface IShard extends IShardProps {
/**
- * The shard-number within the region.
+ * The proper name for a shard (without numeric suffix).
*/
+ readonly name: string;
+}
+
+export abstract class Shard implements IShard {
+ readonly cidr: string;
+ readonly region: string;
readonly number: number;
- toString(): string;
+ constructor(props: IShardProps) {
+ this.cidr = props.cidr;
+ this.region = props.region;
+ this.number = props.number;
+ }
+
+ /**
+ * There are numerous different ways to name a shard. Pick one and stick with
+ * it.
+ */
+ abstract get name(): string;
}
diff --git a/test/Shard.test.ts b/test/Shard.test.ts
new file mode 100644
index 0000000..3ac0477
--- /dev/null
+++ b/test/Shard.test.ts
@@ -0,0 +1,30 @@
+import { IShard, Shard, IShardProps } from '../src';
+
+const env = 'QA';
+class TestShardImpl extends Shard {
+ get name(): string {
+ return `${env}_${this.region}_${this.number}`;
+ }
+}
+
+const testShardProps: IShardProps = { cidr: '10.0.0.0/0', region: 'us-west-2', number: 1 };
+
+let shard: IShard;
+describe('Shard', () => {
+ beforeEach(() => {
+ shard = new TestShardImpl(testShardProps);
+ });
+
+ it('sets CIDR correctly', () => {
+ expect(shard.cidr).toEqual(testShardProps.cidr);
+ });
+ it('sets region correctly', () => {
+ expect(shard.region).toEqual(testShardProps.region);
+ });
+ it('sets number correctly', () => {
+ expect(shard.number).toEqual(testShardProps.number);
+ });
+ it('sets name correctly', () => {
+ expect(shard.name).toEqual('QA_us-west-2_1');
+ });
+});