Skip to content

Commit

Permalink
Add suport to JSON/JSONB types and queries
Browse files Browse the repository at this point in the history
  • Loading branch information
stvkoch committed Feb 18, 2021
1 parent 8a39659 commit 3154a1b
Show file tree
Hide file tree
Showing 15 changed files with 11,705 additions and 330 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,4 @@ typings/

# DynamoDB Local files
.dynamodb/
database.sqlite
*.sqlite
25 changes: 23 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ You define your models and everything it's available!
git clone https://github.com/stvkoch/graphqlize.git
cd graphqlize
npm install# or npm
npm run example # or npm
npm start # or npm
# open url http://localhost:4000/graphql
# can access complete generate schema in http://localhost:4000
```
Expand Down Expand Up @@ -98,6 +98,17 @@ schema> https://graphqlize.herokuapp.com/
name
price
}
# query over JSONB structures
overJsonb: services(where: { meta: { path: "meta.baz.foo", where: { eq: "baz" } } }) {
id
meta
countryId
country {
id
name
}
}
}
```

Expand Down Expand Up @@ -184,7 +195,11 @@ export default (sequelize, DataTypes) => {
autoIncrement: true
},
name: DataTypes.STRING,
price: DataTypes.DECIMAL(10, 2)
price: DataTypes.DECIMAL(10, 2),
meta: {
type: DataTypes.JSONB,
allowNull: false
}
},
{
freezeTableName: true
Expand Down Expand Up @@ -352,6 +367,10 @@ strictLeft
strictRight
```

JSONB type support same operators found into String

in JSON type you can't query looking into the JSON struture, JSON as storage as String/Text, so you can use String operators

## Inputs Create and Update

To able to mutate your data you will need to hold your data inside of the input mutation type. Graphqlizejs will generate the \_inputCreate and \_inputUpdate for each model and _through_ models.
Expand Down Expand Up @@ -497,3 +516,5 @@ export default (sequelize, DataTypes) => {
## Complete example

https://github.com/stvkoch/example-graphqlizejs


4 changes: 4 additions & 0 deletions example/models/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export default (sequelize, DataTypes) => {
price: {
type: DataTypes.DECIMAL(10, 2),
allowNull: false
},
meta: {
type: DataTypes.JSONB,
allowNull: true
}
},
{
Expand Down
46 changes: 31 additions & 15 deletions lib/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ var _sequelize = _interopRequireDefault(require("sequelize"));

var _apolloServer = require("apollo-server");

var _graphqlTypeJson = _interopRequireWildcard(require("graphql-type-json"));

function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
Expand Down Expand Up @@ -65,6 +71,8 @@ function resolvers(sequelize, pubsub) {
};

var additionalResolvers = _objectSpread({
JSON: _graphqlTypeJson["default"],
JSONB: _graphqlTypeJson.GraphQLJSONObject,
Date: GraphQLDate,
Time: GraphQLTime,
DateTime: GraphQLDateTime,
Expand Down Expand Up @@ -413,21 +421,6 @@ function generateFindArgs(sequelize, args) {
order = rawWhere._orderBy,
whereArgs = _objectWithoutProperties(rawWhere, ["_group", "_limit", "_offset", "_orderBy"]);

function keyToOp(key) {
return _sequelize["default"].Op[key] || key;
}

function convertKeyToOperator(values) {
if (!Array.isArray(values) && _typeof(values) === 'object') {
return Object.keys(values).reduce(function (result, key) {
result[keyToOp(key)] = convertKeyToOperator(values[key]);
return result;
}, {});
}

return values;
}

var where = convertKeyToOperator(whereArgs);
return {
order: order,
Expand All @@ -436,4 +429,27 @@ function generateFindArgs(sequelize, args) {
group: group,
where: where
};
}

function keyToOp(key) {
return _sequelize["default"].Op[key] || key;
}

function convertKeyToOperator(values) {
if (!Array.isArray(values) && _typeof(values) === 'object') {
return Object.keys(values).reduce(function (result, key) {
if (values[key].path) {
var _values$key = values[key],
path = _values$key.path,
where = _values$key.where;
result[path] = convertKeyToOperator(where);
return result;
}

result[keyToOp(key)] = convertKeyToOperator(values[key]);
return result;
}, {});
}

return values;
}
22 changes: 16 additions & 6 deletions lib/schemas.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Create your dataTypes from your models
function schema(sequelize) {
var extend = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
assertNotEmpty(sequelize, "schema function should receive a sequelize instance, received ".concat(_typeof(sequelize)));
return ["\n scalar Date\n scalar Time\n scalar DateTime\n ", generateInputOperators(sequelize), generateInputWhere(sequelize), generateInputCreate(sequelize), generateInputUpdate(sequelize), generateTypeModels(sequelize), generateQueries(sequelize), generateMutations(sequelize), generateSubscriptions(sequelize), extend].join('\n');
return ["\n scalar Date\n scalar Time\n scalar DateTime\n scalar JSON\n scalar JSONB\n ", generateInputOperators(sequelize), generateInputWhere(sequelize), generateInputCreate(sequelize), generateInputUpdate(sequelize), generateTypeModels(sequelize), generateQueries(sequelize), generateMutations(sequelize), generateSubscriptions(sequelize), extend].join('\n');
}

function getModelName(model) {
Expand All @@ -59,15 +59,22 @@ function generateInputOperators(sequelize) {
});
return acc;
}, {});
return Object.values(modelsTypes).map(function (gqType) {
return "input _input".concat(gqType, "Operator {\n ").concat(Object.keys(_operators.operatorsAny).map(function (op) {

var conditionsToString = function conditionsToString(gqType) {
return "\n ".concat(Object.keys(_operators.operatorsAny).map(function (op) {
if (_operators.operatorsAny[op] === null) return "".concat(op, ": ").concat(gqType);
return "".concat(op, ": [").concat(gqType, "]");
}).join('\n'), "\n ").concat(gqType === 'String' ? Object.keys(_operators.operatorsString).map(function (op) {
if (_operators.operatorsString[op] === null) return "".concat(op, ": ").concat(gqType);
return "".concat(op, ": [").concat(gqType, "]");
}).join('\n') : '', "\n }");
}).join('\n');
}).join('\n') : '', "\n ");
};

return Object.values(modelsTypes).filter(function (gqType) {
return !['JSON', 'JSONB'].includes(gqType);
}).map(function (gqType) {
return "input _input".concat(gqType, "Operator {\n ").concat(conditionsToString(gqType), "\n }");
}).join('\n').concat("\n input _inputJSONBOperator {\n path: String,\n where: _inputStringOperator\n }\n ").concat("\n input _inputJSONOperator {\n ".concat(conditionsToString('String'), "\n }\n "));
}

function generateInputWhere(sequelize) {
Expand All @@ -84,7 +91,10 @@ function generateInputWhere(sequelize) {

if (attribute.primaryKey) {
type = 'ID';
}
} // if (type === 'JSON' || type === 'JSONB') {
// acc[modelName][attribute.field] = inputOperatorName;
// }


var inputOperatorName = "_input".concat(type, "Operator");
acc[modelName][attribute.field] = inputOperatorName;
Expand Down
2 changes: 2 additions & 0 deletions lib/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ var mapSequelizeToGraphql = {
DECIMAL: 'Float',
BOOLEAN: 'Boolean',
VIRTUAL: 'String',
JSON: 'JSON',
JSONB: 'JSONB',
DEFAULT_TYPE: 'String'
};
exports.mapSequelizeToGraphql = mapSequelizeToGraphql;
Expand Down
Loading

0 comments on commit 3154a1b

Please sign in to comment.