@envseal/protocol 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/LICENSE +201 -0
- package/dist/branded.d.ts +12 -0
- package/dist/branded.js +36 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.js +94 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +14 -0
- package/dist/schemas.d.ts +1294 -0
- package/dist/schemas.js +205 -0
- package/package.json +35 -0
package/dist/schemas.js
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const ManifestEntry = z
|
|
3
|
+
.object({
|
|
4
|
+
key: z.string().regex(/^[A-Z][A-Z0-9_]{0,63}$/),
|
|
5
|
+
description: z.string().max(280),
|
|
6
|
+
required: z.boolean().default(true),
|
|
7
|
+
secret: z.boolean().default(true),
|
|
8
|
+
format: z
|
|
9
|
+
.object({
|
|
10
|
+
pattern: z.string().optional(),
|
|
11
|
+
minLength: z.number().int().optional(),
|
|
12
|
+
maxLength: z.number().int().optional(),
|
|
13
|
+
example: z.string().optional(),
|
|
14
|
+
})
|
|
15
|
+
.optional(),
|
|
16
|
+
provider: z
|
|
17
|
+
.object({
|
|
18
|
+
id: z.string(),
|
|
19
|
+
name: z.string(),
|
|
20
|
+
signupUrl: z.string().url().optional(),
|
|
21
|
+
docsUrl: z.string().url().optional(),
|
|
22
|
+
rotateUrl: z.string().url().optional(),
|
|
23
|
+
scopesNeeded: z.array(z.string()).optional(),
|
|
24
|
+
})
|
|
25
|
+
.optional(),
|
|
26
|
+
verify: z
|
|
27
|
+
.object({
|
|
28
|
+
method: z.enum(['GET', 'POST']),
|
|
29
|
+
url: z.string().url(),
|
|
30
|
+
headerTemplate: z.record(z.string()),
|
|
31
|
+
expectStatus: z.array(z.number().int()).default([200]),
|
|
32
|
+
})
|
|
33
|
+
.optional(),
|
|
34
|
+
sink: z
|
|
35
|
+
.enum(['dotenv', 'keychain', 'sops', 'onepassword', 'doppler', 'vault', 'external'])
|
|
36
|
+
.default('dotenv'),
|
|
37
|
+
rotation: z.object({ maxAgeDays: z.number().int() }).optional(),
|
|
38
|
+
})
|
|
39
|
+
.strict()
|
|
40
|
+
.superRefine((entry, ctx) => {
|
|
41
|
+
if (!entry.verify) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (!entry.verify.url.startsWith('https://')) {
|
|
45
|
+
ctx.addIssue({
|
|
46
|
+
code: z.ZodIssueCode.custom,
|
|
47
|
+
path: ['verify', 'url'],
|
|
48
|
+
message: 'verify.url must start with https://',
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
if (entry.verify.url.includes('{{value}}')) {
|
|
52
|
+
ctx.addIssue({
|
|
53
|
+
code: z.ZodIssueCode.custom,
|
|
54
|
+
path: ['verify', 'url'],
|
|
55
|
+
message: 'verify.url must not contain {{value}}',
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
export const Manifest = z
|
|
60
|
+
.object({
|
|
61
|
+
$schema: z.string().optional(),
|
|
62
|
+
version: z.literal(1),
|
|
63
|
+
entries: z.array(ManifestEntry).default([]),
|
|
64
|
+
})
|
|
65
|
+
.strict();
|
|
66
|
+
export const KeyStatus = z
|
|
67
|
+
.object({
|
|
68
|
+
key: z.string(),
|
|
69
|
+
declared: z.boolean(),
|
|
70
|
+
present: z.boolean(),
|
|
71
|
+
sink: z.string(),
|
|
72
|
+
// Nullable because "we have not validated THIS value" is a real state and
|
|
73
|
+
// must not be reported as true. env_describe deliberately does not
|
|
74
|
+
// re-evaluate a model-supplied format.pattern against a stored secret —
|
|
75
|
+
// doing so is a chosen-predicate oracle over the value.
|
|
76
|
+
formatValid: z.boolean().nullable(),
|
|
77
|
+
lengthBucket: z.string(),
|
|
78
|
+
fingerprint: z.string(),
|
|
79
|
+
lastVerified: z.string().nullable(),
|
|
80
|
+
verifyResult: z
|
|
81
|
+
.enum(['ok', 'auth_failed', 'forbidden', 'rate_limited', 'network_error', 'no_probe', 'probe_not_approved'])
|
|
82
|
+
.nullable(),
|
|
83
|
+
source: z.enum(['user-prompt', 'preexisting', 'ci', 'imported']),
|
|
84
|
+
rotationDue: z.string().nullable(),
|
|
85
|
+
})
|
|
86
|
+
.strict();
|
|
87
|
+
export const Ticket = z
|
|
88
|
+
.object({
|
|
89
|
+
ticket: z.string(),
|
|
90
|
+
nonce: z.string(),
|
|
91
|
+
surface: z.enum(['loopback-browser', 'native-dialog', 'ide', 'tty', 'none']),
|
|
92
|
+
expiresAt: z.string(),
|
|
93
|
+
userMessage: z.string(),
|
|
94
|
+
})
|
|
95
|
+
.strict();
|
|
96
|
+
export const TicketKeyOutcome = z.enum([
|
|
97
|
+
'stored',
|
|
98
|
+
'skipped',
|
|
99
|
+
'cancelled',
|
|
100
|
+
'invalid_format',
|
|
101
|
+
'verify_failed',
|
|
102
|
+
'timeout',
|
|
103
|
+
]);
|
|
104
|
+
export const TicketOutcome = z
|
|
105
|
+
.object({
|
|
106
|
+
ticket: z.string(),
|
|
107
|
+
state: z.enum(['pending', 'resolved', 'expired', 'cancelled']),
|
|
108
|
+
keys: z
|
|
109
|
+
.array(z
|
|
110
|
+
.object({
|
|
111
|
+
key: z.string(),
|
|
112
|
+
outcome: TicketKeyOutcome,
|
|
113
|
+
})
|
|
114
|
+
.strict())
|
|
115
|
+
.default([]),
|
|
116
|
+
})
|
|
117
|
+
.strict();
|
|
118
|
+
export const VerifyResult = z
|
|
119
|
+
.object({
|
|
120
|
+
key: z.string(),
|
|
121
|
+
result: z.enum(['ok', 'auth_failed', 'forbidden', 'rate_limited', 'network_error', 'no_probe', 'probe_not_approved']),
|
|
122
|
+
message: z.string(),
|
|
123
|
+
checkedAt: z.string(),
|
|
124
|
+
})
|
|
125
|
+
.strict();
|
|
126
|
+
export const ExecResult = z
|
|
127
|
+
.object({
|
|
128
|
+
exitCode: z.number().int().nullable(),
|
|
129
|
+
stdout: z.string(),
|
|
130
|
+
stderr: z.string(),
|
|
131
|
+
timedOut: z.boolean(),
|
|
132
|
+
redactedCount: z.number().int(),
|
|
133
|
+
})
|
|
134
|
+
.strict();
|
|
135
|
+
export const DeclareResult = z
|
|
136
|
+
.object({
|
|
137
|
+
added: z.array(z.string()).default([]),
|
|
138
|
+
updated: z.array(z.string()).default([]),
|
|
139
|
+
unchanged: z.array(z.string()).default([]),
|
|
140
|
+
})
|
|
141
|
+
.strict();
|
|
142
|
+
export const RevokeResult = z
|
|
143
|
+
.object({
|
|
144
|
+
key: z.string(),
|
|
145
|
+
removed: z.boolean(),
|
|
146
|
+
rotateUrl: z.string().nullable(),
|
|
147
|
+
})
|
|
148
|
+
.strict();
|
|
149
|
+
export const RevokeResults = z.array(RevokeResult);
|
|
150
|
+
export const ManifestStatus = z
|
|
151
|
+
.object({
|
|
152
|
+
projectRoot: z.string(),
|
|
153
|
+
manifestPath: z.string().nullable(),
|
|
154
|
+
entries: z.array(KeyStatus),
|
|
155
|
+
missingRequired: z.array(z.string()).default([]),
|
|
156
|
+
})
|
|
157
|
+
.strict();
|
|
158
|
+
export const EnvDescribeInput = z
|
|
159
|
+
.object({
|
|
160
|
+
scope: z.string().optional(),
|
|
161
|
+
})
|
|
162
|
+
.strict();
|
|
163
|
+
export const EnvDeclareInput = z
|
|
164
|
+
.object({
|
|
165
|
+
entries: z.array(ManifestEntry).min(1),
|
|
166
|
+
})
|
|
167
|
+
.strict();
|
|
168
|
+
export const EnvRequestInput = z
|
|
169
|
+
.object({
|
|
170
|
+
keys: z.array(z.string()).min(1),
|
|
171
|
+
reason: z.string().min(1).max(280),
|
|
172
|
+
})
|
|
173
|
+
.strict();
|
|
174
|
+
export const EnvAwaitInput = z
|
|
175
|
+
.object({
|
|
176
|
+
ticket: z.string(),
|
|
177
|
+
timeoutMs: z.number().int().min(1000).max(120000).default(90000),
|
|
178
|
+
})
|
|
179
|
+
.strict();
|
|
180
|
+
export const EnvVerifyInput = z
|
|
181
|
+
.object({
|
|
182
|
+
keys: z.array(z.string()).min(1),
|
|
183
|
+
})
|
|
184
|
+
.strict();
|
|
185
|
+
export const EnvUseInput = z
|
|
186
|
+
.object({
|
|
187
|
+
keys: z.array(z.string()).min(1),
|
|
188
|
+
command: z.array(z.string()).min(1),
|
|
189
|
+
})
|
|
190
|
+
.strict();
|
|
191
|
+
export const EnvRevokeInput = z
|
|
192
|
+
.object({
|
|
193
|
+
keys: z.array(z.string()).min(1),
|
|
194
|
+
})
|
|
195
|
+
.strict();
|
|
196
|
+
export const INPUT_SCHEMAS = {
|
|
197
|
+
env_describe: EnvDescribeInput,
|
|
198
|
+
env_declare: EnvDeclareInput,
|
|
199
|
+
env_request: EnvRequestInput,
|
|
200
|
+
env_await: EnvAwaitInput,
|
|
201
|
+
env_verify: EnvVerifyInput,
|
|
202
|
+
env_use: EnvUseInput,
|
|
203
|
+
env_revoke: EnvRevokeInput,
|
|
204
|
+
};
|
|
205
|
+
//# sourceMappingURL=schemas.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@envseal/protocol",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"!dist/**/*.map"
|
|
17
|
+
],
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public",
|
|
20
|
+
"provenance": true
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"zod": "^3.24.1"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"tsx": "^4.19.2",
|
|
27
|
+
"zod-to-json-schema": "^3.24.1"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsc -p tsconfig.json && pnpm gen:schemas",
|
|
31
|
+
"gen:schemas": "tsx scripts/gen-schemas.ts",
|
|
32
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
33
|
+
"test": "vitest run"
|
|
34
|
+
}
|
|
35
|
+
}
|