"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.componentSchema = componentSchema;
function _stripAnsi() {
  const data = _interopRequireDefault(require("strip-ansi"));
  _stripAnsi = function () {
    return data;
  };
  return data;
}
function _graphqlTag() {
  const data = require("graphql-tag");
  _graphqlTag = function () {
    return data;
  };
  return data;
}
function _graphqlTypeJson() {
  const data = require("graphql-type-json");
  _graphqlTypeJson = function () {
    return data;
  };
  return data;
}
function _toolboxPath() {
  const data = require("@teambit/toolbox.path.path");
  _toolboxPath = function () {
    return data;
  };
  return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function componentSchema(componentExtension) {
  return {
    typeDefs: (0, _graphqlTag().gql)`
      scalar JSON
      scalar JSONObject

      type ComponentID {
        name: String!
        version: String
        scope: String
      }

      type Tag {
        # semver assigned to the tag.
        version: String!

        # tag hash.
        hash: String!
      }

      type Snap {
        # hash of the snapshot.
        hash: String!

        # time of the snapshot.
        timestamp: String!

        # parents of the snap
        parents: [String]!

        # snapper
        author: Author!

        # snapshot message
        message: String
      }

      type LogEntry {
        message: String!
        displayName: String
        username: String
        parents: [String]!
        email: String
        date: String
        hash: String!
        tag: String
        id: String!
        profileImage: String
      }

      type Author {
        # display name of the snapper.
        displayName: String!

        # author of the snapper.
        email: String!
      }

      type Component {
        # id of the component.
        id: ComponentID!

        # head snap of the component.
        head: Snap

        # head tag of the component.
        headTag: Tag

        # list of all relative component paths.
        fs: [String]

        # relative path to the main file of the component
        mainFile: String

        # return specific file contents by relative file path.
        getFile(path: String): String

        # latest version of the component.
        latest: String

        # display name of the component
        displayName: String!

        # component buildStatus
        buildStatus: String

        # list of component releases.
        tags: [Tag]!

        # Log entry of the component.
        log: LogEntry!

        """
        component logs
        """
        logs(
          """
          type of logs to show (tag or snap)
          """
          type: String
          offset: Int
          limit: Int
          """
          head to start traversing logs from
          """
          head: String
          sort: String
          """
          start traversing logs from the fetched component's head
          """
          takeHeadFromComponent: Boolean
        ): [LogEntry]!

        aspects(include: [String]): [Aspect]

        """
        element url of the component - this is deprecated, and will return empty string now.
        it's here to not break old queries
        """
        elementsUrl: String @deprecated(reason: "Not in use anymore")
      }

      type Aspect {
        id: String!
        icon: String
        config: JSONObject
        data: JSONObject
      }

      type InvalidComponent {
        id: ComponentID!
        errorName: String!
        errorMessage: String!
      }

      type ComponentHost {
        id: ID!
        name: String!

        # load a component.
        get(id: String!, withState: Boolean): Component

        # list components
        list(offset: Int, limit: Int): [Component]!

        # list invalid components and their errors
        listInvalid: [InvalidComponent]!

        # get component logs(snaps) by component id
        snaps(id: String!): [LogEntry]! @deprecated(reason: "Use the logs field on Component")
      }

      type Query {
        getHost(id: String): ComponentHost
      }
    `,
    resolvers: {
      JSONObject: _graphqlTypeJson().GraphQLJSONObject,
      Component: {
        id: component => component.id.toObject(),
        displayName: component => component.displayName,
        fs: component => {
          return component.state.filesystem.files.map(file => file.relative);
        },
        log: async component => {
          const snap = await component.loadSnap(component.id.version);
          return _objectSpread(_objectSpread({}, snap), {}, {
            date: snap.timestamp.getTime(),
            email: snap.author.email,
            username: snap.author.name,
            displayName: snap.author.displayName,
            id: snap.hash
          });
        },
        getFile: (component, {
          path
        }) => {
          const maybeFile = component.state.filesystem.files.find(file => (0, _toolboxPath().pathNormalizeToLinux)(file.relative) === path);
          if (!maybeFile) return undefined;
          return maybeFile.contents.toString('utf-8');
        },
        mainFile: component => {
          return component.state._consumer.mainFile;
        },
        headTag: component => component.headTag?.toObject(),
        latest: component => component.latest,
        tags: component => {
          // graphql doesn't support map types
          return component.tags.toArray().map(tag => tag.toObject());
        },
        aspects: (component, {
          include
        }) => {
          return component.state.aspects.filter(include).serialize();
        },
        // Here only to not break old queries
        elementsUrl: () => undefined,
        logs: async (component, filter) => {
          let head = filter?.head;
          if (!head && filter?.takeHeadFromComponent) {
            head = component.id.version;
          }
          const finalFilter = _objectSpread(_objectSpread({}, filter), {
            head
          });
          return (await component.getLogs(finalFilter)).map(log => _objectSpread(_objectSpread({}, log), {}, {
            id: log.hash
          }));
        }
      },
      ComponentHost: {
        get: async (host, {
          id
        }) => {
          try {
            const componentId = await host.resolveComponentId(id);
            const component = await host.get(componentId);
            return component;
          } catch (error) {
            return null;
          }
        },
        snaps: async (host, {
          id
        }) => {
          const componentId = await host.resolveComponentId(id);
          // return (await host.getLogs(componentId)).map(log => ({...log, id: log.hash}))
          return host.getLogs(componentId);
        },
        list: async (host, filter) => {
          return host.list(filter);
        },
        listInvalid: async host => {
          const invalidComps = await host.listInvalid();
          return invalidComps.map(({
            id,
            err
          }) => ({
            id: id,
            errorName: err.name,
            errorMessage: err.message ? (0, _stripAnsi().default)(err.message) : err.name
          }));
        },
        id: async host => {
          return host.name;
        },
        name: async host => {
          return host.name;
        }
      },
      Query: {
        getHost: (componentExt, {
          id
        }) => {
          return componentExtension.getHost(id);
        }
      }
    }
  };
}

//# sourceMappingURL=component.graphql.js.map