-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathdeserialize.ts
122 lines (116 loc) · 4.83 KB
/
deserialize.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright 2016-2019, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { asset } from "@pulumi/pulumi";
import {
specialArchiveSig,
specialAssetSig,
specialSecretSig,
specialSigKey,
} from "@pulumi/pulumi/runtime/rpc";
/**
* deserializeProperties fetches the raw outputs and deserializes them from a gRPC call result.
* @internal
*/
export function deserializeProperties(outputsStruct: any): any {
const props: any = {};
const outputs: any = outputsStruct.toJavaScript();
for (const k of Object.keys(outputs)) {
// We treat properties with undefined values as if they do not exist.
if (outputs[k] !== undefined) {
props[k] = deserializeProperty(outputs[k]);
}
}
return props;
}
/**
* deserializeProperty is partly based on, but not functionally or superficially identical to, the
* deserialization code in `@pulumi/pulumi/runtime/rpc.ts`.
*
* Specifically, we explicitly do not want to be compatible with Output<T>. Policies interact with
* raw JSON representations of resource definitions, so things like secrets must be "fully unpacked"
* into plain-old-JSON that the policies can interact with as normal data. If things like secrets
* are not unpacked, every field in every resource type would have to be type `T | Secret<T>`, which
* would severely detract from usability.
*/
function deserializeProperty(prop: any): any {
if (prop === undefined) {
throw new Error("unexpected undefined property value during deserialization");
} else if (
prop === null ||
typeof prop === "boolean" ||
typeof prop === "number" ||
typeof prop === "string"
) {
return prop;
} else if (prop instanceof Array) {
const elems: any[] = [];
for (const e of prop) {
elems.push(deserializeProperty(e));
}
return elems;
} else {
// We need to recognize assets and archives specially, so we can produce the right runtime
// objects.
const sig: any = prop[specialSigKey];
if (sig) {
switch (sig) {
case specialAssetSig:
if (prop["path"]) {
return new asset.FileAsset(<string>prop["path"]);
} else if (prop["text"]) {
return new asset.StringAsset(<string>prop["text"]);
} else if (prop["uri"]) {
return new asset.RemoteAsset(<string>prop["uri"]);
} else {
throw new Error(
"Invalid asset encountered when unmarshaling resource property",
);
}
case specialArchiveSig:
if (prop["assets"]) {
const assets: asset.AssetMap = {};
for (const name of Object.keys(prop["assets"])) {
const a = deserializeProperty(prop["assets"][name]);
if (!asset.Asset.isInstance(a) && !asset.Archive.isInstance(a)) {
throw new Error(
"Expected an AssetArchive's assets to be unmarshaled Asset or Archive objects",
);
}
assets[name] = a;
}
return new asset.AssetArchive(assets);
} else if (prop["path"]) {
return new asset.FileArchive(<string>prop["path"]);
} else if (prop["uri"]) {
return new asset.RemoteArchive(<string>prop["uri"]);
} else {
throw new Error(
"Invalid archive encountered when unmarshaling resource property",
);
}
case specialSecretSig:
return deserializeProperty(prop["value"]);
default:
throw new Error(
`Unrecognized signature '${sig}' when unmarshaling resource property`,
);
}
}
const obj: any = {};
for (const k of Object.keys(prop)) {
obj[k] = deserializeProperty(prop[k]);
}
return obj;
}
}