Skip to content

Commit

Permalink
feat(tags): group paths by tags if provided
Browse files Browse the repository at this point in the history
this will group paths by tags if provided

fix #188
  • Loading branch information
syroegkin committed Dec 27, 2022
1 parent 314902f commit 4a38ad6
Show file tree
Hide file tree
Showing 17 changed files with 469 additions and 29 deletions.
179 changes: 179 additions & 0 deletions examples/instagram.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ callbackFunction({
| In | query |
| Name | access_token |

## Users

### /users/{user-id}

#### GET
Expand Down Expand Up @@ -258,6 +260,14 @@ Search for a user by name.
| ---- | ----------- | ------ |
| 200 | OK | { **"data"**: [ [MiniProfile](#miniprofile) ] } |

## Relationships
Relationships are expressed using the following terms:

**outgoing_status**: Your relationship to the user. Can be "follows",
"requested", "none".
**incoming_status**: A user's relationship to you. Can be "followed_by",
"requested_by", "blocked_by_you", "none".

### /users/{user-id}/follows

#### GET
Expand Down Expand Up @@ -335,6 +345,17 @@ Modify the relationship between the current user and thetarget user.
| --------------- | ------ |
| oauth | relationships |

## Media
At this time, uploading via the API is not possible. We made a conscious
choice not to add this for the following reasons:

* Instagram is about your life on the go – we hope to encourage photos
from within the app.
* We want to fight spam & low quality photos. Once we allow uploading
from other sources, it's harder to control what comes into the Instagram
ecosystem. All this being said, we're working on ways to ensure users
have a consistent and high-quality experience on our platform.

### /media/{media-id}

#### GET
Expand Down Expand Up @@ -547,6 +568,160 @@ Remove a like on this media by the currently authenticated user.
| ---- | ----------- | ------ |
| 200 | OK | { **"meta"**: { **"code"**: number }, **"data"**: object } |

### /locations/{location-id}/media/recent

#### GET
##### Description

Get a list of recent media objects from a given location.

##### Parameters

| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| location-id | path | Location ID | Yes | integer |
| max_timestamp | query | Return media before this UNIX timestamp. | No | integer |
| min_timestamp | query | Return media after this UNIX timestamp. | No | integer |
| min_id | query | Return media later than this min_id. | No | string |
| max_id | query | Return media earlier than this max_id. | No | string |

##### Responses

| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | OK | { **"data"**: [ [Media](#media) ] } |

## default

### /media/{media-id}/comments

#### GET
##### Description

Get a list of recent comments on a media object.

##### Parameters

| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| media-id | path | Media ID | Yes | integer |

##### Responses

| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | OK | { **"meta"**: { **"code"**: number }, **"data"**: [ [Comment](#comment) ] } |

#### POST
##### Description

Create a comment on a media object with the following rules:

* The total length of the comment cannot exceed 300 characters.
* The comment cannot contain more than 4 hashtags.
* The comment cannot contain more than 1 URL.
* The comment cannot consist of all capital letters.

##### Parameters

| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| media-id | path | Media ID | Yes | integer |
| TEXT | body | Text to post as a comment on the media object as specified in media-id. | No | number |

##### Responses

| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | OK | { **"meta"**: { **"code"**: number }, **"data"**: object } |

##### Security

| Security Schema | Scopes |
| --------------- | ------ |
| oauth | comments |

#### DELETE
##### Description

Remove a comment either on the authenticated user's media object or
authored by the authenticated user.

##### Parameters

| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| media-id | path | Media ID | Yes | integer |

##### Responses

| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | OK | { **"meta"**: { **"code"**: number }, **"data"**: object } |

## Likes

### /media/{media-id}/likes

#### GET
##### Description

Get a list of users who have liked this media.

##### Parameters

| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| media-id | path | Media ID | Yes | integer |

##### Responses

| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | OK | { **"meta"**: { **"code"**: number }, **"data"**: [ [Like](#like) ] } |

#### POST
##### Description

Set a like on this media by the currently authenticated user.

##### Parameters

| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| media-id | path | Media ID | Yes | integer |

##### Responses

| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | OK | { **"meta"**: { **"code"**: number }, **"data"**: object } |

##### Security

| Security Schema | Scopes |
| --------------- | ------ |
| oauth | comments |

#### DELETE
##### Description

Remove a like on this media by the currently authenticated user.

##### Parameters

| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| media-id | path | Media ID | Yes | integer |

##### Responses

| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | OK | { **"meta"**: { **"code"**: number }, **"data"**: object } |

## Tags

### /tags/{tag-name}

#### GET
Expand Down Expand Up @@ -602,6 +777,8 @@ these objects.
| ---- | ----------- | ------ |
| 200 | OK | { **"meta"**: { **"code"**: integer }, **"data"**: [ [Tag](#tag) ] } |

## Location

### /locations/{location-id}

#### GET
Expand Down Expand Up @@ -668,6 +845,8 @@ Search for a location by geographic coordinate.
| ---- | ----------- | ------ |
| 200 | OK | { **"data"**: [ [Location](#location) ] } |

## default

### /geographies/{geo-id}/media/recent

#### GET
Expand Down
File renamed without changes.
24 changes: 24 additions & 0 deletions src/models/Tags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { OpenAPIV2 } from 'openapi-types';

export class TagsCollection {
private tags: { [key: string]: OpenAPIV2.TagObject } = {};

public get length(): number {
return Object.keys(this.tags).length;
}

public tag(tag: OpenAPIV2.TagObject): TagsCollection {
if (!('name' in tag)) {
throw new Error('Tag must have name property');
}
this.tags[tag.name] = tag;
return this;
}

public getTag(name: string): OpenAPIV2.TagObject | null {
if (name in this.tags) {
return this.tags[name];
}
return null;
}
}
2 changes: 1 addition & 1 deletion src/transformers/dataTypes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { anchor } from '../lib/anchor';
import { Markdown } from '../lib/markdown';
import { SchemaInterface } from '../models/schema';
import { SchemaInterface } from '../models/Schema';

const resolver = {
integer: {
Expand Down
2 changes: 1 addition & 1 deletion src/transformers/definitions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { OpenAPIV2 } from 'openapi-types';
import { dataTypeResolver } from './dataTypes';
import { Schema } from '../models/schema';
import { Schema } from '../models/Schema';
import { Markdown } from '../lib/markdown';
import { MDtableRow } from '../lib/markdown/mdtable';

Expand Down
47 changes: 34 additions & 13 deletions src/transformers/documentV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,37 @@ import { transformPath } from './path';
import { transformSecurityDefinitions } from './securityDefinitions';
import { transformExternalDocs } from './externalDocs';
import { transformDefinition } from './definitions';
import { TagsCollection } from '../models/Tags';
import { Markdown } from '../lib/markdown';
import { groupPathsByTags } from './groupPathsByTags';
import { transformTag } from './tag';

export function transformSwaggerV2(
inputDoc: OpenAPIV2.Document,
options: Options,
): string {
const document = [];
const md = Markdown.md();

// Process info
if (!options.skipInfo && 'info' in inputDoc) {
document.push(transformInfo(inputDoc.info));
md.line(transformInfo(inputDoc.info));
}

// Collect tags
const tagsCollection = new TagsCollection();
if ('tags' in inputDoc) {
inputDoc.tags.forEach((tag) => {
tagsCollection.tag(tag);
});
}

if ('externalDocs' in inputDoc) {
document.push(transformExternalDocs(inputDoc.externalDocs));
md.line(transformExternalDocs(inputDoc.externalDocs));
}

// Security definitions
if ('securityDefinitions' in inputDoc) {
document.push(transformSecurityDefinitions(inputDoc.securityDefinitions));
md.line(transformSecurityDefinitions(inputDoc.securityDefinitions));
// } else if (inputDoc.components && inputDoc.components.securitySchemas) {
// document.push(transformSecurityDefinitions(inputDoc.components.securityDefinitions));
}
Expand All @@ -33,22 +45,31 @@ export function transformSwaggerV2(

// Process Paths
if ('paths' in inputDoc) {
Object.keys(inputDoc.paths).forEach((path) => document.push(transformPath(
path,
inputDoc.paths[path],
parameters,
)));
// Group paths by tag name
const tagged = groupPathsByTags(inputDoc.paths);

Object.keys(tagged).forEach((tagName) => {
if (tagsCollection.length) {
// Display Tag
const tagObject = tagsCollection.getTag(tagName) || '';
md.line(transformTag(tagObject));
}
const pathsUnderTag = tagged[tagName];
Object.keys(pathsUnderTag).forEach((path: string) => md.line(transformPath(
path,
inputDoc.paths[path],
parameters,
)));
});
}

// Models (definitions)
if ('definitions' in inputDoc) {
document.push(transformDefinition(inputDoc.definitions));
md.line(transformDefinition(inputDoc.definitions));
// } else if (inputDoc.components && inputDoc.components.schemas) {
// document.push(transformDefinition(inputDoc.components.schemas));
}

// Glue all pieces down
const plainDocument = document.join('\n');

return plainDocument;
return md.export();
}
44 changes: 44 additions & 0 deletions src/transformers/groupPathsByTags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { OpenAPIV2 } from 'openapi-types';
import { ALLOWED_METHODS } from '../types';

type Tagged = { [tag: string]: OpenAPIV2.PathsObject };

/**
* Group path and methods by tags they have
*/
export function groupPathsByTags(
inputDoc: OpenAPIV2.PathsObject,
): Tagged {
const tagged: Tagged = {};

Object.keys(inputDoc).forEach((path: string) => {
const data = inputDoc[path];
Object.keys(data).forEach((method) => {
if (ALLOWED_METHODS.includes(method)) {
const pathMethod = data[method];
const tags = pathMethod.tags || [''];
tags.forEach((tagName) => {
if (!tagged[tagName]) {
tagged[tagName] = {
...tagged[tagName],
[path]: {
parameters: data.parameters,
$ref: data.$ref,
},
};
}
tagged[tagName] = {
...tagged[tagName],
...{
[path]: {
...tagged[tagName][path],
[method]: pathMethod,
},
},
};
});
}
});
});
return tagged;
}
Loading

0 comments on commit 4a38ad6

Please sign in to comment.