Skip to main content
This release is 18 versions behind 5.0.12 — the latest version of @lost-c3/lib. Jump to latest

Lost for easy making Construct 3 Addons.

This package works with DenoIt is unknown whether this package works with Cloudflare Workers, Node.js, Bun, Browsers
It is unknown whether this package works with Cloudflare Workers
It is unknown whether this package works with Node.js
This package works with Deno
It is unknown whether this package works with Bun
It is unknown whether this package works with Browsers
JSR Score
35%
Published
4 months ago (3.3.2)
Package root>lib>addon.ts
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
// deno-lint-ignore-file no-case-declarations import type { AddonType, LostConfig } from "./config.ts"; import type { CategoryClassType } from "./entities/category.ts"; import type { PluginProperty } from "./entities/plugin-property.ts"; import { Colors, join, Logger } from "../deps.ts"; import { MIME } from "../shared/mime.ts"; import { dedent, isDirectoryExists, isFileExists } from "../shared/misc.ts"; import { Paths } from "../shared/paths.ts"; import { transpileTs } from "../shared/transpile-ts.ts"; import { Property } from './entities/plugin-property.ts'; import Icon from "./defaults/addon-icon.ts"; import { AddonFileManager } from "./managers/addon-file-manager.ts"; import { LostAddonData } from "./lost-addon-data.ts"; import { ProjectFolders } from "../shared/paths/project-folders.ts"; import { EditorScript, JsonFile, RuntimeScript } from "../shared/paths/addon-files.ts"; import { AddonFolders } from "../shared/paths/addon-folders.ts"; export abstract class Addon<A extends AddonType, I, T extends SDK.ITypeBase> { protected readonly type: AddonType; protected readonly config: LostConfig<A>; protected readonly userFiles: AddonUserFile[] = []; protected readonly userScripts: AddonUserScriptFile[] = []; protected readonly userModules: AddonUserModuleFile[] = []; protected readonly userDomSideScripts: AddonUserDomSideScriptFile[] = []; protected readonly pluginProperties: PluginProperty<A, I, T>[] = []; protected readonly categories: CategoryClassType[] = []; protected readonly remoteScripts: string[] = []; protected readonly runtimeScripts: string[] = []; protected hasDefaultImage: boolean = false; protected icon: AddonIconFile = { type: 'icon', isDefault: true, iconType: 'image/svg+xml', originalName: 'icon.svg', originalPath: '', localName: 'icon.svg', localPath: '', finalPath: 'icon.svg' }; constructor(type: A, config: LostConfig<A>) { this.type = type; this.config = config; if ( this.type === 'plugin' || this.type === 'behavior' ) { this.#load(); } } async #load() { await this.#loadAddonIcon(Paths.Root); await this.#loadUserFiles(Paths.ProjectFolders.Files); await this.#loadUserScripts(Paths.ProjectFolders.Scripts); await this.#loadUserModules(Paths.ProjectFolders.Modules); await this.#loadUserDomSideScripts(Paths.ProjectFolders.DomSide); await this.#createTypes(Paths.ProjectFolders.Types); await this.#loadCategories(Paths.ProjectFolders.Categories); } /** Creates **properties.d.ts** declaration file for plugin properties types */ async #createTypes(folderPath: string) { if (this.pluginProperties.length > 0) { let fileContent = `declare type PluginProperties = [`; this.pluginProperties.forEach((property, i) => { switch (property._opts.type) { case Property.Integer: fileContent = fileContent + `number` break; case Property.Float: fileContent = fileContent + `number` break; case Property.Percent: fileContent = fileContent + `number` break; case Property.Text: fileContent = fileContent + `string` break; case Property.LongText: fileContent = fileContent + `string` break; case Property.Checkbox: fileContent = fileContent + `boolean` break; case Property.Font: fileContent = fileContent + `string` break; case Property.Combo: fileContent = fileContent + `number` break; case Property.Color: fileContent = fileContent + `[number, number, number]` break; case Property.Object: fileContent = fileContent + `number` break; case Property.Group: fileContent = fileContent + `unknown` break; case Property.Info: fileContent = fileContent + `unknown` break; case Property.Link: fileContent = fileContent + `unknown` break; } if (i < this.pluginProperties.length - 1) { fileContent = fileContent + `, ` } }) fileContent = fileContent + `]` await Deno.mkdir(folderPath, { recursive: true }); await Deno.writeTextFile(join(folderPath, 'properties.d.ts'), fileContent); Logger.Success(`Created 'properties.d.ts' file.`); } } async #loadAddonIcon(folderPath: string) { Logger.LogBetweenLines(Colors.bgRed('Loading icon...')); let iconFound = false; for await (const entry of Deno.readDir(folderPath)) { if ( entry.isFile && (entry.name !== 'default.png') && (entry.name.endsWith('.png') || entry.name.endsWith('.svg')) ) { const iconType: AddonIconMimeType = (entry.name.endsWith('.png')) ? 'image/png' : 'image/svg+xml'; this.icon = { isDefault: false, type: 'icon', originalName: entry.name, originalPath: folderPath, localName: entry.name, localPath: Paths.ProjectFolders.Build, iconType, finalPath: entry.name } iconFound = true; } } if (!iconFound) { Logger.Warning( `Addon icon was not detected, will be used default [SVG] icon` ); } else { Logger.Info(`Loaded [${this.icon.iconType}] addon icon`, `Filename: ${this.icon.originalName}`); } } async #loadUserFiles(folderPath: string) { if (await isDirectoryExists(folderPath)) { Logger.LogBetweenLines(Colors.bgGreen('Loading files...')); const readDir = async (path: string) => { for await (const entry of Deno.readDir(path)) { if (entry.isDirectory) { await readDir(join(path, entry.name)); } else if (entry.isFile) { const dependencyType = (entry.name.endsWith('.css')) ? 'external-css' : 'copy-to-output'; switch (dependencyType) { case 'copy-to-output': const mimeType = MIME.getFileType(entry.name); if (mimeType) { this.#addUserFile({ type: 'file', originalName: entry.name, originalPath: path, localName: entry.name, localPath: join(Paths.AddonFolders.Files, ...Paths.getFoldersAfterFolder(path, ProjectFolders.Files)), dependencyType, mimeType, finalPath: `${AddonFolders.Files}` }) } else { Logger.Warning( dedent` Found 'copy-to-output' file (${entry.name}) with unknown MIME type. File will not be included in final addon build' ${'https://www.construct.net/en/make-games/manuals/construct-3/tips-and-guides/mime-types'}` ); } break; case 'external-css': this.#addUserFile({ type: 'file', originalName: entry.name, originalPath: path, localName: entry.name, localPath: join(Paths.AddonFolders.Files, ...Paths.getFoldersAfterFolder(path, ProjectFolders.Files)), dependencyType: 'external-css', finalPath: `${AddonFolders.Files}` }) break; } } } } await readDir(folderPath); } } async #loadUserScripts(folderPath: string) { if (await isDirectoryExists(folderPath)) { Logger.LogBetweenLines(Colors.bgYellow('Loading scripts...')); const readDir = async (path: string) => { for await (const entry of Deno.readDir(path)) { if (entry.isDirectory) { await readDir(join(path, entry.name)); } else if ( entry.isFile && ((entry.name.endsWith('.ts') && !entry.name.endsWith('.d.ts')) || entry.name.endsWith('.js')) ) { if (this.#isFilePathInRuntimeScriptsArray('')) { this.#addUserScript({ type: 'script', originalName: entry.name, originalPath: path, localName: entry.name, localPath: join(Paths.AddonFolders.Scripts, ...Paths.getFoldersAfterFolder(path, ProjectFolders.Scripts)), dependencyType: 'external-runtime-script', isTypescript: (entry.name.endsWith('.ts')) ? true : false, finalPath: `${AddonFolders.Scripts}` }) } else { this.#addUserScript({ type: 'script', originalName: entry.name, originalPath: path, localName: entry.name, localPath: join(Paths.AddonFolders.Scripts, ...Paths.getFoldersAfterFolder(path, ProjectFolders.Scripts)), dependencyType: 'external-dom-script', isTypescript: (entry.name.endsWith('.ts')) ? true : false, finalPath: `${AddonFolders.Scripts}` }) } } } } await readDir(folderPath); } } async #loadUserModules(folderPath: string) { if (await isDirectoryExists(folderPath)) { Logger.LogBetweenLines(Colors.bgBlue('Loading modules...')); const readDir = async (path: string) => { for await (const entry of Deno.readDir(path)) { if (entry.isDirectory) { await readDir(join(path, entry.name)); } else if ( entry.isFile && ((entry.name.endsWith('.ts') && !entry.name.endsWith('.d.ts')) || entry.name.endsWith('.js')) ) { this.#addUserModule({ type: 'module', originalName: entry.name, originalPath: path, localName: entry.name.replace('.ts', '.js'), localPath: join(Paths.AddonFolders.Modules, ...Paths.getFoldersAfterFolder(path, ProjectFolders.Modules)), isTypescript: (entry.name.endsWith('.ts')) ? true : false, finalPath: `${AddonFolders.Runtime}/${AddonFolders.Modules}` }) } } } await readDir(folderPath); } } async #loadUserDomSideScripts(folderPath: string) { if (await isDirectoryExists(folderPath)) { const readDir = async (path: string) => { for await (const entry of Deno.readDir(path)) { if (entry.isDirectory) { await readDir(join(path, entry.name)); } else if ( entry.isFile && entry.name.endsWith('.ts') ) { this.#addUserDomSideScript({ type: 'dom-side-script', originalName: entry.name, originalPath: path, localName: entry.name.replace('.ts', '.js'), localPath: join(Paths.AddonFolders.DomSide, ...Paths.getFoldersAfterFolder(path, ProjectFolders.DomSide)), finalPath: `${AddonFolders.Runtime}/${AddonFolders.DomSide}` }) } } } await readDir(folderPath); } } async #loadCategories(folderPath: string) { if (await isDirectoryExists(folderPath)) { const readDir = async (path: string) => { for await (const entry of Deno.readDir(path)) { if (entry.isDirectory) { await readDir(join(path, entry.name)); } else if ( entry.isFile && entry.name.endsWith('.ts') ) { try { const categoryPath = import.meta.resolve(`file://${join(path, entry.name)}`); const categoryModule = (await import(`${categoryPath}?t=${Date.now()}`)).default; const category = (new categoryModule()).constructor.prototype as CategoryClassType; if (category) { this.#addCategory(category); } } catch (e) { Logger.Error('build', `Error importing category: ${Colors.bold(Colors.magenta(entry.name))}`, e); Deno.exit(); } } } } await readDir(folderPath); } else { Logger.Warning( `Addon categories folder was not detected at path: ${Colors.bold(join('Addon', 'Categories'))}!`, `Your addon is building without any ACEs` ); } } #addUserFile(file: AddonUserFile) { this.userFiles.push(file); switch (file.dependencyType) { case "copy-to-output": Logger.Loading( `Found [${Colors.dim(Colors.bold(file.mimeType))}] file ${Colors.bold(Colors.green(Colors.bold((file.originalName))))}, will be included in project build` ); break; case "external-css": Logger.Loading( `Found [${Colors.dim(Colors.bold('CSS'))}] file ${Colors.bold(Colors.dim(Colors.bold((file.originalName))))}` ); break; } } #addUserScript(file: AddonUserScriptFile) { this.userScripts.push(file); if (file.isTypescript) { if (file.dependencyType === 'external-runtime-script') Logger.Loading( `Found script ${Colors.blue(Colors.bold((file.originalName)))} (${file.dependencyType})` ); } else { Logger.Loading( `Found script ${Colors.yellow(Colors.bold((file.originalName)))} (${file.dependencyType})` ); } } #addUserModule(file: AddonUserModuleFile) { this.userModules.push(file); if (file.isTypescript) { Logger.Loading( `Found [${Colors.dim(Colors.bold('TS'))}] module ${Colors.blue(Colors.bold((file.originalName)))}` ); } else { Logger.Loading( `Found [${Colors.dim(Colors.bold('JS'))}] module ${Colors.yellow(Colors.bold((file.originalName)))}` ); } } #addUserDomSideScript(file: AddonUserDomSideScriptFile) { this.userDomSideScripts.push(file); Logger.Loading( `Found [${Colors.dim(Colors.bold('TS'))}] DOM side script ${Colors.dim(Colors.bold((file.originalName)))}` ); } #addCategory(category: CategoryClassType) { if (!category._inDevelopment) { this.categories.push(category); } } #isFilePathInRuntimeScriptsArray(path: string) { if (this.runtimeScripts.includes(path)) { return true; } else { return false; } } /** * Builder */ public async _build(watch: boolean) { this.#checkCategories(watch); if (!isBuildError) await this.#createAddonStructure(); if (!isBuildError) await this.#createC3RuntimeFiles(); if (!isBuildError) await this.#createC3EditorFiles(); if (!isBuildError) await this.#createC3JsonFiles(); return; } async #createIcon() { if (this.icon.isDefault) { await Deno.writeTextFile(join(this.icon.localPath, this.icon.localName), Icon()) } else { await Deno.copyFile(join(this.icon.originalPath, this.icon.originalName), join(this.icon.localPath, this.icon.localName)); } } async #copyUserFiles() { if (this.userFiles.length > 0) { await Deno.mkdir(Paths.AddonFolders.Files); this.userFiles.forEach(async file => { await Deno.mkdir(file.localPath, { recursive: true }); await Deno.copyFile(join(file.originalPath, file.originalName), join(file.localPath, file.localName)); }) } } async #copyUserScripts() { if (this.userScripts.length > 0) { await Deno.mkdir(Paths.AddonFolders.Scripts); this.userScripts.forEach(async file => { if (file.isTypescript) { const fileContent = await transpileTs(join(file.originalPath, file.originalName)) || ''; await Deno.mkdir(file.localPath, { recursive: true }); await Deno.writeTextFile(join(file.localPath, file.localName), fileContent); } else { await Deno.mkdir(file.localPath, { recursive: true }); await Deno.copyFile(join(file.originalPath, file.originalName), join(file.localPath, file.localName)); } }) } } async #copyUserModules() { if (this.userModules.length > 0) { await Deno.mkdir(Paths.AddonFolders.Modules); this.userModules.forEach(async file => { if (file.isTypescript) { const fileContent = await transpileTs(join(file.originalPath, file.originalName)) || ''; await Deno.mkdir(file.localPath, { recursive: true }); await Deno.writeTextFile(join(file.localPath, file.localName), fileContent); } else { await Deno.mkdir(file.localPath, { recursive: true }); await Deno.copyFile(join(file.originalPath, file.originalName), join(file.localPath, file.localName)); } }) } } async #copyUserDomSideScripts() { if (this.userDomSideScripts.length > 0) { await Deno.mkdir(Paths.AddonFolders.DomSide, { recursive: true }); this.userDomSideScripts.forEach(async file => { const fileContent = await transpileTs(join(file.originalPath, file.originalName)) || ''; await Deno.mkdir(file.localPath, { recursive: true }); await Deno.writeTextFile(join(file.localPath, file.localName), fileContent); }) } } async #copyDefaultImageFile() { const fileName = 'default.png'; const filePath = Paths.Root; if (await isFileExists(join(filePath, fileName))) { this.hasDefaultImage = true; Logger.Loading( `Found default image for drawing plugin` ); await Deno.copyFile(join(filePath, fileName), join(Paths.ProjectFolders.Build, fileName)); } } async #createAddonStructure() { if (await isDirectoryExists(Paths.ProjectFolders.Build)) { await Deno.remove(Paths.ProjectFolders.Build, { recursive: true }); } await Deno.mkdir(Paths.ProjectFolders.Build); await Deno.mkdir(Paths.AddonFolders.Runtime); await Deno.mkdir(Paths.AddonFolders.Lang) await this.#createIcon(); if ( this.config.type === 'plugin' && this.config.pluginType === 'world' ) { await this.#copyDefaultImageFile(); } await this.#copyUserFiles(); await this.#copyUserScripts(); await this.#copyUserModules(); await this.#copyUserDomSideScripts(); } #checkCategories(watch: boolean) { const isCategoryAlreadyExists = (id: string) => { const categories = this.categories.filter(c => c._id === id); if (categories.length > 1) { return true; } else { return false; } } this.categories.forEach(category => { if (category._id.length > 0) { if (!isCategoryAlreadyExists(category._id)) { category._actions.forEach(e => { const isIdAlreadyExists = (id: string) => { const allEntities = this.categories.map(c => c._actions).flat().filter(e => e._id === id); if (allEntities.length > 1) { return true; } else { return false; } } const isFunctionNameAlreadyExists = (funcName: string) => { const allEntities = this.categories.map(c => c._actions).flat().filter(e => e._func.name === funcName); if (allEntities.length > 1) { return true; } else { return false; } } if (e._id.length > 0) { if ( !isIdAlreadyExists(e._id) && !isFunctionNameAlreadyExists(e._func.name) ) { const isParameterIdAlreadyExists = (id: string) => { const parameters = e._params.map(e => e._id).filter(e => e === id); if (parameters.length > 1) { return true; } else { return false; } } if (e._params.length > 0) { e._params.forEach(p => { if (p._id.length > 0) { if (isParameterIdAlreadyExists(p._id)) { Logger.Error('build', `Action with id: "${e._id}" has duplicated parameters id's (${p._id})!`, 'Please change your parameter id.'); if (!watch) Deno.exit(1); } } else { Logger.Error('build', `Action with id: "${e._id}" has empty parameter id!`, 'Please specify your parameter id.'); if (!watch) Deno.exit(1); } }) } } else if (isIdAlreadyExists(e._id)) { Logger.Error('build', `Action with id: "${e._id}" is already exists in plugin!`, 'Please change your action id.'); if (!watch) Deno.exit(1); } else if (isFunctionNameAlreadyExists(e._func.name)) { Logger.Error('build', `Action with id: "${e._id}" has method name that is already exists in plugin!`, 'Please change your action method name.'); if (!watch) Deno.exit(1); } } else { Logger.Error('build', `Action id cannot be empty!`, 'Please specify your action id.', `Category id: ${category._id}`); if (!watch) Deno.exit(1); } }) category._conditions.forEach(e => { const isIdAlreadyExists = (id: string) => { const allEntities = this.categories.map(c => c._conditions).flat().filter(e => e._id === id); if (allEntities.length > 1) { return true; } else { return false; } } const isFunctionNameAlreadyExists = (funcName: string) => { const allEntities = this.categories.map(c => c._conditions).flat().filter(e => e._func.name === funcName); if (allEntities.length > 1) { return true; } else { return false; } } if (e._id.length > 0) { if ( !isIdAlreadyExists(e._id) && !isFunctionNameAlreadyExists(e._func.name) ) { const isParameterIdAlreadyExists = (id: string) => { const parameters = e._params.map(e => e._id).filter(e => e === id); if (parameters.length > 1) { return true; } else { return false; } } if (e._params.length > 0) { e._params.forEach(p => { if (p._id.length > 0) { if (isParameterIdAlreadyExists(p._id)) { Logger.Error('build', `Condition with id: "${e._id}" has duplicated parameters id's (${p._id})!`, 'Please change your parameter id.'); if (!watch) Deno.exit(1); } } else { Logger.Error('build', `Condition with id: "${e._id}" has empty parameter id!`, 'Please specify your parameter id.'); if (!watch) Deno.exit(1); } }) } } else if (isIdAlreadyExists(e._id)) { Logger.Error('build', `Condition with id: "${e._id}" is already exists in plugin!`, 'Please change your condition id.'); if (!watch) Deno.exit(1); } else if (isFunctionNameAlreadyExists(e._func.name)) { Logger.Error('build', `Condition with id: "${e._id}" has method name that is already exists in plugin!`, 'Please change your condition method name.'); if (!watch) Deno.exit(1); } } else { Logger.Error('build', `Condition id cannot be empty!`, 'Please specify your condition id.', `Category id: ${category._id}`); if (!watch) Deno.exit(1); } }) category._expressions.forEach(e => { const isIdAlreadyExists = (id: string) => { const allEntities = this.categories.map(c => c._expressions).flat().filter(e => e._id === id); if (allEntities.length > 1) { return true; } else { return false; } } const isFunctionNameAlreadyExists = (funcName: string) => { const allEntities = this.categories.map(c => c._expressions).flat().filter(e => e._func.name === funcName); if (allEntities.length > 1) { return true; } else { return false; } } if (e._id.length > 0) { if ( !isIdAlreadyExists(e._id) && !isFunctionNameAlreadyExists(e._func.name) ) { const isParameterIdAlreadyExists = (id: string) => { const parameters = e._params.map(e => e._id).filter(e => e === id); if (parameters.length > 1) { return true; } else { return false; } } if (e._params.length > 0) { e._params.forEach(p => { if (p._id.length > 0) { if (isParameterIdAlreadyExists(p._id)) { Logger.Error('build', `Expression with id: "${e._id}" has duplicated parameters id's (${p._id})!`, 'Please change your parameter id.'); if (!watch) Deno.exit(1); } } else { Logger.Error('build', `Expression with id: "${e._id}" has empty parameter id!`, 'Please specify your parameter id.'); if (!watch) Deno.exit(1); } }) } } else if (isIdAlreadyExists(e._id)) { Logger.Error('build', `Expression with id: "${e._id}" is already exists in plugin!`, 'Please change your expression id.'); if (!watch) Deno.exit(1); } else if (isFunctionNameAlreadyExists(e._func.name)) { Logger.Error('build', `Expression with id: "${e._id}" has method name that is already exists in plugin!`, 'Please change your expression method name.'); if (!watch) Deno.exit(1); } } else { Logger.Error('build', `Expression id cannot be empty!`, 'Please specify your expression id.', `Category id: ${category._id}`); if (!watch) Deno.exit(1); } }) } else { Logger.Error('build', `Category with id: "${category._id}" is already exists in plugin!`, 'Please change your category id.'); if (!watch) Deno.exit(1); } } else { Logger.Error('build', `Category id cannot be empty!`, 'Please specify your category id.'); if (!watch) Deno.exit(1); } }) } async #createC3RuntimeFiles() { switch (this.type) { case 'plugin': await AddonFileManager.createRuntimeScript(RuntimeScript.Plugin, this.config); break; case 'behavior': await AddonFileManager.createRuntimeScript(RuntimeScript.Behavior, this.config); break; } await AddonFileManager.createRuntimeScript(RuntimeScript.Instance, this.config); await AddonFileManager.createRuntimeScript(RuntimeScript.Type, this.config); await AddonFileManager.createRuntimeScript(RuntimeScript.Actions, this.config, this.categories); await AddonFileManager.createRuntimeScript(RuntimeScript.Conditions, this.config, this.categories); await AddonFileManager.createRuntimeScript(RuntimeScript.Expressions, this.config, this.categories); if (this.userModules.length > 0) { await AddonFileManager.createRuntimeScript(RuntimeScript.Module, this.config); } } async #createC3EditorFiles() { await AddonFileManager.createEditorScript(EditorScript.Type, this.config); await AddonFileManager.createEditorScript(EditorScript.Instance, this.config); const lostAddonData = new LostAddonData( this.hasDefaultImage, { path: this.icon.finalPath, iconType: this.icon.iconType }, this.config, this.pluginProperties, this.remoteScripts, this.userFiles, this.userScripts, this.userModules, this.userDomSideScripts ) switch (this.type) { case "plugin": await AddonFileManager.createEditorScript(EditorScript.Plugin, this.config, lostAddonData); break; case "behavior": await AddonFileManager.createEditorScript(EditorScript.Behavior, this.config, lostAddonData); break; } } async #createC3JsonFiles() { await AddonFileManager.createJson(JsonFile.Language, this.config, this.categories, this.pluginProperties); await AddonFileManager.createJson(JsonFile.Aces, this.config, this.categories); await AddonFileManager.createJson(JsonFile.AddonMetadata, this.config); } /** * Accessors */ public _getConfig() { return this.config; } }