Skip to content

Commit

Permalink
Added interface
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-of-codecraft committed Mar 19, 2024
1 parent c1255b7 commit 7e7e0ad
Show file tree
Hide file tree
Showing 3 changed files with 379 additions and 0 deletions.
173 changes: 173 additions & 0 deletions src/aidocs-generator-interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import {OpenAI } from "openai";
import Anthropic from "@anthropic-ai/sdk";
import * as fs from "fs";
import * as ts from "typescript";
import * as dotenv from "dotenv";
import { Command } from 'commander';
const program = new Command();


dotenv.config();

const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});

const claude = new Anthropic({
apiKey: process.env.CLAUDE_API_KEY
});

type ClassMethod = {
className: string;
methodName: string;
methodSignature: string;
comments: string; // Add this line to include comments
}

type ParseSettings = {
className: string;
file: string;
exclude?: string[];
include?: string[];
}

function parseDeclarations(settings: ParseSettings): ClassMethod[] {
const filePath = settings.file;

const fileContent = fs.readFileSync(filePath, "utf8");
const sourceFile = ts.createSourceFile(
filePath,
fileContent,
ts.ScriptTarget.Latest,
true
);
let classMethods: ClassMethod[] = [];

function getLeadingComments(node: ts.Node): string {
const fullText = node.getFullText(sourceFile);
const comments = ts.getLeadingCommentRanges(fullText, 0);

if (!comments) return '';
let commentText = '';
comments.forEach((comment) => {
commentText += fullText.substring(comment.pos, comment.end) + '\n';
});
return commentText.trim();
}

function visit(node: ts.Node) {
if ((ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node)) && node.name) {

if (settings.className && node.name.text !== settings.className) {
return;
}

const className = node.name.text;
node.members.forEach((member) => {
if (ts.isMethodSignature(member) || ts.isMethodDeclaration(member)) {
if (member.name) {
let methodName = member.name.getText(sourceFile);

if (settings.exclude && settings.exclude.includes(methodName)) {
return;
}

if (settings.include && !settings.include.includes(methodName)) {
return;
}

let methodSignature = member.getText(sourceFile);
let comments = getLeadingComments(member);
classMethods.push({ className, methodName, methodSignature, comments });
}
}
});
}
ts.forEachChild(node, visit);
}

visit(sourceFile);
return classMethods;
}


type AiModel = 'claude' | 'gpt3' | 'gpt4'

async function createDocs(classMethods: ClassMethod[], aiModel: AiModel): Promise<void> {
const fewShotExample = fs.readFileSync(`${__dirname}/wow.api.ts`);

let currentClass = '';
for (const { className, methodName, methodSignature, comments } of classMethods) {
if (currentClass !== className) {
// When we encounter a new class, we reset currentClass to the new className
currentClass = className;
}

let content: string;
let response: any;
const prompt = `${fewShotExample}\n\n Use the provided examples of documenting methods and knowneldge of mod-eluna, azerothcore, create markdown docs for this method: \n\n declare class ${className} {\n Inline Code Comment: ${comments} Method: ${methodName} MethodSignature ${methodSignature}\n} the examples should be not be too simple, and have 10-20 lines`;
switch(aiModel) {
case 'gpt3':
response = await openai.chat.completions.create({
model: "gpt-3.5-turbo",
messages: [{ role: 'user', content: prompt}],
});

if(typeof response.choices[0].message.content == 'string') {
content = response.choices[0].message.content;
}
break;
case 'gpt4':
response = await openai.chat.completions.create({
model: "gpt-4-turbo-preview",
messages: [{ role: 'user', content: prompt}],
});
if(typeof response.choices[0].message.content == 'string') {
content = response.choices[0].message.content;
}
break;
case 'claude':
response = await claude.messages.create({
model: 'claude-3-opus-20240229',
max_tokens: 2000,
messages: [{ role: "user", content: prompt}]
});
if(typeof response.content[0].text == 'string') {
content = response.content[0].text;
}
break;
}


console.log(`writing documentation for ${className}.${methodName}`);
const documentation = content.replace(`filename: ${className.toLowerCase()}.md\n`, '');
// Ensure directory exists
const dir = './docs/wowapi/classes';
if (!fs.existsSync(dir)){
fs.mkdirSync(dir);
}
// Write to a separate markdown file for each class
fs.appendFileSync(`${dir}/${className}.md`, documentation + '\n\n');
}
}

