123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.ParseGraphQLSchema = void 0;
- var _node = _interopRequireDefault(require("parse/node"));
- var _graphql = require("graphql");
- var _schema = require("@graphql-tools/schema");
- var _merge = require("@graphql-tools/merge");
- var _util = require("util");
- var _requiredParameter = _interopRequireDefault(require("../requiredParameter"));
- var defaultGraphQLTypes = _interopRequireWildcard(require("./loaders/defaultGraphQLTypes"));
- var parseClassTypes = _interopRequireWildcard(require("./loaders/parseClassTypes"));
- var parseClassQueries = _interopRequireWildcard(require("./loaders/parseClassQueries"));
- var parseClassMutations = _interopRequireWildcard(require("./loaders/parseClassMutations"));
- var defaultGraphQLQueries = _interopRequireWildcard(require("./loaders/defaultGraphQLQueries"));
- var defaultGraphQLMutations = _interopRequireWildcard(require("./loaders/defaultGraphQLMutations"));
- var _ParseGraphQLController = _interopRequireWildcard(require("../Controllers/ParseGraphQLController"));
- var _DatabaseController = _interopRequireDefault(require("../Controllers/DatabaseController"));
- var _SchemaCache = _interopRequireDefault(require("../Adapters/Cache/SchemaCache"));
- var _parseGraphQLUtils = require("./parseGraphQLUtils");
- var schemaDirectives = _interopRequireWildcard(require("./loaders/schemaDirectives"));
- var schemaTypes = _interopRequireWildcard(require("./loaders/schemaTypes"));
- var _triggers = require("../triggers");
- var defaultRelaySchema = _interopRequireWildcard(require("./loaders/defaultRelaySchema"));
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
- const RESERVED_GRAPHQL_TYPE_NAMES = ['String', 'Boolean', 'Int', 'Float', 'ID', 'ArrayResult', 'Query', 'Mutation', 'Subscription', 'CreateFileInput', 'CreateFilePayload', 'Viewer', 'SignUpInput', 'SignUpPayload', 'LogInInput', 'LogInPayload', 'LogOutInput', 'LogOutPayload', 'CloudCodeFunction', 'CallCloudCodeInput', 'CallCloudCodePayload', 'CreateClassInput', 'CreateClassPayload', 'UpdateClassInput', 'UpdateClassPayload', 'DeleteClassInput', 'DeleteClassPayload', 'PageInfo'];
- const RESERVED_GRAPHQL_QUERY_NAMES = ['health', 'viewer', 'class', 'classes'];
- const RESERVED_GRAPHQL_MUTATION_NAMES = ['signUp', 'logIn', 'logOut', 'createFile', 'callCloudCode', 'createClass', 'updateClass', 'deleteClass'];
- class ParseGraphQLSchema {
- constructor(params = {}) {
- this.parseGraphQLController = params.parseGraphQLController || (0, _requiredParameter.default)('You must provide a parseGraphQLController instance!');
- this.databaseController = params.databaseController || (0, _requiredParameter.default)('You must provide a databaseController instance!');
- this.log = params.log || (0, _requiredParameter.default)('You must provide a log instance!');
- this.graphQLCustomTypeDefs = params.graphQLCustomTypeDefs;
- this.appId = params.appId || (0, _requiredParameter.default)('You must provide the appId!');
- this.schemaCache = _SchemaCache.default;
- this.logCache = {};
- }
- async load() {
- const {
- parseGraphQLConfig
- } = await this._initializeSchemaAndConfig();
- const parseClassesArray = await this._getClassesForSchema(parseGraphQLConfig);
- const functionNames = await this._getFunctionNames();
- const functionNamesString = functionNames.join();
- const parseClasses = parseClassesArray.reduce((acc, clazz) => {
- acc[clazz.className] = clazz;
- return acc;
- }, {});
- if (!this._hasSchemaInputChanged({
- parseClasses,
- parseGraphQLConfig,
- functionNamesString
- })) {
- return this.graphQLSchema;
- }
- this.parseClasses = parseClasses;
- this.parseGraphQLConfig = parseGraphQLConfig;
- this.functionNames = functionNames;
- this.functionNamesString = functionNamesString;
- this.parseClassTypes = {};
- this.viewerType = null;
- this.graphQLAutoSchema = null;
- this.graphQLSchema = null;
- this.graphQLTypes = [];
- this.graphQLQueries = {};
- this.graphQLMutations = {};
- this.graphQLSubscriptions = {};
- this.graphQLSchemaDirectivesDefinitions = null;
- this.graphQLSchemaDirectives = {};
- this.relayNodeInterface = null;
- defaultGraphQLTypes.load(this);
- defaultRelaySchema.load(this);
- schemaTypes.load(this);
- this._getParseClassesWithConfig(parseClassesArray, parseGraphQLConfig).forEach(([parseClass, parseClassConfig]) => {
-
-
- if (parseClass.className === '_User') {
- Object.keys(parseClass.fields).forEach(fieldName => {
- if (fieldName.startsWith('_auth_data_')) {
- delete parseClass.fields[fieldName];
- }
- });
- }
-
-
-
- const orderedFields = {};
- Object.keys(parseClass.fields).sort().forEach(fieldName => {
- orderedFields[fieldName] = parseClass.fields[fieldName];
- });
- parseClass.fields = orderedFields;
- parseClassTypes.load(this, parseClass, parseClassConfig);
- parseClassQueries.load(this, parseClass, parseClassConfig);
- parseClassMutations.load(this, parseClass, parseClassConfig);
- });
- defaultGraphQLTypes.loadArrayResult(this, parseClassesArray);
- defaultGraphQLQueries.load(this);
- defaultGraphQLMutations.load(this);
- let graphQLQuery = undefined;
- if (Object.keys(this.graphQLQueries).length > 0) {
- graphQLQuery = new _graphql.GraphQLObjectType({
- name: 'Query',
- description: 'Query is the top level type for queries.',
- fields: this.graphQLQueries
- });
- this.addGraphQLType(graphQLQuery, true, true);
- }
- let graphQLMutation = undefined;
- if (Object.keys(this.graphQLMutations).length > 0) {
- graphQLMutation = new _graphql.GraphQLObjectType({
- name: 'Mutation',
- description: 'Mutation is the top level type for mutations.',
- fields: this.graphQLMutations
- });
- this.addGraphQLType(graphQLMutation, true, true);
- }
- let graphQLSubscription = undefined;
- if (Object.keys(this.graphQLSubscriptions).length > 0) {
- graphQLSubscription = new _graphql.GraphQLObjectType({
- name: 'Subscription',
- description: 'Subscription is the top level type for subscriptions.',
- fields: this.graphQLSubscriptions
- });
- this.addGraphQLType(graphQLSubscription, true, true);
- }
- this.graphQLAutoSchema = new _graphql.GraphQLSchema({
- types: this.graphQLTypes,
- query: graphQLQuery,
- mutation: graphQLMutation,
- subscription: graphQLSubscription
- });
- if (this.graphQLCustomTypeDefs) {
- schemaDirectives.load(this);
- if (typeof this.graphQLCustomTypeDefs.getTypeMap === 'function') {
-
- const customGraphQLSchemaTypeMap = this.graphQLCustomTypeDefs._typeMap;
- const findAndReplaceLastType = (parent, key) => {
- if (parent[key].name) {
- if (this.graphQLAutoSchema._typeMap[parent[key].name] && this.graphQLAutoSchema._typeMap[parent[key].name] !== parent[key]) {
-
-
- parent[key] = this.graphQLAutoSchema._typeMap[parent[key].name];
- }
- } else {
- if (parent[key].ofType) {
- findAndReplaceLastType(parent[key], 'ofType');
- }
- }
- };
-
-
-
-
- Object.keys(customGraphQLSchemaTypeMap).sort().forEach(customGraphQLSchemaTypeKey => {
- const customGraphQLSchemaType = customGraphQLSchemaTypeMap[customGraphQLSchemaTypeKey];
- if (!customGraphQLSchemaType || !customGraphQLSchemaType.name || customGraphQLSchemaType.name.startsWith('__')) {
- return;
- }
- const autoGraphQLSchemaType = this.graphQLAutoSchema._typeMap[customGraphQLSchemaType.name];
- if (!autoGraphQLSchemaType) {
- this.graphQLAutoSchema._typeMap[customGraphQLSchemaType.name] = customGraphQLSchemaType;
- }
- });
-
-
-
- Object.keys(customGraphQLSchemaTypeMap).sort().forEach(customGraphQLSchemaTypeKey => {
- const customGraphQLSchemaType = customGraphQLSchemaTypeMap[customGraphQLSchemaTypeKey];
- if (!customGraphQLSchemaType || !customGraphQLSchemaType.name || customGraphQLSchemaType.name.startsWith('__')) {
- return;
- }
- const autoGraphQLSchemaType = this.graphQLAutoSchema._typeMap[customGraphQLSchemaType.name];
- if (autoGraphQLSchemaType && typeof customGraphQLSchemaType.getFields === 'function') {
- Object.keys(customGraphQLSchemaType._fields).sort().forEach(fieldKey => {
- const field = customGraphQLSchemaType._fields[fieldKey];
- findAndReplaceLastType(field, 'type');
- autoGraphQLSchemaType._fields[field.name] = field;
- });
- }
- });
- this.graphQLSchema = this.graphQLAutoSchema;
- } else if (typeof this.graphQLCustomTypeDefs === 'function') {
- this.graphQLSchema = await this.graphQLCustomTypeDefs({
- directivesDefinitionsSchema: this.graphQLSchemaDirectivesDefinitions,
- autoSchema: this.graphQLAutoSchema,
- graphQLSchemaDirectives: this.graphQLSchemaDirectives
- });
- } else {
- this.graphQLSchema = (0, _schema.mergeSchemas)({
- schemas: [this.graphQLAutoSchema],
- typeDefs: (0, _merge.mergeTypeDefs)([this.graphQLCustomTypeDefs, this.graphQLSchemaDirectivesDefinitions])
- });
- this.graphQLSchema = this.graphQLSchemaDirectives(this.graphQLSchema);
- }
- } else {
- this.graphQLSchema = this.graphQLAutoSchema;
- }
- return this.graphQLSchema;
- }
- _logOnce(severity, message) {
- if (this.logCache[message]) {
- return;
- }
- this.log[severity](message);
- this.logCache[message] = true;
- }
- addGraphQLType(type, throwError = false, ignoreReserved = false, ignoreConnection = false) {
- if (!ignoreReserved && RESERVED_GRAPHQL_TYPE_NAMES.includes(type.name) || this.graphQLTypes.find(existingType => existingType.name === type.name) || !ignoreConnection && type.name.endsWith('Connection')) {
- const message = `Type ${type.name} could not be added to the auto schema because it collided with an existing type.`;
- if (throwError) {
- throw new Error(message);
- }
- this._logOnce('warn', message);
- return undefined;
- }
- this.graphQLTypes.push(type);
- return type;
- }
- addGraphQLQuery(fieldName, field, throwError = false, ignoreReserved = false) {
- if (!ignoreReserved && RESERVED_GRAPHQL_QUERY_NAMES.includes(fieldName) || this.graphQLQueries[fieldName]) {
- const message = `Query ${fieldName} could not be added to the auto schema because it collided with an existing field.`;
- if (throwError) {
- throw new Error(message);
- }
- this._logOnce('warn', message);
- return undefined;
- }
- this.graphQLQueries[fieldName] = field;
- return field;
- }
- addGraphQLMutation(fieldName, field, throwError = false, ignoreReserved = false) {
- if (!ignoreReserved && RESERVED_GRAPHQL_MUTATION_NAMES.includes(fieldName) || this.graphQLMutations[fieldName]) {
- const message = `Mutation ${fieldName} could not be added to the auto schema because it collided with an existing field.`;
- if (throwError) {
- throw new Error(message);
- }
- this._logOnce('warn', message);
- return undefined;
- }
- this.graphQLMutations[fieldName] = field;
- return field;
- }
- handleError(error) {
- if (error instanceof _node.default.Error) {
- this.log.error('Parse error: ', error);
- } else {
- this.log.error('Uncaught internal server error.', error, error.stack);
- }
- throw (0, _parseGraphQLUtils.toGraphQLError)(error);
- }
- async _initializeSchemaAndConfig() {
- const [schemaController, parseGraphQLConfig] = await Promise.all([this.databaseController.loadSchema(), this.parseGraphQLController.getGraphQLConfig()]);
- this.schemaController = schemaController;
- return {
- parseGraphQLConfig
- };
- }
-
- async _getClassesForSchema(parseGraphQLConfig) {
- const {
- enabledForClasses,
- disabledForClasses
- } = parseGraphQLConfig;
- const allClasses = await this.schemaController.getAllClasses();
- if (Array.isArray(enabledForClasses) || Array.isArray(disabledForClasses)) {
- let includedClasses = allClasses;
- if (enabledForClasses) {
- includedClasses = allClasses.filter(clazz => {
- return enabledForClasses.includes(clazz.className);
- });
- }
- if (disabledForClasses) {
-
-
-
- includedClasses = includedClasses.filter(clazz => {
- return !disabledForClasses.includes(clazz.className);
- });
- }
- this.isUsersClassDisabled = !includedClasses.some(clazz => {
- return clazz.className === '_User';
- });
- return includedClasses;
- } else {
- return allClasses;
- }
- }
-
- _getParseClassesWithConfig(parseClasses, parseGraphQLConfig) {
- const {
- classConfigs
- } = parseGraphQLConfig;
-
-
- const sortClasses = (a, b) => {
- a = a.className;
- b = b.className;
- if (a[0] === '_') {
- if (b[0] !== '_') {
- return -1;
- }
- }
- if (b[0] === '_') {
- if (a[0] !== '_') {
- return 1;
- }
- }
- if (a === b) {
- return 0;
- } else if (a < b) {
- return -1;
- } else {
- return 1;
- }
- };
- return parseClasses.sort(sortClasses).map(parseClass => {
- let parseClassConfig;
- if (classConfigs) {
- parseClassConfig = classConfigs.find(c => c.className === parseClass.className);
- }
- return [parseClass, parseClassConfig];
- });
- }
- async _getFunctionNames() {
- return await (0, _triggers.getFunctionNames)(this.appId).filter(functionName => {
- if (/^[_a-zA-Z][_a-zA-Z0-9]*$/.test(functionName)) {
- return true;
- } else {
- this._logOnce('warn', `Function ${functionName} could not be added to the auto schema because GraphQL names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/.`);
- return false;
- }
- });
- }
-
- _hasSchemaInputChanged(params) {
- const {
- parseClasses,
- parseGraphQLConfig,
- functionNamesString
- } = params;
-
- if (!this.graphQLSchema) {
- return true;
- }
- if ((0, _util.isDeepStrictEqual)(this.parseGraphQLConfig, parseGraphQLConfig) && this.functionNamesString === functionNamesString && (0, _util.isDeepStrictEqual)(this.parseClasses, parseClasses)) {
- return false;
- }
- return true;
- }
- }
- exports.ParseGraphQLSchema = ParseGraphQLSchema;
|