@highstate/backend 0.9.15 → 0.9.18
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/dist/chunk-NAAIDR4U.js +8499 -0
- package/dist/chunk-NAAIDR4U.js.map +1 -0
- package/dist/chunk-OU5OQBLB.js +74 -0
- package/dist/chunk-OU5OQBLB.js.map +1 -0
- package/dist/chunk-Y7DXREVO.js +1745 -0
- package/dist/chunk-Y7DXREVO.js.map +1 -0
- package/dist/highstate.manifest.json +4 -4
- package/dist/index.js +7227 -2501
- package/dist/index.js.map +1 -1
- package/dist/library/package-resolution-worker.js +7 -5
- package/dist/library/package-resolution-worker.js.map +1 -1
- package/dist/library/worker/main.js +76 -185
- package/dist/library/worker/main.js.map +1 -1
- package/dist/magic-string.es-5ABAC4JN.js +1292 -0
- package/dist/magic-string.es-5ABAC4JN.js.map +1 -0
- package/dist/shared/index.js +3 -98
- package/dist/shared/index.js.map +1 -1
- package/package.json +31 -10
- package/src/artifact/abstractions.ts +46 -0
- package/src/artifact/encryption.ts +109 -0
- package/src/artifact/factory.ts +36 -0
- package/src/artifact/index.ts +3 -0
- package/src/artifact/local.ts +138 -0
- package/src/business/__traces__/secret/update-instance-secrets/create-and-delete-secrets-simultaneously.md +356 -0
- package/src/business/__traces__/secret/update-instance-secrets/create-new-secrets-for-instance.md +274 -0
- package/src/business/__traces__/secret/update-instance-secrets/delete-existing-secrets.md +223 -0
- package/src/business/__traces__/secret/update-instance-secrets/no-op-when-no-changes.md +147 -0
- package/src/business/__traces__/secret/update-instance-secrets/update-existing-secrets.md +280 -0
- package/src/business/__traces__/worker/update-unit-registrations/add-new-unit-registration-when-other-exists.md +360 -0
- package/src/business/__traces__/worker/update-unit-registrations/add-new-unit-registration.md +215 -0
- package/src/business/__traces__/worker/update-unit-registrations/create-multiple-workers-with-different-identities.md +427 -0
- package/src/business/__traces__/worker/update-unit-registrations/handle-nonexistent-registration-id-gracefully.md +217 -0
- package/src/business/__traces__/worker/update-unit-registrations/no-op-when-no-changes.md +132 -0
- package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-when-image-changes.md +454 -0
- package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-when-image-version-changes.md +426 -0
- package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-with-same-identity-reuses-service-account.md +372 -0
- package/src/business/__traces__/worker/update-unit-registrations/remove-one-of-multiple-unit-registrations.md +383 -0
- package/src/business/__traces__/worker/update-unit-registrations/remove-unit-registration.md +245 -0
- package/src/business/__traces__/worker/update-unit-registrations/update-existing-unit-registration-when-params-change.md +174 -0
- package/src/business/__traces__/worker/update-unit-registrations/update-params-and-image-simultaneously.md +432 -0
- package/src/business/__traces__/worker/update-unit-registrations/worker-with-multiple-registrations-not-deleted-when-one-removed.md +220 -0
- package/src/business/api-key.ts +65 -0
- package/src/business/artifact.ts +289 -0
- package/src/business/backend-unlock.ts +10 -0
- package/src/business/index.ts +10 -0
- package/src/business/instance-lock.ts +125 -0
- package/src/business/instance-state.ts +434 -0
- package/src/business/operation.ts +251 -0
- package/src/business/project-unlock.ts +260 -0
- package/src/business/project.ts +299 -0
- package/src/business/secret.test.ts +178 -0
- package/src/business/secret.ts +281 -0
- package/src/business/worker.test.ts +614 -0
- package/src/business/worker.ts +398 -0
- package/src/common/clock.ts +18 -0
- package/src/common/index.ts +5 -1
- package/src/common/performance.ts +44 -0
- package/src/common/random.ts +68 -0
- package/src/common/test/index.ts +2 -0
- package/src/common/test/render.ts +98 -0
- package/src/common/test/tracer.ts +359 -0
- package/src/common/tree.ts +33 -0
- package/src/common/utils.ts +40 -1
- package/src/config.ts +19 -11
- package/src/hotstate/abstractions.ts +48 -0
- package/src/hotstate/factory.ts +17 -0
- package/src/{secret → hotstate}/index.ts +1 -0
- package/src/hotstate/manager.ts +192 -0
- package/src/hotstate/memory.ts +100 -0
- package/src/hotstate/validation.ts +100 -0
- package/src/index.ts +2 -1
- package/src/library/abstractions.ts +24 -28
- package/src/library/factory.ts +2 -2
- package/src/library/local.ts +91 -111
- package/src/library/worker/evaluator.ts +36 -73
- package/src/library/worker/loader.lite.ts +54 -0
- package/src/library/worker/main.ts +15 -66
- package/src/library/worker/protocol.ts +6 -33
- package/src/lock/abstractions.ts +6 -0
- package/src/lock/factory.ts +15 -0
- package/src/lock/index.ts +4 -0
- package/src/lock/manager.ts +97 -0
- package/src/lock/memory.ts +19 -0
- package/src/lock/test.ts +108 -0
- package/src/orchestrator/manager.ts +118 -90
- package/src/orchestrator/operation-workset.ts +181 -93
- package/src/orchestrator/operation.ts +1021 -283
- package/src/project/abstractions.ts +27 -38
- package/src/project/evaluation.ts +248 -0
- package/src/project/factory.ts +1 -1
- package/src/project/index.ts +1 -2
- package/src/project/local.ts +107 -103
- package/src/pubsub/abstractions.ts +13 -0
- package/src/pubsub/factory.ts +19 -0
- package/src/{workspace → pubsub}/index.ts +1 -0
- package/src/pubsub/local.ts +36 -0
- package/src/pubsub/manager.ts +108 -0
- package/src/pubsub/validation.ts +33 -0
- package/src/runner/abstractions.ts +155 -68
- package/src/runner/artifact-env.ts +160 -0
- package/src/runner/factory.ts +20 -5
- package/src/runner/force-abort.ts +117 -0
- package/src/runner/local.ts +292 -372
- package/src/{common → runner}/pulumi.ts +89 -37
- package/src/services.ts +251 -40
- package/src/shared/index.ts +3 -11
- package/src/shared/models/backend/index.ts +3 -0
- package/src/shared/{library.ts → models/backend/library.ts} +4 -4
- package/src/shared/models/backend/project.ts +82 -0
- package/src/shared/models/backend/unlock-method.ts +20 -0
- package/src/shared/models/base.ts +68 -0
- package/src/shared/models/errors.ts +5 -0
- package/src/shared/models/index.ts +4 -0
- package/src/shared/models/project/api-key.ts +65 -0
- package/src/shared/models/project/artifact.ts +83 -0
- package/src/shared/models/project/index.ts +13 -0
- package/src/shared/models/project/lock.ts +91 -0
- package/src/shared/models/project/model.ts +14 -0
- package/src/shared/{operation.ts → models/project/operation.ts} +29 -8
- package/src/shared/models/project/page.ts +57 -0
- package/src/shared/models/project/secret.ts +98 -0
- package/src/shared/models/project/service-account.ts +22 -0
- package/src/shared/models/project/state.ts +449 -0
- package/src/shared/models/project/terminal.ts +98 -0
- package/src/shared/models/project/trigger.ts +56 -0
- package/src/shared/models/project/unlock-method.ts +38 -0
- package/src/shared/models/project/worker.ts +107 -0
- package/src/shared/resolvers/graph-resolver.ts +61 -18
- package/src/shared/resolvers/index.ts +5 -0
- package/src/shared/resolvers/input-hash.ts +53 -15
- package/src/shared/resolvers/input.ts +47 -13
- package/src/shared/resolvers/registry.ts +3 -2
- package/src/shared/resolvers/state.ts +2 -2
- package/src/shared/resolvers/validation.ts +82 -25
- package/src/shared/utils/args.ts +25 -0
- package/src/shared/{async-batcher.ts → utils/async-batcher.ts} +13 -1
- package/src/shared/utils/hash.ts +6 -0
- package/src/shared/utils/index.ts +4 -0
- package/src/shared/utils/promise-tracker.ts +23 -0
- package/src/state/abstractions.ts +199 -131
- package/src/state/encryption.ts +98 -0
- package/src/state/factory.ts +3 -5
- package/src/state/index.ts +4 -0
- package/src/state/keyring.ts +22 -0
- package/src/state/local/backend.ts +106 -0
- package/src/state/local/collection.ts +361 -0
- package/src/state/local/index.ts +2 -0
- package/src/state/manager.ts +875 -18
- package/src/state/memory/backend.ts +70 -0
- package/src/state/memory/collection.ts +270 -0
- package/src/state/memory/index.ts +2 -0
- package/src/state/repository/index.ts +2 -0
- package/src/state/repository/repository.index.ts +193 -0
- package/src/state/repository/repository.ts +507 -0
- package/src/state/test.ts +457 -0
- package/src/terminal/{shared.ts → abstractions.ts} +3 -3
- package/src/terminal/docker.ts +18 -14
- package/src/terminal/factory.ts +3 -3
- package/src/terminal/index.ts +1 -1
- package/src/terminal/manager.ts +131 -79
- package/src/terminal/run.sh.ts +21 -11
- package/src/unlock/abstractions.ts +49 -0
- package/src/unlock/index.ts +2 -0
- package/src/unlock/memory.ts +32 -0
- package/src/worker/abstractions.ts +42 -0
- package/src/worker/docker.ts +83 -0
- package/src/worker/factory.ts +20 -0
- package/src/worker/index.ts +3 -0
- package/src/worker/manager.ts +167 -0
- package/dist/chunk-KTGKNSKM.js +0 -979
- package/dist/chunk-KTGKNSKM.js.map +0 -1
- package/dist/chunk-WXDYCRTT.js +0 -234
- package/dist/chunk-WXDYCRTT.js.map +0 -1
- package/src/library/worker/loader.ts +0 -114
- package/src/preferences/shared.ts +0 -1
- package/src/project/lock.ts +0 -39
- package/src/project/manager.ts +0 -433
- package/src/secret/abstractions.ts +0 -59
- package/src/secret/factory.ts +0 -22
- package/src/secret/local.ts +0 -152
- package/src/shared/project.ts +0 -62
- package/src/shared/state.ts +0 -247
- package/src/shared/terminal.ts +0 -14
- package/src/state/local.ts +0 -612
- package/src/workspace/abstractions.ts +0 -41
- package/src/workspace/factory.ts +0 -14
- package/src/workspace/local.ts +0 -54
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import type { Logger } from "pino"
|
|
2
|
+
import type { LibraryBackend } from "../library"
|
|
3
|
+
import type { StateManager } from "../state"
|
|
4
|
+
import type { InstanceStateService } from "./instance-state"
|
|
5
|
+
import type { RandomProvider } from "../common"
|
|
6
|
+
import {
|
|
7
|
+
HighstateSignature,
|
|
8
|
+
isUnitModel,
|
|
9
|
+
parseInstanceId,
|
|
10
|
+
type UnitSecretModel,
|
|
11
|
+
} from "@highstate/contract"
|
|
12
|
+
import { isNonNullish } from "remeda"
|
|
13
|
+
import { formatSecretDescriptor, type Project, type Secret, type SecretDescriptor } from "../shared"
|
|
14
|
+
|
|
15
|
+
export class SecretService {
|
|
16
|
+
constructor(
|
|
17
|
+
private readonly stateManager: StateManager,
|
|
18
|
+
private readonly libraryBackend: LibraryBackend,
|
|
19
|
+
private readonly instanceStateService: InstanceStateService,
|
|
20
|
+
private readonly random: RandomProvider,
|
|
21
|
+
private readonly logger: Logger,
|
|
22
|
+
) {}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Updates secrets for a specific instance, handling both creation/updates and deletions.
|
|
26
|
+
* Also updates the instance state's secretNames field.
|
|
27
|
+
*
|
|
28
|
+
* @param project The project to which the instance belongs.
|
|
29
|
+
* @param instanceId The instance ID.
|
|
30
|
+
* @param changedSecretValues The secrets to create or update.
|
|
31
|
+
* @param deletedSecretNames The names of secrets to delete.
|
|
32
|
+
* @param invalidateState Whether to invalidate the instance state after updating secrets.
|
|
33
|
+
*/
|
|
34
|
+
async updateInstanceSecrets(
|
|
35
|
+
project: Project,
|
|
36
|
+
instanceId: string,
|
|
37
|
+
changedSecretValues: Record<string, unknown>,
|
|
38
|
+
deletedSecretNames: string[],
|
|
39
|
+
invalidateState = true,
|
|
40
|
+
): Promise<void> {
|
|
41
|
+
const library = await this.libraryBackend.loadLibrary(project.libraryId)
|
|
42
|
+
|
|
43
|
+
const [type] = parseInstanceId(instanceId)
|
|
44
|
+
const component = library.components[type]
|
|
45
|
+
if (!component) {
|
|
46
|
+
throw new Error(`Component type ${type} not found in library`)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!isUnitModel(component)) {
|
|
50
|
+
throw new Error(`Component type ${type} is not a unit model`)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// validate changed secrets
|
|
54
|
+
for (const secretName of Object.keys(changedSecretValues)) {
|
|
55
|
+
if (!component.secrets[secretName]) {
|
|
56
|
+
throw new Error(`Secret ${secretName} not found in component ${type}`)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// validate deleted secrets
|
|
61
|
+
for (const secretName of deletedSecretNames) {
|
|
62
|
+
if (!component.secrets[secretName]) {
|
|
63
|
+
throw new Error(`Secret ${secretName} not found in component ${type}`)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// use a batch for atomic operations
|
|
68
|
+
await using batch = this.stateManager.batch()
|
|
69
|
+
|
|
70
|
+
const secretRepo = this.stateManager.getSecretRepository(project.id)
|
|
71
|
+
const secretContentRepo = this.stateManager.getSecretContentRepository(project.id)
|
|
72
|
+
const indexRepo = this.stateManager.getSecretIndexRepository(project.id)
|
|
73
|
+
|
|
74
|
+
// process changed secrets
|
|
75
|
+
for (const [secretName, value] of Object.entries(changedSecretValues)) {
|
|
76
|
+
const descriptor: SecretDescriptor = { type: "instance", instanceId, secretName }
|
|
77
|
+
const indexKey = formatSecretDescriptor(descriptor)
|
|
78
|
+
|
|
79
|
+
// check if secret already exists
|
|
80
|
+
const existingSecret = await indexRepo.get(indexKey)
|
|
81
|
+
|
|
82
|
+
// create or update secret info
|
|
83
|
+
const secret: Secret = {
|
|
84
|
+
id: existingSecret?.id ?? this.random.uuidv7(),
|
|
85
|
+
descriptor: descriptor,
|
|
86
|
+
meta: {
|
|
87
|
+
...existingSecret?.meta,
|
|
88
|
+
...component.secrets[secretName].meta,
|
|
89
|
+
icon: component.secrets[secretName].meta.icon ?? component.meta.icon,
|
|
90
|
+
},
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// store secret info and content
|
|
94
|
+
await secretRepo.putItem(secret, batch)
|
|
95
|
+
await secretContentRepo.put(indexKey, value, batch)
|
|
96
|
+
|
|
97
|
+
// update index mapping
|
|
98
|
+
await indexRepo.indexRepository.put(indexKey, secret.id, batch)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// process deleted secrets
|
|
102
|
+
for (const secretName of deletedSecretNames) {
|
|
103
|
+
const indexKey = formatSecretDescriptor({ type: "instance", instanceId, secretName })
|
|
104
|
+
|
|
105
|
+
// get the secret ID from index
|
|
106
|
+
const secretId = await indexRepo.indexRepository.get(indexKey)
|
|
107
|
+
if (secretId) {
|
|
108
|
+
// delete secret info, content, and index entry
|
|
109
|
+
await secretRepo.delete(secretId, batch)
|
|
110
|
+
await secretContentRepo.delete(indexKey, batch)
|
|
111
|
+
await indexRepo.indexRepository.delete(indexKey, batch)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// write all changes atomically
|
|
116
|
+
await batch.write()
|
|
117
|
+
|
|
118
|
+
// update instance state secretNames
|
|
119
|
+
await this.instanceStateService.updateStateSecretNames(
|
|
120
|
+
project.id,
|
|
121
|
+
instanceId,
|
|
122
|
+
Object.keys(changedSecretValues),
|
|
123
|
+
deletedSecretNames,
|
|
124
|
+
invalidateState,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
this.logger.info(
|
|
128
|
+
{
|
|
129
|
+
projectId: project.id,
|
|
130
|
+
instanceId,
|
|
131
|
+
changedCount: Object.keys(changedSecretValues).length,
|
|
132
|
+
deletedCount: deletedSecretNames.length,
|
|
133
|
+
},
|
|
134
|
+
`updated instance secrets for instance "%s"`,
|
|
135
|
+
instanceId,
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Gets the values of all secrets for a specific instance.
|
|
141
|
+
*
|
|
142
|
+
* @param project The project to which the instance belongs.
|
|
143
|
+
* @param instanceId The instance ID.
|
|
144
|
+
* @returns A record of secret key-value pairs.
|
|
145
|
+
*/
|
|
146
|
+
async getInstanceSecretValues(
|
|
147
|
+
project: Project,
|
|
148
|
+
instanceId: string,
|
|
149
|
+
): Promise<Record<string, unknown>> {
|
|
150
|
+
const { indexKeys, secrets, secretContentMap } = await this.getInstanceSecretData(
|
|
151
|
+
project,
|
|
152
|
+
instanceId,
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
// build the result mapping secret names to values
|
|
156
|
+
const values: Record<string, unknown> = {}
|
|
157
|
+
for (const descriptor of indexKeys) {
|
|
158
|
+
const secret = secrets[descriptor]
|
|
159
|
+
if (!secret) {
|
|
160
|
+
continue
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const content = secretContentMap[secret.id]
|
|
164
|
+
if (content) {
|
|
165
|
+
values[descriptor] = content
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return secrets
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Gets the secrets for a specific instance, including metadata.
|
|
174
|
+
* Will create missing secrets with empty values.
|
|
175
|
+
*
|
|
176
|
+
* @param project The project to which the instance belongs.
|
|
177
|
+
* @param instanceId The instance ID.
|
|
178
|
+
* @return A record of secret key-value pairs with metadata.
|
|
179
|
+
*/
|
|
180
|
+
async getUnitSecrets(
|
|
181
|
+
project: Project,
|
|
182
|
+
instanceId: string,
|
|
183
|
+
): Promise<Record<string, UnitSecretModel>> {
|
|
184
|
+
const { descriptors, component, secrets, secretContentMap } = await this.getInstanceSecretData(
|
|
185
|
+
project,
|
|
186
|
+
instanceId,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
const missingDescriptors: SecretDescriptor[] = []
|
|
190
|
+
const result: Record<string, UnitSecretModel> = {}
|
|
191
|
+
|
|
192
|
+
for (const descriptor of descriptors) {
|
|
193
|
+
const secret = secrets[formatSecretDescriptor(descriptor)]
|
|
194
|
+
|
|
195
|
+
if (secret) {
|
|
196
|
+
result[descriptor.secretName] = {
|
|
197
|
+
[HighstateSignature.Secret]: true,
|
|
198
|
+
id: secret.id,
|
|
199
|
+
value: secretContentMap[secret.id],
|
|
200
|
+
}
|
|
201
|
+
} else {
|
|
202
|
+
missingDescriptors.push(descriptor)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const batch = this.stateManager.batch()
|
|
207
|
+
|
|
208
|
+
// create missing secrets with empty values
|
|
209
|
+
for (const descriptor of missingDescriptors) {
|
|
210
|
+
const secret: Secret = {
|
|
211
|
+
id: this.random.uuidv7(),
|
|
212
|
+
meta: {
|
|
213
|
+
...component.secrets[descriptor.secretName].meta,
|
|
214
|
+
icon: component.secrets[descriptor.secretName].meta.icon ?? component.meta.icon,
|
|
215
|
+
},
|
|
216
|
+
descriptor,
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const rawDescriptor = formatSecretDescriptor(descriptor)
|
|
220
|
+
|
|
221
|
+
await this.stateManager.getSecretRepository(project.id).putItem(secret, batch)
|
|
222
|
+
await this.stateManager.getSecretContentRepository(project.id).put(rawDescriptor, null, batch)
|
|
223
|
+
|
|
224
|
+
await this.stateManager
|
|
225
|
+
.getSecretIndexRepository(project.id)
|
|
226
|
+
.indexRepository.put(rawDescriptor, secret.id, batch)
|
|
227
|
+
|
|
228
|
+
result[descriptor.secretName] = {
|
|
229
|
+
[HighstateSignature.Secret]: true,
|
|
230
|
+
id: secret.id,
|
|
231
|
+
value: null,
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
await batch.write()
|
|
236
|
+
|
|
237
|
+
return result
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
private async getInstanceSecretData(project: Project, instanceId: string) {
|
|
241
|
+
const library = await this.libraryBackend.loadLibrary(project.libraryId)
|
|
242
|
+
|
|
243
|
+
const [type] = parseInstanceId(instanceId)
|
|
244
|
+
const component = library.components[type]
|
|
245
|
+
if (!component) {
|
|
246
|
+
throw new Error(`Component type ${type} not found in library`)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (!isUnitModel(component)) {
|
|
250
|
+
throw new Error(`Component type ${type} is not a unit model`)
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const descriptors = Object.keys(component.secrets).map(secretName => ({
|
|
254
|
+
type: "instance" as const,
|
|
255
|
+
instanceId,
|
|
256
|
+
secretName,
|
|
257
|
+
}))
|
|
258
|
+
|
|
259
|
+
const indexKeys = descriptors.map(formatSecretDescriptor)
|
|
260
|
+
|
|
261
|
+
const secrets = await this.stateManager
|
|
262
|
+
.getSecretIndexRepository(project.id)
|
|
263
|
+
.getManyRecord(indexKeys)
|
|
264
|
+
|
|
265
|
+
const secretIds = Object.values(secrets)
|
|
266
|
+
.map(secret => secret?.id)
|
|
267
|
+
.filter(isNonNullish)
|
|
268
|
+
|
|
269
|
+
const secretContentMap = await this.stateManager
|
|
270
|
+
.getSecretContentRepository(project.id)
|
|
271
|
+
.getManyRecord(secretIds)
|
|
272
|
+
|
|
273
|
+
return {
|
|
274
|
+
indexKeys,
|
|
275
|
+
descriptors,
|
|
276
|
+
component,
|
|
277
|
+
secrets,
|
|
278
|
+
secretContentMap,
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|