( async() => {

program
.option('-m, --model <model>', 'The AI model to use for documentation generation. Options are gpt3, gpt4, claude', 'gpt3')
.requiredOption('-f, --file <file>', 'The file to parse for class methods')
.requiredOption('-c, --class <class>', 'Which classe to process from the file')
.option('-e, --exclude <exclude>', 'The file to parse for class methods')
.option('-i, --include <include>', 'The file to parse for class methods')
program.parse();

const options = program.opts();
const classOutputs = parseDeclarations({
file: options.file,
className: options.class,
exclude: options.exclude ? options.exclude.split(',') : undefined,
include: options.include ? options.include.split(',') : undefined
});
console.log(classOutputs);
await createDocs(classOutputs, options.model);
})();
99 changes: 99 additions & 0 deletions src/player.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
Here is an example of how to convert TypeScript Class definitions into
readme documentation in a consistent format based on how it will be used
to build mods for mod-eluna on Azerothcore.

Given the following TypeScript class definition for the Player class:

declare class Player extends Unit {
/**
* Adds combo points to the [Player]
*/
AddComboPoints(target: Unit, count: number): void;

/**
* Adds the given amount of the specified item entry to the player.
*/
AddItem(entry: number, itemCount?: number): Item;

/**
*/
AddLifetimeKills(): void;

/**
* Tries to add the given quest entry for the [Player].
*/
AddQuest(entry: number): void;

/**
* Advances all of the [Player]s skills to the amount specified
*/
AdvanceAllSkills(skillStep: number): void;

/**
* Advances a [Player]s specific skill to the amount specified
*/
AdvanceSkill(skillId: number, skillStep: number): void;

/**
* Advances all of the [Player]s weapon skills to the maximum amount available
*/
AdvanceSkillsToMax(): void;

/**
* Completes the [Quest] if a [Quest] area is explored, or completes the [Quest]
*/
AreaExploredOrEventHappens(quest: number): void;

/**
* Returns 'true' if the [Player] can block incomming attacks, 'false' otherwise.
*/
CanBlock(): boolean;

/**
* Returns 'true' if the [Player] satisfies all requirements to complete the quest entry.
*/
CanCompleteQuest(entry: number): boolean;
}
## AddComboPoints
If the player is a rogue or druid, this method will add combo points to the player
based on the target and the count of combo points to add.

### Parameters
* enemy: [Unit](./unit.md) - Unit to apply combo points to
* count: number - The number of combo points to apply

### Example Usage:
Simple script to start a rogue/druid with an advantage.
```typescript
const onPlayerEnter: player_event_on_enter_combat = (event: number, player: Player, enemy: Unit): void => {
player.AddComboPoints(enemy, 5);
}
RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_ENTER_COMBAT, (...args) => onPlayerEnter(...args));
```
## AddItem
Give the player an item based on the item entry. These items can be referenced in World Database item_template.
for more information about items you can find more information here: https://www.azerothcore.org/wiki/item_template.
Items will be added to the current bag inventory if there is space.

### Parameters <hr />
entry: number - Item Entry Id from item_template table
count: number - number of items to grant (Items that exceed unique counts or limits to amount will fail)
### Returns
item: [Item](./item.md) - The item(s) that was given to the player.
### Example Usage:
Grant bonus Badges of Justice
const BADGE_OF_JUSTICE_ENTRY = 29434;
const BADGE_OF_JUSTICE_BONUS = 2;

