Skip to content

Commit 3c6bc92

Browse files
committed
refactoring pt 1
1 parent 5b597b5 commit 3c6bc92

6 files changed

+5970
-332
lines changed

index.js

+42-100
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,72 @@
11
const AWS = require("aws-sdk");
22
const schemas = new AWS.Schemas();
33
const inputUtil = require("./input-util");
4+
const patternBuilder = require("./pattern-builder");
45
const inquirer = require("inquirer");
5-
const prompt = inquirer.createPromptModule();
6-
run();
7-
async function run() {
8-
const registriesResponse = await schemas.listRegistries().promise();
9-
const registries = [
10-
...new Set(registriesResponse.Registries.map(p => p.RegistryName))
11-
];
126

13-
const registry = await prompt({
14-
name: "id",
15-
type: "list",
16-
message: "Select registry",
17-
choices: registries
18-
});
19-
const registryName = registry.id;
20-
const result = await schemas
21-
.listSchemas({ RegistryName: registryName })
7+
async function run() {
8+
const registry = await inputUtil.getRegistry(schemas);
9+
const schemaResponse = await schemas
10+
.listSchemas({ RegistryName: registry.id })
2211
.promise();
23-
const sources = [
24-
...new Set(result.Schemas.map(p => p.SchemaName.split("@")[0]))
25-
];
26-
const source = await prompt({
27-
name: "id",
28-
type: "list",
29-
message: "Select source",
30-
choices: sources
31-
});
32-
const detailTypes = result.Schemas.filter(p =>
33-
p.SchemaName.startsWith(`${source.id}@`)
34-
).map(p => p.SchemaName.split("@")[1]);
3512

36-
const detailType = await prompt({
37-
name: "id",
38-
type: "list",
39-
message: "Select source",
40-
choices: detailTypes
41-
});
13+
const sourceName = await inputUtil.getSourceName(schemaResponse);
14+
const detailTypeName = await inputUtil.getDetailTypeName(
15+
schemaResponse,
16+
sourceName
17+
);
18+
const schemaName = `${sourceName}@${detailTypeName}`;
4219

43-
const schemaName = `${source.id}@${detailType.id}`;
4420
const describeSchemaResponse = await schemas
45-
.describeSchema({ RegistryName: registryName, SchemaName: schemaName })
21+
.describeSchema({ RegistryName: registry.id, SchemaName: schemaName })
4622
.promise();
23+
4724
const schema = JSON.parse(describeSchemaResponse.Content);
48-
let pattern = { source: [source.id], "detail-type": [detailType.id] };
25+
26+
let pattern = patternBuilder.init(sourceName, detailTypeName);
4927

5028
let currentObject = schema.components.schemas.AWSEvent;
51-
let pathArray = undefined;
29+
5230
let objectArray = [];
5331
while (true) {
54-
let fieldList = Object.keys(currentObject.properties);
32+
const { property, chosenProp } = await inputUtil.getProperty(
33+
currentObject,
34+
objectArray
35+
);
5536

56-
const field = await prompt({
57-
name: "id",
58-
type: "list",
59-
message: `Add ${currentObject} item`,
60-
choices: fieldList
61-
});
62-
objectArray.push(field.id);
63-
const chosenProp = currentObject.properties[field.id];
6437
const path = chosenProp.$ref;
6538
if (path) {
66-
pathArray = path && path.split("/");
67-
pathArray.shift();
68-
let current = schema;
69-
for (var node of pathArray) {
70-
current = current[node];
71-
}
72-
currentObject = current;
39+
// If property points at reference, go to reference in schema and continue
40+
currentObject = findCurrent(path, schema);
7341
continue;
7442
}
7543

76-
let answer = undefined;
77-
switch (chosenProp.type) {
78-
case "string":
79-
answer = await inputUtil.string(field.id);
80-
break;
81-
default:
82-
answer = await inputUtil.string(field.id);
83-
}
84-
let x = {};
85-
let current = answer;
86-
for (let i = objectArray.length - 2; i >= 0; i--) {
87-
const newObj = {};
88-
newObj[objectArray[i]] = current;
89-
x[objectArray[i]] = newObj;
90-
current = x[objectArray[i]];
91-
}
44+
let answer = await inputUtil.getPropertyValue(chosenProp, property);
45+
46+
let current = patternBuilder.getPatternSegment(answer, objectArray);
47+
48+
pattern = patternBuilder.deepMerge(pattern, current);
49+
outputPattern();
9250

93-
pattern = mergeDeep(pattern, current);
94-
console.log("Generated pattern:");
95-
console.log(JSON.stringify(pattern, null, 2));
96-
pathArray = [];
9751
objectArray = [];
98-
9952
currentObject = schema.components.schemas.AWSEvent;
10053
}
101-
}
102-
103-
10454

105-
function isObject(item) {
106-
return item && typeof item === "object" && !Array.isArray(item);
55+
function outputPattern() {
56+
console.log("Generated pattern:");
57+
console.log(JSON.stringify(pattern, null, 2));
58+
console.log("Press ctrl+c to quit");
59+
}
10760
}
10861

109-
/**
110-
* Deep merge two objects.
111-
* @param target
112-
* @param ...sources
113-
*/
114-
function mergeDeep(target, ...sources) {
115-
if (!sources.length) return target;
116-
const source = sources.shift();
117-
118-
if (isObject(target) && isObject(source)) {
119-
for (const key in source) {
120-
if (isObject(source[key])) {
121-
if (!target[key]) Object.assign(target, { [key]: {} });
122-
mergeDeep(target[key], source[key]);
123-
} else {
124-
Object.assign(target, { [key]: source[key] });
125-
}
126-
}
62+
function findCurrent(path, schema) {
63+
const pathArray = path.split("/");
64+
pathArray.shift(); // Remove leading #
65+
let current = schema;
66+
for (var node of pathArray) {
67+
current = current[node];
12768
}
128-
129-
return mergeDeep(target, ...sources);
69+
return current;
13070
}
71+
72+
run();

input-util.js

+104-3
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,28 @@ const filterRules = [
99
"null"
1010
];
1111

12-
async function string(fieldName) {
12+
const numericOperands = [
13+
">",
14+
"<",
15+
"=",
16+
">=",
17+
"<=",
18+
"!="
19+
]
20+
21+
async function getStringValue(fieldName, type) {
22+
console.log(type);
23+
const rules = JSON.parse(JSON.stringify(filterRules));
24+
if (type !== "number") {
25+
rules.splice( rules.indexOf('numeric'), 1 );
26+
}
1327
const rule = await prompt({
1428
name: "id",
1529
type: "list",
1630
message: `Enter rule for ${fieldName} matching`,
17-
choices: filterRules
31+
choices: rules
1832
});
33+
1934
let val = undefined;
2035
if (rule.id !== "exists") {
2136
const value = await prompt({
@@ -30,6 +45,16 @@ async function string(fieldName) {
3045
val = true;
3146
}
3247
let returnObj = {};
48+
if (rule.id === "numeric") {
49+
const operand = await prompt({
50+
name: "id",
51+
type: "list",
52+
message: `Select operand`,
53+
choices: numericOperands
54+
});
55+
val = [operand.id, val];
56+
console.log(val);
57+
}
3358
let ruleObj = rule.id === "equals" ? val : undefined;
3459
if (!ruleObj) {
3560
ruleObj = {};
@@ -45,6 +70,82 @@ async function string(fieldName) {
4570
return returnObj;
4671
}
4772

73+
async function getProperty(currentObject, objectArray) {
74+
let fieldList = Object.keys(currentObject.properties);
75+
const property = await prompt({
76+
name: "id",
77+
type: "list",
78+
message: `Add ${objectArray[objectArray.length - 1] ||
79+
currentObject["x-amazon-events-detail-type"]} item`,
80+
choices: fieldList
81+
});
82+
objectArray.push(property.id);
83+
const chosenProp = currentObject.properties[property.id];
84+
85+
return { property, chosenProp };
86+
}
87+
88+
async function getDetailTypeName(schemas, sourceName) {
89+
const detailTypes = schemas.Schemas.filter(p =>
90+
p.SchemaName.startsWith(`${sourceName}@`)
91+
).map(p => p.SchemaName.split("@")[1]);
92+
const detailType = await prompt({
93+
name: "id",
94+
type: "list",
95+
message: "Select source",
96+
choices: detailTypes
97+
});
98+
const detailTypeName = detailType.id;
99+
return detailTypeName;
100+
}
101+
102+
async function getSourceName(schemas) {
103+
const sources = [
104+
...new Set(schemas.Schemas.map(p => p.SchemaName.split("@")[0]))
105+
];
106+
const source = await prompt({
107+
name: "id",
108+
type: "list",
109+
message: "Select source",
110+
choices: sources
111+
});
112+
const sourceName = source.id;
113+
return sourceName;
114+
}
115+
116+
async function selectRegistry(schemas) {
117+
const registriesResponse = await schemas.listRegistries().promise();
118+
const registries = [
119+
...new Set(registriesResponse.Registries.map(p => p.RegistryName))
120+
];
121+
const registry = await prompt({
122+
name: "id",
123+
type: "list",
124+
message: "Select registry",
125+
choices: registries
126+
});
127+
return registry;
128+
}
129+
130+
async function getPropertyValue(chosenProp, property) {
131+
let answer = undefined;
132+
switch (chosenProp.type) {
133+
case "string":
134+
answer = await getStringValue(property.id, chosenProp.type);
135+
break;
136+
// placeholder for dateselector, etc
137+
default:
138+
answer = await getStringValue(property.id, chosenProp.type);
139+
}
140+
return answer;
141+
}
142+
143+
48144
module.exports = {
49-
string
145+
string: getStringValue,
146+
getRegistry: selectRegistry,
147+
getSourceName,
148+
getDetailTypeName,
149+
getProperty,
150+
getPropertyValue,
50151
};

0 commit comments

Comments
 (0)