<commit_before>import { json as jsonParser } from 'body-parser';
import { NextFunction, Router } from 'express';
import * as jp from 'jsonpolice';
import * as _ from 'lodash';
import { API, APIRequest, APIRequestHandler, APIResponse } from './api';
import { Resource } from './resource';
import { Scopes } from './scopes';
import { Swagger } from './swagger';

const swaggerPathRegExp = /\/:([^#\?\/]*)/g;
const __api = Symbol();
const __resource = Symbol();
const __id = Symbol();
const __path = Symbol();
const __method = Symbol();
const __scopes = Symbol();

export type Method = "get" | "put" | "post" | "delete" | "options" | "head" | "patch";

export abstract class Operation implements Swagger.Operation {
  operationId: string;
  summary?: string;
  description?: string;
  externalDocs?: Swagger.ExternalDocs;
  consumes?: string[];
  produces?: string[];
  parameters?: Swagger.Parameters;
  responses: Swagger.Responses;
  schemes?: Swagger.Scheme[];
  deprecated?: boolean;
  security?: Swagger.Security[];

  protected [__api]: API;
  protected [__resource]: Resource;
  protected [__id]: string;
  protected [__path]: string;
  protected [__method]: Method;
  protected [__scopes]: Scopes;

  constructor(resource: Resource, path: string, method: Method, id?: string) {
    if (!id) {
      id = path;
      if (id.length && id[0] === '/') {
        id = id.substr(1);
      }
      if (!id.length) {
        id = method;
      } else if (method !== 'get') {
        id += '-' + method;
      }
    }
    this[__resource] = resource;
    this[__id] = id;
    this[__path] = path;
    this[__method] = method;
    this.setInfo(this.getDefaultInfo());
  }

  get api():API {
    return this[__api];
  }
  get resource():Resource {
    return this[__resource];
  }
  get path():string {
    return this[__path];
  }
  get swaggerPath(): string {
    return this.path.replace(swaggerPathRegExp, "/{$1}");
  }
  get method():Method {
    return this[__method];
  }
  get swaggerScopes(): Swagger.Scopes {
    return {
      [this.operationId]: this.summary || `Execute ${this.operationId} on a ${this.resource.name}`
    };
  }
  get scopes(): Scopes {
    return this[__scopes];
  }

  protected getDefaultInfo(): Swagger.Operation {
    return {
      "operationId": `${this.resource.name}.${this[__id]}`,
      "tags": [ '' + this.resource.name ],
      "responses": {
        "default": {
          "$ref": "#/responses/defaultError"
        }
      }
    };
  }
  protected setInfo(info: Swagger.Operation): this {
    Object.assign(this, info);
    return this;
  }
  protected async createValidators(key: string, parameters: Swagger.Parameter[]): Promise<APIRequestHandler> {
    let validatorFactories: Promise<(req: APIRequest) => Promise<void>>[] = parameters.map(async (parameter: Swagger.Parameter) => {
      let required = parameter.required;
      delete parameter.required;
      let schema:jp.Schema = await this.api.registry.create(parameter);

      return async function(req: APIRequest) {
        req.logger.debug(`validator ${key}.${parameter.name}, required ${required}, value ${req[key][parameter.name]}`);
        if (typeof req[key][parameter.name] === 'undefined') {
          if (required === true) {
            throw new jp.ValidationError(key + '.' + parameter.name, (schema as any).scope, 'required');
          }
        } else {
          req[key][parameter.name] = await schema.validate(req[key][parameter.name], key + '.' + parameter.name);
        }
      }
    });<commit_msg>feat(operation.ts): Add getter for the operation id<commit_after>import { json as jsonParser } from 'body-parser';
import { NextFunction, Router } from 'express';
import * as jp from 'jsonpolice';
import * as _ from 'lodash';
import { API, APIRequest, APIRequestHandler, APIResponse } from './api';
import { Resource } from './resource';
import { Scopes } from './scopes';
import { Swagger } from './swagger';

const swaggerPathRegExp = /\/:([^#\?\/]*)/g;
const __api = Symbol();
const __resource = Symbol();
const __id = Symbol();
const __path = Symbol();
const __method = Symbol();
const __scopes = Symbol();

export type Method = "get" | "put" | "post" | "delete" | "options" | "head" | "patch";

export abstract class Operation implements Swagger.Operation {
  operationId: string;
  summary?: string;
  description?: string;
  externalDocs?: Swagger.ExternalDocs;
  consumes?: string[];
  produces?: string[];
  parameters?: Swagger.Parameters;
  responses: Swagger.Responses;
  schemes?: Swagger.Scheme[];
  deprecated?: boolean;
  security?: Swagger.Security[];

  protected [__api]: API;
  protected [__resource]: Resource;
  protected [__id]: string;
  protected [__path]: string;
  protected [__method]: Method;
  protected [__scopes]: Scopes;

  constructor(resource: Resource, path: string, method: Method, id?: string) {
    if (!id) {
      id = path;
      if (id.length && id[0] === '/') {
        id = id.substr(1);
      }
      if (!id.length) {
        id = method;
      } else if (method !== 'get') {
        id += '-' + method;
      }
    }
    this[__resource] = resource;
    this[__id] = id;
    this[__path] = path;
    this[__method] = method;
    this.setInfo(this.getDefaultInfo());
  }

  get api(): API {
    return this[__api];
  }
  get resource(): Resource {
    return this[__resource];
  }
  get opId(): string {
    return this[__id];
  }
  get path(): string {
    return this[__path];
  }
  get swaggerPath(): string {
    return this.path.replace(swaggerPathRegExp, "/{$1}");
  }
  get method(): Method {
    return this[__method];
  }
  get swaggerScopes(): Swagger.Scopes {
    return {
      [this.operationId]: this.summary || `Execute ${this.operationId} on a ${this.resource.name}`
    };
  }
  get scopes(): Scopes {
    return this[__scopes];
  }

  protected getDefaultInfo(): Swagger.Operation {
    return {
      "operationId": `${this.resource.name}.${this.opId}`,
      "tags": [ '' + this.resource.name ],
      "responses": {
        "default": {
          "$ref": "#/responses/defaultError"
        }
      }
    };
  }
  protected setInfo(info: Swagger.Operation): this {
    Object.assign(this, info);
    return this;
  }
  protected async createValidators(key: string, parameters: Swagger.Parameter[]): Promise<APIRequestHandler> {
    let validatorFactories: Promise<(req: APIRequest) => Promise<void>>[] = parameters.map(async (parameter: Swagger.Parameter) => {
      let required = parameter.required;
      delete parameter.required;
      let schema:jp.Schema = await this.api.registry.create(parameter);

      return async function(req: APIRequest) {
        req.logger.debug(`validator ${key}.${parameter.name}, required ${required}, value ${req[key][parameter.name]}`);
        if (typeof req[key][parameter.name] === 'undefined') {
          if (required === true) {
            throw new jp.ValidationError(key + '.' + parameter.name, (schema as any).scope, 'required');
          }
        } else {
          req[key][parameter.name] = await schema.validate(req[key][parameter.name], key + '.' + parameter.name);
        }
      }
    });
{'fraction_non_alphanumeric': 0.1621129326047359, 'fraction_numerical': 0.0008406893652795292, 'mean_word_length': 3.2087264150943398, 'pattern_counts': {'":': 10, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5239782', 'n_tokens_mistral': 2192, 'n_tokens_neox': 2197, 'n_words': 545}