const LootToken: player_event_on_loot_item = (event: number, player: Player, item: Item) => {

if(item.GetEntry() == BADGE_OF_JUSTICE_ENTRY) {
player.AddItem(BADGE_OF_JUSTICE_ENTRY, BADGE_OF_JUSTICE_BONUS);
}
}

RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (...args) => LootToken(...args));

107 changes: 107 additions & 0 deletions src/wow.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { isReturnStatement } from "typescript"

Here is an example of how to convert TypeScript Class definitions into
readme documentation in a consistent format based on how it will be used
to build AIO plugins which is similar to World of Warcraft AddOns, which reference
the World of Warcraft API that can be found here: https://wowpedia.fandom.com/wiki/World_of_Warcraft_API


/**
* This is another abstract object type that groups together a number of font related methods that are used by multiple other widget types.
* This doesn't have a direct correlation to a UI object. See FontInstance object information for details.
*/
interface FontInstance extends UIObject {

/**
* Returns detailed information on a font object.
* @returns MultipleReturnValues:
* - **fontName**: Path to font file
* - **fontHeight**: Font height in pixels. Due to internal graphics engine workings, this will be ridiculously close to an integer number,
* but not quite ever fully.
* - **fontFlags**: See FontInstance:SetFont().
* @tupleReturn
*/
GetFont(): [string, number, string];

/**
* Gets the text color of of a Font Instance.
* @return MultipleReturnValues:
* r: The red color
* g: The green color
* b: The blue color
* a?: the alpha (opacity)
* @tupleReturn
*/
GetTextColor(): [number, number, number, number?];

/**
* The function is used to set the font to use for displaying text.
*
* @param font path to the font file, relative to the WoW base directory.
* @param size size in points.
* @param flags any comma-delimited combination of "OUTLINE", "THICKOUTLINE" and "MONOCHROME".
*/
SetFont(font: string, size: number, flags?: FontInstanceFlags): void;

/**
* Sets horizontal text justification
*
* @param align the new align
*/
SetJustifyH(align: HorizontalAlign): void;

/**
* Sets vertical text justification
*
* @param align the new align
*/
SetJustifyV(align: VerticalAlign): void;

/**
* Sets the default text color.
*
* @param r red color
* @param g green color
* @param b blue color
* @param a alpha (opacity)
*/
SetTextColor(r: number, g: number, b: number, a?: number): void;
}
## GetFont
This will return detailed information about the current font instanceof.

### Parameters
None

### Returns
**fontName** string - Path to font file
**fontHeight** number - Font height in pixels. Due to internal graphics engine workings, this will be ridiculously close to an integer number, but not quite ever fully
**fontFlags** atring - string - Any comma-delimited combination of OUTLINE, THICK and MONOCHROME; otherwise must be at least an empty string (except for FontString objects).

### Example Usage:
Get the font information for the current font instance.
```typescript
const myfont = CreateFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE");
const [fontName, height, flags] = myfont.GetFont();
const text = myFrame.CreateFontString(myId, "OVERLAY", myfont);
text.SetText("Hello, World!");
```
## SetFont
This will change the font details on an existing font instance.

### Parameters <hr />
**fontName** string - Path to font file
**fontHeight** number - Font height in pixels. Due to internal graphics engine workings, this will be ridiculously close to an integer number, but not quite ever fully
**fontFlags** atring - string - Any comma-delimited combination of OUTLINE, THICK and MONOCHROME; otherwise must be at least an empty string (except for FontString objects).

### Example Usage:
```typescript
const myfont = CreateFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE");
myFont.SetFont("Fonts\\Arial.TTF", 10, "OUTLINE");
const [fontName, height, flags] = myfont.GetFont();
const text = myFrame.CreateFontString(myId, "OVERLAY", myfont);
text.SetText("I am Arial now!");
```

0 comments on commit 7e7e0ad

Please sign in to comment.