@shipfox/api-secrets 2.0.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/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +116 -0
- package/LICENSE +21 -0
- package/README.md +207 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +38 -0
- package/dist/config.js.map +1 -0
- package/dist/core/crypto.d.ts +25 -0
- package/dist/core/crypto.d.ts.map +1 -0
- package/dist/core/crypto.js +85 -0
- package/dist/core/crypto.js.map +1 -0
- package/dist/core/dek-manager.d.ts +16 -0
- package/dist/core/dek-manager.d.ts.map +1 -0
- package/dist/core/dek-manager.js +85 -0
- package/dist/core/dek-manager.js.map +1 -0
- package/dist/core/errors.d.ts +53 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +86 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/fingerprint.d.ts +2 -0
- package/dist/core/fingerprint.d.ts.map +1 -0
- package/dist/core/fingerprint.js +9 -0
- package/dist/core/fingerprint.js.map +1 -0
- package/dist/core/index.d.ts +30 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +97 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/key-provider.d.ts +17 -0
- package/dist/core/key-provider.d.ts.map +1 -0
- package/dist/core/key-provider.js +45 -0
- package/dist/core/key-provider.js.map +1 -0
- package/dist/core/local-secret-store.d.ts +19 -0
- package/dist/core/local-secret-store.d.ts.map +1 -0
- package/dist/core/local-secret-store.js +40 -0
- package/dist/core/local-secret-store.js.map +1 -0
- package/dist/core/management.d.ts +37 -0
- package/dist/core/management.d.ts.map +1 -0
- package/dist/core/management.js +403 -0
- package/dist/core/management.js.map +1 -0
- package/dist/core/rotate-kek.d.ts +10 -0
- package/dist/core/rotate-kek.d.ts.map +1 -0
- package/dist/core/rotate-kek.js +94 -0
- package/dist/core/rotate-kek.js.map +1 -0
- package/dist/core/secret-store.d.ts +33 -0
- package/dist/core/secret-store.d.ts.map +1 -0
- package/dist/core/secret-store.js +209 -0
- package/dist/core/secret-store.js.map +1 -0
- package/dist/core/store-resolver.d.ts +18 -0
- package/dist/core/store-resolver.d.ts.map +1 -0
- package/dist/core/store-resolver.js +10 -0
- package/dist/core/store-resolver.js.map +1 -0
- package/dist/core/store-validation.d.ts +11 -0
- package/dist/core/store-validation.d.ts.map +1 -0
- package/dist/core/store-validation.js +30 -0
- package/dist/core/store-validation.js.map +1 -0
- package/dist/core/value-cipher.d.ts +10 -0
- package/dist/core/value-cipher.d.ts.map +1 -0
- package/dist/core/value-cipher.js +22 -0
- package/dist/core/value-cipher.js.map +1 -0
- package/dist/core/variable-store.d.ts +24 -0
- package/dist/core/variable-store.d.ts.map +1 -0
- package/dist/core/variable-store.js +194 -0
- package/dist/core/variable-store.js.map +1 -0
- package/dist/db/cap.d.ts +8 -0
- package/dist/db/cap.d.ts.map +1 -0
- package/dist/db/cap.js +39 -0
- package/dist/db/cap.js.map +1 -0
- package/dist/db/data-keys.d.ts +24 -0
- package/dist/db/data-keys.d.ts.map +1 -0
- package/dist/db/data-keys.js +61 -0
- package/dist/db/data-keys.js.map +1 -0
- package/dist/db/db.d.ts +1254 -0
- package/dist/db/db.d.ts.map +1 -0
- package/dist/db/db.js +24 -0
- package/dist/db/db.js.map +1 -0
- package/dist/db/index.d.ts +13 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +15 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/management.d.ts +50 -0
- package/dist/db/management.d.ts.map +1 -0
- package/dist/db/management.js +127 -0
- package/dist/db/management.js.map +1 -0
- package/dist/db/schema/common.d.ts +3 -0
- package/dist/db/schema/common.d.ts.map +1 -0
- package/dist/db/schema/common.js +8 -0
- package/dist/db/schema/common.js.map +1 -0
- package/dist/db/schema/data-keys.d.ts +103 -0
- package/dist/db/schema/data-keys.d.ts.map +1 -0
- package/dist/db/schema/data-keys.js +24 -0
- package/dist/db/schema/data-keys.js.map +1 -0
- package/dist/db/schema/outbox.d.ts +195 -0
- package/dist/db/schema/outbox.d.ts.map +1 -0
- package/dist/db/schema/outbox.js +5 -0
- package/dist/db/schema/outbox.js.map +1 -0
- package/dist/db/schema/values.d.ts +193 -0
- package/dist/db/schema/values.d.ts.map +1 -0
- package/dist/db/schema/values.js +43 -0
- package/dist/db/schema/values.js.map +1 -0
- package/dist/db/schema/variables.d.ts +175 -0
- package/dist/db/schema/variables.d.ts.map +1 -0
- package/dist/db/schema/variables.js +41 -0
- package/dist/db/schema/variables.js.map +1 -0
- package/dist/db/scope.d.ts +20 -0
- package/dist/db/scope.d.ts.map +1 -0
- package/dist/db/scope.js +19 -0
- package/dist/db/scope.js.map +1 -0
- package/dist/db/values.d.ts +33 -0
- package/dist/db/values.d.ts.map +1 -0
- package/dist/db/values.js +119 -0
- package/dist/db/values.js.map +1 -0
- package/dist/db/variables.d.ts +32 -0
- package/dist/db/variables.d.ts.map +1 -0
- package/dist/db/variables.js +117 -0
- package/dist/db/variables.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics/index.d.ts +3 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +4 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/instance.d.ts +39 -0
- package/dist/metrics/instance.d.ts.map +1 -0
- package/dist/metrics/instance.js +151 -0
- package/dist/metrics/instance.js.map +1 -0
- package/dist/metrics/service.d.ts +2 -0
- package/dist/metrics/service.d.ts.map +1 -0
- package/dist/metrics/service.js +21 -0
- package/dist/metrics/service.js.map +1 -0
- package/dist/presentation/dto/index.d.ts +2 -0
- package/dist/presentation/dto/index.d.ts.map +1 -0
- package/dist/presentation/dto/index.js +3 -0
- package/dist/presentation/dto/index.js.map +1 -0
- package/dist/presentation/dto/management.d.ts +7 -0
- package/dist/presentation/dto/management.d.ts.map +1 -0
- package/dist/presentation/dto/management.js +32 -0
- package/dist/presentation/dto/management.js.map +1 -0
- package/dist/presentation/e2eRoutes/create-secret.d.ts +2 -0
- package/dist/presentation/e2eRoutes/create-secret.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/create-secret.js +34 -0
- package/dist/presentation/e2eRoutes/create-secret.js.map +1 -0
- package/dist/presentation/e2eRoutes/create-variable.d.ts +2 -0
- package/dist/presentation/e2eRoutes/create-variable.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/create-variable.js +34 -0
- package/dist/presentation/e2eRoutes/create-variable.js.map +1 -0
- package/dist/presentation/e2eRoutes/index.d.ts +3 -0
- package/dist/presentation/e2eRoutes/index.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/index.js +11 -0
- package/dist/presentation/e2eRoutes/index.js.map +1 -0
- package/dist/presentation/routes/auth.d.ts +16 -0
- package/dist/presentation/routes/auth.d.ts.map +1 -0
- package/dist/presentation/routes/auth.js +42 -0
- package/dist/presentation/routes/auth.js.map +1 -0
- package/dist/presentation/routes/batch-secrets.d.ts +2 -0
- package/dist/presentation/routes/batch-secrets.d.ts.map +1 -0
- package/dist/presentation/routes/batch-secrets.js +44 -0
- package/dist/presentation/routes/batch-secrets.js.map +1 -0
- package/dist/presentation/routes/batch-variables.d.ts +2 -0
- package/dist/presentation/routes/batch-variables.d.ts.map +1 -0
- package/dist/presentation/routes/batch-variables.js +44 -0
- package/dist/presentation/routes/batch-variables.js.map +1 -0
- package/dist/presentation/routes/cursor.d.ts +3 -0
- package/dist/presentation/routes/cursor.d.ts.map +1 -0
- package/dist/presentation/routes/cursor.js +19 -0
- package/dist/presentation/routes/cursor.js.map +1 -0
- package/dist/presentation/routes/delete-secret.d.ts +2 -0
- package/dist/presentation/routes/delete-secret.d.ts.map +1 -0
- package/dist/presentation/routes/delete-secret.js +40 -0
- package/dist/presentation/routes/delete-secret.js.map +1 -0
- package/dist/presentation/routes/delete-variable.d.ts +2 -0
- package/dist/presentation/routes/delete-variable.d.ts.map +1 -0
- package/dist/presentation/routes/delete-variable.js +40 -0
- package/dist/presentation/routes/delete-variable.js.map +1 -0
- package/dist/presentation/routes/errors.d.ts +2 -0
- package/dist/presentation/routes/errors.d.ts.map +1 -0
- package/dist/presentation/routes/errors.js +73 -0
- package/dist/presentation/routes/errors.js.map +1 -0
- package/dist/presentation/routes/get-variable.d.ts +2 -0
- package/dist/presentation/routes/get-variable.d.ts.map +1 -0
- package/dist/presentation/routes/get-variable.js +42 -0
- package/dist/presentation/routes/get-variable.js.map +1 -0
- package/dist/presentation/routes/index.d.ts +3 -0
- package/dist/presentation/routes/index.d.ts.map +1 -0
- package/dist/presentation/routes/index.js +29 -0
- package/dist/presentation/routes/index.js.map +1 -0
- package/dist/presentation/routes/list-secrets.d.ts +2 -0
- package/dist/presentation/routes/list-secrets.d.ts.map +1 -0
- package/dist/presentation/routes/list-secrets.js +50 -0
- package/dist/presentation/routes/list-secrets.js.map +1 -0
- package/dist/presentation/routes/list-variables.d.ts +2 -0
- package/dist/presentation/routes/list-variables.d.ts.map +1 -0
- package/dist/presentation/routes/list-variables.js +50 -0
- package/dist/presentation/routes/list-variables.js.map +1 -0
- package/dist/presentation/routes/put-secret.d.ts +2 -0
- package/dist/presentation/routes/put-secret.d.ts.map +1 -0
- package/dist/presentation/routes/put-secret.js +52 -0
- package/dist/presentation/routes/put-secret.js.map +1 -0
- package/dist/presentation/routes/put-variable.d.ts +2 -0
- package/dist/presentation/routes/put-variable.d.ts.map +1 -0
- package/dist/presentation/routes/put-variable.js +52 -0
- package/dist/presentation/routes/put-variable.js.map +1 -0
- package/dist/presentation/routes/warnings.d.ts +5 -0
- package/dist/presentation/routes/warnings.d.ts.map +1 -0
- package/dist/presentation/routes/warnings.js +16 -0
- package/dist/presentation/routes/warnings.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/drizzle/0000_lowly_ogun.sql +59 -0
- package/drizzle/meta/0000_snapshot.json +547 -0
- package/drizzle/meta/_journal.json +13 -0
- package/drizzle.config.ts +7 -0
- package/package.json +77 -0
- package/src/config.test.ts +41 -0
- package/src/config.ts +41 -0
- package/src/core/crypto.test.ts +115 -0
- package/src/core/crypto.ts +105 -0
- package/src/core/dek-manager.test.ts +120 -0
- package/src/core/dek-manager.ts +98 -0
- package/src/core/errors.ts +100 -0
- package/src/core/fingerprint.test.ts +27 -0
- package/src/core/fingerprint.ts +14 -0
- package/src/core/index.ts +153 -0
- package/src/core/key-provider.test.ts +44 -0
- package/src/core/key-provider.ts +70 -0
- package/src/core/local-secret-store.ts +49 -0
- package/src/core/management.test.ts +37 -0
- package/src/core/management.ts +503 -0
- package/src/core/rotate-kek.test.ts +183 -0
- package/src/core/rotate-kek.ts +100 -0
- package/src/core/secret-store.test.ts +301 -0
- package/src/core/secret-store.ts +251 -0
- package/src/core/store-resolver.test.ts +20 -0
- package/src/core/store-resolver.ts +28 -0
- package/src/core/store-validation.ts +43 -0
- package/src/core/value-cipher.ts +26 -0
- package/src/core/variable-store.test.ts +106 -0
- package/src/core/variable-store.ts +232 -0
- package/src/db/cap.ts +58 -0
- package/src/db/data-keys.ts +99 -0
- package/src/db/db.ts +26 -0
- package/src/db/index.ts +45 -0
- package/src/db/management.ts +252 -0
- package/src/db/schema/common.ts +8 -0
- package/src/db/schema/data-keys.ts +31 -0
- package/src/db/schema/outbox.ts +4 -0
- package/src/db/schema/values.ts +74 -0
- package/src/db/schema/variables.ts +71 -0
- package/src/db/scope.ts +42 -0
- package/src/db/values.ts +191 -0
- package/src/db/variables.ts +187 -0
- package/src/index.test.ts +11 -0
- package/src/index.ts +50 -0
- package/src/metrics/index.ts +19 -0
- package/src/metrics/instance.ts +219 -0
- package/src/metrics/service.ts +19 -0
- package/src/presentation/dto/index.ts +1 -0
- package/src/presentation/dto/management.ts +36 -0
- package/src/presentation/e2eRoutes/create-secret.ts +31 -0
- package/src/presentation/e2eRoutes/create-variable.ts +34 -0
- package/src/presentation/e2eRoutes/index.test.ts +94 -0
- package/src/presentation/e2eRoutes/index.ts +8 -0
- package/src/presentation/routes/auth.ts +50 -0
- package/src/presentation/routes/batch-secrets.ts +33 -0
- package/src/presentation/routes/batch-variables.ts +33 -0
- package/src/presentation/routes/cursor.ts +23 -0
- package/src/presentation/routes/delete-secret.ts +26 -0
- package/src/presentation/routes/delete-variable.ts +26 -0
- package/src/presentation/routes/errors.ts +63 -0
- package/src/presentation/routes/get-variable.ts +32 -0
- package/src/presentation/routes/index.ts +29 -0
- package/src/presentation/routes/list-secrets.ts +41 -0
- package/src/presentation/routes/list-variables.ts +41 -0
- package/src/presentation/routes/management.test.ts +452 -0
- package/src/presentation/routes/put-secret.ts +39 -0
- package/src/presentation/routes/put-variable.ts +39 -0
- package/src/presentation/routes/warnings.ts +23 -0
- package/test/env.ts +8 -0
- package/test/globalSetup.ts +18 -0
- package/test/setup.ts +17 -0
- package/tsconfig.build.json +10 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +7 -0
- package/tsconfig.test.json +8 -0
- package/vitest.config.ts +12 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { instanceMetrics } from '@shipfox/node-opentelemetry';
|
|
2
|
+
import { DekUnwrapError, DekWrapError, KekVersionStrandedError, NamespaceValidationError, SecretBatchDuplicateKeyError, SecretBatchScopeMismatchError, SecretDecryptionError, SecretKeyValidationError, SecretNotFoundError, SecretValueTooLargeError, UnknownSecretStoreError, VariableNotFoundError, WorkspaceSecretCapExceededError } from '#core/errors.js';
|
|
3
|
+
const meter = instanceMetrics.getMeter('secrets');
|
|
4
|
+
const operationCount = meter.createCounter('secrets_operation', {
|
|
5
|
+
description: 'Secrets module operation attempts by resource, surface, scope, and outcome'
|
|
6
|
+
});
|
|
7
|
+
const operationDuration = meter.createHistogram('secrets_operation_duration', {
|
|
8
|
+
description: 'Secrets module operation duration',
|
|
9
|
+
unit: 'ms',
|
|
10
|
+
advice: {
|
|
11
|
+
explicitBucketBoundaries: [
|
|
12
|
+
1,
|
|
13
|
+
5,
|
|
14
|
+
10,
|
|
15
|
+
25,
|
|
16
|
+
50,
|
|
17
|
+
100,
|
|
18
|
+
250,
|
|
19
|
+
500,
|
|
20
|
+
1000,
|
|
21
|
+
2500,
|
|
22
|
+
5000
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
const entriesMutatedCount = meter.createCounter('secrets_entries_mutated', {
|
|
27
|
+
description: 'Secret and variable entries mutated by operation, effect, and surface'
|
|
28
|
+
});
|
|
29
|
+
const dekAccessCount = meter.createCounter('secrets_dek_access', {
|
|
30
|
+
description: 'Plaintext data-encryption key access attempts by outcome'
|
|
31
|
+
});
|
|
32
|
+
const dekAccessDuration = meter.createHistogram('secrets_dek_access_duration', {
|
|
33
|
+
description: 'Plaintext data-encryption key access duration',
|
|
34
|
+
unit: 'ms',
|
|
35
|
+
advice: {
|
|
36
|
+
explicitBucketBoundaries: [
|
|
37
|
+
0,
|
|
38
|
+
1,
|
|
39
|
+
5,
|
|
40
|
+
10,
|
|
41
|
+
25,
|
|
42
|
+
50,
|
|
43
|
+
100,
|
|
44
|
+
250,
|
|
45
|
+
500,
|
|
46
|
+
1000
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
const kekRotationCount = meter.createCounter('secrets_kek_rotation', {
|
|
51
|
+
description: 'Workspace data-key KEK rotation outcomes'
|
|
52
|
+
});
|
|
53
|
+
const kekRotationDuration = meter.createHistogram('secrets_kek_rotation_duration', {
|
|
54
|
+
description: 'Workspace data-key KEK rotation duration',
|
|
55
|
+
unit: 'ms',
|
|
56
|
+
advice: {
|
|
57
|
+
explicitBucketBoundaries: [
|
|
58
|
+
10,
|
|
59
|
+
50,
|
|
60
|
+
100,
|
|
61
|
+
250,
|
|
62
|
+
500,
|
|
63
|
+
1000,
|
|
64
|
+
2500,
|
|
65
|
+
5000,
|
|
66
|
+
10000,
|
|
67
|
+
30000
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
function recordMetric(record) {
|
|
72
|
+
try {
|
|
73
|
+
record();
|
|
74
|
+
} catch {
|
|
75
|
+
// Metrics must not affect secret storage outcomes.
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export function operationScope(params) {
|
|
79
|
+
return params.projectId ? 'project' : 'workspace';
|
|
80
|
+
}
|
|
81
|
+
export function classifySecretsOperationError(error) {
|
|
82
|
+
if (error instanceof SecretNotFoundError || error instanceof VariableNotFoundError) {
|
|
83
|
+
return 'not_found';
|
|
84
|
+
}
|
|
85
|
+
if (error instanceof WorkspaceSecretCapExceededError) return 'cap_exceeded';
|
|
86
|
+
if (error instanceof SecretValueTooLargeError) return 'value_too_large';
|
|
87
|
+
if (error instanceof SecretDecryptionError) return 'decryption_failed';
|
|
88
|
+
if (error instanceof DekUnwrapError || error instanceof DekWrapError) return 'crypto_failed';
|
|
89
|
+
if (error instanceof NamespaceValidationError || error instanceof SecretKeyValidationError || error instanceof SecretBatchDuplicateKeyError || error instanceof SecretBatchScopeMismatchError || error instanceof UnknownSecretStoreError) {
|
|
90
|
+
return 'validation_failed';
|
|
91
|
+
}
|
|
92
|
+
return 'failure';
|
|
93
|
+
}
|
|
94
|
+
export function recordSecretsOperation(params) {
|
|
95
|
+
recordMetric(()=>{
|
|
96
|
+
const labels = {
|
|
97
|
+
resource: params.resource,
|
|
98
|
+
operation: params.operation,
|
|
99
|
+
surface: params.surface,
|
|
100
|
+
scope: params.scope,
|
|
101
|
+
outcome: params.outcome
|
|
102
|
+
};
|
|
103
|
+
operationCount.add(1, labels);
|
|
104
|
+
operationDuration.record(params.durationMs, labels);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
export function recordSecretsEntriesMutated(params) {
|
|
108
|
+
if (params.count <= 0) return;
|
|
109
|
+
recordMetric(()=>entriesMutatedCount.add(params.count, {
|
|
110
|
+
resource: params.resource,
|
|
111
|
+
operation: params.operation,
|
|
112
|
+
effect: params.effect,
|
|
113
|
+
surface: params.surface
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
export function recordSecretsDekAccess(params) {
|
|
117
|
+
recordMetric(()=>{
|
|
118
|
+
dekAccessCount.add(1, {
|
|
119
|
+
outcome: params.outcome
|
|
120
|
+
});
|
|
121
|
+
dekAccessDuration.record(params.durationMs, {
|
|
122
|
+
outcome: params.outcome
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
export function classifyDekAccessError(error) {
|
|
127
|
+
if (error instanceof DekUnwrapError) return 'unwrap_failed';
|
|
128
|
+
if (error instanceof DekWrapError) return 'wrap_failed';
|
|
129
|
+
return 'failure';
|
|
130
|
+
}
|
|
131
|
+
export function recordSecretsKekRotation(params) {
|
|
132
|
+
const count = params.count ?? 1;
|
|
133
|
+
if (count <= 0 && params.durationMs === undefined) return;
|
|
134
|
+
recordMetric(()=>{
|
|
135
|
+
if (count > 0) kekRotationCount.add(count, {
|
|
136
|
+
outcome: params.outcome
|
|
137
|
+
});
|
|
138
|
+
if (params.durationMs !== undefined) {
|
|
139
|
+
kekRotationDuration.record(params.durationMs, {
|
|
140
|
+
outcome: params.outcome
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
export function classifyKekRotationError(error) {
|
|
146
|
+
if (error instanceof KekVersionStrandedError) return 'stranded';
|
|
147
|
+
if (error instanceof DekUnwrapError || error instanceof DekWrapError) return 'failure';
|
|
148
|
+
return 'failure';
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
//# sourceMappingURL=instance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/metrics/instance.ts"],"sourcesContent":["import {instanceMetrics} from '@shipfox/node-opentelemetry';\nimport {\n DekUnwrapError,\n DekWrapError,\n KekVersionStrandedError,\n NamespaceValidationError,\n SecretBatchDuplicateKeyError,\n SecretBatchScopeMismatchError,\n SecretDecryptionError,\n SecretKeyValidationError,\n SecretNotFoundError,\n SecretValueTooLargeError,\n UnknownSecretStoreError,\n VariableNotFoundError,\n WorkspaceSecretCapExceededError,\n} from '#core/errors.js';\n\nconst meter = instanceMetrics.getMeter('secrets');\n\nexport type SecretsMetricResource = 'secret' | 'variable';\nexport type SecretsMetricOperation = 'get' | 'get_namespace' | 'set' | 'delete' | 'list';\nexport type SecretsMetricSurface = 'internal' | 'management';\nexport type SecretsMetricScope = 'workspace' | 'project';\nexport type SecretsOperationOutcome =\n | 'success'\n | 'not_found'\n | 'validation_failed'\n | 'cap_exceeded'\n | 'value_too_large'\n | 'decryption_failed'\n | 'crypto_failed'\n | 'failure';\nexport type SecretsMutationEffect = 'created' | 'updated' | 'deleted';\nexport type SecretsDekAccessOutcome =\n | 'cache_hit'\n | 'cache_expired'\n | 'db_unwrapped'\n | 'generated'\n | 'unwrap_failed'\n | 'wrap_failed'\n | 'failure';\nexport type SecretsKekRotationOutcome =\n | 'rotated'\n | 'skipped_current'\n | 'skipped_race'\n | 'none'\n | 'stranded'\n | 'failure';\n\nconst operationCount = meter.createCounter<{\n resource: SecretsMetricResource;\n operation: SecretsMetricOperation;\n surface: SecretsMetricSurface;\n scope: SecretsMetricScope;\n outcome: SecretsOperationOutcome;\n}>('secrets_operation', {\n description: 'Secrets module operation attempts by resource, surface, scope, and outcome',\n});\n\nconst operationDuration = meter.createHistogram<{\n resource: SecretsMetricResource;\n operation: SecretsMetricOperation;\n surface: SecretsMetricSurface;\n scope: SecretsMetricScope;\n outcome: SecretsOperationOutcome;\n}>('secrets_operation_duration', {\n description: 'Secrets module operation duration',\n unit: 'ms',\n advice: {explicitBucketBoundaries: [1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000]},\n});\n\nconst entriesMutatedCount = meter.createCounter<{\n resource: SecretsMetricResource;\n operation: 'set' | 'delete';\n effect: SecretsMutationEffect;\n surface: SecretsMetricSurface;\n}>('secrets_entries_mutated', {\n description: 'Secret and variable entries mutated by operation, effect, and surface',\n});\n\nconst dekAccessCount = meter.createCounter<{outcome: SecretsDekAccessOutcome}>(\n 'secrets_dek_access',\n {description: 'Plaintext data-encryption key access attempts by outcome'},\n);\n\nconst dekAccessDuration = meter.createHistogram<{outcome: SecretsDekAccessOutcome}>(\n 'secrets_dek_access_duration',\n {\n description: 'Plaintext data-encryption key access duration',\n unit: 'ms',\n advice: {explicitBucketBoundaries: [0, 1, 5, 10, 25, 50, 100, 250, 500, 1000]},\n },\n);\n\nconst kekRotationCount = meter.createCounter<{outcome: SecretsKekRotationOutcome}>(\n 'secrets_kek_rotation',\n {description: 'Workspace data-key KEK rotation outcomes'},\n);\n\nconst kekRotationDuration = meter.createHistogram<{outcome: SecretsKekRotationOutcome}>(\n 'secrets_kek_rotation_duration',\n {\n description: 'Workspace data-key KEK rotation duration',\n unit: 'ms',\n advice: {explicitBucketBoundaries: [10, 50, 100, 250, 500, 1000, 2500, 5000, 10000, 30000]},\n },\n);\n\nfunction recordMetric(record: () => void): void {\n try {\n record();\n } catch {\n // Metrics must not affect secret storage outcomes.\n }\n}\n\nexport function operationScope(params: {\n projectId?: string | null | undefined;\n}): SecretsMetricScope {\n return params.projectId ? 'project' : 'workspace';\n}\n\nexport function classifySecretsOperationError(error: unknown): SecretsOperationOutcome {\n if (error instanceof SecretNotFoundError || error instanceof VariableNotFoundError) {\n return 'not_found';\n }\n if (error instanceof WorkspaceSecretCapExceededError) return 'cap_exceeded';\n if (error instanceof SecretValueTooLargeError) return 'value_too_large';\n if (error instanceof SecretDecryptionError) return 'decryption_failed';\n if (error instanceof DekUnwrapError || error instanceof DekWrapError) return 'crypto_failed';\n if (\n error instanceof NamespaceValidationError ||\n error instanceof SecretKeyValidationError ||\n error instanceof SecretBatchDuplicateKeyError ||\n error instanceof SecretBatchScopeMismatchError ||\n error instanceof UnknownSecretStoreError\n ) {\n return 'validation_failed';\n }\n return 'failure';\n}\n\nexport function recordSecretsOperation(params: {\n resource: SecretsMetricResource;\n operation: SecretsMetricOperation;\n surface: SecretsMetricSurface;\n scope: SecretsMetricScope;\n outcome: SecretsOperationOutcome;\n durationMs: number;\n}): void {\n recordMetric(() => {\n const labels = {\n resource: params.resource,\n operation: params.operation,\n surface: params.surface,\n scope: params.scope,\n outcome: params.outcome,\n };\n operationCount.add(1, labels);\n operationDuration.record(params.durationMs, labels);\n });\n}\n\nexport function recordSecretsEntriesMutated(params: {\n resource: SecretsMetricResource;\n operation: 'set' | 'delete';\n effect: SecretsMutationEffect;\n surface: SecretsMetricSurface;\n count: number;\n}): void {\n if (params.count <= 0) return;\n\n recordMetric(() =>\n entriesMutatedCount.add(params.count, {\n resource: params.resource,\n operation: params.operation,\n effect: params.effect,\n surface: params.surface,\n }),\n );\n}\n\nexport function recordSecretsDekAccess(params: {\n outcome: SecretsDekAccessOutcome;\n durationMs: number;\n}): void {\n recordMetric(() => {\n dekAccessCount.add(1, {outcome: params.outcome});\n dekAccessDuration.record(params.durationMs, {outcome: params.outcome});\n });\n}\n\nexport function classifyDekAccessError(error: unknown): SecretsDekAccessOutcome {\n if (error instanceof DekUnwrapError) return 'unwrap_failed';\n if (error instanceof DekWrapError) return 'wrap_failed';\n return 'failure';\n}\n\nexport function recordSecretsKekRotation(params: {\n outcome: SecretsKekRotationOutcome;\n count?: number | undefined;\n durationMs?: number | undefined;\n}): void {\n const count = params.count ?? 1;\n if (count <= 0 && params.durationMs === undefined) return;\n\n recordMetric(() => {\n if (count > 0) kekRotationCount.add(count, {outcome: params.outcome});\n if (params.durationMs !== undefined) {\n kekRotationDuration.record(params.durationMs, {outcome: params.outcome});\n }\n });\n}\n\nexport function classifyKekRotationError(error: unknown): SecretsKekRotationOutcome {\n if (error instanceof KekVersionStrandedError) return 'stranded';\n if (error instanceof DekUnwrapError || error instanceof DekWrapError) return 'failure';\n return 'failure';\n}\n"],"names":["instanceMetrics","DekUnwrapError","DekWrapError","KekVersionStrandedError","NamespaceValidationError","SecretBatchDuplicateKeyError","SecretBatchScopeMismatchError","SecretDecryptionError","SecretKeyValidationError","SecretNotFoundError","SecretValueTooLargeError","UnknownSecretStoreError","VariableNotFoundError","WorkspaceSecretCapExceededError","meter","getMeter","operationCount","createCounter","description","operationDuration","createHistogram","unit","advice","explicitBucketBoundaries","entriesMutatedCount","dekAccessCount","dekAccessDuration","kekRotationCount","kekRotationDuration","recordMetric","record","operationScope","params","projectId","classifySecretsOperationError","error","recordSecretsOperation","labels","resource","operation","surface","scope","outcome","add","durationMs","recordSecretsEntriesMutated","count","effect","recordSecretsDekAccess","classifyDekAccessError","recordSecretsKekRotation","undefined","classifyKekRotationError"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/metrics/service.ts"],"names":[],"mappings":"AAGA,wBAAgB,6BAA6B,IAAI,IAAI,CAepD"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { getServiceMetricsProvider } from '@shipfox/node-opentelemetry';
|
|
2
|
+
import { countPublicEntriesByResource } from '#db/index.js';
|
|
3
|
+
export function registerSecretsServiceMetrics() {
|
|
4
|
+
const meter = getServiceMetricsProvider().getMeter('secrets');
|
|
5
|
+
const publicEntries = meter.createObservableGauge('secrets_public_entries', {
|
|
6
|
+
description: 'Public secret and variable entries currently stored, excluding system namespaces'
|
|
7
|
+
});
|
|
8
|
+
meter.addBatchObservableCallback(async (observer)=>{
|
|
9
|
+
const counts = await countPublicEntriesByResource();
|
|
10
|
+
observer.observe(publicEntries, counts.secrets, {
|
|
11
|
+
resource: 'secret'
|
|
12
|
+
});
|
|
13
|
+
observer.observe(publicEntries, counts.variables, {
|
|
14
|
+
resource: 'variable'
|
|
15
|
+
});
|
|
16
|
+
}, [
|
|
17
|
+
publicEntries
|
|
18
|
+
]);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/metrics/service.ts"],"sourcesContent":["import {getServiceMetricsProvider} from '@shipfox/node-opentelemetry';\nimport {countPublicEntriesByResource} from '#db/index.js';\n\nexport function registerSecretsServiceMetrics(): void {\n const meter = getServiceMetricsProvider().getMeter('secrets');\n\n const publicEntries = meter.createObservableGauge('secrets_public_entries', {\n description: 'Public secret and variable entries currently stored, excluding system namespaces',\n });\n\n meter.addBatchObservableCallback(\n async (observer) => {\n const counts = await countPublicEntriesByResource();\n observer.observe(publicEntries, counts.secrets, {resource: 'secret'});\n observer.observe(publicEntries, counts.variables, {resource: 'variable'});\n },\n [publicEntries],\n );\n}\n"],"names":["getServiceMetricsProvider","countPublicEntriesByResource","registerSecretsServiceMetrics","meter","getMeter","publicEntries","createObservableGauge","description","addBatchObservableCallback","observer","counts","observe","secrets","resource","variables"],"mappings":"AAAA,SAAQA,yBAAyB,QAAO,8BAA8B;AACtE,SAAQC,4BAA4B,QAAO,eAAe;AAE1D,OAAO,SAASC;IACd,MAAMC,QAAQH,4BAA4BI,QAAQ,CAAC;IAEnD,MAAMC,gBAAgBF,MAAMG,qBAAqB,CAAC,0BAA0B;QAC1EC,aAAa;IACf;IAEAJ,MAAMK,0BAA0B,CAC9B,OAAOC;QACL,MAAMC,SAAS,MAAMT;QACrBQ,SAASE,OAAO,CAACN,eAAeK,OAAOE,OAAO,EAAE;YAACC,UAAU;QAAQ;QACnEJ,SAASE,OAAO,CAACN,eAAeK,OAAOI,SAAS,EAAE;YAACD,UAAU;QAAU;IACzE,GACA;QAACR;KAAc;AAEnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/presentation/dto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAE,aAAa,EAAE,qBAAqB,EAAC,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/dto/index.ts"],"sourcesContent":["export {toSecretDto, toVariableDto, toVariableListItemDto} from './management.js';\n"],"names":["toSecretDto","toVariableDto","toVariableListItemDto"],"mappings":"AAAA,SAAQA,WAAW,EAAEC,aAAa,EAAEC,qBAAqB,QAAO,kBAAkB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SecretDto, VariableDto, VariableListItemDto } from '@shipfox/api-secrets-dto';
|
|
2
|
+
import type { SecretManagementRow, VariableManagementListRow } from '#db/index.js';
|
|
3
|
+
import type { SecretVariable } from '#db/schema/variables.js';
|
|
4
|
+
export declare function toSecretDto(secret: SecretManagementRow): SecretDto;
|
|
5
|
+
export declare function toVariableDto(variable: SecretVariable): VariableDto;
|
|
6
|
+
export declare function toVariableListItemDto(variable: VariableManagementListRow): VariableListItemDto;
|
|
7
|
+
//# sourceMappingURL=management.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"management.d.ts","sourceRoot":"","sources":["../../../src/presentation/dto/management.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAE,WAAW,EAAE,mBAAmB,EAAC,MAAM,0BAA0B,CAAC;AAC1F,OAAO,KAAK,EAAC,mBAAmB,EAAE,yBAAyB,EAAC,MAAM,cAAc,CAAC;AACjF,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,yBAAyB,CAAC;AAE5D,wBAAgB,WAAW,CAAC,MAAM,EAAE,mBAAmB,GAAG,SAAS,CAQlE;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,cAAc,GAAG,WAAW,CASnE;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,yBAAyB,GAAG,mBAAmB,CAU9F"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function toSecretDto(secret) {
|
|
2
|
+
return {
|
|
3
|
+
key: secret.key,
|
|
4
|
+
project_id: secret.projectId,
|
|
5
|
+
created_at: secret.createdAt.toISOString(),
|
|
6
|
+
updated_at: secret.updatedAt.toISOString(),
|
|
7
|
+
last_edited_by: secret.lastEditedBy
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function toVariableDto(variable) {
|
|
11
|
+
return {
|
|
12
|
+
key: variable.key,
|
|
13
|
+
project_id: variable.projectId,
|
|
14
|
+
value: variable.value,
|
|
15
|
+
created_at: variable.createdAt.toISOString(),
|
|
16
|
+
updated_at: variable.updatedAt.toISOString(),
|
|
17
|
+
last_edited_by: variable.lastEditedBy
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function toVariableListItemDto(variable) {
|
|
21
|
+
return {
|
|
22
|
+
key: variable.key,
|
|
23
|
+
project_id: variable.projectId,
|
|
24
|
+
value: variable.value,
|
|
25
|
+
value_truncated: variable.valueTruncated,
|
|
26
|
+
created_at: variable.createdAt.toISOString(),
|
|
27
|
+
updated_at: variable.updatedAt.toISOString(),
|
|
28
|
+
last_edited_by: variable.lastEditedBy
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=management.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/dto/management.ts"],"sourcesContent":["import type {SecretDto, VariableDto, VariableListItemDto} from '@shipfox/api-secrets-dto';\nimport type {SecretManagementRow, VariableManagementListRow} from '#db/index.js';\nimport type {SecretVariable} from '#db/schema/variables.js';\n\nexport function toSecretDto(secret: SecretManagementRow): SecretDto {\n return {\n key: secret.key,\n project_id: secret.projectId,\n created_at: secret.createdAt.toISOString(),\n updated_at: secret.updatedAt.toISOString(),\n last_edited_by: secret.lastEditedBy,\n };\n}\n\nexport function toVariableDto(variable: SecretVariable): VariableDto {\n return {\n key: variable.key,\n project_id: variable.projectId,\n value: variable.value,\n created_at: variable.createdAt.toISOString(),\n updated_at: variable.updatedAt.toISOString(),\n last_edited_by: variable.lastEditedBy,\n };\n}\n\nexport function toVariableListItemDto(variable: VariableManagementListRow): VariableListItemDto {\n return {\n key: variable.key,\n project_id: variable.projectId,\n value: variable.value,\n value_truncated: variable.valueTruncated,\n created_at: variable.createdAt.toISOString(),\n updated_at: variable.updatedAt.toISOString(),\n last_edited_by: variable.lastEditedBy,\n };\n}\n"],"names":["toSecretDto","secret","key","project_id","projectId","created_at","createdAt","toISOString","updated_at","updatedAt","last_edited_by","lastEditedBy","toVariableDto","variable","value","toVariableListItemDto","value_truncated","valueTruncated"],"mappings":"AAIA,OAAO,SAASA,YAAYC,MAA2B;IACrD,OAAO;QACLC,KAAKD,OAAOC,GAAG;QACfC,YAAYF,OAAOG,SAAS;QAC5BC,YAAYJ,OAAOK,SAAS,CAACC,WAAW;QACxCC,YAAYP,OAAOQ,SAAS,CAACF,WAAW;QACxCG,gBAAgBT,OAAOU,YAAY;IACrC;AACF;AAEA,OAAO,SAASC,cAAcC,QAAwB;IACpD,OAAO;QACLX,KAAKW,SAASX,GAAG;QACjBC,YAAYU,SAAST,SAAS;QAC9BU,OAAOD,SAASC,KAAK;QACrBT,YAAYQ,SAASP,SAAS,CAACC,WAAW;QAC1CC,YAAYK,SAASJ,SAAS,CAACF,WAAW;QAC1CG,gBAAgBG,SAASF,YAAY;IACvC;AACF;AAEA,OAAO,SAASI,sBAAsBF,QAAmC;IACvE,OAAO;QACLX,KAAKW,SAASX,GAAG;QACjBC,YAAYU,SAAST,SAAS;QAC9BU,OAAOD,SAASC,KAAK;QACrBE,iBAAiBH,SAASI,cAAc;QACxCZ,YAAYQ,SAASP,SAAS,CAACC,WAAW;QAC1CC,YAAYK,SAASJ,SAAS,CAACF,WAAW;QAC1CG,gBAAgBG,SAASF,YAAY;IACvC;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-secret.d.ts","sourceRoot":"","sources":["../../../src/presentation/e2eRoutes/create-secret.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,oBAAoB,iDAsB/B,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { e2eCreateSecretBodySchema, e2eCreateSecretResponseSchema } from '@shipfox/api-secrets-dto';
|
|
2
|
+
import { defineRoute } from '@shipfox/node-fastify';
|
|
3
|
+
import { setManagedSecrets } from '#core/index.js';
|
|
4
|
+
import { toSecretDto } from '#presentation/dto/index.js';
|
|
5
|
+
import { translateManagementError } from '#presentation/routes/errors.js';
|
|
6
|
+
export const createE2eSecretRoute = defineRoute({
|
|
7
|
+
method: 'POST',
|
|
8
|
+
path: '/secret',
|
|
9
|
+
description: 'Create a workspace secret for E2E tests.',
|
|
10
|
+
schema: {
|
|
11
|
+
body: e2eCreateSecretBodySchema,
|
|
12
|
+
response: {
|
|
13
|
+
201: e2eCreateSecretResponseSchema
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
errorHandler: translateManagementError,
|
|
17
|
+
handler: async (request, reply)=>{
|
|
18
|
+
const secret = (await setManagedSecrets({
|
|
19
|
+
workspaceId: request.body.workspace_id,
|
|
20
|
+
actorId: request.body.actor_id,
|
|
21
|
+
projectId: request.body.project_id,
|
|
22
|
+
entries: [
|
|
23
|
+
{
|
|
24
|
+
key: request.body.key,
|
|
25
|
+
value: request.body.value
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}))[0];
|
|
29
|
+
reply.code(201);
|
|
30
|
+
return toSecretDto(secret);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=create-secret.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/e2eRoutes/create-secret.ts"],"sourcesContent":["import {e2eCreateSecretBodySchema, e2eCreateSecretResponseSchema} from '@shipfox/api-secrets-dto';\nimport {defineRoute} from '@shipfox/node-fastify';\nimport {setManagedSecrets} from '#core/index.js';\nimport {toSecretDto} from '#presentation/dto/index.js';\nimport {translateManagementError} from '#presentation/routes/errors.js';\n\ntype ManagedSecret = Awaited<ReturnType<typeof setManagedSecrets>>[number];\n\nexport const createE2eSecretRoute = defineRoute({\n method: 'POST',\n path: '/secret',\n description: 'Create a workspace secret for E2E tests.',\n schema: {\n body: e2eCreateSecretBodySchema,\n response: {201: e2eCreateSecretResponseSchema},\n },\n errorHandler: translateManagementError,\n handler: async (request, reply) => {\n const secret = (\n await setManagedSecrets({\n workspaceId: request.body.workspace_id,\n actorId: request.body.actor_id,\n projectId: request.body.project_id,\n entries: [{key: request.body.key, value: request.body.value}],\n })\n )[0] as ManagedSecret;\n\n reply.code(201);\n return toSecretDto(secret);\n },\n});\n"],"names":["e2eCreateSecretBodySchema","e2eCreateSecretResponseSchema","defineRoute","setManagedSecrets","toSecretDto","translateManagementError","createE2eSecretRoute","method","path","description","schema","body","response","errorHandler","handler","request","reply","secret","workspaceId","workspace_id","actorId","actor_id","projectId","project_id","entries","key","value","code"],"mappings":"AAAA,SAAQA,yBAAyB,EAAEC,6BAA6B,QAAO,2BAA2B;AAClG,SAAQC,WAAW,QAAO,wBAAwB;AAClD,SAAQC,iBAAiB,QAAO,iBAAiB;AACjD,SAAQC,WAAW,QAAO,6BAA6B;AACvD,SAAQC,wBAAwB,QAAO,iCAAiC;AAIxE,OAAO,MAAMC,uBAAuBJ,YAAY;IAC9CK,QAAQ;IACRC,MAAM;IACNC,aAAa;IACbC,QAAQ;QACNC,MAAMX;QACNY,UAAU;YAAC,KAAKX;QAA6B;IAC/C;IACAY,cAAcR;IACdS,SAAS,OAAOC,SAASC;QACvB,MAAMC,SAAS,AACb,CAAA,MAAMd,kBAAkB;YACtBe,aAAaH,QAAQJ,IAAI,CAACQ,YAAY;YACtCC,SAASL,QAAQJ,IAAI,CAACU,QAAQ;YAC9BC,WAAWP,QAAQJ,IAAI,CAACY,UAAU;YAClCC,SAAS;gBAAC;oBAACC,KAAKV,QAAQJ,IAAI,CAACc,GAAG;oBAAEC,OAAOX,QAAQJ,IAAI,CAACe,KAAK;gBAAA;aAAE;QAC/D,EAAC,CACF,CAAC,EAAE;QAEJV,MAAMW,IAAI,CAAC;QACX,OAAOvB,YAAYa;IACrB;AACF,GAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-variable.d.ts","sourceRoot":"","sources":["../../../src/presentation/e2eRoutes/create-variable.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,sBAAsB,iDAsBjC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { e2eCreateVariableBodySchema, e2eCreateVariableResponseSchema } from '@shipfox/api-secrets-dto';
|
|
2
|
+
import { defineRoute } from '@shipfox/node-fastify';
|
|
3
|
+
import { setManagedVariables } from '#core/index.js';
|
|
4
|
+
import { toVariableDto } from '#presentation/dto/index.js';
|
|
5
|
+
import { translateManagementError } from '#presentation/routes/errors.js';
|
|
6
|
+
export const createE2eVariableRoute = defineRoute({
|
|
7
|
+
method: 'POST',
|
|
8
|
+
path: '/variable',
|
|
9
|
+
description: 'Create a workspace variable for E2E tests.',
|
|
10
|
+
schema: {
|
|
11
|
+
body: e2eCreateVariableBodySchema,
|
|
12
|
+
response: {
|
|
13
|
+
201: e2eCreateVariableResponseSchema
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
errorHandler: translateManagementError,
|
|
17
|
+
handler: async (request, reply)=>{
|
|
18
|
+
const variable = (await setManagedVariables({
|
|
19
|
+
workspaceId: request.body.workspace_id,
|
|
20
|
+
actorId: request.body.actor_id,
|
|
21
|
+
projectId: request.body.project_id,
|
|
22
|
+
entries: [
|
|
23
|
+
{
|
|
24
|
+
key: request.body.key,
|
|
25
|
+
value: request.body.value
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}))[0];
|
|
29
|
+
reply.code(201);
|
|
30
|
+
return toVariableDto(variable);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=create-variable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/e2eRoutes/create-variable.ts"],"sourcesContent":["import {\n e2eCreateVariableBodySchema,\n e2eCreateVariableResponseSchema,\n} from '@shipfox/api-secrets-dto';\nimport {defineRoute} from '@shipfox/node-fastify';\nimport {setManagedVariables} from '#core/index.js';\nimport {toVariableDto} from '#presentation/dto/index.js';\nimport {translateManagementError} from '#presentation/routes/errors.js';\n\ntype ManagedVariable = Awaited<ReturnType<typeof setManagedVariables>>[number];\n\nexport const createE2eVariableRoute = defineRoute({\n method: 'POST',\n path: '/variable',\n description: 'Create a workspace variable for E2E tests.',\n schema: {\n body: e2eCreateVariableBodySchema,\n response: {201: e2eCreateVariableResponseSchema},\n },\n errorHandler: translateManagementError,\n handler: async (request, reply) => {\n const variable = (\n await setManagedVariables({\n workspaceId: request.body.workspace_id,\n actorId: request.body.actor_id,\n projectId: request.body.project_id,\n entries: [{key: request.body.key, value: request.body.value}],\n })\n )[0] as ManagedVariable;\n\n reply.code(201);\n return toVariableDto(variable);\n },\n});\n"],"names":["e2eCreateVariableBodySchema","e2eCreateVariableResponseSchema","defineRoute","setManagedVariables","toVariableDto","translateManagementError","createE2eVariableRoute","method","path","description","schema","body","response","errorHandler","handler","request","reply","variable","workspaceId","workspace_id","actorId","actor_id","projectId","project_id","entries","key","value","code"],"mappings":"AAAA,SACEA,2BAA2B,EAC3BC,+BAA+B,QAC1B,2BAA2B;AAClC,SAAQC,WAAW,QAAO,wBAAwB;AAClD,SAAQC,mBAAmB,QAAO,iBAAiB;AACnD,SAAQC,aAAa,QAAO,6BAA6B;AACzD,SAAQC,wBAAwB,QAAO,iCAAiC;AAIxE,OAAO,MAAMC,yBAAyBJ,YAAY;IAChDK,QAAQ;IACRC,MAAM;IACNC,aAAa;IACbC,QAAQ;QACNC,MAAMX;QACNY,UAAU;YAAC,KAAKX;QAA+B;IACjD;IACAY,cAAcR;IACdS,SAAS,OAAOC,SAASC;QACvB,MAAMC,WAAW,AACf,CAAA,MAAMd,oBAAoB;YACxBe,aAAaH,QAAQJ,IAAI,CAACQ,YAAY;YACtCC,SAASL,QAAQJ,IAAI,CAACU,QAAQ;YAC9BC,WAAWP,QAAQJ,IAAI,CAACY,UAAU;YAClCC,SAAS;gBAAC;oBAACC,KAAKV,QAAQJ,IAAI,CAACc,GAAG;oBAAEC,OAAOX,QAAQJ,IAAI,CAACe,KAAK;gBAAA;aAAE;QAC/D,EAAC,CACF,CAAC,EAAE;QAEJV,MAAMW,IAAI,CAAC;QACX,OAAOvB,cAAca;IACvB;AACF,GAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/presentation/e2eRoutes/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAItD,eAAO,MAAM,gBAAgB,EAAE,UAG9B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createE2eSecretRoute } from './create-secret.js';
|
|
2
|
+
import { createE2eVariableRoute } from './create-variable.js';
|
|
3
|
+
export const secretsE2eRoutes = {
|
|
4
|
+
prefix: '/secrets',
|
|
5
|
+
routes: [
|
|
6
|
+
createE2eSecretRoute,
|
|
7
|
+
createE2eVariableRoute
|
|
8
|
+
]
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/e2eRoutes/index.ts"],"sourcesContent":["import type {RouteGroup} from '@shipfox/node-fastify';\nimport {createE2eSecretRoute} from './create-secret.js';\nimport {createE2eVariableRoute} from './create-variable.js';\n\nexport const secretsE2eRoutes: RouteGroup = {\n prefix: '/secrets',\n routes: [createE2eSecretRoute, createE2eVariableRoute],\n};\n"],"names":["createE2eSecretRoute","createE2eVariableRoute","secretsE2eRoutes","prefix","routes"],"mappings":"AACA,SAAQA,oBAAoB,QAAO,qBAAqB;AACxD,SAAQC,sBAAsB,QAAO,uBAAuB;AAE5D,OAAO,MAAMC,mBAA+B;IAC1CC,QAAQ;IACRC,QAAQ;QAACJ;QAAsBC;KAAuB;AACxD,EAAE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FastifyRequest } from 'fastify';
|
|
2
|
+
export interface ManagementAccess {
|
|
3
|
+
workspaceId: string;
|
|
4
|
+
userId: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function requireManagementRead(params: {
|
|
7
|
+
request: FastifyRequest;
|
|
8
|
+
workspaceId: string;
|
|
9
|
+
projectId?: string | undefined;
|
|
10
|
+
}): Promise<ManagementAccess>;
|
|
11
|
+
export declare function requireManagementWrite(params: {
|
|
12
|
+
request: FastifyRequest;
|
|
13
|
+
workspaceId: string;
|
|
14
|
+
projectId?: string | undefined;
|
|
15
|
+
}): Promise<ManagementAccess>;
|
|
16
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/auth.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,SAAS,CAAC;AAE5C,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAa5B;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE;IACnD,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAgB5B"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { requireWorkspaceAccess } from '@shipfox/api-auth-context';
|
|
2
|
+
import { requireProjectForWorkspace } from '@shipfox/api-projects';
|
|
3
|
+
import { ClientError } from '@shipfox/node-fastify';
|
|
4
|
+
export async function requireManagementRead(params) {
|
|
5
|
+
const membership = requireWorkspaceAccess({
|
|
6
|
+
request: params.request,
|
|
7
|
+
workspaceId: params.workspaceId
|
|
8
|
+
});
|
|
9
|
+
if (params.projectId) {
|
|
10
|
+
await requireProjectForWorkspace({
|
|
11
|
+
workspaceId: params.workspaceId,
|
|
12
|
+
projectId: params.projectId
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
workspaceId: params.workspaceId,
|
|
17
|
+
userId: membership.userId
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export async function requireManagementWrite(params) {
|
|
21
|
+
const membership = requireWorkspaceAccess({
|
|
22
|
+
request: params.request,
|
|
23
|
+
workspaceId: params.workspaceId
|
|
24
|
+
});
|
|
25
|
+
if (membership.role !== 'admin') {
|
|
26
|
+
throw new ClientError('Workspace admin role required', 'forbidden', {
|
|
27
|
+
status: 403
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
if (params.projectId) {
|
|
31
|
+
await requireProjectForWorkspace({
|
|
32
|
+
workspaceId: params.workspaceId,
|
|
33
|
+
projectId: params.projectId
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
workspaceId: params.workspaceId,
|
|
38
|
+
userId: membership.userId
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/routes/auth.ts"],"sourcesContent":["import {requireWorkspaceAccess} from '@shipfox/api-auth-context';\nimport {requireProjectForWorkspace} from '@shipfox/api-projects';\nimport {ClientError} from '@shipfox/node-fastify';\nimport type {FastifyRequest} from 'fastify';\n\nexport interface ManagementAccess {\n workspaceId: string;\n userId: string;\n}\n\nexport async function requireManagementRead(params: {\n request: FastifyRequest;\n workspaceId: string;\n projectId?: string | undefined;\n}): Promise<ManagementAccess> {\n const membership = requireWorkspaceAccess({\n request: params.request,\n workspaceId: params.workspaceId,\n });\n if (params.projectId) {\n await requireProjectForWorkspace({\n workspaceId: params.workspaceId,\n projectId: params.projectId,\n });\n }\n\n return {workspaceId: params.workspaceId, userId: membership.userId};\n}\n\nexport async function requireManagementWrite(params: {\n request: FastifyRequest;\n workspaceId: string;\n projectId?: string | undefined;\n}): Promise<ManagementAccess> {\n const membership = requireWorkspaceAccess({\n request: params.request,\n workspaceId: params.workspaceId,\n });\n if (membership.role !== 'admin') {\n throw new ClientError('Workspace admin role required', 'forbidden', {status: 403});\n }\n if (params.projectId) {\n await requireProjectForWorkspace({\n workspaceId: params.workspaceId,\n projectId: params.projectId,\n });\n }\n\n return {workspaceId: params.workspaceId, userId: membership.userId};\n}\n"],"names":["requireWorkspaceAccess","requireProjectForWorkspace","ClientError","requireManagementRead","params","membership","request","workspaceId","projectId","userId","requireManagementWrite","role","status"],"mappings":"AAAA,SAAQA,sBAAsB,QAAO,4BAA4B;AACjE,SAAQC,0BAA0B,QAAO,wBAAwB;AACjE,SAAQC,WAAW,QAAO,wBAAwB;AAQlD,OAAO,eAAeC,sBAAsBC,MAI3C;IACC,MAAMC,aAAaL,uBAAuB;QACxCM,SAASF,OAAOE,OAAO;QACvBC,aAAaH,OAAOG,WAAW;IACjC;IACA,IAAIH,OAAOI,SAAS,EAAE;QACpB,MAAMP,2BAA2B;YAC/BM,aAAaH,OAAOG,WAAW;YAC/BC,WAAWJ,OAAOI,SAAS;QAC7B;IACF;IAEA,OAAO;QAACD,aAAaH,OAAOG,WAAW;QAAEE,QAAQJ,WAAWI,MAAM;IAAA;AACpE;AAEA,OAAO,eAAeC,uBAAuBN,MAI5C;IACC,MAAMC,aAAaL,uBAAuB;QACxCM,SAASF,OAAOE,OAAO;QACvBC,aAAaH,OAAOG,WAAW;IACjC;IACA,IAAIF,WAAWM,IAAI,KAAK,SAAS;QAC/B,MAAM,IAAIT,YAAY,iCAAiC,aAAa;YAACU,QAAQ;QAAG;IAClF;IACA,IAAIR,OAAOI,SAAS,EAAE;QACpB,MAAMP,2BAA2B;YAC/BM,aAAaH,OAAOG,WAAW;YAC/BC,WAAWJ,OAAOI,SAAS;QAC7B;IACF;IAEA,OAAO;QAACD,aAAaH,OAAOG,WAAW;QAAEE,QAAQJ,WAAWI,MAAM;IAAA;AACpE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-secrets.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/batch-secrets.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,iBAAiB,iDAuB5B,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { batchSecretsBodySchema, batchSecretsResponseSchema } from '@shipfox/api-secrets-dto';
|
|
2
|
+
import { defineRoute } from '@shipfox/node-fastify';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { setManagedSecrets } from '#core/index.js';
|
|
5
|
+
import { toSecretDto } from '#presentation/dto/index.js';
|
|
6
|
+
import { requireManagementWrite } from './auth.js';
|
|
7
|
+
import { translateManagementError } from './errors.js';
|
|
8
|
+
import { secretWarnings } from './warnings.js';
|
|
9
|
+
export const batchSecretsRoute = defineRoute({
|
|
10
|
+
method: 'POST',
|
|
11
|
+
path: '/secrets::batch',
|
|
12
|
+
description: 'Create or update multiple user-managed secrets in one scope.',
|
|
13
|
+
schema: {
|
|
14
|
+
params: z.object({
|
|
15
|
+
workspaceId: z.string().uuid()
|
|
16
|
+
}),
|
|
17
|
+
body: batchSecretsBodySchema,
|
|
18
|
+
response: {
|
|
19
|
+
200: batchSecretsResponseSchema
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
errorHandler: translateManagementError,
|
|
23
|
+
handler: async (request)=>{
|
|
24
|
+
const { workspaceId } = request.params;
|
|
25
|
+
const { project_id: projectId, entries } = request.body;
|
|
26
|
+
const access = await requireManagementWrite({
|
|
27
|
+
request,
|
|
28
|
+
workspaceId,
|
|
29
|
+
projectId
|
|
30
|
+
});
|
|
31
|
+
const secrets = await setManagedSecrets({
|
|
32
|
+
workspaceId,
|
|
33
|
+
projectId,
|
|
34
|
+
actorId: access.userId,
|
|
35
|
+
entries
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
secrets: secrets.map(toSecretDto),
|
|
39
|
+
warnings: secretWarnings(entries)
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=batch-secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/routes/batch-secrets.ts"],"sourcesContent":["import {batchSecretsBodySchema, batchSecretsResponseSchema} from '@shipfox/api-secrets-dto';\nimport {defineRoute} from '@shipfox/node-fastify';\nimport {z} from 'zod';\nimport {setManagedSecrets} from '#core/index.js';\nimport {toSecretDto} from '#presentation/dto/index.js';\nimport {requireManagementWrite} from './auth.js';\nimport {translateManagementError} from './errors.js';\nimport {secretWarnings} from './warnings.js';\n\nexport const batchSecretsRoute = defineRoute({\n method: 'POST',\n path: '/secrets::batch',\n description: 'Create or update multiple user-managed secrets in one scope.',\n schema: {\n params: z.object({workspaceId: z.string().uuid()}),\n body: batchSecretsBodySchema,\n response: {200: batchSecretsResponseSchema},\n },\n errorHandler: translateManagementError,\n handler: async (request) => {\n const {workspaceId} = request.params;\n const {project_id: projectId, entries} = request.body;\n const access = await requireManagementWrite({request, workspaceId, projectId});\n const secrets = await setManagedSecrets({\n workspaceId,\n projectId,\n actorId: access.userId,\n entries,\n });\n\n return {secrets: secrets.map(toSecretDto), warnings: secretWarnings(entries)};\n },\n});\n"],"names":["batchSecretsBodySchema","batchSecretsResponseSchema","defineRoute","z","setManagedSecrets","toSecretDto","requireManagementWrite","translateManagementError","secretWarnings","batchSecretsRoute","method","path","description","schema","params","object","workspaceId","string","uuid","body","response","errorHandler","handler","request","project_id","projectId","entries","access","secrets","actorId","userId","map","warnings"],"mappings":"AAAA,SAAQA,sBAAsB,EAAEC,0BAA0B,QAAO,2BAA2B;AAC5F,SAAQC,WAAW,QAAO,wBAAwB;AAClD,SAAQC,CAAC,QAAO,MAAM;AACtB,SAAQC,iBAAiB,QAAO,iBAAiB;AACjD,SAAQC,WAAW,QAAO,6BAA6B;AACvD,SAAQC,sBAAsB,QAAO,YAAY;AACjD,SAAQC,wBAAwB,QAAO,cAAc;AACrD,SAAQC,cAAc,QAAO,gBAAgB;AAE7C,OAAO,MAAMC,oBAAoBP,YAAY;IAC3CQ,QAAQ;IACRC,MAAM;IACNC,aAAa;IACbC,QAAQ;QACNC,QAAQX,EAAEY,MAAM,CAAC;YAACC,aAAab,EAAEc,MAAM,GAAGC,IAAI;QAAE;QAChDC,MAAMnB;QACNoB,UAAU;YAAC,KAAKnB;QAA0B;IAC5C;IACAoB,cAAcd;IACde,SAAS,OAAOC;QACd,MAAM,EAACP,WAAW,EAAC,GAAGO,QAAQT,MAAM;QACpC,MAAM,EAACU,YAAYC,SAAS,EAAEC,OAAO,EAAC,GAAGH,QAAQJ,IAAI;QACrD,MAAMQ,SAAS,MAAMrB,uBAAuB;YAACiB;YAASP;YAAaS;QAAS;QAC5E,MAAMG,UAAU,MAAMxB,kBAAkB;YACtCY;YACAS;YACAI,SAASF,OAAOG,MAAM;YACtBJ;QACF;QAEA,OAAO;YAACE,SAASA,QAAQG,GAAG,CAAC1B;YAAc2B,UAAUxB,eAAekB;QAAQ;IAC9E;AACF,GAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-variables.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/batch-variables.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,mBAAmB,iDAuB9B,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { batchVariablesBodySchema, batchVariablesResponseSchema } from '@shipfox/api-secrets-dto';
|
|
2
|
+
import { defineRoute } from '@shipfox/node-fastify';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { setManagedVariables } from '#core/index.js';
|
|
5
|
+
import { toVariableDto } from '#presentation/dto/index.js';
|
|
6
|
+
import { requireManagementWrite } from './auth.js';
|
|
7
|
+
import { translateManagementError } from './errors.js';
|
|
8
|
+
import { variableWarnings } from './warnings.js';
|
|
9
|
+
export const batchVariablesRoute = defineRoute({
|
|
10
|
+
method: 'POST',
|
|
11
|
+
path: '/variables::batch',
|
|
12
|
+
description: 'Create or update multiple user-managed variables in one scope.',
|
|
13
|
+
schema: {
|
|
14
|
+
params: z.object({
|
|
15
|
+
workspaceId: z.string().uuid()
|
|
16
|
+
}),
|
|
17
|
+
body: batchVariablesBodySchema,
|
|
18
|
+
response: {
|
|
19
|
+
200: batchVariablesResponseSchema
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
errorHandler: translateManagementError,
|
|
23
|
+
handler: async (request)=>{
|
|
24
|
+
const { workspaceId } = request.params;
|
|
25
|
+
const { project_id: projectId, entries } = request.body;
|
|
26
|
+
const access = await requireManagementWrite({
|
|
27
|
+
request,
|
|
28
|
+
workspaceId,
|
|
29
|
+
projectId
|
|
30
|
+
});
|
|
31
|
+
const variables = await setManagedVariables({
|
|
32
|
+
workspaceId,
|
|
33
|
+
projectId,
|
|
34
|
+
actorId: access.userId,
|
|
35
|
+
entries
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
variables: variables.map(toVariableDto),
|
|
39
|
+
warnings: variableWarnings(entries)
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=batch-variables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/routes/batch-variables.ts"],"sourcesContent":["import {batchVariablesBodySchema, batchVariablesResponseSchema} from '@shipfox/api-secrets-dto';\nimport {defineRoute} from '@shipfox/node-fastify';\nimport {z} from 'zod';\nimport {setManagedVariables} from '#core/index.js';\nimport {toVariableDto} from '#presentation/dto/index.js';\nimport {requireManagementWrite} from './auth.js';\nimport {translateManagementError} from './errors.js';\nimport {variableWarnings} from './warnings.js';\n\nexport const batchVariablesRoute = defineRoute({\n method: 'POST',\n path: '/variables::batch',\n description: 'Create or update multiple user-managed variables in one scope.',\n schema: {\n params: z.object({workspaceId: z.string().uuid()}),\n body: batchVariablesBodySchema,\n response: {200: batchVariablesResponseSchema},\n },\n errorHandler: translateManagementError,\n handler: async (request) => {\n const {workspaceId} = request.params;\n const {project_id: projectId, entries} = request.body;\n const access = await requireManagementWrite({request, workspaceId, projectId});\n const variables = await setManagedVariables({\n workspaceId,\n projectId,\n actorId: access.userId,\n entries,\n });\n\n return {variables: variables.map(toVariableDto), warnings: variableWarnings(entries)};\n },\n});\n"],"names":["batchVariablesBodySchema","batchVariablesResponseSchema","defineRoute","z","setManagedVariables","toVariableDto","requireManagementWrite","translateManagementError","variableWarnings","batchVariablesRoute","method","path","description","schema","params","object","workspaceId","string","uuid","body","response","errorHandler","handler","request","project_id","projectId","entries","access","variables","actorId","userId","map","warnings"],"mappings":"AAAA,SAAQA,wBAAwB,EAAEC,4BAA4B,QAAO,2BAA2B;AAChG,SAAQC,WAAW,QAAO,wBAAwB;AAClD,SAAQC,CAAC,QAAO,MAAM;AACtB,SAAQC,mBAAmB,QAAO,iBAAiB;AACnD,SAAQC,aAAa,QAAO,6BAA6B;AACzD,SAAQC,sBAAsB,QAAO,YAAY;AACjD,SAAQC,wBAAwB,QAAO,cAAc;AACrD,SAAQC,gBAAgB,QAAO,gBAAgB;AAE/C,OAAO,MAAMC,sBAAsBP,YAAY;IAC7CQ,QAAQ;IACRC,MAAM;IACNC,aAAa;IACbC,QAAQ;QACNC,QAAQX,EAAEY,MAAM,CAAC;YAACC,aAAab,EAAEc,MAAM,GAAGC,IAAI;QAAE;QAChDC,MAAMnB;QACNoB,UAAU;YAAC,KAAKnB;QAA4B;IAC9C;IACAoB,cAAcd;IACde,SAAS,OAAOC;QACd,MAAM,EAACP,WAAW,EAAC,GAAGO,QAAQT,MAAM;QACpC,MAAM,EAACU,YAAYC,SAAS,EAAEC,OAAO,EAAC,GAAGH,QAAQJ,IAAI;QACrD,MAAMQ,SAAS,MAAMrB,uBAAuB;YAACiB;YAASP;YAAaS;QAAS;QAC5E,MAAMG,YAAY,MAAMxB,oBAAoB;YAC1CY;YACAS;YACAI,SAASF,OAAOG,MAAM;YACtBJ;QACF;QAEA,OAAO;YAACE,WAAWA,UAAUG,GAAG,CAAC1B;YAAgB2B,UAAUxB,iBAAiBkB;QAAQ;IACtF;AACF,GAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/cursor.ts"],"names":[],"mappings":"AAIA,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAI7D;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAYrF"}
|