How to use @keystonejs/utils - 10 common examples

To help you get started, we’ve selected a few @keystonejs/utils examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github keystonejs / keystone / packages / adapter-mongoose / index.js View on Github external
// Push all the complex stages onto the pipeline as-is
      while (!itr.done && itr.value.$isComplexStage) {
        pipeline.push(...itr.value.pipeline);
        if (itr.value.mutator) {
          postAggregateMutation.push(itr.value.mutator);
        }
        itr = iterator.next();
      }
    }

    if (args.search) {
      // TODO: Implement configurable search fields for lists
      pipeline.push({
        $match: {
          name: new RegExp(`${escapeRegExp(args.search)}`, 'i'),
        },
      });
    }

    if (args.orderBy) {
      const [orderField, orderDirection] = args.orderBy.split('_');

      pipeline.push({
        $sort: {
          [orderField]: orderDirection === 'ASC' ? 1 : -1,
        },
      });
    }

    if (args.skip < Infinity && args.skip > 0) {
      pipeline.push({
github keystonejs / keystone / packages / app-admin-ui / client / classes / List.js View on Github external
deserializeItemData(item) {
    return {
      ...mapKeys(this._fieldsByPath, field => field.deserialize(item)),
      // Handle the special case of `_label_` (and potentially others)
      ...omit(item, Object.keys(this._fieldsByPath)),
    };
  }
github keystonejs / keystone / packages / keystone / lib / List / index.js View on Github external
(idFilters.id_in && idFilters.id_in.length === 0) ||
      // All the passed in ids have been explicitly disallowed
      (idFilters.id_not_in && idFilters.id_not_in.length === uniqueIds.length)
    ) {
      // NOTE: We don't throw an error for multi-actions, only return an empty
      // array because there's no mechanism in GraphQL to return more than one
      // error for a list result.
      return [];
    }

    // NOTE: The fields will be filtered by the ACL checking in gqlFieldResolvers()
    // NOTE: Unlike in the single-operation variation, there is no security risk
    // in returning the result of the query here, because if no items match, we
    // return an empty array regardless of if that's because of lack of
    // permissions or because of those items don't exist.
    const remainingAccess = omit(access, ['id', 'id_not', 'id_in', 'id_not_in']);
    return await this._itemsQuery(
      { where: { ...remainingAccess, ...idFilters } },
      { context, info }
    );
  }
github keystonejs / keystone / packages / adapter-mongoose / lib / adapter-mongoose.js View on Github external
function graphQlQueryToMongoJoinQuery(query) {
      const _query = {
        ...query.where,
        ...mapKeyNames(
          // Grab all the modifiers
          pick(query, ['search', 'orderBy', 'skip', 'first']),
          // and prefix with a dollar symbol so they can be picked out by the
          // query builder tokeniser
          key => `$${key}`
        ),
      };

      return mapKeys(_query, field => {
        if (getType(field) !== 'Object' || !field.where) {
          return field;
        }

        // recurse on object (ie; relationship) types
        return graphQlQueryToMongoJoinQuery(field);
      });
    }
github keystonejs / keystone / packages / keystone / lib / List / index.js View on Github external
initFields() {
    if (this.fieldsInitialised) return;
    this.fieldsInitialised = true;

    let sanitisedFieldsConfig = mapKeys(this._fields, (fieldConfig, path) => ({
      ...fieldConfig,
      type: mapNativeTypeToKeystoneType(fieldConfig.type, this.key, path),
    }));

    // Add an 'id' field if none supplied
    if (!sanitisedFieldsConfig.id) {
      if (typeof this.adapter.parentAdapter.getDefaultPrimaryKeyConfig !== 'function') {
        throw `No 'id' field given for the '${this.key}' list and the list adapter ` +
          `in used (${this.adapter.key}) doesn't supply a default primary key config ` +
          `(no 'getDefaultPrimaryKeyConfig()' function)`;
      }
      // Rebuild the object so id is "first"
      sanitisedFieldsConfig = {
        id: this.adapter.parentAdapter.getDefaultPrimaryKeyConfig(),
        ...sanitisedFieldsConfig,
      };
github keystonejs / keystone / packages / keystone / lib / List / index.js View on Github external
getAdminMeta({ schemaName }) {
    const schemaAccess = this.access[schemaName];
    return {
      key: this.key,
      // Reduce to truthy values (functions can't be passed over the webpack
      // boundary)
      access: mapKeys(schemaAccess, val => !!val),
      label: this.adminUILabels.label,
      singular: this.adminUILabels.singular,
      plural: this.adminUILabels.plural,
      path: this.adminUILabels.path,
      gqlNames: this.gqlNames,
      fields: this.fields
        .filter(field => field.access[schemaName].read)
        .map(field => field.getAdminMeta({ schemaName })),
      views: this.views,
      adminConfig: {
        defaultPageSize: this.adminConfig.defaultPageSize,
        defaultColumns: this.adminConfig.defaultColumns.replace(/\s/g, ''), // remove all whitespace
        defaultSort: this.adminConfig.defaultSort,
        maximumPageSize: Math.max(
          this.adminConfig.defaultPageSize,
          this.adminConfig.maximumPageSize
github keystonejs / keystone / packages / app-admin-ui / client / pages / Item / index.js View on Github external
onSave = async () => {
      const { item, validationErrors, validationWarnings } = this.state;

      // There are errors, no need to proceed - the entire save can be aborted.
      if (countArrays(validationErrors)) {
        return;
      }

      const {
        onUpdate,
        toastManager: { addToast },
        updateItem,
        item: initialData,
      } = this.props;

      const fieldsObject = this.getFieldsObject();

      const initialValues = getInitialValues(fieldsObject, initialData);
      const currentValues = getCurrentValues(fieldsObject, item);

      // Don't try to update anything that hasn't changed.
github keystonejs / keystone / packages / app-admin-ui / client / pages / Item / index.js View on Github external
const fields = Object.values(omitBy(fieldsObject, path => !data.hasOwnProperty(path)));

      // On the first pass through, there wont be any warnings, so we go ahead
      // and check.
      // On the second pass through, there _may_ be warnings, and by this point
      // we know there are no errors (see the `validationErrors` check above),
      // if so, we let the user force the update through anyway and hence skip
      // this check.
      // Later, on every change, we reset the warnings, so we know if things
      // have changed since last time we checked.
      if (!countArrays(validationWarnings)) {
        const { errors, warnings } = await validateFields(fields, item, data);

        const totalErrors = countArrays(errors);
        const totalWarnings = countArrays(warnings);

        if (totalErrors + totalWarnings > 0) {
          const messages = [];
          if (totalErrors > 0) {
            messages.push(`${totalErrors} error${totalErrors > 1 ? 's' : ''}`);
          }
          if (totalWarnings > 0) {
            messages.push(`${totalWarnings} warning${totalWarnings > 1 ? 's' : ''}`);
          }

          addToast(`Validation failed: ${messages.join(' and ')}.`, {
            autoDismiss: true,
            appearance: errors.length ? 'error' : 'warning',
          });

          this.setState(() => ({
github keystonejs / keystone / packages / app-admin-ui / client / pages / Item / index.js View on Github external
);

      const fields = Object.values(omitBy(fieldsObject, path => !data.hasOwnProperty(path)));

      // On the first pass through, there wont be any warnings, so we go ahead
      // and check.
      // On the second pass through, there _may_ be warnings, and by this point
      // we know there are no errors (see the `validationErrors` check above),
      // if so, we let the user force the update through anyway and hence skip
      // this check.
      // Later, on every change, we reset the warnings, so we know if things
      // have changed since last time we checked.
      if (!countArrays(validationWarnings)) {
        const { errors, warnings } = await validateFields(fields, item, data);

        const totalErrors = countArrays(errors);
        const totalWarnings = countArrays(warnings);

        if (totalErrors + totalWarnings > 0) {
          const messages = [];
          if (totalErrors > 0) {
            messages.push(`${totalErrors} error${totalErrors > 1 ? 's' : ''}`);
          }
          if (totalWarnings > 0) {
            messages.push(`${totalWarnings} warning${totalWarnings > 1 ? 's' : ''}`);
          }

          addToast(`Validation failed: ${messages.join(' and ')}.`, {
            autoDismiss: true,
            appearance: errors.length ? 'error' : 'warning',
          });
github keystonejs / keystone / packages / app-admin-ui / client / classes / List.js View on Github external
constructor(config, adminMeta, views) {
    this.config = config;
    this.adminMeta = adminMeta;

    // TODO: undo this
    Object.assign(this, config);

    this.fields = config.fields.map(fieldConfig => {
      const [Controller] = adminMeta.readViews([views[fieldConfig.path].Controller]);
      return new Controller(fieldConfig, this, adminMeta, views[fieldConfig.path]);
    });

    this._fieldsByPath = arrayToObject(this.fields, 'path');

    this.createMutation = gql`
      mutation create($data: ${this.gqlNames.createInputName}!) {
        ${this.gqlNames.createMutationName}(data: $data) {
          id
          _label_
        }
      }
    `;
    this.createManyMutation = gql`
    mutation createMany($data: ${this.gqlNames.createManyInputName}!) {
      ${this.gqlNames.createManyMutationName}(data: $data) {
        id
      }
    }
  `;