Skip to content

Commit 2b14b8a

Browse files
committed
Merge main branch and resolve pnpm-lock.yaml conflict
2 parents d042f9c + 22bd10f commit 2b14b8a

File tree

19 files changed

+798
-437
lines changed

19 files changed

+798
-437
lines changed

functions/send-email-link/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"dependencies": {
3636
"@constructive-io/knative-job-fn": "workspace:^",
3737
"@launchql/mjml": "0.1.1",
38-
"@launchql/postmaster": "0.1.4",
38+
"@constructive-io/postmaster": "workspace:^",
3939
"@launchql/styled-email": "0.1.0",
4040
"@pgpmjs/env": "workspace:^",
4141
"@pgpmjs/logger": "workspace:^",

functions/send-email-link/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { createJobApp } from '@constructive-io/knative-job-fn';
22
import { GraphQLClient } from 'graphql-request';
33
import gql from 'graphql-tag';
44
import { generate } from '@launchql/mjml';
5-
import { send as sendPostmaster } from '@launchql/postmaster';
5+
import { send as sendPostmaster } from '@constructive-io/postmaster';
66
import { send as sendSmtp } from 'simple-smtp-server';
77
import { parseEnvBoolean } from '@pgpmjs/env';
88
import { createLogger } from '@pgpmjs/logger';

functions/simple-email/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
},
3535
"dependencies": {
3636
"@constructive-io/knative-job-fn": "workspace:^",
37-
"@launchql/postmaster": "0.1.4",
37+
"@constructive-io/postmaster": "workspace:^",
3838
"@pgpmjs/env": "workspace:^",
3939
"@pgpmjs/logger": "workspace:^",
4040
"simple-smtp-server": "workspace:^"

functions/simple-email/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createJobApp } from '@constructive-io/knative-job-fn';
22
import { send as sendSmtp } from 'simple-smtp-server';
3-
import { send as sendPostmaster } from '@launchql/postmaster';
3+
import { send as sendPostmaster } from '@constructive-io/postmaster';
44
import { parseEnvBoolean } from '@pgpmjs/env';
55
import { createLogger } from '@pgpmjs/logger';
66

jobs/knative-job-service/__tests__/jobs.e2e.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ type MailgunFailurePayload = {
206206
};
207207

