@emmett-community/emmett-google-services-bootstrap 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +164 -0
- package/dist/index.cjs +947 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +382 -0
- package/dist/index.d.ts +382 -0
- package/dist/index.js +908 -0
- package/dist/index.js.map +1 -0
- package/package.json +88 -0
package/README.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# @emmett-community/emmett-google-services-bootstrap
|
|
2
|
+
|
|
3
|
+
Service bootstrap for event-driven apps using Google Cloud. This package wires Firebase Admin, Firestore event store, Realtime DB projections, PubSub message bus, and lifecycle utilities so services can start with minimal boilerplate.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@emmett-community/emmett-google-services-bootstrap) [](https://opensource.org/licenses/MIT) [](https://github.com/emmett-community/emmett-google-services-bootstrap/actions/workflows/build_and_test.yml)
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- ✅ One orchestrator to initialize Firebase, PubSub, and event store wiring
|
|
10
|
+
- ✅ Realtime DB projections hooked automatically
|
|
11
|
+
- ✅ Built-in dependency checks and graceful shutdown
|
|
12
|
+
- ✅ OpenAPI-ready app creation with sensible defaults
|
|
13
|
+
- ✅ Auth security handlers available without extra service deps
|
|
14
|
+
- ✅ No side effects on import
|
|
15
|
+
|
|
16
|
+
## Why this package exists
|
|
17
|
+
|
|
18
|
+
Most Emmett services repeat the same bootstrap work: Firebase Admin init, Firestore event store setup, PubSub wiring, and shutdown logic. This package centralizes that boilerplate into a single, explicit orchestrator.
|
|
19
|
+
|
|
20
|
+
## How it relates to other emmett-community packages
|
|
21
|
+
|
|
22
|
+
- It is **for application entrypoints** (service `index.ts`).
|
|
23
|
+
- It composes existing packages (firestore, pubsub, realtime-db, observability, expressjs-with-openapi).
|
|
24
|
+
- It keeps domain code untouched and wiring centralized.
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @emmett-community/emmett-google-services-bootstrap
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Minimal service dependencies:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@emmett-community/emmett-google-services-bootstrap": "^0.1.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/express": "^4.17.21"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Quick start
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { ServiceBootstrap } from '@emmett-community/emmett-google-services-bootstrap';
|
|
49
|
+
import { userDetailsProjection } from './projections/userDetailsProjection';
|
|
50
|
+
import { setupUserDataRemovalSubscriber } from './subscriptions/userDataRemovalSubscriber';
|
|
51
|
+
|
|
52
|
+
const bootstrap = new ServiceBootstrap({
|
|
53
|
+
serviceName: 'user-service',
|
|
54
|
+
projections: [userDetailsProjection],
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
await bootstrap.startApi({
|
|
58
|
+
port: Number(process.env.PORT ?? 3000),
|
|
59
|
+
openApiPath: './openapi.yml',
|
|
60
|
+
handlersPath: './handlers',
|
|
61
|
+
initializeHandlers: (handlers, ctx) => {
|
|
62
|
+
handlers.users.initializeHandlers(
|
|
63
|
+
ctx.eventStore,
|
|
64
|
+
ctx.database,
|
|
65
|
+
ctx.messageBus,
|
|
66
|
+
ctx.getCurrentTime,
|
|
67
|
+
);
|
|
68
|
+
},
|
|
69
|
+
beforeStart: (ctx) => {
|
|
70
|
+
setupUserDataRemovalSubscriber({
|
|
71
|
+
eventStore: ctx.eventStore,
|
|
72
|
+
messageBus: ctx.messageBus,
|
|
73
|
+
auth: ctx.auth,
|
|
74
|
+
getCurrentTime: ctx.getCurrentTime,
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Configuration
|
|
81
|
+
|
|
82
|
+
### Environment variables
|
|
83
|
+
|
|
84
|
+
- `FIRESTORE_PROJECT_ID`: Firebase project id (fallback to `GCLOUD_PROJECT` / `GOOGLE_CLOUD_PROJECT`)
|
|
85
|
+
- `demo-project` fallback: if project id is missing and any emulator host is configured, defaults to `demo-project` (also used for PubSub)
|
|
86
|
+
- `FIRESTORE_EMULATOR_HOST`: Firestore emulator host
|
|
87
|
+
- `FIREBASE_DATABASE_EMULATOR_HOST`: Realtime DB emulator host
|
|
88
|
+
- `PUBSUB_PROJECT_ID`: PubSub project id
|
|
89
|
+
- `PUBSUB_EMULATOR_HOST`: PubSub emulator host
|
|
90
|
+
- `LOG_LEVEL`: default log level for built-in logger
|
|
91
|
+
- `NODE_ENV`: forwarded to logging helpers
|
|
92
|
+
|
|
93
|
+
### Options
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import type { ServiceBootstrapConfig } from '@emmett-community/emmett-google-services-bootstrap';
|
|
97
|
+
|
|
98
|
+
const config: ServiceBootstrapConfig = {
|
|
99
|
+
serviceName: 'user-service',
|
|
100
|
+
firebase: {
|
|
101
|
+
projectId: 'demo-project',
|
|
102
|
+
databaseURL: 'https://demo-project-default-rtdb.firebaseio.com',
|
|
103
|
+
},
|
|
104
|
+
pubsub: {
|
|
105
|
+
projectId: 'demo-project',
|
|
106
|
+
topicPrefix: 'user-service',
|
|
107
|
+
autoCreateResources: true,
|
|
108
|
+
},
|
|
109
|
+
projections: [],
|
|
110
|
+
observability: {
|
|
111
|
+
createLogger: true,
|
|
112
|
+
logLevel: 'info',
|
|
113
|
+
},
|
|
114
|
+
includeDefaultDependencyChecks: true,
|
|
115
|
+
autoStartMessageBus: true,
|
|
116
|
+
shutdownOnDependencyFailure: true,
|
|
117
|
+
};
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## API
|
|
121
|
+
|
|
122
|
+
### ServiceBootstrap
|
|
123
|
+
|
|
124
|
+
- `initialize()` initializes Firebase, PubSub, and the event store.
|
|
125
|
+
- `start()` runs dependency checks and returns the same context as `initialize()`.
|
|
126
|
+
- `createApp()` returns an Express app wired with OpenAPI validation.
|
|
127
|
+
- `shutdown(reason, exitCode?)` runs graceful shutdown tasks.
|
|
128
|
+
- `registerSignalHandlers()` installs SIGINT/SIGTERM handlers.
|
|
129
|
+
- `startApi()` initializes, runs checks, creates the app, and starts the HTTP server.
|
|
130
|
+
|
|
131
|
+
### Lifecycle utilities
|
|
132
|
+
|
|
133
|
+
- `DependencyChecker` and `startDependency()` for health checks.
|
|
134
|
+
- `GracefulShutdown` for ordered shutdown tasks.
|
|
135
|
+
- `registerSignalHandlers()` to attach process signals.
|
|
136
|
+
|
|
137
|
+
## What this package intentionally does NOT do
|
|
138
|
+
|
|
139
|
+
- Hide application infrastructure choices behind magic defaults
|
|
140
|
+
- Create domain handlers or business rules
|
|
141
|
+
- Start HTTP servers automatically (use `startApi()` if you want the helper)
|
|
142
|
+
- Require any specific deployment model
|
|
143
|
+
|
|
144
|
+
## Testing
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npm run test:unit
|
|
148
|
+
npm run test:int
|
|
149
|
+
npm run test:e2e
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Contributing
|
|
153
|
+
|
|
154
|
+
Contributions are welcome! Please:
|
|
155
|
+
|
|
156
|
+
1. Fork the repository
|
|
157
|
+
2. Create a feature branch
|
|
158
|
+
3. Add tests for new functionality
|
|
159
|
+
4. Ensure all tests pass
|
|
160
|
+
5. Submit a pull request
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
Made with ❤️ by the Emmett Community
|