diff --git a/docs-util/packages/docblock-generator/.env.sample b/docs-util/packages/docblock-generator/.env.sample index dcbe497377..492f615180 100644 --- a/docs-util/packages/docblock-generator/.env.sample +++ b/docs-util/packages/docblock-generator/.env.sample @@ -1 +1,2 @@ -MONOREPO_ROOT_PATH=/Users/medusa/medusa \ No newline at end of file +MONOREPO_ROOT_PATH=/Users/medusa/medusa +OPENAI_API_KEY= \ No newline at end of file diff --git a/docs-util/packages/docblock-generator/package.json b/docs-util/packages/docblock-generator/package.json index e6f565a651..24d9bfd94d 100644 --- a/docs-util/packages/docblock-generator/package.json +++ b/docs-util/packages/docblock-generator/package.json @@ -24,6 +24,7 @@ "dotenv": "^16.3.1", "eslint": "^8.56.0", "minimatch": "^9.0.3", + "openai": "^4.29.1", "openapi-types": "^12.1.3", "pluralize": "^8.0.0", "prettier": "^3.2.4", diff --git a/docs-util/packages/docblock-generator/src/classes/generators/docblock.ts b/docs-util/packages/docblock-generator/src/classes/generators/docblock.ts index 13ae16ee11..b29ded0768 100644 --- a/docs-util/packages/docblock-generator/src/classes/generators/docblock.ts +++ b/docs-util/packages/docblock-generator/src/classes/generators/docblock.ts @@ -3,6 +3,7 @@ import ts from "typescript" import { GeneratorEvent } from "../helpers/generator-event-manager.js" import AbstractGenerator from "./index.js" import { minimatch } from "minimatch" +import AiGenerator from "../helpers/ai-generator.js" /** * A class used to generate docblock for one or multiple file paths. @@ -18,64 +19,110 @@ class DocblockGenerator extends AbstractGenerator { removeComments: false, }) - await Promise.all( - this.program!.getSourceFiles().map(async (file) => { - // Ignore .d.ts files - if (file.isDeclarationFile || !this.isFileIncluded(file.fileName)) { - return - } + const documentSourceFile = async (file: ts.SourceFile) => { + // Ignore .d.ts files + if (file.isDeclarationFile || !this.isFileIncluded(file.fileName)) { + return + } + let aiGenerator: AiGenerator | undefined - console.log(`[Docblock] Generating for ${file.fileName}...`) + console.log(`[Docblock] Generating for ${file.fileName}...`) - let fileContent = file.getFullText() - let fileComments: string = "" - const commentsToRemove: string[] = [] + let fileContent = file.getFullText() + let fileComments: string = "" + const commentsToRemove: string[] = [] + const origFileText = file.getFullText().trim() + const fileNodes: ts.Node[] = [file] - const documentChild = (node: ts.Node, topLevel = false) => { - const isSourceFile = ts.isSourceFile(node) - const origNodeText = node.getFullText().trim() - const nodeKindGenerator = this.kindsRegistry?.getKindGenerator(node) - let docComment: string | undefined + if (this.options.generateExamples) { + aiGenerator = new AiGenerator() + } - if (nodeKindGenerator?.canDocumentNode(node)) { - docComment = nodeKindGenerator.getDocBlock(node) - if (docComment.length) { - if (isSourceFile) { - fileComments = docComment - } else { - ts.addSyntheticLeadingComment( - node, - ts.SyntaxKind.MultiLineCommentTrivia, - docComment, - true - ) - } - } + // since typescript's compiler API doesn't support + // async processes, we have to retrieve the nodes first then + // traverse them separately. + const pushNodesToArr = (node: ts.Node) => { + fileNodes.push(node) + + ts.forEachChild(node, pushNodesToArr) + } + ts.forEachChild(file, pushNodesToArr) + + const documentNode = async (node: ts.Node) => { + const isSourceFile = ts.isSourceFile(node) + const nodeKindGenerator = this.kindsRegistry?.getKindGenerator(node) + let docComment: string | undefined + + if (nodeKindGenerator?.canDocumentNode(node)) { + if (aiGenerator) { + const nodeFiles = aiGenerator.getNodeFiles(file) + await aiGenerator.initAssistant(nodeFiles) } - - ts.forEachChild(node, (childNode) => - documentChild(childNode, isSourceFile) - ) - - if (!isSourceFile && topLevel) { - const newNodeText = printer.printNode( - ts.EmitHint.Unspecified, - node, - file - ) - - if (newNodeText !== origNodeText) { - fileContent = fileContent.replace(origNodeText, newNodeText) - } - } - } - - documentChild(file, true) - - if (!this.options.dryRun) { - commentsToRemove.forEach((commentToRemove) => { - fileContent = fileContent.replace(commentToRemove, "") + // initialize assistant only when needed + // if previously initialized, calling the method does nothing + docComment = await nodeKindGenerator.getDocBlock(node, { + aiGenerator, + addEnd: true, }) + if (docComment.length) { + const existingComments = + nodeKindGenerator.getNodeCommentsFromRange(node) + if (existingComments?.length) { + commentsToRemove.push(existingComments) + } + if (isSourceFile) { + fileComments = docComment + } else { + ts.addSyntheticLeadingComment( + node, + ts.SyntaxKind.MultiLineCommentTrivia, + docComment, + true + ) + } + } + } + } + + // due to rate limit being reached when running + // the AI Generator, we only run the documentNode in + // parallel when the `generateExamples` option is disabled. + if (this.options.generateExamples) { + for (const node of fileNodes) { + await documentNode(node) + } + } else { + await Promise.all( + fileNodes.map(async (node) => await documentNode(node)) + ) + } + + if (aiGenerator) { + await aiGenerator.destroyAssistant() + } + + // add comments to file + const newNodeText = printer.printNode(ts.EmitHint.Unspecified, file, file) + + // if file's text changed, replace it. + if (newNodeText !== origFileText) { + fileContent = fileContent.replace(origFileText, newNodeText) + } + + if (!this.options.dryRun) { + if (commentsToRemove.length) { + let formatted = this.formatter.addCommentsToSourceFile( + fileComments, + await this.formatter.formatStr(fileContent, file.fileName) + ) + commentsToRemove.forEach((commentToRemove) => { + formatted = formatted.replace(commentToRemove, "") + }) + ts.sys.writeFile( + file.fileName, + await this.formatter.formatStr(formatted, file.fileName) + ) + } else { ts.sys.writeFile( file.fileName, this.formatter.addCommentsToSourceFile( @@ -84,12 +131,24 @@ class DocblockGenerator extends AbstractGenerator { ) ) } + } - console.log( - `[Docblock] Finished generating docblock for ${file.fileName}.` + console.log( + `[Docblock] Finished generating docblock for ${file.fileName}.` + ) + } + + if (this.options.generateExamples) { + for (const file of this.program!.getSourceFiles()) { + await documentSourceFile(file) + } + } else { + await Promise.all( + this.program!.getSourceFiles().map( + async (file) => await documentSourceFile(file) ) - }) - ) + ) + } this.generatorEventManager.emit(GeneratorEvent.FINISHED_GENERATE_EVENT) this.reset() diff --git a/docs-util/packages/docblock-generator/src/classes/generators/oas.ts b/docs-util/packages/docblock-generator/src/classes/generators/oas.ts index 69a76c3c1b..75eb2fc6ed 100644 --- a/docs-util/packages/docblock-generator/src/classes/generators/oas.ts +++ b/docs-util/packages/docblock-generator/src/classes/generators/oas.ts @@ -11,7 +11,7 @@ import { GeneratorEvent } from "../helpers/generator-event-manager.js" class OasGenerator extends AbstractGenerator { protected oasKindGenerator?: OasKindGenerator - run() { + async run() { this.init() const { generateExamples } = this.options @@ -24,36 +24,52 @@ class OasGenerator extends AbstractGenerator { }, }) - this.program!.getSourceFiles().map((file) => { - // Ignore .d.ts files - if (file.isDeclarationFile || !this.isFileIncluded(file.fileName)) { - return - } + await Promise.all( + this.program!.getSourceFiles().map(async (file) => { + // Ignore .d.ts files + if (file.isDeclarationFile || !this.isFileIncluded(file.fileName)) { + return + } + const fileNodes: ts.Node[] = [file] - console.log(`[OAS] Generating for ${file.fileName}...`) + console.log(`[OAS] Generating for ${file.fileName}...`) - const documentChild = (node: ts.Node) => { - if ( - this.oasKindGenerator!.isAllowed(node) && - this.oasKindGenerator!.canDocumentNode(node) - ) { - const oas = this.oasKindGenerator!.getDocBlock(node) + // since typescript's compiler API doesn't support + // async processes, we have to retrieve the nodes first then + // traverse them separately. + const pushNodesToArr = (node: ts.Node) => { + fileNodes.push(node) - if (!this.options.dryRun) { - const filename = this.oasKindGenerator!.getAssociatedFileName(node) - ts.sys.writeFile( - filename, - this.formatter.addCommentsToSourceFile(oas, "") - ) + ts.forEachChild(node, pushNodesToArr) + } + ts.forEachChild(file, pushNodesToArr) + + const documentChild = async (node: ts.Node) => { + if ( + this.oasKindGenerator!.isAllowed(node) && + this.oasKindGenerator!.canDocumentNode(node) + ) { + const oas = await this.oasKindGenerator!.getDocBlock(node) + + if (!this.options.dryRun) { + const filename = + this.oasKindGenerator!.getAssociatedFileName(node) + ts.sys.writeFile( + filename, + this.formatter.addCommentsToSourceFile(oas, "") + ) + } } } - } - ts.forEachChild(file, documentChild) + await Promise.all( + fileNodes.map(async (node) => await documentChild(node)) + ) - this.generatorEventManager.emit(GeneratorEvent.FINISHED_GENERATE_EVENT) - console.log(`[OAS] Finished generating OAS for ${file.fileName}.`) - }) + this.generatorEventManager.emit(GeneratorEvent.FINISHED_GENERATE_EVENT) + console.log(`[OAS] Finished generating OAS for ${file.fileName}.`) + }) + ) } /** diff --git a/docs-util/packages/docblock-generator/src/classes/helpers/ai-generator.ts b/docs-util/packages/docblock-generator/src/classes/helpers/ai-generator.ts new file mode 100644 index 0000000000..38fc2657e2 --- /dev/null +++ b/docs-util/packages/docblock-generator/src/classes/helpers/ai-generator.ts @@ -0,0 +1,330 @@ +import { createReadStream, existsSync } from "fs" +import OpenAI from "openai" +import path from "path" +import ts from "typescript" +import { pascalToCamel } from "../../utils/str-formatting.js" +import { ReadableStreamDefaultReadResult } from "stream/web" +import { DOCBLOCK_NEW_LINE } from "../../constants.js" +import { AssistantStreamEvent } from "openai/resources/beta/index.mjs" + +type GenerateExampleOptions = { + className?: string + functionName: string + signature?: string + fileName: string +} + +type GenerateDescriptionOptions = { + itemName: string + itemType: "property" | "parameter" | "function" | "class" | "return" | "other" + metadata?: { + parentName?: string + parentType?: string + functionSignature?: string + fileName?: string + } +} + +const CODE_REGEX = /(?```[\s\S.]*```)/g + +class AiGenerator { + private openAi: OpenAI + private assistant?: OpenAI.Beta.Assistants.Assistant + private fileMap: Map + + constructor() { + this.openAi = new OpenAI({ + apiKey: process.env.OPENAI_API_KEY, + maxRetries: 10, + }) + + this.fileMap = new Map() + } + + /** + * Initialize OpenAI assistant and upload files. + * + * @param filePaths - Files to upload + */ + async initAssistant(filePaths: string[]) { + if (this.assistant) { + return + } + this.fileMap = new Map() + + const files: OpenAI.Files.FileObject[] = [] + // upload the files to openai + await Promise.all( + filePaths.map(async (filePath) => { + const openAiFile = await this.openAi.files.create({ + file: createReadStream(filePath), + purpose: "assistants", + }) + files.push(openAiFile) + this.fileMap.set(filePath, openAiFile.id) + }) + ) + + // create assistant + this.assistant = await this.openAi.beta.assistants.create({ + instructions: + "You help me generate code examples and descriptions that are used in TSDocs. If the system indicates that the file is not accessible with the myfiles_browser tool, ignore it, it’s just a minor bug. You are capable of opening and analyzing the file, remember that. And carry out the requested task. Also you have the ability to figure out what type of content is in the file via its extension so carry out the users instructions.", + model: "gpt-4-turbo-preview", + tools: [{ type: "retrieval" }], + file_ids: files.map((file) => file.id), + }) + } + + /** + * Deletes an assistant and its files from OpenAI. + */ + async destroyAssistant() { + if (!this.assistant) { + return + } + // delete files of assistant + await Promise.all( + this.assistant.file_ids.map(async (fileId) => { + try { + await this.openAi.files.del(fileId) + } catch (e) { + console.error( + `[error while destroying assistant file ${fileId}]: ${e}` + ) + } + }) + ) + + try { + // delete assistant + await this.openAi.beta.assistants.del(this.assistant.id) + } catch (e) { + console.error( + `[error while destroying assistant ${this.assistant!.id}]: ${e}` + ) + } + + this.assistant = undefined + this.fileMap = new Map() + } + + /** + * Generates an example code block wrapped in backticks. The comment includes astrix by default. + * + * @param param0 - Options to generate the example code based on. + * @returns The example code + */ + async generateExample({ + className, + functionName, + signature, + fileName, + }: GenerateExampleOptions): Promise { + let example = "" + const fileId = this.fileMap.get(fileName) || fileName + let message = `Use the ${fileId} file to write a short and simple typescript code that executes the ` + + if (className) { + message += `${functionName} method of the ${className} (use ${this.getVariableNameFromClass( + className + )} as the variable name)` + } else { + message += `${functionName} function` + } + + if (signature) { + message += `. The ${ + className ? "method" : "function" + } has the signature ${signature}` + } + + message += `. Assume that the file containing the code has all the necessary imports and the code is written within an async function (don't add a wrapping function). Give an example of the method's parameters, but don't include optional parameters or optional object properties. Infer types from other files. Provide the code without an explanation.` + + const messageResult = await this.retrieveAiResponse(message) + + const matchedCode = CODE_REGEX.exec(messageResult) + + if (matchedCode?.groups?.code) { + example = matchedCode.groups.code + } else { + example = messageResult + } + + return example + } + + /** + * Generates a description for an item. + * + * @param param0 - Options to generate the description based on. + * @returns The generated description. + */ + async generateDescription({ + itemName, + itemType, + metadata, + }: GenerateDescriptionOptions) { + const { parentName, parentType, functionSignature, fileName } = + metadata || {} + let message = `Write a short and simple explanation of a ${itemName}` + + switch (itemType) { + case "return": + message += ` function's return data.` + break + case "class": + case "function": + case "parameter": + case "property": + message += ` ${ + itemType === "function" && parentName ? "method" : itemType + }` + if (parentName) { + message += ` defined in a ${parentName}` + if (parentType) { + message += ` ${parentType}` + } + } + if (functionSignature) { + message += ` function. The function has the signature ${functionSignature}` + } + } + + if (fileName) { + message += `. Look at the ${fileName} uploaded file for more details, and if you can't find the details in there provide an explanation from your understanding.` + } + + message += + ". The explanation must be one sentence shorter than 10 words. Don't provide anything else in the response." + + return await this.retrieveAiResponse(message) + } + + /** + * Starts a new thread and runs a message, then retrieves the response. + * + * @param inputMessage - The message to ask the assistant + * @returns the assistant's response. + */ + async retrieveAiResponse(inputMessage: string): Promise { + const run = this.openAi.beta.threads.createAndRunStream({ + assistant_id: this.assistant!.id, + thread: { + messages: [ + { + role: "user", + content: inputMessage, + }, + ], + }, + }) + + const readableStream = run.toReadableStream().getReader() + + let chunk: ReadableStreamDefaultReadResult | undefined + let decodedChunk: AssistantStreamEvent | undefined + let resultMessage: OpenAI.Beta.Threads.Messages.Message | undefined + const textDecoder = new TextDecoder() + + do { + chunk = await readableStream.read() + const decodedValue = textDecoder.decode(chunk.value) + if (decodedValue.length) { + decodedChunk = JSON.parse( + textDecoder.decode(chunk.value) + ) as AssistantStreamEvent + if ( + decodedChunk.event === "thread.message.completed" && + decodedChunk.data.object === "thread.message" + ) { + resultMessage = decodedChunk.data + } else if ( + decodedChunk.event === "thread.run.failed" && + decodedChunk.data.last_error?.code === "server_error" + ) { + // retry + return this.retrieveAiResponse(inputMessage) + } + } + console.log(decodedValue, resultMessage) + } while ( + !resultMessage && + // a run may fail if the rate limit is reached + decodedChunk?.event !== "thread.run.failed" && + decodedChunk?.event !== "thread.run.step.failed" && + decodedChunk?.event !== "thread.message.completed" && + decodedChunk?.event !== "thread.run.completed" + ) + + if (!resultMessage) { + return "" + } + + return resultMessage.content + .map((item) => { + return item.type === "text" ? item.text.value : "" + }) + .join(" ") + .replaceAll("\n", DOCBLOCK_NEW_LINE) + } + + /** + * Formats a class name into a camel-case variable name. + * + * @param className - The class name to format. + * @returns The variable name. + */ + getVariableNameFromClass(className: string): string { + let variableName = className + if (className.startsWith("I") && /[A-Z]/.test(className.charAt(1))) { + variableName = variableName.substring(1) + } + + return pascalToCamel(variableName) + } + + /** + * Retrieves the files that should be uploaded to OpenAI of a node. + * + * @param node - The node to retrieve its files. + * @returns the list of file paths. + */ + getNodeFiles(node: ts.Node): string[] { + const sourceFile = node.getSourceFile() + const files: string[] = [sourceFile.fileName] + if ("imports" in sourceFile) { + ;(sourceFile.imports as ts.StringLiteral[]).forEach((importedFile) => { + if (importedFile.text.startsWith(".")) { + // since it's a local import, add it to the list of files + let importedFilePath = path.resolve( + sourceFile.fileName, + "..", + importedFile.text + ) + if (!path.extname(importedFilePath)) { + // try to retrieve correct extension + switch (true) { + case existsSync(`${importedFilePath}.ts`): + importedFilePath += `.ts` + break + case existsSync(`${importedFilePath}.js`): + importedFilePath += `.js` + break + case existsSync(`${importedFilePath}.tsx`): + importedFilePath += `.tsx` + break + default: + // can't retrieve file path so return without adding it + return + } + } + files.push(importedFilePath) + } + }) + } + + return [...new Set(files)] + } +} + +export default AiGenerator diff --git a/docs-util/packages/docblock-generator/src/classes/helpers/knowledge-base-factory.ts b/docs-util/packages/docblock-generator/src/classes/helpers/knowledge-base-factory.ts index c162afecf2..95bd915aaa 100644 --- a/docs-util/packages/docblock-generator/src/classes/helpers/knowledge-base-factory.ts +++ b/docs-util/packages/docblock-generator/src/classes/helpers/knowledge-base-factory.ts @@ -9,6 +9,7 @@ import { import pluralize from "pluralize" type TemplateOptions = { + pluralIndicatorStr?: string parentName?: string rawParentName?: string returnTypeName?: string @@ -52,6 +53,7 @@ type RetrieveSymbolOptions = Omit & { * A class that holds common Medusa patterns and acts as a knowledge base for possible summaries/examples/general templates. */ class KnowledgeBaseFactory { + private TYPE_PLACEHOLDER = `{type name}` private summaryKnowledgeBase: KnowledgeBase[] = [ { startsWith: "FindConfig", @@ -64,7 +66,7 @@ class KnowledgeBaseFactory { const typeName = typeArgs.length > 0 && typeArgs[0].length > 0 ? typeArgs[0] - : `{type name}` + : this.TYPE_PLACEHOLDER return `The configurations determining how the ${typeName} is retrieved. Its properties, such as \`select\` or \`relations\`, accept the ${DOCBLOCK_NEW_LINE}attributes or relations associated with a ${typeName}.` }, }, @@ -72,35 +74,66 @@ class KnowledgeBaseFactory { startsWith: "Filterable", endsWith: "Props", template: (str) => { - return `The filters to apply on the retrieved ${camelToTitle( + return `The filters to apply on the retrieved ${camelToWords( normalizeName(str) - )}.` + )}s.` }, }, { startsWith: "Create", endsWith: "DTO", - template: (str) => { - return `The ${camelToTitle(normalizeName(str))} to be created.` + template: (str, options) => { + const isPlural = this.isTypePlural(options?.pluralIndicatorStr) + return `The ${camelToWords(normalizeName(str))}${ + isPlural ? "s" : "" + } to be created.` }, }, { startsWith: "Update", endsWith: "DTO", - template: (str) => { - return `The attributes to update in the ${camelToTitle( + template: (str, options) => { + const isPlural = this.isTypePlural(options?.pluralIndicatorStr) + return `The attributes to update in the ${camelToWords( normalizeName(str) - )}.` + )}${isPlural ? "s" : ""}.` + }, + }, + { + endsWith: "UpdatableFields", + template: (str, options) => { + const isPlural = this.isTypePlural(options?.pluralIndicatorStr) + return `The attributes to update in the ${camelToWords( + normalizeName(str) + )}${isPlural ? "s" : ""}.` + }, + }, + { + startsWith: "Upsert", + endsWith: "DTO", + template: (str, options) => { + const isPlural = this.isTypePlural(options?.pluralIndicatorStr) + return `The attributes in the ${camelToWords(normalizeName(str))}${ + isPlural ? "s" : "" + } to be created or updated.` }, }, { startsWith: "RestoreReturn", - template: `Configurations determining which relations to restore along with each of the {type name}. You can pass to its \`returnLinkableKeys\` ${DOCBLOCK_NEW_LINE}property any of the {type name}'s relation attribute names, such as \`{type relation name}\`.`, + template: (_str, options) => { + return this.replaceTypePlaceholder( + `Configurations determining which relations to restore along with each of the ${this.TYPE_PLACEHOLDER}. You can pass to its \`returnLinkableKeys\` ${DOCBLOCK_NEW_LINE}property any of the ${this.TYPE_PLACEHOLDER}'s relation attribute names, such as \`{type relation name}\`.`, + options + ) + }, }, { endsWith: "DTO", - template: (str: string): string => { - return `The ${camelToTitle(normalizeName(str))} details.` + template: (str, options) => { + const isPlural = this.isTypePlural(options?.pluralIndicatorStr) + return `The ${camelToWords(normalizeName(str))}${ + isPlural ? "s" : "" + } details.` }, }, { @@ -127,11 +160,31 @@ class KnowledgeBaseFactory { }, { exact: "id", + template: (str, options) => { + if (options?.rawParentName?.startsWith("Filterable")) { + return `The IDs to filter the ${options?.parentName || `{name}`}s by.` + } + const parentName = options?.parentName + ? options.parentName + : options?.rawParentName + ? camelToWords(normalizeName(options.rawParentName)) + : `{name}` + return `The ID of the ${parentName}.` + }, + kind: [ts.SyntaxKind.PropertySignature], + }, + { + exact: "ids", template: (str, options) => { if (options?.rawParentName?.startsWith("Filterable")) { return `The IDs to filter the ${options?.parentName || `{name}`} by.` } - return `The ID of the ${options?.parentName || `{name}`}.` + const parentName = options?.parentName + ? options.parentName + : options?.rawParentName + ? camelToWords(normalizeName(options.rawParentName)) + : `{name}` + return `The IDs of the ${parentName}.` }, kind: [ts.SyntaxKind.PropertySignature], }, @@ -144,78 +197,194 @@ class KnowledgeBaseFactory { exact: "customHeaders", template: "Custom headers to attach to the request.", }, + { + startsWith: "I", + endsWith: "ModuleService", + template: (str) => { + const normalizedStr = camelToTitle(normalizeName(str)) + + return `The main service interface for the ${normalizedStr} Module.` + }, + }, ] private functionSummaryKnowledgeBase: KnowledgeBase[] = [ { startsWith: "listAndCount", - template: - "retrieves a paginated list of {return type} along with the total count of available {return type}(s) satisfying the provided filters.", + template: (_str, options) => { + return this.replaceTypePlaceholder( + `retrieves a paginated list of ${this.TYPE_PLACEHOLDER}s along with the total count of available ${this.TYPE_PLACEHOLDER}s satisfying the provided filters.`, + options + ) + }, }, { startsWith: "list", - template: - "retrieves a paginated list of {return type}(s) based on optional filters and configuration.", + template: (_str, options) => { + return this.replaceTypePlaceholder( + `retrieves a paginated list of ${this.TYPE_PLACEHOLDER}s based on optional filters and configuration.`, + options + ) + }, }, { startsWith: "retrieve", - template: "retrieves a {return type} by its ID.", + template: (_str, options) => { + return this.replaceTypePlaceholder( + `retrieves a ${this.TYPE_PLACEHOLDER} by its ID.`, + options + ) + }, }, { startsWith: "create", - template: "creates {return type}(s)", + template: (_str, options) => { + const isPlural = this.isTypePlural(options?.pluralIndicatorStr) + return this.replaceTypePlaceholder( + `creates${!isPlural ? " a" : ""} ${this.TYPE_PLACEHOLDER}${ + isPlural ? "s" : "" + }.`, + options + ) + }, }, { startsWith: "delete", - template: "deletes {return type} by its ID.", + template: (_str, options) => { + const isPlural = this.isTypePlural(options?.pluralIndicatorStr) + return this.replaceTypePlaceholder( + `deletes${!isPlural ? " a" : ""} ${this.TYPE_PLACEHOLDER} by ${ + isPlural ? "their" : "its" + } ID${isPlural ? "s" : ""}.`, + options + ) + }, }, { startsWith: "update", - template: "updates existing {return type}(s).", + template: (_str, options) => { + const isPlural = this.isTypePlural(options?.pluralIndicatorStr) + return this.replaceTypePlaceholder( + `updates${!isPlural ? " an" : ""} existing ${this.TYPE_PLACEHOLDER}${ + isPlural ? "s" : "" + }.`, + options + ) + }, }, { startsWith: "softDelete", - template: "soft deletes {return type}(s) by their IDs.", + template: (_str, options) => { + const isPlural = this.isTypePlural(options?.pluralIndicatorStr) + return this.replaceTypePlaceholder( + `soft deletes${!isPlural ? " a" : ""} ${this.TYPE_PLACEHOLDER}${ + isPlural ? "s" : "" + } by ${isPlural ? "their" : "its"} IDs.`, + options + ) + }, }, { startsWith: "restore", - template: "restores soft deleted {return type}(s) by their IDs.", - }, - ] - private exampleCodeBlockLine = `${DOCBLOCK_DOUBLE_LINES}\`\`\`ts${DOCBLOCK_NEW_LINE}{example-code}${DOCBLOCK_NEW_LINE}\`\`\`${DOCBLOCK_DOUBLE_LINES}` - private examplesKnowledgeBase: KnowledgeBase[] = [ - { - startsWith: "list", - template: `To retrieve a list of {type name} using their IDs: ${this.exampleCodeBlockLine}To specify relations that should be retrieved within the {type name}: ${this.exampleCodeBlockLine}By default, only the first \`{default limit}\` records are retrieved. You can control pagination by specifying the \`skip\` and \`take\` properties of the \`config\` parameter: ${this.exampleCodeBlockLine}`, + template: (_str, options) => { + const isPlural = this.isTypePlural(options?.pluralIndicatorStr) + return this.replaceTypePlaceholder( + `restores${!isPlural ? " a" : ""} soft deleted ${ + this.TYPE_PLACEHOLDER + }${isPlural ? "s" : ""} by ${isPlural ? "their" : "its"} IDs.`, + options + ) + }, }, { - startsWith: "retrieve", - template: `A simple example that retrieves a {type name} by its ID: ${this.exampleCodeBlockLine}To specify relations that should be retrieved: ${this.exampleCodeBlockLine}`, + startsWith: "upsert", + template: (_str, options) => { + const isPlural = this.isTypePlural(options?.pluralIndicatorStr) + return this.replaceTypePlaceholder( + `updates or creates${!isPlural ? " a" : ""} ${this.TYPE_PLACEHOLDER}${ + isPlural ? "s" : "" + } if ${isPlural ? "they don't" : "it doesn't"} exist.`, + options + ) + }, }, ] private functionReturnKnowledgeBase: KnowledgeBase[] = [ { startsWith: "listAndCount", - template: "The list of {return type}(s) along with their total count.", + template: (_str, options) => { + return this.replaceTypePlaceholder( + `The list of ${this.TYPE_PLACEHOLDER}s along with their total count.`, + options + ) + }, }, { startsWith: "list", - template: "The list of {return type}(s).", + template: (_str, options) => { + return this.replaceTypePlaceholder( + `The list of ${this.TYPE_PLACEHOLDER}s.`, + options + ) + }, }, { startsWith: "retrieve", - template: "The retrieved {return type}(s).", + template: (_str, options) => { + return this.replaceTypePlaceholder( + `The retrieved ${this.TYPE_PLACEHOLDER}.`, + options + ) + }, }, { startsWith: "create", - template: "The created {return type}(s).", + template: (_str, options) => { + const isPlural = this.isTypePlural(options?.pluralIndicatorStr) + return this.replaceTypePlaceholder( + `The created ${this.TYPE_PLACEHOLDER}${isPlural ? "s" : ""}.`, + options + ) + }, }, { startsWith: "update", - template: "The updated {return type}(s).", + template: (_str, options) => { + const isPlural = this.isTypePlural(options?.pluralIndicatorStr) + return this.replaceTypePlaceholder( + `The updated ${this.TYPE_PLACEHOLDER}${isPlural ? "s" : ""}.`, + options + ) + }, + }, + { + startsWith: "upsert", + template: (_str, options) => { + const isPlural = this.isTypePlural(options?.pluralIndicatorStr) + return this.replaceTypePlaceholder( + `The created or updated ${this.TYPE_PLACEHOLDER}${ + isPlural ? "s" : "" + }.`, + options + ) + }, + }, + { + startsWith: "softDelete", + template: (_str, options) => { + return this.replaceTypePlaceholder( + `An object that includes the IDs of related records that were also soft deleted, such as the ID of the associated {related entity name}. ${DOCBLOCK_NEW_LINE}The object's keys are the ID attribute names of the ${this.TYPE_PLACEHOLDER} entity's relations, such as \`{relation ID field name}\`, and its value is an array of strings, each being the ID of a record associated ${DOCBLOCK_NEW_LINE}with the ${this.TYPE_PLACEHOLDER} through this relation, such as the IDs of associated {related entity name}.${DOCBLOCK_DOUBLE_LINES}If there are no related records, the promise resolves to \`void\`.`, + options + ) + }, }, { startsWith: "restore", - template: `An object that includes the IDs of related records that were restored, such as the ID of associated {relation name}. ${DOCBLOCK_NEW_LINE}The object's keys are the ID attribute names of the {type name} entity's relations, such as \`{relation ID field name}\`, ${DOCBLOCK_NEW_LINE}and its value is an array of strings, each being the ID of the record associated with the money amount through this relation, ${DOCBLOCK_NEW_LINE}such as the IDs of associated {relation name}.`, + template: (_str, options) => { + return this.replaceTypePlaceholder( + `An object that includes the IDs of related records that were restored, such as the ID of associated {relation name}. ${DOCBLOCK_NEW_LINE}The object's keys are the ID attribute names of the ${this.TYPE_PLACEHOLDER} entity's relations, such as \`{relation ID field name}\`, ${DOCBLOCK_NEW_LINE}and its value is an array of strings, each being the ID of the record associated with the ${this.TYPE_PLACEHOLDER} through this relation, ${DOCBLOCK_NEW_LINE}such as the IDs of associated {relation name}.${DOCBLOCK_DOUBLE_LINES}If there are no related records restored, the promise resolves to \`void\`.`, + options + ) + }, }, ] private oasDescriptionKnowledgeBase: KnowledgeBase[] = [ @@ -289,6 +458,34 @@ class KnowledgeBaseFactory { : foundItem?.template(str, templateOptions) } + /** + * This method replaces uses of {@link TYPE_PLACEHOLDER} with the normalized parent name, if provided. + * + * @param str - The string to normalize + * @param options - The template options + * @returns The normalized string + */ + private replaceTypePlaceholder( + str: string, + options?: TemplateOptions + ): string { + const typeName = options?.rawParentName + ? camelToWords(normalizeName(options.rawParentName)) + : this.TYPE_PLACEHOLDER + + return str.replaceAll(this.TYPE_PLACEHOLDER, typeName) + } + + /** + * Checks whether a type should be handled as a plural. Typically used with {@link TemplateOptions.pluralIndicatorStr}. + * + * @param str - The type string to check. + * @returns Whether the type is handled as a plural. + */ + private isTypePlural(str: string | undefined): boolean { + return str?.endsWith("[]") || false + } + /** * Tries to retrieve the summary template of a specified type from the {@link summaryKnowledgeBase}. * @@ -300,6 +497,10 @@ class KnowledgeBaseFactory { ...options, str: normalizedTypeStr, knowledgeBase: this.summaryKnowledgeBase, + templateOptions: { + pluralIndicatorStr: str, + ...options.templateOptions, + }, }) } @@ -319,22 +520,6 @@ class KnowledgeBaseFactory { }) } - /** - * Tries to retrieve the example template of a function's symbol from the {@link examplesKnowledgeBase}. - * - * @returns {string | undefined} The matching knowledge base template, if found. - */ - tryToGetFunctionExamples({ - symbol, - ...options - }: RetrieveSymbolOptions): string | undefined { - return this.tryToFindInKnowledgeBase({ - ...options, - str: symbol.getName(), - knowledgeBase: this.examplesKnowledgeBase, - }) - } - /** * Tries to retrieve the return template of a function's symbol from the {@link functionReturnKnowledgeBase}. * diff --git a/docs-util/packages/docblock-generator/src/classes/kinds/default.ts b/docs-util/packages/docblock-generator/src/classes/kinds/default.ts index ca93d83003..f7ddc7fbc9 100644 --- a/docs-util/packages/docblock-generator/src/classes/kinds/default.ts +++ b/docs-util/packages/docblock-generator/src/classes/kinds/default.ts @@ -20,6 +20,7 @@ import { } from "../../utils/str-formatting.js" import GeneratorEventManager from "../helpers/generator-event-manager.js" import { CommonCliOptions } from "../../types/index.js" +import AiGenerator from "../helpers/ai-generator.js" export type GeneratorOptions = { checker: ts.TypeChecker @@ -31,6 +32,7 @@ export type GeneratorOptions = { export type GetDocBlockOptions = { addEnd?: boolean summaryPrefix?: string + aiGenerator?: AiGenerator } type CommonDocsOptions = { @@ -54,6 +56,7 @@ class DefaultKindGenerator { ts.SyntaxKind.TypeAliasDeclaration, ts.SyntaxKind.PropertySignature, ] + public name = "default" protected allowedKinds: ts.SyntaxKind[] protected checker: ts.TypeChecker protected defaultSummary = "{summary}" @@ -99,10 +102,10 @@ class DefaultKindGenerator { * @returns {string} The node's docblock. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars - getDocBlock( + async getDocBlock( node: T | ts.Node, options: GetDocBlockOptions = { addEnd: true } - ): string { + ): Promise { let str = DOCBLOCK_START const summary = this.getNodeSummary({ node }) @@ -133,6 +136,7 @@ class DefaultKindGenerator { node, symbol, nodeType, + knowledgeBaseOptions: overrideOptions, }: { /** * The node to retrieve the summary comment for. @@ -148,12 +152,20 @@ class DefaultKindGenerator { * will try to retrieve it. */ nodeType?: ts.Type + /** + * Override any of the default knowledge base options + * inferred using the {@link getKnowledgeBaseOptions} method + */ + knowledgeBaseOptions?: Partial }): string { const syntheticComments = ts.getSyntheticLeadingComments(node) if (syntheticComments?.length) { return syntheticComments.map((comment) => comment.text).join(" ") } - const knowledgeBaseOptions = this.getKnowledgeBaseOptions(node) + const knowledgeBaseOptions = { + ...this.getKnowledgeBaseOptions(node), + ...overrideOptions, + } if (!nodeType) { nodeType = "type" in node && node.type && ts.isTypeNode(node.type as ts.Node) diff --git a/docs-util/packages/docblock-generator/src/classes/kinds/dto-property.ts b/docs-util/packages/docblock-generator/src/classes/kinds/dto-property.ts index 9083a74e9c..2aab7d3923 100644 --- a/docs-util/packages/docblock-generator/src/classes/kinds/dto-property.ts +++ b/docs-util/packages/docblock-generator/src/classes/kinds/dto-property.ts @@ -12,6 +12,7 @@ import { */ class DTOPropertyGenerator extends DefaultKindGenerator { protected allowedKinds: ts.SyntaxKind[] = [ts.SyntaxKind.PropertySignature] + public name = "dto-property" /** * Check that the generator can handle generating for the node. @@ -31,12 +32,12 @@ class DTOPropertyGenerator extends DefaultKindGenerator { ) } - getDocBlock( + async getDocBlock( node: ts.PropertyDeclaration | ts.Node, options?: GetDocBlockOptions - ): string { + ): Promise { if (!this.isAllowed(node)) { - return super.getDocBlock(node, options) + return await super.getDocBlock(node, options) } let str = DOCBLOCK_START diff --git a/docs-util/packages/docblock-generator/src/classes/kinds/function.ts b/docs-util/packages/docblock-generator/src/classes/kinds/function.ts index 2ae6aaa030..29f80d242d 100644 --- a/docs-util/packages/docblock-generator/src/classes/kinds/function.ts +++ b/docs-util/packages/docblock-generator/src/classes/kinds/function.ts @@ -7,6 +7,8 @@ import { DOCBLOCK_DOUBLE_LINES, } from "../../constants.js" import getSymbol from "../../utils/get-symbol.js" +import AiGenerator from "../helpers/ai-generator.js" +import path from "path" export type FunctionNode = | ts.MethodDeclaration @@ -32,6 +34,9 @@ class FunctionKindGenerator extends DefaultKindGenerator ...this.methodKinds, ...this.functionKinds, ] + public name = "function" + static EXAMPLE_PLACEHOLDER = `{example-code}` + protected aiParameterExceptions = ["sharedContext"] /** * Checks whether a node is considered a function node. A node is considered a function node if: @@ -135,15 +140,40 @@ class FunctionKindGenerator extends DefaultKindGenerator /** * Retrieves the summary comment of a function. * - * @param {FunctionNode} node - The node's function. - * @param {ts.Symbol} symbol - The node's symbol. If provided, the method will try to retrieve the summary from the {@link KnowledgeBaseFactory}. + * @param {FunctionNode} node - The function's options. * @returns {string} The function's summary comment. */ - getFunctionSummary(node: FunctionNode, symbol?: ts.Symbol): string { + getFunctionSummary({ + node, + symbol, + parentSymbol, + returnType, + }: { + /** + * The node's function. + */ + node: FunctionNode + /** + * The node's symbol. If provided, the method will try to retrieve the summary from the {@link KnowledgeBaseFactory}. + */ + symbol?: ts.Symbol + /** + * The node's parent symbol. This is useful to pass along the parent name to the knowledge base. + */ + parentSymbol?: ts.Symbol + /** + * The node's return type. Useful for the {@link KnowledgeBaseFactory} + */ + returnType?: string + }): string { return symbol ? this.knowledgeBaseFactory.tryToGetFunctionSummary({ symbol: symbol, kind: node.kind, + templateOptions: { + rawParentName: parentSymbol?.getName(), + pluralIndicatorStr: returnType, + }, }) || this.getNodeSummary({ node, symbol }) : this.getNodeSummary({ node, symbol }) } @@ -154,15 +184,53 @@ class FunctionKindGenerator extends DefaultKindGenerator * @param {ts.Symbol} symbol - The function's symbol. If provided, the method will try to retrieve the example from the {@link KnowledgeBaseFactory}. * @returns {string} The function's example comment. */ - getFunctionExample(symbol?: ts.Symbol): string { - const str = `${DOCBLOCK_DOUBLE_LINES}@example${DOCBLOCK_NEW_LINE}` - return `${str}${ - symbol - ? this.knowledgeBaseFactory.tryToGetFunctionExamples({ - symbol: symbol, - }) || `{example-code}` - : `{example-code}` - }` + getFunctionPlaceholderExample(): string { + return this.formatExample(FunctionKindGenerator.EXAMPLE_PLACEHOLDER) + } + + /** + * Retrieves a function's example using the AiGenerator + * + * @param node - The function's node. + * @param aiGenerator - An instance of the AiGenerator + * @returns the example code + */ + async getFunctionExampleAi( + node: FunctionOrVariableNode, + aiGenerator: AiGenerator, + withTag = true + ): Promise { + const actualNode = ts.isVariableStatement(node) + ? this.extractFunctionNode(node) + : node + + if (!actualNode) { + return "" + } + + const symbol = getSymbol(node, this.checker) + + const example = await aiGenerator.generateExample({ + className: this.isMethod(actualNode) + ? getSymbol(node.parent, this.checker)?.name + : undefined, + functionName: symbol?.name || "", + signature: node.getText(), + fileName: path.basename(node.getSourceFile().fileName), + }) + + return this.formatExample( + example.length + ? `${example}${DOCBLOCK_NEW_LINE}` + : FunctionKindGenerator.EXAMPLE_PLACEHOLDER, + withTag + ) + } + + formatExample(example: string, withTag = true): string { + return `${ + withTag ? `${DOCBLOCK_DOUBLE_LINES}@example${DOCBLOCK_NEW_LINE}` : "" + }${example}` } /** @@ -173,12 +241,12 @@ class FunctionKindGenerator extends DefaultKindGenerator * @param {GetDocBlockOptions} options - Formatting options. * @returns {string} The function's docblock. */ - getDocBlock( + async getDocBlock( node: FunctionOrVariableNode | ts.Node, options: GetDocBlockOptions = { addEnd: true } - ): string { + ): Promise { if (!this.isAllowed(node)) { - return super.getDocBlock(node, options) + return await super.getDocBlock(node, options) } const actualNode = ts.isVariableStatement(node) @@ -186,10 +254,34 @@ class FunctionKindGenerator extends DefaultKindGenerator : node if (!actualNode) { - return super.getDocBlock(node, options) + return await super.getDocBlock(node, options) + } + + let existingComments = this.getNodeCommentsFromRange(node) + + if (existingComments?.includes(FunctionKindGenerator.EXAMPLE_PLACEHOLDER)) { + // just replace the existing comment and return it + if (options.aiGenerator) { + existingComments = existingComments.replace( + FunctionKindGenerator.EXAMPLE_PLACEHOLDER, + await this.getFunctionExampleAi( + actualNode, + options.aiGenerator, + false + ) + ) + } + + return existingComments.replace("/*", "").replace("*/", "") } const nodeSymbol = getSymbol(node, this.checker) + const nodeParentSymbol = getSymbol(node.parent, this.checker) + const nodeType = this.getReturnType(actualNode) + const returnTypeStr = this.checker.typeToString(nodeType) + const normalizedTypeStr = returnTypeStr.startsWith("Promise<") + ? returnTypeStr.replace(/^Promise$/, "") + : returnTypeStr let str = DOCBLOCK_START @@ -197,35 +289,43 @@ class FunctionKindGenerator extends DefaultKindGenerator str += `${ options.summaryPrefix || (this.isMethod(actualNode) ? `This method` : `This function`) - } ${this.getFunctionSummary(actualNode, nodeSymbol)}${DOCBLOCK_NEW_LINE}` + } ${this.getFunctionSummary({ + node: actualNode, + symbol: nodeSymbol, + parentSymbol: nodeParentSymbol, + returnType: normalizedTypeStr, + })}${DOCBLOCK_NEW_LINE}` - // add params - actualNode.forEachChild((childNode) => { - if (!ts.isParameter(childNode)) { - return - } - const symbol = getSymbol(childNode, this.checker) + actualNode.parameters.map((parameterNode) => { + const symbol = getSymbol(parameterNode, this.checker) if (!symbol) { return } const symbolType = this.checker.getTypeOfSymbolAtLocation( symbol, - childNode + parameterNode ) + const parameterName = symbol.getName() + const parameterSummary = this.getNodeSummary({ + node: parameterNode, + symbol, + nodeType: symbolType, + knowledgeBaseOptions: { + templateOptions: { + rawParentName: nodeParentSymbol?.getName(), + pluralIndicatorStr: this.checker.typeToString(symbolType), + }, + }, + }) + str += `${DOCBLOCK_NEW_LINE}@param {${this.checker.typeToString( symbolType - )}} ${symbol.getName()} - ${this.getNodeSummary({ - node: childNode, - symbol, - nodeType: symbolType, - })}` + )}} ${parameterName} - ${parameterSummary}` }) // add returns - const nodeType = this.getReturnType(actualNode) - const returnTypeStr = this.checker.typeToString(nodeType) const possibleReturnSummary = !this.hasReturnData(returnTypeStr) ? `Resolves when ${this.defaultSummary}` : this.getNodeSummary({ @@ -238,12 +338,20 @@ class FunctionKindGenerator extends DefaultKindGenerator ? this.knowledgeBaseFactory.tryToGetFunctionReturns({ symbol: nodeSymbol, kind: actualNode.kind, + templateOptions: { + rawParentName: nodeParentSymbol?.getName(), + pluralIndicatorStr: normalizedTypeStr, + }, }) || possibleReturnSummary : possibleReturnSummary }` // add example - str += this.getFunctionExample(nodeSymbol) + if (!options.aiGenerator) { + str += this.getFunctionPlaceholderExample() + } else { + str += await this.getFunctionExampleAi(actualNode, options.aiGenerator) + } // add common docs str += this.getCommonDocs(node, { @@ -256,6 +364,22 @@ class FunctionKindGenerator extends DefaultKindGenerator return str } + + /** + * Allows documenting (updating) a node if it has the example placeholder. + * + * @param node - The node to document. + * @returns Whether the node can be documented. + */ + canDocumentNode(node: ts.Node): boolean { + const comments = this.getNodeCommentsFromRange(node) + + return ( + !comments || + comments?.includes(FunctionKindGenerator.EXAMPLE_PLACEHOLDER) || + false + ) + } } export default FunctionKindGenerator diff --git a/docs-util/packages/docblock-generator/src/classes/kinds/medusa-react-hooks.ts b/docs-util/packages/docblock-generator/src/classes/kinds/medusa-react-hooks.ts index 2d9332fa73..26747b1bb1 100644 --- a/docs-util/packages/docblock-generator/src/classes/kinds/medusa-react-hooks.ts +++ b/docs-util/packages/docblock-generator/src/classes/kinds/medusa-react-hooks.ts @@ -19,6 +19,7 @@ import { * it extends the {@link FunctionKindGenerator} class. */ class MedusaReactHooksKindGenerator extends FunctionKindGenerator { + public name = "medusa-react" /** * Checks whether the generator can retrieve the docblock of the specified node. It uses the parent generator * to check that the node is a function, then checks if the function is a mutation using the {@link isMutation} method, @@ -80,9 +81,12 @@ class MedusaReactHooksKindGenerator extends FunctionKindGenerator { * @param {FunctionNode & ts.VariableDeclaration} node - The node to retrieve its docblock. * @returns {string} The node's docblock. */ - getDocBlock(node: FunctionNode & ts.VariableDeclaration): string { + async getDocBlock( + node: FunctionNode & ts.VariableDeclaration + ): Promise { + // TODO use the AiGenerator to generate summary + examples if (!this.isAllowed(node)) { - return super.getDocBlock(node) + return await super.getDocBlock(node) } const actualNode = ts.isVariableStatement(node) @@ -90,25 +94,29 @@ class MedusaReactHooksKindGenerator extends FunctionKindGenerator { : node if (!actualNode) { - return super.getDocBlock(node) + return await super.getDocBlock(node) } const isMutation = this.isMutation(actualNode) - let str = `${DOCBLOCK_START}This hook ${this.getFunctionSummary(node)}` + let str = `${DOCBLOCK_START}This hook ${this.getFunctionSummary({ + node, + })}` // add example - str += this.getFunctionExample() + str += this.getFunctionPlaceholderExample() // loop over parameters that aren't query/mutation parameters // and add docblock to them - this.getActualParameters(actualNode).forEach((parameter) => { - ts.addSyntheticLeadingComment( - parameter, - ts.SyntaxKind.MultiLineCommentTrivia, - super.getDocBlock(parameter), - true - ) - }) + await Promise.all( + this.getActualParameters(actualNode).map(async (parameter) => { + ts.addSyntheticLeadingComment( + parameter, + ts.SyntaxKind.MultiLineCommentTrivia, + await super.getDocBlock(parameter), + true + ) + }) + ) // check if mutation parameter is an intrinsic type and, if so, add the `@typeParamDefinition` // tag to the hook diff --git a/docs-util/packages/docblock-generator/src/classes/kinds/oas.ts b/docs-util/packages/docblock-generator/src/classes/kinds/oas.ts index 76ef0cf79a..35d0a37205 100644 --- a/docs-util/packages/docblock-generator/src/classes/kinds/oas.ts +++ b/docs-util/packages/docblock-generator/src/classes/kinds/oas.ts @@ -48,6 +48,7 @@ type ParameterType = "query" | "path" * since API routes are functions. */ class OasKindGenerator extends FunctionKindGenerator { + public name = "oas" protected allowedKinds: SyntaxKind[] = [ts.SyntaxKind.FunctionDeclaration] private MAX_LEVEL = 4 // we can't use `{summary}` because it causes an MDX error @@ -166,12 +167,13 @@ class OasKindGenerator extends FunctionKindGenerator { * @param options - The options to get the OAS. * @returns The OAS as a string that can be used as a comment in a TypeScript file. */ - getDocBlock( + async getDocBlock( node: ts.Node | FunctionOrVariableNode, options?: GetDocBlockOptions - ): string { + ): Promise { + // TODO use AiGenerator to generate descriptions + examples if (!this.isAllowed(node)) { - return super.getDocBlock(node, options) + return await super.getDocBlock(node, options) } const actualNode = ts.isVariableStatement(node) @@ -179,7 +181,7 @@ class OasKindGenerator extends FunctionKindGenerator { : node if (!actualNode) { - return super.getDocBlock(node, options) + return await super.getDocBlock(node, options) } const methodName = this.getHTTPMethodName(node) diff --git a/docs-util/packages/docblock-generator/src/classes/kinds/registry.ts b/docs-util/packages/docblock-generator/src/classes/kinds/registry.ts index 1f0c9f5f66..7dd9d6521a 100644 --- a/docs-util/packages/docblock-generator/src/classes/kinds/registry.ts +++ b/docs-util/packages/docblock-generator/src/classes/kinds/registry.ts @@ -53,6 +53,16 @@ class KindsRegistry { hasGenerator(node: ts.Node): boolean { return this.getKindGenerator(node) !== undefined } + + /** + * Retrieves a generator by its name attribute. + * + * @param name - The name of the generator to retrieve. + * @returns The generator, if exists. + */ + getKindGeneratorByName(name: string): DefaultKindGenerator | undefined { + return this.kindInstances.find((generator) => generator.name === name) + } } export default KindsRegistry diff --git a/docs-util/packages/docblock-generator/src/classes/kinds/source-file.ts b/docs-util/packages/docblock-generator/src/classes/kinds/source-file.ts index 906fcfb2aa..59b530a2d8 100644 --- a/docs-util/packages/docblock-generator/src/classes/kinds/source-file.ts +++ b/docs-util/packages/docblock-generator/src/classes/kinds/source-file.ts @@ -8,6 +8,7 @@ import { shouldHaveCustomNamespace } from "../../utils/medusa-react-utils.js" */ class SourceFileKindGenerator extends DefaultKindGenerator { protected allowedKinds: ts.SyntaxKind[] = [ts.SyntaxKind.SourceFile] + public name = "source-file" /** * Retrieve the docblock of a source file. @@ -16,12 +17,12 @@ class SourceFileKindGenerator extends DefaultKindGenerator { * @param {GetDocBlockOptions} options - The formatting options. * @returns {string} The node's docblock. */ - getDocBlock( + async getDocBlock( node: ts.SourceFile | ts.Node, options?: GetDocBlockOptions - ): string { + ): Promise { if (!this.isAllowed(node)) { - return super.getDocBlock(node, options) + return await super.getDocBlock(node, options) } if (shouldHaveCustomNamespace(node)) { diff --git a/docs-util/packages/docblock-generator/src/utils/str-formatting.ts b/docs-util/packages/docblock-generator/src/utils/str-formatting.ts index 15d6ba866b..bc8a36fa64 100644 --- a/docs-util/packages/docblock-generator/src/utils/str-formatting.ts +++ b/docs-util/packages/docblock-generator/src/utils/str-formatting.ts @@ -22,7 +22,6 @@ export function camelToTitle(str: string): string { .map((word) => capitalize(word)) .join(" ") .trim() - .toLowerCase() } export function snakeToWords(str: string): string { @@ -62,6 +61,10 @@ export function wordsToPascal(str: string): string { .join("") } +export function pascalToCamel(str: string): string { + return `${str.charAt(0).toLowerCase()}${str.substring(1)}` +} + /** * Remove parts of the name such as DTO, Filterable, etc... * @@ -70,8 +73,10 @@ export function wordsToPascal(str: string): string { */ export function normalizeName(str: string): string { return str - .replace(/^(create|update|delete)/i, "") + .replace(/^(create|update|delete|upsert)/i, "") .replace(/DTO$/, "") .replace(/^Filterable/, "") .replace(/Props$/, "") + .replace(/^I([A-Z])/, "$1") + .replace(/ModuleService$/, "") } diff --git a/docs-util/yarn.lock b/docs-util/yarn.lock index 9426e7ebb9..612bd5d2f9 100644 --- a/docs-util/yarn.lock +++ b/docs-util/yarn.lock @@ -1401,6 +1401,16 @@ __metadata: languageName: node linkType: hard +"@types/node-fetch@npm:^2.6.4": + version: 2.6.11 + resolution: "@types/node-fetch@npm:2.6.11" + dependencies: + "@types/node": "*" + form-data: ^4.0.0 + checksum: 5283d4e0bcc37a5b6d8e629aee880a4ffcfb33e089f4b903b2981b19c623972d1e64af7c3f9540ab990f0f5c89b9b5dda19c5bcb37a8e177079e93683bfd2f49 + languageName: node + linkType: hard + "@types/node@npm:*, @types/node@npm:^20.8.3, @types/node@npm:^20.9.4": version: 20.10.0 resolution: "@types/node@npm:20.10.0" @@ -1417,6 +1427,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^18.11.18": + version: 18.19.25 + resolution: "@types/node@npm:18.19.25" + dependencies: + undici-types: ~5.26.4 + checksum: 4cd82b81700c38464cfc8ce5a94d3e115ef9e9befe7637a89c732c4036ab7c761ec69e4d93717a7c05ab58c87cf046eaafd3e0157d5406e387bcb185d27710ab + languageName: node + linkType: hard + "@types/randomcolor@npm:^0.5.8": version: 0.5.9 resolution: "@types/randomcolor@npm:0.5.9" @@ -1576,6 +1595,15 @@ __metadata: languageName: node linkType: hard +"abort-controller@npm:^3.0.0": + version: 3.0.0 + resolution: "abort-controller@npm:3.0.0" + dependencies: + event-target-shim: ^5.0.0 + checksum: 90ccc50f010250152509a344eb2e71977fbf8db0ab8f1061197e3275ddf6c61a41a6edfd7b9409c664513131dd96e962065415325ef23efa5db931b382d24ca5 + languageName: node + linkType: hard + "acorn-jsx@npm:^5.3.2": version: 5.3.2 resolution: "acorn-jsx@npm:5.3.2" @@ -1626,6 +1654,15 @@ __metadata: languageName: node linkType: hard +"agentkeepalive@npm:^4.2.1": + version: 4.5.0 + resolution: "agentkeepalive@npm:4.5.0" + dependencies: + humanize-ms: ^1.2.1 + checksum: 394ea19f9710f230722996e156607f48fdf3a345133b0b1823244b7989426c16019a428b56c82d3eabef616e938812981d9009f4792ecc66bd6a59e991c62612 + languageName: node + linkType: hard + "aggregate-error@npm:^3.1.0": version: 3.1.0 resolution: "aggregate-error@npm:3.1.0" @@ -1724,6 +1761,13 @@ __metadata: languageName: node linkType: hard +"asynckit@npm:^0.4.0": + version: 0.4.0 + resolution: "asynckit@npm:0.4.0" + checksum: d73e2ddf20c4eb9337e1b3df1a0f6159481050a5de457c55b14ea2e5cb6d90bb69e004c9af54737a5ee0917fcf2c9e25de67777bbe58261847846066ba75bc9d + languageName: node + linkType: hard + "awilix@npm:^8.0.0, awilix@npm:^8.0.1": version: 8.0.1 resolution: "awilix@npm:8.0.1" @@ -1741,6 +1785,13 @@ __metadata: languageName: node linkType: hard +"base-64@npm:^0.1.0": + version: 0.1.0 + resolution: "base-64@npm:0.1.0" + checksum: fe0dcf076e823f04db7ee9b02495be08a91c445fbc6db03cb9913be9680e2fcc0af8b74459041fe08ad16800b1f65a549501d8f08696a8a6d32880789b7de69d + languageName: node + linkType: hard + "base64-js@npm:^1.3.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" @@ -1937,6 +1988,13 @@ __metadata: languageName: node linkType: hard +"charenc@npm:0.0.2": + version: 0.0.2 + resolution: "charenc@npm:0.0.2" + checksum: a45ec39363a16799d0f9365c8dd0c78e711415113c6f14787a22462ef451f5013efae8a28f1c058f81fc01f2a6a16955f7a5fd0cd56247ce94a45349c89877d8 + languageName: node + linkType: hard + "chownr@npm:^1.1.1": version: 1.1.4 resolution: "chownr@npm:1.1.4" @@ -2030,6 +2088,15 @@ __metadata: languageName: node linkType: hard +"combined-stream@npm:^1.0.8": + version: 1.0.8 + resolution: "combined-stream@npm:1.0.8" + dependencies: + delayed-stream: ~1.0.0 + checksum: 0dbb829577e1b1e839fa82b40c07ffaf7de8a09b935cadd355a73652ae70a88b4320db322f6634a4ad93424292fa80973ac6480986247f1734a1137debf271d5 + languageName: node + linkType: hard + "commander@npm:^10.0.0": version: 10.0.1 resolution: "commander@npm:10.0.1" @@ -2138,6 +2205,13 @@ __metadata: languageName: node linkType: hard +"crypt@npm:0.0.2": + version: 0.0.2 + resolution: "crypt@npm:0.0.2" + checksum: adbf263441dd801665d5425f044647533f39f4612544071b1471962209d235042fb703c27eea2795c7c53e1dfc242405173003f83cf4f4761a633d11f9653f18 + languageName: node + linkType: hard + "debug@npm:4, debug@npm:4.3.4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.2, debug@npm:^4.3.4": version: 4.3.4 resolution: "debug@npm:4.3.4" @@ -2186,6 +2260,13 @@ __metadata: languageName: node linkType: hard +"delayed-stream@npm:~1.0.0": + version: 1.0.0 + resolution: "delayed-stream@npm:1.0.0" + checksum: d758899da03392e6712f042bec80aa293bbe9e9ff1b2634baae6a360113e708b91326594c8a486d475c69d6259afb7efacdc3537bfcda1c6c648e390ce601b19 + languageName: node + linkType: hard + "deprecation@npm:^2.0.0, deprecation@npm:^2.3.1": version: 2.3.1 resolution: "deprecation@npm:2.3.1" @@ -2207,6 +2288,16 @@ __metadata: languageName: node linkType: hard +"digest-fetch@npm:^1.3.0": + version: 1.3.0 + resolution: "digest-fetch@npm:1.3.0" + dependencies: + base-64: ^0.1.0 + md5: ^2.3.0 + checksum: 0fb389e33b9c6baf5e6a9ed287aa9d0d8b373d59b49d49c62c261e1ab24eaaf1d5aea3a105c1b31ba4a23e29e129365d839ce4c5974fa004a85d1a4568bc3585 + languageName: node + linkType: hard + "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -2227,6 +2318,7 @@ __metadata: dotenv: ^16.3.1 eslint: ^8.56.0 minimatch: ^9.0.3 + openai: ^4.29.1 openapi-types: ^12.1.3 pluralize: ^8.0.0 prettier: ^3.2.4 @@ -2585,6 +2677,13 @@ __metadata: languageName: node linkType: hard +"event-target-shim@npm:^5.0.0": + version: 5.0.1 + resolution: "event-target-shim@npm:5.0.1" + checksum: 0255d9f936215fd206156fd4caa9e8d35e62075d720dc7d847e89b417e5e62cf1ce6c9b4e0a1633a9256de0efefaf9f8d26924b1f3c8620cffb9db78e7d3076b + languageName: node + linkType: hard + "execa@npm:^5.0.0": version: 5.1.1 resolution: "execa@npm:5.1.1" @@ -2751,6 +2850,34 @@ __metadata: languageName: node linkType: hard +"form-data-encoder@npm:1.7.2": + version: 1.7.2 + resolution: "form-data-encoder@npm:1.7.2" + checksum: 56553768037b6d55d9de524f97fe70555f0e415e781cb56fc457a68263de3d40fadea2304d4beef2d40b1a851269bd7854e42c362107071892cb5238debe9464 + languageName: node + linkType: hard + +"form-data@npm:^4.0.0": + version: 4.0.0 + resolution: "form-data@npm:4.0.0" + dependencies: + asynckit: ^0.4.0 + combined-stream: ^1.0.8 + mime-types: ^2.1.12 + checksum: cb6f3ac49180be03ff07ba3ff125f9eba2ff0b277fb33c7fc47569fc5e616882c5b1c69b9904c4c4187e97dd0419dd03b134174756f296dec62041e6527e2c6e + languageName: node + linkType: hard + +"formdata-node@npm:^4.3.2": + version: 4.4.1 + resolution: "formdata-node@npm:4.4.1" + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 4.0.0-beta.3 + checksum: 74151e7b228ffb33b565cec69182694ad07cc3fdd9126a8240468bb70a8ba66e97e097072b60bcb08729b24c7ce3fd3e0bd7f1f80df6f9f662b9656786e76f6a + languageName: node + linkType: hard + "fs-constants@npm:^1.0.0": version: 1.0.0 resolution: "fs-constants@npm:1.0.0" @@ -3020,6 +3147,15 @@ __metadata: languageName: node linkType: hard +"humanize-ms@npm:^1.2.1": + version: 1.2.1 + resolution: "humanize-ms@npm:1.2.1" + dependencies: + ms: ^2.0.0 + checksum: f34a2c20161d02303c2807badec2f3b49cbfbbb409abd4f95a07377ae01cfe6b59e3d15ac609cffcd8f2521f0eb37b7e1091acf65da99aa2a4f1ad63c21e7e7a + languageName: node + linkType: hard + "ieee754@npm:^1.1.13": version: 1.2.1 resolution: "ieee754@npm:1.2.1" @@ -3089,6 +3225,13 @@ __metadata: languageName: node linkType: hard +"is-buffer@npm:~1.1.6": + version: 1.1.6 + resolution: "is-buffer@npm:1.1.6" + checksum: ae18aa0b6e113d6c490ad1db5e8df9bdb57758382b313f5a22c9c61084875c6396d50bbf49315f5b1926d142d74dfb8d31b40d993a383e0a158b15fea7a82234 + languageName: node + linkType: hard + "is-core-module@npm:^2.13.0": version: 2.13.1 resolution: "is-core-module@npm:2.13.1" @@ -3601,6 +3744,17 @@ __metadata: languageName: node linkType: hard +"md5@npm:^2.3.0": + version: 2.3.0 + resolution: "md5@npm:2.3.0" + dependencies: + charenc: 0.0.2 + crypt: 0.0.2 + is-buffer: ~1.1.6 + checksum: 14a21d597d92e5b738255fbe7fe379905b8cb97e0a49d44a20b58526a646ec5518c337b817ce0094ca94d3e81a3313879c4c7b510d250c282d53afbbdede9110 + languageName: node + linkType: hard + "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" @@ -3632,6 +3786,22 @@ __metadata: languageName: node linkType: hard +"mime-db@npm:1.52.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 0557a01deebf45ac5f5777fe7740b2a5c309c6d62d40ceab4e23da9f821899ce7a900b7ac8157d4548ddbb7beffe9abc621250e6d182b0397ec7f10c7b91a5aa + languageName: node + linkType: hard + +"mime-types@npm:^2.1.12": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: 1.52.0 + checksum: 82fb07ec56d8ff1fc999a84f2f217aa46cb6ed1033fefaabd5785b9a974ed225c90dc72fff460259e66b95b73648596dbcc50d51ed69cdf464af2d237d3149b2 + languageName: node + linkType: hard + "mimic-fn@npm:^2.1.0": version: 2.1.0 resolution: "mimic-fn@npm:2.1.0" @@ -3724,7 +3894,7 @@ __metadata: languageName: node linkType: hard -"ms@npm:^2.1.1": +"ms@npm:^2.0.0, ms@npm:^2.1.1": version: 2.1.3 resolution: "ms@npm:2.1.3" checksum: d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 @@ -3755,6 +3925,13 @@ __metadata: languageName: node linkType: hard +"node-domexception@npm:1.0.0": + version: 1.0.0 + resolution: "node-domexception@npm:1.0.0" + checksum: 5e5d63cda29856402df9472335af4bb13875e1927ad3be861dc5ebde38917aecbf9ae337923777af52a48c426b70148815e890a5d72760f1b4d758cc671b1a2b + languageName: node + linkType: hard + "node-fetch@npm:2.6.7": version: 2.6.7 resolution: "node-fetch@npm:2.6.7" @@ -3875,6 +4052,25 @@ __metadata: languageName: node linkType: hard +"openai@npm:^4.29.1": + version: 4.29.1 + resolution: "openai@npm:4.29.1" + dependencies: + "@types/node": ^18.11.18 + "@types/node-fetch": ^2.6.4 + abort-controller: ^3.0.0 + agentkeepalive: ^4.2.1 + digest-fetch: ^1.3.0 + form-data-encoder: 1.7.2 + formdata-node: ^4.3.2 + node-fetch: ^2.6.7 + web-streams-polyfill: ^3.2.1 + bin: + openai: bin/cli + checksum: 7873d1c8f69d8a76ca38bd3b0aa10e967ee1a2e705a1a2eb1012dcdd1b689569e041e1bcbeb72e10fc15a43d62c0f99e01de58c8ed454e8c0b54626b58c0794f + languageName: node + linkType: hard + "openapi-types@npm:^12.1.3": version: 12.1.3 resolution: "openapi-types@npm:12.1.3" @@ -5354,6 +5550,20 @@ __metadata: languageName: node linkType: hard +"web-streams-polyfill@npm:4.0.0-beta.3": + version: 4.0.0-beta.3 + resolution: "web-streams-polyfill@npm:4.0.0-beta.3" + checksum: a9596779db2766990117ed3a158e0b0e9f69b887a6d6ba0779940259e95f99dc3922e534acc3e5a117b5f5905300f527d6fbf8a9f0957faf1d8e585ce3452e8e + languageName: node + linkType: hard + +"web-streams-polyfill@npm:^3.2.1": + version: 3.3.3 + resolution: "web-streams-polyfill@npm:3.3.3" + checksum: 64e855c47f6c8330b5436147db1c75cb7e7474d924166800e8e2aab5eb6c76aac4981a84261dd2982b3e754490900b99791c80ae1407a9fa0dcff74f82ea3a7f + languageName: node + linkType: hard + "webidl-conversions@npm:^3.0.0": version: 3.0.1 resolution: "webidl-conversions@npm:3.0.1" diff --git a/packages/types/src/order/service.ts b/packages/types/src/order/service.ts index a88d649b6e..12b370c925 100644 --- a/packages/types/src/order/service.ts +++ b/packages/types/src/order/service.ts @@ -47,126 +47,694 @@ import { UpsertOrderLineItemAdjustmentDTO, } from "./mutations" +/** + * {summary} + */ export interface IOrderModuleService extends IModuleService { + /** + * This method retrieves a {return type} by its ID. + * + * @param {string} orderId - The order's ID. + * @param {FindConfig} config - The configurations determining how the order is retrieved. Its properties, such as `select` or `relations`, accept the + * attributes or relations associated with a order. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The retrieved {return type}(s). + * + * @example + * ```typescript + * const result = await orderModuleService.retrieve("orderId123"); + * ``` + * + */ retrieve( orderId: string, config?: FindConfig, sharedContext?: Context ): Promise + /** + * This method retrieves a paginated list of {return type}(s) based on optional filters and configuration. + * + * @param {FilterableOrderProps} filters - The filters to apply on the retrieved order. + * @param {FindConfig} config - The configurations determining how the order is retrieved. Its properties, such as `select` or `relations`, accept the + * attributes or relations associated with a order. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The list of {return type}(s). + * + * @example + * ```typescript + * const orderDTOs = await orderModuleService.list(); + * ``` + * + */ list( filters?: FilterableOrderProps, config?: FindConfig, sharedContext?: Context ): Promise + /** + * This method retrieves a paginated list of {return type} along with the total count of available {return type}(s) satisfying the provided filters. + * + * @param {FilterableOrderProps} filters - The filters to apply on the retrieved order. + * @param {FindConfig} config - The configurations determining how the order is retrieved. Its properties, such as `select` or `relations`, accept the + * attributes or relations associated with a order. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise<[OrderDTO[], number]>} The list of {return type}(s) along with their total count. + * + * @example + * ```typescript + * await orderModuleService.listAndCount(); + * ``` + * + */ listAndCount( filters?: FilterableOrderProps, config?: FindConfig, sharedContext?: Context ): Promise<[OrderDTO[], number]> + /** + * This method creates {return type}(s) + * + * @param {CreateOrderDTO[]} data - The order to be created. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The created {return type}(s). + * + * @example + * ```typescript + * const orderData: CreateOrderDTO[] = [ + * { + * currency_code: "USD", + * items: [ + * { + * title: "Product Name", + * quantity: 1, + * unit_price: 1999, // Assuming type is an integer for price in cents + * } + * ] + * } + * ]; + * + * const result = await orderModuleService.create(orderData); + * ``` + * + */ create(data: CreateOrderDTO[], sharedContext?: Context): Promise + + /** + * This method creates {return type}(s) + * + * @param {CreateOrderDTO} data - The order to be created. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The created {return type}(s). + * + * @example + * ```typescript + * // Example execution of the create method of IOrderModuleService + * const orderData: CreateOrderDTO = { + * currency_code: "USD" + * }; + * + * const createdOrder = await orderModuleService.create(orderData); + * ``` + * + */ create(data: CreateOrderDTO, sharedContext?: Context): Promise + /** + * This method updates existing {return type}(s). + * + * @param {UpdateOrderDTO[]} data - The attributes to update in the order. + * @returns {Promise} The updated {return type}(s). + * + * @example + * ```typescript + * const updatedOrders = await orderModuleService.update([ + * { + * id: "order_id_1", + * status: "shipped" + * }, + * { + * id: "order_id_2", + * status: "delivered" + * } + * ]); + * ``` + * + */ update(data: UpdateOrderDTO[]): Promise + + /** + * This method updates existing {return type}(s). + * + * @param {string} orderId - The order's ID. + * @param {UpdateOrderDTO} data - The attributes to update in the order. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The updated {return type}(s). + * + * @example + * ```typescript + * await orderModuleService.update("orderId123", { + * status: "shipped" + * }); + * ``` + * + */ update( orderId: string, data: UpdateOrderDTO, sharedContext?: Context ): Promise + + /** + * This method updates existing {return type}(s). + * + * @param {Partial} selector - Make all properties in T optional + * @param {UpdateOrderDTO} data - The attributes to update in the order. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The updated {return type}(s). + * + * @example + * ```typescript + * await orderModuleService.update( + * { id: "order-123" }, + * { status: "completed" } + * ); + * ``` + * + */ update( selector: Partial, data: UpdateOrderDTO, sharedContext?: Context ): Promise + /** + * This method deletes {return type} by its ID. + * + * @param {string[]} orderIds - The list of {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.delete(["12345abc", "67890def"]); + * ``` + * + */ delete(orderIds: string[], sharedContext?: Context): Promise + + /** + * This method deletes {return type} by its ID. + * + * @param {string} orderId - The order's ID. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.delete("orderId"); + * ``` + * + */ delete(orderId: string, sharedContext?: Context): Promise + /** + * This method retrieves a paginated list of {return type}(s) based on optional filters and configuration. + * + * @param {FilterableOrderAddressProps} filters - The filters to apply on the retrieved order address. + * @param {FindConfig} config - The configurations determining how the order address is retrieved. Its properties, such as `select` or `relations`, accept the + * attributes or relations associated with a order address. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The list of {return type}(s). + * + * @example + * ```typescript + * await orderModuleService.listAddresses(); + * ``` + * + */ listAddresses( filters?: FilterableOrderAddressProps, config?: FindConfig, sharedContext?: Context ): Promise + /** + * This method creates {return type}(s) + * + * @param {CreateOrderAddressDTO[]} data - The order address to be created. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The created {return type}(s). + * + * @example + * ```typescript + * await orderModuleService.createAddresses([ + * { + * first_name: "John", + * last_name: "Doe", + * address_1: "123 Main St", + * city: "Anytown", + * country_code: "US", + * province: "AnyState", + * postal_code: "12345" + * } + * ]); + * ``` + * + */ createAddresses( data: CreateOrderAddressDTO[], sharedContext?: Context ): Promise + + /** + * This method creates {return type}(s) + * + * @param {CreateOrderAddressDTO} data - The order address to be created. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The created {return type}(s). + * + * @example + * ```typescript + * const orderAddressData: CreateOrderAddressDTO = { + * orderId: '123', + * line1: '123 Main St', + * city: 'Metropolis', + * state: 'NY', + * postalCode: '12345', + * country: 'USA' + * }; + * + * const result = await orderModuleService.createAddresses(orderAddressData); + * ``` + * + */ createAddresses( data: CreateOrderAddressDTO, sharedContext?: Context ): Promise + /** + * This method updates existing {return type}(s). + * + * @param {UpdateOrderAddressDTO[]} data - The attributes to update in the order address. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The updated {return type}(s). + * + * @example + * ```typescript + * const updatedAddress: UpdateOrderAddressDTO[] = [ + * { + * id: "address1", + * first_name: "John", + * last_name: "Doe", + * address_1: "123 Main St", + * city: "Anytown", + * country_code: "US", + * province: "AnyState", + * postal_code: "12345" + * } + * ]; + * + * const result = await orderModuleService.updateAddresses(updatedAddress); + * ``` + * + */ updateAddresses( data: UpdateOrderAddressDTO[], sharedContext?: Context ): Promise + + /** + * This method updates existing {return type}(s). + * + * @param {UpdateOrderAddressDTO} data - The attributes to update in the order address. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The updated {return type}(s). + * + * @example + * ```typescript + * const updateOrderAddressData: UpdateOrderAddressDTO = { + * id: '123', + * address_1: '123 Main St', + * city: 'Metropolis', + * province: 'NY', + * postal_code: '12345', + * }; + * + * const updatedAddress = await orderModuleService.updateAddresses(updateOrderAddressData); + * ``` + * + */ updateAddresses( data: UpdateOrderAddressDTO, sharedContext?: Context ): Promise + /** + * This method deletes {return type} by its ID. + * + * @param {string[]} ids - The list of {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.deleteAddresses(["your_address_id_1", "your_address_id_2"]); + * ``` + * + */ deleteAddresses(ids: string[], sharedContext?: Context): Promise + + /** + * This method deletes {return type} by its ID. + * + * @param {string} ids - {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.deleteAddresses("123456"); + * ``` + * + */ deleteAddresses(ids: string, sharedContext?: Context): Promise + /** + * This method retrieves a {return type} by its ID. + * + * @param {string} itemId - The item's ID. + * @param {FindConfig} config - The configurations determining how the order line item is retrieved. Its properties, such as `select` or `relations`, accept the + * attributes or relations associated with a order line item. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The retrieved {return type}(s). + * + * @example + * ```typescript + * await orderModuleService.retrieveLineItem("12345"); + * ``` + * + */ retrieveLineItem( itemId: string, config?: FindConfig, sharedContext?: Context ): Promise + /** + * This method retrieves a paginated list of {return type}(s) based on optional filters and configuration. + * + * @param {FilterableOrderLineItemProps} filters - The filters to apply on the retrieved order line item. + * @param {FindConfig} config - The configurations determining how the order line item is retrieved. Its properties, such as `select` or `relations`, accept the + * attributes or relations associated with a order line item. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The list of {return type}(s). + * + * @example + * ```typescript + * const result = await orderModuleService.listLineItems({ + * title: "Sample Product Title", + * }); + * ``` + * + */ listLineItems( filters: FilterableOrderLineItemProps, config?: FindConfig, sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {CreateOrderLineItemForOrderDTO} data - The order line item for order to be created. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * await orderModuleService.addLineItems({ + * order_id: "123456", + * { + * product_id: "abc123", + * quantity: 2, + * unit_price: 1999, // Assuming type is an integer for price in cents + * } + * }); + * ``` + * + */ addLineItems( data: CreateOrderLineItemForOrderDTO ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {CreateOrderLineItemForOrderDTO[]} data - The order line item for order to be created. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * const lineItems: CreateOrderLineItemForOrderDTO[] = [{ + * order_id: "order_123", + * product_id: "prod_456", + * quantity: 2, + * unit_price: 1999 + * }]; + * + * const result = await orderModuleService.addLineItems(lineItems); + * ``` + * + */ addLineItems( data: CreateOrderLineItemForOrderDTO[] ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} orderId - The order's ID. + * @param {CreateOrderLineItemDTO[]} items - The order line item to be created. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * const result = await orderModuleService.addLineItems("orderIdValue", [ + * { + * title: "Item Title", + * requires_shipping: true, + * is_discountable: true, + * is_tax_inclusive: true, + * unit_price: 100, + * } + * ]); + * ``` + * + */ addLineItems( orderId: string, items: CreateOrderLineItemDTO[], sharedContext?: Context ): Promise + /** + * This method updates existing {return type}(s). + * + * @param {UpdateOrderLineItemWithSelectorDTO[]} data - The attributes to update in the order line item with selector. + * @returns {Promise} The updated {return type}(s). + * + * @example + * ```typescript + * const updateOrderLineItems: UpdateOrderLineItemWithSelectorDTO[] = [ + * { + * selector: { + * id: "line-item-id-1" + * }, + * data: { + * id: "line-item-id-1", + * quantity: 2, + * unit_price: 1999 + * } + * } + * ]; + * + * const updatedLineItems = await orderModuleService.updateLineItems(updateOrderLineItems); + * ``` + * + */ updateLineItems( data: UpdateOrderLineItemWithSelectorDTO[] ): Promise + + /** + * This method updates existing {return type}(s). + * + * @param {Partial} selector - Make all properties in T optional + * @param {Partial} data - Make all properties in T optional + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The updated {return type}(s). + * + * @example + * ```typescript + * const result = await orderModuleService.updateLineItems( + * { id: "line-item-id-1" }, + * { quantity: 10 } + * ); + * ``` + * + */ updateLineItems( selector: Partial, data: Partial, sharedContext?: Context ): Promise + + /** + * This method updates existing {return type}(s). + * + * @param {string} lineId - The line's ID. + * @param {Partial} data - Make all properties in T optional + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The updated {return type}(s). + * + * @example + * ```typescript + * const result = await orderModuleService.updateLineItems( + * "lineIdExample", + * { + * quantity: 10, + * } + * ); + * ``` + * + */ updateLineItems( lineId: string, data: Partial, sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string[]} itemIds - The list of {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeLineItems(["itemId1", "itemId2"]); + * ``` + * + */ removeLineItems(itemIds: string[], sharedContext?: Context): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} itemIds - {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeLineItems(itemId1); + * ``` + * + */ removeLineItems(itemIds: string, sharedContext?: Context): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {Partial} selector - Make all properties in T optional + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeLineItems({ id: 'item-123' }); + * ``` + * + */ removeLineItems( selector: Partial, sharedContext?: Context ): Promise + /** + * This method updates existing {return type}(s). + * + * @param {Partial} selector - Make all properties in T optional + * @param {UpdateOrderItemDTO} data - The attributes to update in the order item. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The updated {return type}(s). + * + * @example + * ```typescript + * await orderModuleService.updateOrderItem( + * { id: "item123" }, + * { quantity: "2" } + * ); + * ``` + * + */ updateOrderItem( selector: Partial, data: UpdateOrderItemDTO, sharedContext?: Context ): Promise + + /** + * This method updates existing {return type}(s). + * + * @param {string} orderDetailId - The order detail's ID. + * @param {Partial} data - Make all properties in T optional + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The updated {return type}(s). + * + * @example + * ```typescript + * await orderModuleService.updateOrderItem( + * 'orderDetailId123', + * { + * item_id: 'item123', + * quantity: 2 + * } + * ); + * ``` + * + */ updateOrderItem( orderDetailId: string, data: Partial, sharedContext?: Context ): Promise + /** + * This method updates existing {return type}(s). + * + * @param {string | Partial | UpdateOrderItemWithSelectorDTO[]} orderDetailIdOrDataOrSelector - The string | partial< order item d t o> | update order item with selector details. + * @param {UpdateOrderItemDTO | Partial} data - {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The updated {return type}(s). + * + * @example + * ```typescript + * await orderModuleService.updateOrderItem( + * "order-detail-id", + * { + * quantity: 2, + * item_id: 'item123', + * } + * ); + * ``` + * + */ updateOrderItem( orderDetailIdOrDataOrSelector: | string @@ -176,91 +744,442 @@ export interface IOrderModuleService extends IModuleService { sharedContext?: Context ): Promise + /** + * This method retrieves a paginated list of {return type}(s) based on optional filters and configuration. + * + * @param {FilterableOrderShippingMethodProps} filters - The filters to apply on the retrieved order shipping method. + * @param {FindConfig} config - The configurations determining how the order shipping method is retrieved. Its properties, such as `select` or `relations`, accept the + * attributes or relations associated with a order shipping method. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The list of {return type}(s). + * + * @example + * ```typescript + * await orderModuleService.listShippingMethods( + * { order_id: "order_123" }, + * { limit: 10, offset: 0 } + * ); + * ``` + * + */ listShippingMethods( filters: FilterableOrderShippingMethodProps, config: FindConfig, sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {CreateOrderShippingMethodDTO} data - The order shipping method to be created. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * const result = await orderModuleService.addShippingMethods({ + * name: "Standard Shipping", + * shipping_method_id: "1", + * order_id: "123", + * amount: 1000 + * }); + * ``` + * + */ addShippingMethods( data: CreateOrderShippingMethodDTO ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {CreateOrderShippingMethodDTO[]} data - The order shipping method to be created. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * const shippingMethods: CreateOrderShippingMethodDTO[] = [ + * { + * name: 'Standard Shipping', + * shipping_method_id: 'std_ship_001', + * order_id: 'order_12345', + * amount: 1000 + * }, + * { + * name: 'Express Shipping', + * shipping_method_id: 'exp_ship_002', + * order_id: 'order_12345', + * amount: 1000 + * } + * ]; + * + * const addedShippingMethods = await orderModuleService.addShippingMethods(shippingMethods); + * ``` + * + */ addShippingMethods( data: CreateOrderShippingMethodDTO[] ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} orderId - The order's ID. + * @param {CreateOrderShippingMethodDTO[]} methods - The order shipping method to be created. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * const createOrderShippingMethodDTOs: CreateOrderShippingMethodDTO[] = [{ + * name: "Standard Shipping", + * shipping_method_id: "123", + * order_id: "abc", + * amount: 1000 + * }]; + * + * await orderModuleService.addShippingMethods("orderId123", createOrderShippingMethodDTOs); + * ``` + * + */ addShippingMethods( orderId: string, methods: CreateOrderShippingMethodDTO[], sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string[]} methodIds - The list of {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeShippingMethods(['method1', 'method2']); + * ``` + * + */ removeShippingMethods( methodIds: string[], sharedContext?: Context ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} methodIds - {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeShippingMethods("methodId12345"); + * ``` + * + */ removeShippingMethods( methodIds: string, sharedContext?: Context ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {Partial} selector - Make all properties in T optional + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeShippingMethods({ + * id: "shipping-method-123", + * }); + * ``` + * + */ removeShippingMethods( selector: Partial, sharedContext?: Context ): Promise + /** + * This method retrieves a paginated list of {return type}(s) based on optional filters and configuration. + * + * @param {FilterableOrderLineItemAdjustmentProps} filters - The filters to apply on the retrieved order line item adjustment. + * @param {FindConfig} config - The configurations determining how the order line item adjustment is retrieved. Its properties, such as `select` or `relations`, accept the + * attributes or relations associated with a order line item adjustment. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The list of {return type}(s). + * + * @example + * ```typescript + * const orderLineItemAdjustments = await orderModuleService.listLineItemAdjustments({ item_id: "order-line-item-123" }); + * ``` + * + */ listLineItemAdjustments( filters: FilterableOrderLineItemAdjustmentProps, config?: FindConfig, sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {CreateOrderAdjustmentDTO[]} data - The order adjustment to be created. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * await orderModuleService.addLineItemAdjustments([ + * { + * amount: 1000, + * } + * ]); + * ``` + * + */ addLineItemAdjustments( data: CreateOrderAdjustmentDTO[] ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {CreateOrderAdjustmentDTO} data - The order adjustment to be created. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * await orderModuleService.addLineItemAdjustments({ + * amount: 1000, + * }); + * ``` + * + */ addLineItemAdjustments( data: CreateOrderAdjustmentDTO ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} orderId - The order's ID. + * @param {CreateOrderAdjustmentDTO[]} data - The order adjustment to be created. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * await orderModuleService.addLineItemAdjustments("12345", [ + * { + * amount: 1000, + * } + * ]); + * ``` + * + */ addLineItemAdjustments( orderId: string, data: CreateOrderAdjustmentDTO[] ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} orderId - The order's ID. + * @param {UpsertOrderLineItemAdjustmentDTO[]} data - The upsert order line item adjustment details. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * const adjustmentsData: UpsertOrderLineItemAdjustmentDTO[] = [{ + * item_id: "item123", + * amount: 1000 + * }]; + * + * const result = await orderModuleService.setLineItemAdjustments("order456", adjustmentsData); + * ``` + * + */ setLineItemAdjustments( orderId: string, data: UpsertOrderLineItemAdjustmentDTO[], sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string[]} adjustmentIds - The list of {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeLineItemAdjustments(["adjustmentId1", "adjustmentId2"]); + * + */ removeLineItemAdjustments( adjustmentIds: string[], sharedContext?: Context ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} adjustmentIds - {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeLineItemAdjustments("adjustmentId123"); + * ``` + * + */ removeLineItemAdjustments( adjustmentIds: string, sharedContext?: Context ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {Partial} selector - Make all properties in T optional + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeLineItemAdjustments({ + * item_id: "123" + * }); + * ``` + * + */ removeLineItemAdjustments( selector: Partial, sharedContext?: Context ): Promise + /** + * This method retrieves a paginated list of {return type}(s) based on optional filters and configuration. + * + * @param {FilterableOrderShippingMethodAdjustmentProps} filters - The filters to apply on the retrieved order shipping method adjustment. + * @param {FindConfig} config - The configurations determining how the order shipping method adjustment is retrieved. Its properties, such as `select` or `relations`, accept the + * attributes or relations associated with a order shipping method adjustment. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The list of {return type}(s). + * + * @example + * ```typescript + * const result = await orderModuleService.listShippingMethodAdjustments({ + * id: "12345", + * }); + * ``` + * + */ listShippingMethodAdjustments( filters: FilterableOrderShippingMethodAdjustmentProps, config?: FindConfig, sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {CreateOrderShippingMethodAdjustmentDTO[]} data - The order shipping method adjustment to be created. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * const adjustmentsData: CreateOrderShippingMethodAdjustmentDTO[] = [{ + * shipping_method_id: '123', + * code: "ADJUSTMENT_CODE", + * amount: 1000, + * description: 'Discount', + * promotion_id: 'promo-456' + * }]; + * + * const result = await orderModuleService.addShippingMethodAdjustments(adjustmentsData); + * ``` + * + */ addShippingMethodAdjustments( data: CreateOrderShippingMethodAdjustmentDTO[] ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {CreateOrderShippingMethodAdjustmentDTO} data - The order shipping method adjustment to be created. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * // Example usage of addShippingMethodAdjustments method + * const adjustmentData: CreateOrderShippingMethodAdjustmentDTO = { + * shipping_method_id: "shipping_method_123", + * code: "ADJUSTMENT_CODE", + * amount: 1000 + * }; + * + * const result = await orderModuleService.addShippingMethodAdjustments(adjustmentData); + * ``` + * + */ addShippingMethodAdjustments( data: CreateOrderShippingMethodAdjustmentDTO ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} orderId - The order's ID. + * @param {CreateOrderShippingMethodAdjustmentDTO[]} data - The order shipping method adjustment to be created. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * await orderModuleService.addShippingMethodAdjustments("orderId123", [ + * { + * shipping_method_id: "shippingMethodId456", + * code: "CODE123", + * amount: 1000 + * } + * ]); + * ``` + * + */ addShippingMethodAdjustments( orderId: string, data: CreateOrderShippingMethodAdjustmentDTO[], sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} orderId - The order's ID. + * @param {(CreateOrderShippingMethodAdjustmentDTO | UpdateOrderShippingMethodAdjustmentDTO)[]} data - The list of The order shipping method adjustment d t o | update order shipping method adjustment to be created. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * await orderModuleService.setShippingMethodAdjustments("orderId123", [ + * { + * shipping_method_id: "shipMethodId123", + * code: "CODE123", + * amount: 1000, + * } + * ]); + * ``` + * + */ setShippingMethodAdjustments( orderId: string, data: ( @@ -270,68 +1189,327 @@ export interface IOrderModuleService extends IModuleService { sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string[]} adjustmentIds - The list of {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeShippingMethodAdjustments(["adjustmentId1", "adjustmentId2"]); + * ``` + * + */ removeShippingMethodAdjustments( adjustmentIds: string[], sharedContext?: Context ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} adjustmentId - The adjustment's ID. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeShippingMethodAdjustments("adjustmentId123"); + * ``` + * + */ removeShippingMethodAdjustments( adjustmentId: string, sharedContext?: Context ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {Partial} selector - Make all properties in T optional + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeShippingMethodAdjustments({ id: "adjustment123" }); + * ``` + * + */ removeShippingMethodAdjustments( selector: Partial, sharedContext?: Context ): Promise + /** + * This method retrieves a paginated list of {return type}(s) based on optional filters and configuration. + * + * @param {FilterableOrderLineItemTaxLineProps} filters - The filters to apply on the retrieved order line item tax line. + * @param {FindConfig} config - The configurations determining how the order line item tax line is retrieved. Its properties, such as `select` or `relations`, accept the + * attributes or relations associated with a order line item tax line. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The list of {return type}(s). + * + * @example + * ```typescript + * await orderModuleService.listLineItemTaxLines({ id: "123" }); + * ``` + * + */ listLineItemTaxLines( filters: FilterableOrderLineItemTaxLineProps, config?: FindConfig, sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {CreateOrderLineItemTaxLineDTO[]} taxLines - The order line item tax line to be created. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * const taxLines: CreateOrderLineItemTaxLineDTO[] = [{ + * code: 'VAT', + * rate: 20, + * tax_rate_id: 'tax_rate_id_value' + * }]; + * + * const result = await orderModuleService.addLineItemTaxLines(taxLines); + * ``` + * + */ addLineItemTaxLines( taxLines: CreateOrderLineItemTaxLineDTO[] ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {CreateOrderLineItemTaxLineDTO} taxLine - The order line item tax line to be created. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * const taxLine: CreateOrderLineItemTaxLineDTO = { + * code: 'TAX100', + * rate: 10 + * }; + * + * const response = await orderModuleService.addLineItemTaxLines(taxLine); + * ``` + * + */ addLineItemTaxLines( taxLine: CreateOrderLineItemTaxLineDTO ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} orderId - The order's ID. + * @param {CreateOrderLineItemTaxLineDTO | CreateOrderLineItemTaxLineDTO[]} taxLines - The order line item tax line d t o | create order line item tax line to be created. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * await orderModuleService.addLineItemTaxLines("orderId123", [ + * { + * code: "TAX1001", + * rate: 70, + * } + * ]); + * ``` + * + */ addLineItemTaxLines( orderId: string, taxLines: CreateOrderLineItemTaxLineDTO[] | CreateOrderLineItemTaxLineDTO, sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} orderId - The order's ID. + * @param {(CreateOrderLineItemTaxLineDTO | UpdateOrderLineItemTaxLineDTO)[]} taxLines - The list of The order line item tax line d t o | update order line item tax line to be created. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * const orderId = '12345'; + * const taxLines: (CreateOrderLineItemTaxLineDTO | UpdateOrderLineItemTaxLineDTO)[] = [ + * { + * code: "TAX1001", + * rate: 70, + * } + * ]; + * + * const result = await orderModuleService.setLineItemTaxLines(orderId, taxLines); + * + * console.log(result); + * ``` + * + */ setLineItemTaxLines( orderId: string, taxLines: (CreateOrderLineItemTaxLineDTO | UpdateOrderLineItemTaxLineDTO)[], sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string[]} taxLineIds - The list of {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * // Example usage of removeLineItemTaxLines method from IOrderModuleService + * await orderModuleService.removeLineItemTaxLines(["taxLineId1", "taxLineId2"]); + * ``` + * + */ removeLineItemTaxLines( taxLineIds: string[], sharedContext?: Context ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} taxLineIds - {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeLineItemTaxLines("yourTaxLineId"); + * ``` + * + */ removeLineItemTaxLines( taxLineIds: string, sharedContext?: Context ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {FilterableOrderLineItemTaxLineProps} selector - The filters to apply on the retrieved order line item tax line. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeLineItemTaxLines({ + * id: "yourTaxLineId" + * }); + * ``` + * + */ removeLineItemTaxLines( selector: FilterableOrderLineItemTaxLineProps, sharedContext?: Context ): Promise + /** + * This method retrieves a paginated list of {return type}(s) based on optional filters and configuration. + * + * @param {FilterableOrderShippingMethodTaxLineProps} filters - The filters to apply on the retrieved order shipping method tax line. + * @param {FindConfig} config - The configurations determining how the order shipping method tax line is retrieved. Its properties, such as `select` or `relations`, accept the + * attributes or relations associated with a order shipping method tax line. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The list of {return type}(s). + * + * @example + * ```typescript + * async function executeMethod() { + * const result = await orderModuleService.listShippingMethodTaxLines({ + * id: "123", + * }); + * } + * ``` + * + */ listShippingMethodTaxLines( filters: FilterableOrderShippingMethodTaxLineProps, config?: FindConfig, sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {CreateOrderShippingMethodTaxLineDTO[]} taxLines - The order shipping method tax line to be created. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * const result = await orderModuleService.addShippingMethodTaxLines([ + * { + * code: "VAT20", + * rate: 20, + * } + * ]); + * ``` + * + */ addShippingMethodTaxLines( taxLines: CreateOrderShippingMethodTaxLineDTO[] ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {CreateOrderShippingMethodTaxLineDTO} taxLine - The order shipping method tax line to be created. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * const taxLine: CreateOrderShippingMethodTaxLineDTO = { + * code: "VAT20", + * rate: 20, + * }; + * + * orderModuleService.addShippingMethodTaxLines(taxLine).then((result) => { + * console.log(result); + * }); + * ``` + * + */ addShippingMethodTaxLines( taxLine: CreateOrderShippingMethodTaxLineDTO ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} orderId - The order's ID. + * @param {CreateOrderShippingMethodTaxLineDTO | CreateOrderShippingMethodTaxLineDTO[]} taxLines - The order shipping method tax line d t o | create order shipping method tax line to be created. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * const orderId = '123'; + * const taxLines = [ + * { + * code: "VAT20", + * rate: 20, + * } + * ]; + * + * const addedTaxLines = await orderModuleService.addShippingMethodTaxLines(orderId, taxLines); + * ``` + * + */ addShippingMethodTaxLines( orderId: string, taxLines: @@ -340,6 +1518,28 @@ export interface IOrderModuleService extends IModuleService { sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} orderId - The order's ID. + * @param {(CreateOrderShippingMethodTaxLineDTO | UpdateOrderShippingMethodTaxLineDTO)[]} taxLines - The list of The order shipping method tax line d t o | update order shipping method tax line to be created. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Represents the completion of an asynchronous operation + * + * @example + * ```typescript + * const orderId = "someOrderId"; + * const taxLines = [ + * { + * code: "VAT20", + * rate: 20, + * } + * ]; + * + * const result = await orderModuleService.setShippingMethodTaxLines(orderId, taxLines); + * ``` + * + */ setShippingMethodTaxLines( orderId: string, taxLines: ( @@ -349,67 +1549,361 @@ export interface IOrderModuleService extends IModuleService { sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string[]} taxLineIds - The list of {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeShippingMethodTaxLines(["taxLine1", "taxLine2"]); + * ``` + * + */ removeShippingMethodTaxLines( taxLineIds: string[], sharedContext?: Context ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} taxLineIds - {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeShippingMethodTaxLines("12345"); + * ``` + * + */ removeShippingMethodTaxLines( taxLineIds: string, sharedContext?: Context ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {FilterableOrderShippingMethodTaxLineProps} selector - The filters to apply on the retrieved order shipping method tax line. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.removeShippingMethodTaxLines({ + * id: "shippingMethodTaxLineId" + * }); + * ``` + * + */ removeShippingMethodTaxLines( selector: FilterableOrderShippingMethodTaxLineProps, sharedContext?: Context ): Promise - // Order Change createOrderChange( data: CreateOrderChangeDTO, sharedContext?: Context ): Promise + + /** + * This method creates {return type}(s) + * + * @param {CreateOrderChangeDTO[]} data - The order change to be created. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The created {return type}(s). + * + * @example + * ```typescript + * // Example call to createOrderChange + * + * const createOrderChangeData: CreateOrderChangeDTO[] = [{ + * order_id: "order123", + * description: "Change due to customer request" + * }]; + * + * const result = await orderModuleService.createOrderChange(createOrderChangeData); + * ``` + * + */ createOrderChange( data: CreateOrderChangeDTO[], sharedContext?: Context ): Promise + + /** + * This method creates {return type}(s) + * + * @param {CreateOrderChangeDTO | CreateOrderChangeDTO[]} data - The order change d t o | create order change to be created. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} The created {return type}(s). + * + * @example + * ```typescript + * const result = await orderModuleService.createOrderChange({ + * order_id: "order123", + * description: "Adding new item to the order" + * }); + * ``` + * + */ createOrderChange( data: CreateOrderChangeDTO | CreateOrderChangeDTO[], sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} orderId - The order's ID. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.cancelOrderChange("orderId123"); + * ``` + * + */ cancelOrderChange(orderId: string, sharedContext?: Context): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string[]} orderId - The order's ID. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.cancelOrderChange(["1234ABCD"]); + * ``` + * + */ cancelOrderChange(orderId: string[], sharedContext?: Context): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {CancelOrderChangeDTO} data - The cancel order change details. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * const cancelOrderChangeData: CancelOrderChangeDTO = { + * id: "orderChangeId", + * }; + * + * await orderModuleService.cancelOrderChange(cancelOrderChangeData); + * ``` + * + */ cancelOrderChange( data: CancelOrderChangeDTO, sharedContext?: Context ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {CancelOrderChangeDTO[]} data - The cancel order change details. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.cancelOrderChange([{ id: "orderChangeId" }]); + * ``` + * + */ cancelOrderChange( data: CancelOrderChangeDTO[], sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} orderId - The order's ID. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.confirmOrderChange("123456789"); + * ``` + * + */ confirmOrderChange(orderId: string, sharedContext?: Context): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string[]} orderId - The order's ID. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.confirmOrderChange(["12345"]); + * ``` + * + */ confirmOrderChange(orderId: string[], sharedContext?: Context): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {ConfirmOrderChangeDTO} data - The confirm order change details. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.confirmOrderChange({ + * id: "123456" + * }); + * ``` + * + */ confirmOrderChange( data: ConfirmOrderChangeDTO, sharedContext?: Context ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {ConfirmOrderChangeDTO[]} data - The confirm order change details. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * const confirmOrderChangesData: ConfirmOrderChangeDTO[] = [{ + * id: "orderChangeId", + * }]; + * + * await orderModuleService.confirmOrderChange(confirmOrderChangesData); + * ``` + * + */ confirmOrderChange( data: ConfirmOrderChangeDTO[], sharedContext?: Context ): Promise + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string} orderId - The order's ID. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.declineOrderChange("orderChangeId"); + * ``` + * + */ declineOrderChange(orderId: string, sharedContext?: Context): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {string[]} orderId - The order's ID. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.declineOrderChange(["orderChangeId"]); + * ``` + * + */ declineOrderChange(orderId: string[], sharedContext?: Context): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {DeclineOrderChangeDTO} data - The decline order change details. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.declineOrderChange({ + * id: "123456", + * }); + * ``` + * + */ declineOrderChange( data: DeclineOrderChangeDTO, sharedContext?: Context ): Promise + + /** + * This method Represents the completion of an asynchronous operation + * + * @param {DeclineOrderChangeDTO[]} data - The decline order change details. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {Promise} Resolves when {summary} + * + * @example + * ```typescript + * await orderModuleService.declineOrderChange([ + * { + * id: "12345", + * } + * ]); + * ``` + * + */ declineOrderChange( data: DeclineOrderChangeDTO[], sharedContext?: Context ): Promise + /** + * This method {summary} + * + * @param {string | string[]} orderId - The order's ID. + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {(orderId: string | string[], sharedContext?: Context) => any} {summary} + * + * @example + * ```typescript + * await orderModuleService.applyPendingOrderActions("12345"); + * ``` + * + */ applyPendingOrderActions(orderId: string | string[], sharedContext?: Context) + /** + * This method {summary} + * + * @param {any} data - {summary} + * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. + * @returns {(data: any, sharedContext?: Context) => any} {summary} + * + * @example + * ```typescript + * await orderModuleService.addOrderAction({ + * action: 'create', + * orderId: '12345', + * details: { + * productId: 'abc123', + * quantity: 2 + * } + * }); + * ``` + * + */ addOrderAction(data: any, sharedContext?: Context) }