208208
const createMailgunFailureApp = () => {
209-
const { send: sendPostmaster } = require('@launchql/postmaster');
209+
const { send: sendPostmaster } = require('@constructive-io/postmaster');
210210
const app = createJobApp();
211211

212212
app.post('/', async (req: any, res: any, next: any) => {

jobs/knative-job-service/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@
3737
"bugs": {
3838
"url": "https://github.com/constructive-io/jobs/issues"
3939
},
40-
"devDependencies": {
41-
"@constructive-io/graphql-server": "workspace:^",
40+
"devDependencies": {
41+
"@constructive-io/postmaster": "workspace:^",
42+
"@constructive-io/graphql-server": "workspace:^",
4243
"@constructive-io/graphql-types": "workspace:^",
4344
"@pgpm/database-jobs": "^0.16.0",
4445
"@pgpm/inflection": "^0.16.0",

packages/12factor-env/README.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# 12factor-env
2+
3+
<p align="center" width="100%">
4+
<img height="250" src="https://raw.githubusercontent.com/constructive-io/constructive/refs/heads/main/assets/outline-logo.svg" />
5+
</p>
6+
7+
<p align="center" width="100%">
8+
<a href="https://github.com/constructive-io/constructive/actions/workflows/run-tests.yaml">
9+
<img height="20" src="https://github.com/constructive-io/constructive/actions/workflows/run-tests.yaml/badge.svg" />
10+
</a>
11+
<a href="https://github.com/constructive-io/constructive/blob/main/LICENSE">
12+
<img height="20" src="https://img.shields.io/badge/license-MIT-blue.svg"/>
13+
</a>
14+
<a href="https://www.npmjs.com/package/12factor-env">
15+
<img height="20" src="https://img.shields.io/github/package-json/v/constructive-io/constructive?filename=packages%2F12factor-env%2Fpackage.json"/>
16+
</a>
17+
</p>
18+
19+
> Environment variable validation with secret file support for 12-factor apps
20+
21+
A TypeScript library for validating environment variables with built-in support for Docker/Kubernetes secret files. Built on top of [envalid](https://github.com/af/envalid) with additional features for reading secrets from files.
22+
23+
## Installation
24+
25+
```bash
26+
npm install 12factor-env
27+
```
28+
29+
## Usage
30+
31+
```ts
32+
import { env, str, num, bool, port, email, host } from '12factor-env';
33+
34+
const config = env(
35+
process.env,
36+
{
37+
// Required environment variables
38+
DATABASE_URL: str(),
39+
API_KEY: str()
40+
},
41+
{
42+
// Optional environment variables with defaults
43+
PORT: port({ default: 3000 }),
44+
DEBUG: bool({ default: false }),
45+
LOG_LEVEL: str({ default: 'info' })
46+
}
47+
);
48+
49+
console.log(config.DATABASE_URL); // Validated string
50+
console.log(config.PORT); // Validated number
51+
```
52+
53+
## Secret File Support
54+
55+
This library supports reading secrets from files, which is useful for Docker secrets and Kubernetes secrets that are mounted as files.
56+
57+
### Direct Secret Files
58+
59+
Secrets can be read from `/run/secrets/` (or a custom path via `ENV_SECRETS_PATH`):
60+
61+
```ts
62+
import { env, str } from '12factor-env';
63+
64+
// If /run/secrets/DATABASE_PASSWORD exists, it will be read automatically
65+
const config = env(process.env, {
66+
DATABASE_PASSWORD: str()
67+
});
68+
```
69+
70+
### _FILE Suffix Pattern
71+
72+
You can also use the `_FILE` suffix pattern commonly used with Docker:
73+
74+
```bash
75+
# Set the path to the secret file
76+
export DATABASE_PASSWORD_FILE=/run/secrets/db-password
77+
```
78+
79+
```ts
80+
import { env, str } from '12factor-env';
81+
82+
// Will read from the file specified in DATABASE_PASSWORD_FILE
83+
const config = env(process.env, {
84+
DATABASE_PASSWORD: str()
85+
});
86+
```
87+
88+
### Custom Secrets Path
89+
90+
Set `ENV_SECRETS_PATH` to change the default secrets directory:
91+
92+
```bash
93+
export ENV_SECRETS_PATH=/custom/secrets/path
94+
```
95+
96+
## Validators
97+
98+
All validators from [envalid](https://github.com/af/envalid) are re-exported:
99+
100+
| Validator | Description |
101+
|-----------|-------------|
102+
| `str()` | String value |
103+
| `bool()` | Boolean (`true`, `false`, `1`, `0`) |
104+
| `num()` | Number |
105+
| `port()` | Port number (1-65535) |
106+
| `host()` | Hostname or IP address |
107+
| `url()` | Valid URL |
108+
| `email()` | Valid email address |
109+
| `json()` | JSON string (parsed) |
110+
111+
### Validator Options
112+
113+
All validators accept options:
114+
115+
```ts
116+
import { str, num } from '12factor-env';
117+
118+
const config = env(process.env, {
119+
API_KEY: str({ desc: 'API key for external service' }),
120+
TIMEOUT: num({ default: 5000, desc: 'Request timeout in ms' })
121+
});
122+
```
123+
124+
## API
125+
126+
### `env(inputEnv, secrets, vars)`
127+
128+
Main function to validate environment variables.
129+
130+
- `inputEnv` - The environment object (usually `process.env`)
131+
- `secrets` - Required environment variables
132+
- `vars` - Optional environment variables
133+
134+
### `secret(envFile)`
135+
136+
Create a validator for a secret file:
137+
138+
```ts
139+
import { env, secret } from '12factor-env';
140+
141+
const config = env(process.env, {
142+
DB_PASSWORD: secret('DATABASE_PASSWORD')
143+
});
144+
```
145+
146+
### `getSecret(name)`
147+
148+
Read a secret from a file:
149+
150+
```ts
151+
import { getSecret } from '12factor-env';
152+
153+
const password = getSecret('DATABASE_PASSWORD');
154+
```
155+
156+
### `secretPath(name)`
157+
158+
Resolve the full path to a secret file:
159+
160+
```ts
161+
import { secretPath } from '12factor-env';
162+
163+
const path = secretPath('DATABASE_PASSWORD');
164+
// Returns: /run/secrets/DATABASE_PASSWORD
165+
```
166+
167+
## Re-exports from envalid
168+
169+
The following are re-exported from envalid for convenience:
170+
171+
- `cleanEnv` - Low-level env cleaning function
172+
- `makeValidator` - Create custom validators
173+
- `EnvError` - Error class for validation errors
174+
- `EnvMissingError` - Error class for missing required vars
175+
- `testOnly` - Helper for test-only defaults

packages/12factor-env/package.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"name": "12factor-env",
3+
"version": "0.1.0",
4+
"author": "Constructive <developers@constructive.io>",
5+
"description": "Environment variable validation with secret file support for 12-factor apps",
6+
"main": "index.js",
7+
"module": "esm/index.js",
8+
"types": "index.d.ts",
9+
"homepage": "https://github.com/constructive-io/constructive",
10+
"license": "MIT",
11+
"publishConfig": {
12+
"access": "public",
13+
"directory": "dist"
14+
},
15+
"repository": {
16+
"type": "git",
17+
"url": "https://github.com/constructive-io/constructive"
18+
},
19+
"bugs": {
20+
"url": "https://github.com/constructive-io/constructive/issues"
21+
},
22+
"scripts": {
23+
"clean": "makage clean",
24+
"prepack": "npm run build",
25+
"build": "makage build",
26+
"build:dev": "makage build --dev",
27+
"lint": "eslint . --fix",
28+
"test": "jest --passWithNoTests",
29+
"test:watch": "jest --watch"
30+
},
31+
"dependencies": {
32+
"envalid": "^8.1.1"
33+
},
34+
"devDependencies": {
35+
"@types/node": "^20.12.7",
36+
"makage": "^0.1.10",
37+
"ts-node": "^10.9.2"
38+
},
39+
"keywords": [
40+
"environment",
41+
"env",
42+
"validation",
43+
"12factor",
44+
"secrets",
45+
"kubernetes",
46+
"docker",
47+
"constructive"
48+
]
49+
}

0 commit comments

Comments
 (0)