@suss/manifest-aws 0.0.1 → 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/dist/index.cjs +161 -0
- package/dist/index.d.cts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +160 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ __export(index_exports, {
|
|
|
33
33
|
CLOUDFORMATION_YAML_TAGS: () => CLOUDFORMATION_YAML_TAGS,
|
|
34
34
|
loadCloudFormationTemplate: () => loadCloudFormationTemplate,
|
|
35
35
|
parseHandler: () => parseHandler,
|
|
36
|
+
readAppSyncResolvers: () => readAppSyncResolvers,
|
|
36
37
|
readServerlessFunctions: () => readServerlessFunctions,
|
|
37
38
|
refTarget: () => refTarget
|
|
38
39
|
});
|
|
@@ -100,6 +101,165 @@ function refTarget(value) {
|
|
|
100
101
|
return null;
|
|
101
102
|
}
|
|
102
103
|
|
|
104
|
+
// src/appsyncResolvers.ts
|
|
105
|
+
var LAMBDA_CATEGORIES = ["Lambda", "Lambdas"];
|
|
106
|
+
function readAppSyncResolvers(template) {
|
|
107
|
+
const resources = template.Resources ?? {};
|
|
108
|
+
return [
|
|
109
|
+
...fromServerlessShorthand(resources),
|
|
110
|
+
...fromRawResources(resources)
|
|
111
|
+
];
|
|
112
|
+
}
|
|
113
|
+
function fromServerlessShorthand(resources) {
|
|
114
|
+
const bindings = [];
|
|
115
|
+
for (const resource of Object.values(resources)) {
|
|
116
|
+
if (resource?.Type !== "AWS::Serverless::GraphQLApi") {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const props = asRecord(resource.Properties) ?? {};
|
|
120
|
+
const lambdaByDataSource = shorthandDataSources(props.DataSources);
|
|
121
|
+
const dataSourceByFunction = shorthandFunctions(props.Functions);
|
|
122
|
+
for (const [typeName, fields] of entriesOf(props.Resolvers)) {
|
|
123
|
+
for (const [fieldName, config] of entriesOf(fields)) {
|
|
124
|
+
const dataSources = dataSourcesReached(config, dataSourceByFunction);
|
|
125
|
+
bindings.push({
|
|
126
|
+
typeName,
|
|
127
|
+
fieldName,
|
|
128
|
+
lambdaFunctionLogicalIds: dataSources.map((name) => lambdaByDataSource.get(name) ?? null).filter((id) => id !== null)
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return bindings;
|
|
134
|
+
}
|
|
135
|
+
function shorthandDataSources(block) {
|
|
136
|
+
const out = /* @__PURE__ */ new Map();
|
|
137
|
+
for (const [category, entries] of entriesOf(block)) {
|
|
138
|
+
if (!LAMBDA_CATEGORIES.includes(category)) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
for (const [name, config] of entriesOf(entries)) {
|
|
142
|
+
const props = asRecord(config);
|
|
143
|
+
out.set(name, props === null ? null : refTarget(props.FunctionArn));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return out;
|
|
147
|
+
}
|
|
148
|
+
function shorthandFunctions(block) {
|
|
149
|
+
const out = /* @__PURE__ */ new Map();
|
|
150
|
+
for (const [name, config] of entriesOf(block)) {
|
|
151
|
+
const props = asRecord(config);
|
|
152
|
+
const dataSource = props === null ? null : stringOf(props.DataSource);
|
|
153
|
+
if (dataSource !== null) {
|
|
154
|
+
out.set(name, dataSource);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return out;
|
|
158
|
+
}
|
|
159
|
+
function dataSourcesReached(config, dataSourceByFunction) {
|
|
160
|
+
const props = asRecord(config);
|
|
161
|
+
if (props === null) {
|
|
162
|
+
return [];
|
|
163
|
+
}
|
|
164
|
+
const direct = stringOf(props.DataSource);
|
|
165
|
+
if (direct !== null) {
|
|
166
|
+
return [direct];
|
|
167
|
+
}
|
|
168
|
+
const pipeline = Array.isArray(props.Pipeline) ? props.Pipeline : [];
|
|
169
|
+
return pipeline.map((name) => dataSourceByFunction.get(String(name))).filter((name) => name !== void 0);
|
|
170
|
+
}
|
|
171
|
+
function fromRawResources(resources) {
|
|
172
|
+
const lambdaByLogicalId = /* @__PURE__ */ new Map();
|
|
173
|
+
const lambdaByApiAndName = /* @__PURE__ */ new Map();
|
|
174
|
+
for (const [logicalId, resource] of Object.entries(resources)) {
|
|
175
|
+
if (resource?.Type !== "AWS::AppSync::DataSource") {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
const props = asRecord(resource.Properties) ?? {};
|
|
179
|
+
const lambdaConfig = asRecord(props.LambdaConfig);
|
|
180
|
+
const lambda = lambdaConfig === null ? null : refTarget(lambdaConfig.LambdaFunctionArn);
|
|
181
|
+
if (lambda === null) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
lambdaByLogicalId.set(logicalId, lambda);
|
|
185
|
+
const name = stringOf(props.Name);
|
|
186
|
+
if (name !== null) {
|
|
187
|
+
lambdaByApiAndName.set(
|
|
188
|
+
apiScopedKey(refTarget(props.ApiId), name),
|
|
189
|
+
lambda
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const dataSourceByLogicalId = /* @__PURE__ */ new Map();
|
|
194
|
+
const dataSourceByApiAndName = /* @__PURE__ */ new Map();
|
|
195
|
+
for (const [logicalId, resource] of Object.entries(resources)) {
|
|
196
|
+
if (resource?.Type !== "AWS::AppSync::FunctionConfiguration") {
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
const props = asRecord(resource.Properties) ?? {};
|
|
200
|
+
const dataSource = refTarget(props.DataSourceName);
|
|
201
|
+
if (dataSource === null) {
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
dataSourceByLogicalId.set(logicalId, dataSource);
|
|
205
|
+
const name = stringOf(props.Name);
|
|
206
|
+
if (name !== null) {
|
|
207
|
+
dataSourceByApiAndName.set(
|
|
208
|
+
apiScopedKey(refTarget(props.ApiId), name),
|
|
209
|
+
dataSource
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
const bindings = [];
|
|
214
|
+
for (const resource of Object.values(resources)) {
|
|
215
|
+
if (resource?.Type !== "AWS::AppSync::Resolver") {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
const props = asRecord(resource.Properties) ?? {};
|
|
219
|
+
const typeName = stringOf(props.TypeName);
|
|
220
|
+
const fieldName = stringOf(props.FieldName);
|
|
221
|
+
if (typeName === null || fieldName === null) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const apiId = refTarget(props.ApiId);
|
|
225
|
+
const lookup = (byLogicalId, byName) => (reference) => byLogicalId.get(reference) ?? byName.get(apiScopedKey(apiId, reference));
|
|
226
|
+
bindings.push({
|
|
227
|
+
typeName,
|
|
228
|
+
fieldName,
|
|
229
|
+
lambdaFunctionLogicalIds: rawDataSourcesReached(
|
|
230
|
+
props,
|
|
231
|
+
lookup(dataSourceByLogicalId, dataSourceByApiAndName)
|
|
232
|
+
).map(lookup(lambdaByLogicalId, lambdaByApiAndName)).filter((id) => id !== void 0)
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
return bindings;
|
|
236
|
+
}
|
|
237
|
+
function apiScopedKey(apiId, name) {
|
|
238
|
+
return `${apiId ?? ""}::${name}`;
|
|
239
|
+
}
|
|
240
|
+
function rawDataSourcesReached(props, dataSourceOf) {
|
|
241
|
+
const direct = refTarget(props.DataSourceName);
|
|
242
|
+
if (direct !== null) {
|
|
243
|
+
return [direct];
|
|
244
|
+
}
|
|
245
|
+
const pipeline = asRecord(props.PipelineConfig);
|
|
246
|
+
const functions = Array.isArray(pipeline?.Functions) ? pipeline.Functions : [];
|
|
247
|
+
return functions.map((fn) => {
|
|
248
|
+
const reference = refTarget(fn);
|
|
249
|
+
return reference === null ? void 0 : dataSourceOf(reference);
|
|
250
|
+
}).filter((name) => name !== void 0);
|
|
251
|
+
}
|
|
252
|
+
function asRecord(value) {
|
|
253
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
254
|
+
}
|
|
255
|
+
function entriesOf(value) {
|
|
256
|
+
const record = asRecord(value);
|
|
257
|
+
return record === null ? [] : Object.entries(record);
|
|
258
|
+
}
|
|
259
|
+
function stringOf(value) {
|
|
260
|
+
return typeof value === "string" ? value : null;
|
|
261
|
+
}
|
|
262
|
+
|
|
103
263
|
// src/serverlessFunctions.ts
|
|
104
264
|
function parseHandler(handler) {
|
|
105
265
|
const trimmed = handler.trim();
|
|
@@ -201,6 +361,7 @@ function readServerlessFunctions(template) {
|
|
|
201
361
|
CLOUDFORMATION_YAML_TAGS,
|
|
202
362
|
loadCloudFormationTemplate,
|
|
203
363
|
parseHandler,
|
|
364
|
+
readAppSyncResolvers,
|
|
204
365
|
readServerlessFunctions,
|
|
205
366
|
refTarget
|
|
206
367
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -44,6 +44,24 @@ declare function loadCloudFormationTemplate(templatePath: string): CloudFormatio
|
|
|
44
44
|
*/
|
|
45
45
|
declare function refTarget(value: unknown): string | null;
|
|
46
46
|
|
|
47
|
+
/** One GraphQL field and the Lambdas behind it. */
|
|
48
|
+
interface AppSyncResolverBinding {
|
|
49
|
+
typeName: string;
|
|
50
|
+
fieldName: string;
|
|
51
|
+
/**
|
|
52
|
+
* Every Lambda a request for this field runs, in pipeline order.
|
|
53
|
+
* Usually one. A pipeline can chain several, and nothing in the
|
|
54
|
+
* template says which of them is the one that produces the value:
|
|
55
|
+
* the first is as often an auth step as it is the resolver, and the
|
|
56
|
+
* last is as often a formatter. So all of them are reported, and a
|
|
57
|
+
* reader that needs to pick says so itself.
|
|
58
|
+
*
|
|
59
|
+
* Empty when the field is served by something other than a Lambda.
|
|
60
|
+
*/
|
|
61
|
+
lambdaFunctionLogicalIds: string[];
|
|
62
|
+
}
|
|
63
|
+
declare function readAppSyncResolvers(template: CloudFormationTemplate): AppSyncResolverBinding[];
|
|
64
|
+
|
|
47
65
|
/** A route-bearing SAM Event (`Type: Api` or `Type: HttpApi`). */
|
|
48
66
|
interface ServerlessHttpRoute {
|
|
49
67
|
/** Key of the event in the function's `Events` map. */
|
|
@@ -104,4 +122,4 @@ declare function parseHandler(handler: string): ParsedHandler | null;
|
|
|
104
122
|
*/
|
|
105
123
|
declare function readServerlessFunctions(template: CloudFormationTemplate): ServerlessFunctionInfo[];
|
|
106
124
|
|
|
107
|
-
export { CLOUDFORMATION_YAML_TAGS, type CloudFormationResource, type CloudFormationTemplate, type ParsedHandler, type ServerlessFunctionInfo, type ServerlessHttpRoute, type ServerlessNonHttpEvent, loadCloudFormationTemplate, parseHandler, readServerlessFunctions, refTarget };
|
|
125
|
+
export { type AppSyncResolverBinding, CLOUDFORMATION_YAML_TAGS, type CloudFormationResource, type CloudFormationTemplate, type ParsedHandler, type ServerlessFunctionInfo, type ServerlessHttpRoute, type ServerlessNonHttpEvent, loadCloudFormationTemplate, parseHandler, readAppSyncResolvers, readServerlessFunctions, refTarget };
|
package/dist/index.d.ts
CHANGED
|
@@ -44,6 +44,24 @@ declare function loadCloudFormationTemplate(templatePath: string): CloudFormatio
|
|
|
44
44
|
*/
|
|
45
45
|
declare function refTarget(value: unknown): string | null;
|
|
46
46
|
|
|
47
|
+
/** One GraphQL field and the Lambdas behind it. */
|
|
48
|
+
interface AppSyncResolverBinding {
|
|
49
|
+
typeName: string;
|
|
50
|
+
fieldName: string;
|
|
51
|
+
/**
|
|
52
|
+
* Every Lambda a request for this field runs, in pipeline order.
|
|
53
|
+
* Usually one. A pipeline can chain several, and nothing in the
|
|
54
|
+
* template says which of them is the one that produces the value:
|
|
55
|
+
* the first is as often an auth step as it is the resolver, and the
|
|
56
|
+
* last is as often a formatter. So all of them are reported, and a
|
|
57
|
+
* reader that needs to pick says so itself.
|
|
58
|
+
*
|
|
59
|
+
* Empty when the field is served by something other than a Lambda.
|
|
60
|
+
*/
|
|
61
|
+
lambdaFunctionLogicalIds: string[];
|
|
62
|
+
}
|
|
63
|
+
declare function readAppSyncResolvers(template: CloudFormationTemplate): AppSyncResolverBinding[];
|
|
64
|
+
|
|
47
65
|
/** A route-bearing SAM Event (`Type: Api` or `Type: HttpApi`). */
|
|
48
66
|
interface ServerlessHttpRoute {
|
|
49
67
|
/** Key of the event in the function's `Events` map. */
|
|
@@ -104,4 +122,4 @@ declare function parseHandler(handler: string): ParsedHandler | null;
|
|
|
104
122
|
*/
|
|
105
123
|
declare function readServerlessFunctions(template: CloudFormationTemplate): ServerlessFunctionInfo[];
|
|
106
124
|
|
|
107
|
-
export { CLOUDFORMATION_YAML_TAGS, type CloudFormationResource, type CloudFormationTemplate, type ParsedHandler, type ServerlessFunctionInfo, type ServerlessHttpRoute, type ServerlessNonHttpEvent, loadCloudFormationTemplate, parseHandler, readServerlessFunctions, refTarget };
|
|
125
|
+
export { type AppSyncResolverBinding, CLOUDFORMATION_YAML_TAGS, type CloudFormationResource, type CloudFormationTemplate, type ParsedHandler, type ServerlessFunctionInfo, type ServerlessHttpRoute, type ServerlessNonHttpEvent, loadCloudFormationTemplate, parseHandler, readAppSyncResolvers, readServerlessFunctions, refTarget };
|
package/dist/index.js
CHANGED
|
@@ -60,6 +60,165 @@ function refTarget(value) {
|
|
|
60
60
|
return null;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
// src/appsyncResolvers.ts
|
|
64
|
+
var LAMBDA_CATEGORIES = ["Lambda", "Lambdas"];
|
|
65
|
+
function readAppSyncResolvers(template) {
|
|
66
|
+
const resources = template.Resources ?? {};
|
|
67
|
+
return [
|
|
68
|
+
...fromServerlessShorthand(resources),
|
|
69
|
+
...fromRawResources(resources)
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
function fromServerlessShorthand(resources) {
|
|
73
|
+
const bindings = [];
|
|
74
|
+
for (const resource of Object.values(resources)) {
|
|
75
|
+
if (resource?.Type !== "AWS::Serverless::GraphQLApi") {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const props = asRecord(resource.Properties) ?? {};
|
|
79
|
+
const lambdaByDataSource = shorthandDataSources(props.DataSources);
|
|
80
|
+
const dataSourceByFunction = shorthandFunctions(props.Functions);
|
|
81
|
+
for (const [typeName, fields] of entriesOf(props.Resolvers)) {
|
|
82
|
+
for (const [fieldName, config] of entriesOf(fields)) {
|
|
83
|
+
const dataSources = dataSourcesReached(config, dataSourceByFunction);
|
|
84
|
+
bindings.push({
|
|
85
|
+
typeName,
|
|
86
|
+
fieldName,
|
|
87
|
+
lambdaFunctionLogicalIds: dataSources.map((name) => lambdaByDataSource.get(name) ?? null).filter((id) => id !== null)
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return bindings;
|
|
93
|
+
}
|
|
94
|
+
function shorthandDataSources(block) {
|
|
95
|
+
const out = /* @__PURE__ */ new Map();
|
|
96
|
+
for (const [category, entries] of entriesOf(block)) {
|
|
97
|
+
if (!LAMBDA_CATEGORIES.includes(category)) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
for (const [name, config] of entriesOf(entries)) {
|
|
101
|
+
const props = asRecord(config);
|
|
102
|
+
out.set(name, props === null ? null : refTarget(props.FunctionArn));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return out;
|
|
106
|
+
}
|
|
107
|
+
function shorthandFunctions(block) {
|
|
108
|
+
const out = /* @__PURE__ */ new Map();
|
|
109
|
+
for (const [name, config] of entriesOf(block)) {
|
|
110
|
+
const props = asRecord(config);
|
|
111
|
+
const dataSource = props === null ? null : stringOf(props.DataSource);
|
|
112
|
+
if (dataSource !== null) {
|
|
113
|
+
out.set(name, dataSource);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return out;
|
|
117
|
+
}
|
|
118
|
+
function dataSourcesReached(config, dataSourceByFunction) {
|
|
119
|
+
const props = asRecord(config);
|
|
120
|
+
if (props === null) {
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
const direct = stringOf(props.DataSource);
|
|
124
|
+
if (direct !== null) {
|
|
125
|
+
return [direct];
|
|
126
|
+
}
|
|
127
|
+
const pipeline = Array.isArray(props.Pipeline) ? props.Pipeline : [];
|
|
128
|
+
return pipeline.map((name) => dataSourceByFunction.get(String(name))).filter((name) => name !== void 0);
|
|
129
|
+
}
|
|
130
|
+
function fromRawResources(resources) {
|
|
131
|
+
const lambdaByLogicalId = /* @__PURE__ */ new Map();
|
|
132
|
+
const lambdaByApiAndName = /* @__PURE__ */ new Map();
|
|
133
|
+
for (const [logicalId, resource] of Object.entries(resources)) {
|
|
134
|
+
if (resource?.Type !== "AWS::AppSync::DataSource") {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const props = asRecord(resource.Properties) ?? {};
|
|
138
|
+
const lambdaConfig = asRecord(props.LambdaConfig);
|
|
139
|
+
const lambda = lambdaConfig === null ? null : refTarget(lambdaConfig.LambdaFunctionArn);
|
|
140
|
+
if (lambda === null) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
lambdaByLogicalId.set(logicalId, lambda);
|
|
144
|
+
const name = stringOf(props.Name);
|
|
145
|
+
if (name !== null) {
|
|
146
|
+
lambdaByApiAndName.set(
|
|
147
|
+
apiScopedKey(refTarget(props.ApiId), name),
|
|
148
|
+
lambda
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const dataSourceByLogicalId = /* @__PURE__ */ new Map();
|
|
153
|
+
const dataSourceByApiAndName = /* @__PURE__ */ new Map();
|
|
154
|
+
for (const [logicalId, resource] of Object.entries(resources)) {
|
|
155
|
+
if (resource?.Type !== "AWS::AppSync::FunctionConfiguration") {
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
const props = asRecord(resource.Properties) ?? {};
|
|
159
|
+
const dataSource = refTarget(props.DataSourceName);
|
|
160
|
+
if (dataSource === null) {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
dataSourceByLogicalId.set(logicalId, dataSource);
|
|
164
|
+
const name = stringOf(props.Name);
|
|
165
|
+
if (name !== null) {
|
|
166
|
+
dataSourceByApiAndName.set(
|
|
167
|
+
apiScopedKey(refTarget(props.ApiId), name),
|
|
168
|
+
dataSource
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const bindings = [];
|
|
173
|
+
for (const resource of Object.values(resources)) {
|
|
174
|
+
if (resource?.Type !== "AWS::AppSync::Resolver") {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
const props = asRecord(resource.Properties) ?? {};
|
|
178
|
+
const typeName = stringOf(props.TypeName);
|
|
179
|
+
const fieldName = stringOf(props.FieldName);
|
|
180
|
+
if (typeName === null || fieldName === null) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const apiId = refTarget(props.ApiId);
|
|
184
|
+
const lookup = (byLogicalId, byName) => (reference) => byLogicalId.get(reference) ?? byName.get(apiScopedKey(apiId, reference));
|
|
185
|
+
bindings.push({
|
|
186
|
+
typeName,
|
|
187
|
+
fieldName,
|
|
188
|
+
lambdaFunctionLogicalIds: rawDataSourcesReached(
|
|
189
|
+
props,
|
|
190
|
+
lookup(dataSourceByLogicalId, dataSourceByApiAndName)
|
|
191
|
+
).map(lookup(lambdaByLogicalId, lambdaByApiAndName)).filter((id) => id !== void 0)
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
return bindings;
|
|
195
|
+
}
|
|
196
|
+
function apiScopedKey(apiId, name) {
|
|
197
|
+
return `${apiId ?? ""}::${name}`;
|
|
198
|
+
}
|
|
199
|
+
function rawDataSourcesReached(props, dataSourceOf) {
|
|
200
|
+
const direct = refTarget(props.DataSourceName);
|
|
201
|
+
if (direct !== null) {
|
|
202
|
+
return [direct];
|
|
203
|
+
}
|
|
204
|
+
const pipeline = asRecord(props.PipelineConfig);
|
|
205
|
+
const functions = Array.isArray(pipeline?.Functions) ? pipeline.Functions : [];
|
|
206
|
+
return functions.map((fn) => {
|
|
207
|
+
const reference = refTarget(fn);
|
|
208
|
+
return reference === null ? void 0 : dataSourceOf(reference);
|
|
209
|
+
}).filter((name) => name !== void 0);
|
|
210
|
+
}
|
|
211
|
+
function asRecord(value) {
|
|
212
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
213
|
+
}
|
|
214
|
+
function entriesOf(value) {
|
|
215
|
+
const record = asRecord(value);
|
|
216
|
+
return record === null ? [] : Object.entries(record);
|
|
217
|
+
}
|
|
218
|
+
function stringOf(value) {
|
|
219
|
+
return typeof value === "string" ? value : null;
|
|
220
|
+
}
|
|
221
|
+
|
|
63
222
|
// src/serverlessFunctions.ts
|
|
64
223
|
function parseHandler(handler) {
|
|
65
224
|
const trimmed = handler.trim();
|
|
@@ -160,6 +319,7 @@ export {
|
|
|
160
319
|
CLOUDFORMATION_YAML_TAGS,
|
|
161
320
|
loadCloudFormationTemplate,
|
|
162
321
|
parseHandler,
|
|
322
|
+
readAppSyncResolvers,
|
|
163
323
|
readServerlessFunctions,
|
|
164
324
|
refTarget
|
|
165
325
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/manifest-aws",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Parse AWS CloudFormation / SAM templates into plain data — the shared facts layer contract readers and manifest-driven framework packs both consume.",
|
|
6
6
|
"keywords": [
|