@crossdelta/infrastructure 0.1.41 → 0.2.2
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 +41 -12
- package/dist/env.d.ts +0 -1
- package/dist/helpers/discover-services.d.ts +11 -0
- package/dist/helpers/service-runtime.d.ts +4 -21
- package/dist/index.cjs +3 -2
- package/dist/index.js +4 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,6 @@ npm install @crossdelta/infrastructure
|
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
## Quick Start
|
|
24
|
-
|
|
25
24
|
### 1. Create a service config
|
|
26
25
|
|
|
27
26
|
```typescript
|
|
@@ -42,7 +41,6 @@ export default config
|
|
|
42
41
|
|
|
43
42
|
```typescript
|
|
44
43
|
// infra/index.ts
|
|
45
|
-
import { join } from 'node:path'
|
|
46
44
|
import {
|
|
47
45
|
buildServices,
|
|
48
46
|
buildIngressRules,
|
|
@@ -52,7 +50,7 @@ import {
|
|
|
52
50
|
} from '@crossdelta/infrastructure'
|
|
53
51
|
import { App } from '@pulumi/digitalocean'
|
|
54
52
|
|
|
55
|
-
const serviceConfigs = discoverServices(
|
|
53
|
+
const serviceConfigs = discoverServices('services')
|
|
56
54
|
|
|
57
55
|
const app = new App('my-app', {
|
|
58
56
|
spec: {
|
|
@@ -104,7 +102,7 @@ const config: ServiceConfig = {
|
|
|
104
102
|
|
|
105
103
|
## CLI: generate-env
|
|
106
104
|
|
|
107
|
-
Generate `.env.local`
|
|
105
|
+
Generate `.env.local` and service-specific `env.ts` files for local development.
|
|
108
106
|
|
|
109
107
|
### Setup
|
|
110
108
|
|
|
@@ -113,16 +111,12 @@ Add a script to your workspace `package.json`:
|
|
|
113
111
|
```json
|
|
114
112
|
{
|
|
115
113
|
"scripts": {
|
|
116
|
-
"generate-env": "
|
|
114
|
+
"generate-env": "turbo run generate-env --ui=stream"
|
|
117
115
|
}
|
|
118
116
|
}
|
|
119
117
|
```
|
|
120
118
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
npm run generate-env
|
|
125
|
-
```
|
|
119
|
+
Or use `pf dev` which runs `generate-env` automatically before starting services.
|
|
126
120
|
|
|
127
121
|
### What it does
|
|
128
122
|
|
|
@@ -130,7 +124,8 @@ npm run generate-env
|
|
|
130
124
|
2. Discovers services from `infra/services/*.ts`
|
|
131
125
|
3. Generates `SERVICE_URL` and `SERVICE_PORT` env vars for localhost
|
|
132
126
|
4. Writes `.env.local` to your workspace root
|
|
133
|
-
5. Generates
|
|
127
|
+
5. Generates `infra/env.ts` with type-safe `ServiceName` union type
|
|
128
|
+
6. Generates `services/*/src/env.ts` for each service (Docker-compatible)
|
|
134
129
|
|
|
135
130
|
### Example output
|
|
136
131
|
|
|
@@ -145,17 +140,51 @@ API_GATEWAY_PORT=4000
|
|
|
145
140
|
STOREFRONT_PORT=3000
|
|
146
141
|
```
|
|
147
142
|
|
|
143
|
+
`services/orders/src/env.ts`:
|
|
144
|
+
```typescript
|
|
145
|
+
import { getServicePort, getServiceUrl } from '@crossdelta/infrastructure/env'
|
|
146
|
+
|
|
147
|
+
export const SERVICE_NAME = 'orders' as const
|
|
148
|
+
export const getServicePort = (defaultPort = 8080) => _getServicePort(SERVICE_NAME, defaultPort)
|
|
149
|
+
export const getServiceUrl = () => _getServiceUrl(SERVICE_NAME)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Runtime Helpers
|
|
153
|
+
|
|
154
|
+
Use `@crossdelta/infrastructure/env` in your services to read environment configuration:
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
import { getServicePort, getServiceUrl } from '@crossdelta/infrastructure/env'
|
|
158
|
+
|
|
159
|
+
// Get port from ORDERS_PORT env var (fallback: 8080)
|
|
160
|
+
const port = getServicePort('orders', 8080)
|
|
161
|
+
|
|
162
|
+
// Get URL from ORDERS_URL env var
|
|
163
|
+
const url = getServiceUrl('orders')
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
These helpers work both locally (via `.env.local`) and in production (via DO App Platform env injection).
|
|
167
|
+
|
|
148
168
|
## API
|
|
149
169
|
|
|
170
|
+
### Main Export (`@crossdelta/infrastructure`)
|
|
171
|
+
|
|
150
172
|
| Function | Description |
|
|
151
173
|
|----------|-------------|
|
|
152
|
-
| `discoverServices(dir)` | Auto-discover service configs
|
|
174
|
+
| `discoverServices(dir)` | Auto-discover service configs (relative to cwd or absolute) |
|
|
153
175
|
| `buildServices(options)` | Build App Platform service specs |
|
|
154
176
|
| `buildIngressRules(configs)` | Generate ingress rules |
|
|
155
177
|
| `buildServiceUrlEnvs(configs)` | Create SERVICE_NAME_URL env vars |
|
|
156
178
|
| `buildServicePortEnvs(configs)` | Create SERVICE_NAME_PORT env vars |
|
|
157
179
|
| `buildLocalUrls(configs)` | Generate localhost URLs for local dev |
|
|
158
180
|
|
|
181
|
+
### Env Export (`@crossdelta/infrastructure/env`)
|
|
182
|
+
|
|
183
|
+
| Function | Description |
|
|
184
|
+
|----------|-------------|
|
|
185
|
+
| `getServicePort(name, default)` | Read SERVICE_NAME_PORT from env |
|
|
186
|
+
| `getServiceUrl(name)` | Read SERVICE_NAME_URL from env |
|
|
187
|
+
|
|
159
188
|
## License
|
|
160
189
|
|
|
161
190
|
MIT
|
package/dist/env.d.ts
CHANGED
|
@@ -2,6 +2,17 @@ import type { ServiceConfig } from '../types';
|
|
|
2
2
|
/**
|
|
3
3
|
* Auto-discovers all service configurations from a directory.
|
|
4
4
|
* Each .ts file (except index.ts) should export a ServiceConfig as default.
|
|
5
|
+
*
|
|
6
|
+
* @param servicesDir - Path to services directory (relative to cwd or absolute)
|
|
5
7
|
* @throws Error if duplicate ports are detected
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Relative path (resolved from process.cwd())
|
|
12
|
+
* const configs = discoverServices('infra/services')
|
|
13
|
+
*
|
|
14
|
+
* // Absolute path
|
|
15
|
+
* const configs = discoverServices('/absolute/path/to/services')
|
|
16
|
+
* ```
|
|
6
17
|
*/
|
|
7
18
|
export declare function discoverServices(servicesDir: string): ServiceConfig[];
|
|
@@ -3,37 +3,20 @@
|
|
|
3
3
|
* These functions read from environment variables set by generate-env (local)
|
|
4
4
|
* or injected by DO App Platform (production).
|
|
5
5
|
*/
|
|
6
|
-
import type { ServiceName } from '../types';
|
|
7
6
|
/**
|
|
8
7
|
* Get the port for a service from environment variables.
|
|
9
|
-
* Reads from
|
|
8
|
+
* Reads from SERVICE_NAME_PORT (e.g., ORDERS_PORT, API_GATEWAY_PORT)
|
|
10
9
|
*
|
|
11
10
|
* @param serviceName - The service name (e.g., 'orders', 'api-gateway')
|
|
12
11
|
* @param defaultPort - Fallback port if env var is not set (default: 8080)
|
|
13
12
|
* @returns The configured port number
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```typescript
|
|
17
|
-
* import { getServicePort } from '@crossdelta/infrastructure/env'
|
|
18
|
-
*
|
|
19
|
-
* const port = getServicePort('orders', 3001)
|
|
20
|
-
* // Reads process.env.ORDERS_PORT, falls back to 3001
|
|
21
|
-
* ```
|
|
22
13
|
*/
|
|
23
|
-
export declare function getServicePort(serviceName:
|
|
14
|
+
export declare function getServicePort(serviceName: string, defaultPort?: number): number;
|
|
24
15
|
/**
|
|
25
16
|
* Get the URL for a service from environment variables.
|
|
26
|
-
* Reads from
|
|
17
|
+
* Reads from SERVICE_NAME_URL (e.g., ORDERS_URL, API_GATEWAY_URL)
|
|
27
18
|
*
|
|
28
19
|
* @param serviceName - The service name (e.g., 'orders', 'api-gateway')
|
|
29
20
|
* @returns The service URL or undefined if not set
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* ```typescript
|
|
33
|
-
* import { getServiceUrl } from '@crossdelta/infrastructure/env'
|
|
34
|
-
*
|
|
35
|
-
* const ordersUrl = getServiceUrl('orders')
|
|
36
|
-
* // Returns process.env.ORDERS_URL
|
|
37
|
-
* ```
|
|
38
21
|
*/
|
|
39
|
-
export declare function getServiceUrl(serviceName:
|
|
22
|
+
export declare function getServiceUrl(serviceName: string): string | undefined;
|
package/dist/index.cjs
CHANGED
|
@@ -105,9 +105,10 @@ ${conflicts.join(`
|
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
function discoverServices(servicesDir) {
|
|
108
|
-
const
|
|
108
|
+
const resolvedDir = import_node_path.isAbsolute(servicesDir) ? servicesDir : import_node_path.resolve(process.cwd(), servicesDir);
|
|
109
|
+
const files = import_node_fs.readdirSync(resolvedDir).filter((file) => file.endsWith(".ts") && file !== "index.ts");
|
|
109
110
|
const configs = files.map((file) => {
|
|
110
|
-
const module2 = require(import_node_path.join(
|
|
111
|
+
const module2 = require(import_node_path.join(resolvedDir, file));
|
|
111
112
|
return module2.default;
|
|
112
113
|
});
|
|
113
114
|
validateNoDuplicatePorts(configs);
|
package/dist/index.js
CHANGED
|
@@ -32,7 +32,7 @@ var defaultHealthCheck = {
|
|
|
32
32
|
};
|
|
33
33
|
// lib/helpers/discover-services.ts
|
|
34
34
|
import { readdirSync } from "node:fs";
|
|
35
|
-
import { join } from "node:path";
|
|
35
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
36
36
|
function getServicePort(config) {
|
|
37
37
|
if (config.httpPort)
|
|
38
38
|
return config.httpPort;
|
|
@@ -57,9 +57,10 @@ ${conflicts.join(`
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
function discoverServices(servicesDir) {
|
|
60
|
-
const
|
|
60
|
+
const resolvedDir = isAbsolute(servicesDir) ? servicesDir : resolve(process.cwd(), servicesDir);
|
|
61
|
+
const files = readdirSync(resolvedDir).filter((file) => file.endsWith(".ts") && file !== "index.ts");
|
|
61
62
|
const configs = files.map((file) => {
|
|
62
|
-
const module = __require(join(
|
|
63
|
+
const module = __require(join(resolvedDir, file));
|
|
63
64
|
return module.default;
|
|
64
65
|
});
|
|
65
66
|
validateNoDuplicatePorts(configs);
|