From b370947815fbbbd871dab971a987cce61d9778f4 Mon Sep 17 00:00:00 2001 From: Sean Warren Date: Fri, 9 Feb 2024 15:25:52 -0800 Subject: [PATCH] chore: ++appliaction-flavors --- .babelrc | 2 +- package-lock.json | 6 +-- package.json | 4 +- src/application.ts | 12 +++--- src/template.ts | 3 +- src/tree.ts | 87 +++++++++++++++++++++++++-------------- src/types/index.ts | 8 ++-- tests/application.test.ts | 2 + 8 files changed, 75 insertions(+), 49 deletions(-) diff --git a/.babelrc b/.babelrc index 2981506..a7bf19a 100644 --- a/.babelrc +++ b/.babelrc @@ -8,7 +8,7 @@ } } ], - "@babel/preset-react", + "@babel/preset-react" ], "plugins": [ "@babel/plugin-proposal-class-properties" diff --git a/package-lock.json b/package-lock.json index 66c4e8d..7ebf656 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1295,9 +1295,8 @@ } }, "@exabyte-io/application-flavors.js": { - "version": "2024.1.23-1", - "resolved": "https://registry.npmjs.org/@exabyte-io/application-flavors.js/-/application-flavors.js-2024.1.23-1.tgz", - "integrity": "sha512-PfLh2wrs0KsVLroGVMFJuPHyleMpILtECNi1heKQGlOif0ObP1fxiE1Pb621BvaZhTXl4zdLOHlhM8XJYZy58w==", + "version": "git+https://github.com/Exabyte-io/application-flavors.git#513e4daf188c1ef1fcfe8195e2c90e289f616296", + "from": "git+https://github.com/Exabyte-io/application-flavors.git#513e4daf188c1ef1fcfe8195e2c90e289f616296", "dev": true, "requires": { "@babel/cli": "7.16.0", @@ -1309,6 +1308,7 @@ "@babel/register": "7.16.0", "js-yaml": "^4.1.0", "lodash": "^4.17.21", + "typescript": "^5.3.3", "underscore": "^1.12.1", "underscore.string": "^3.3.4" }, diff --git a/package.json b/package.json index ff96cab..42bebd7 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@babel/preset-react": "7.16.7", "@babel/register": "^7.16.0", "@babel/runtime-corejs3": "7.16.8", - "@exabyte-io/application-flavors.js": "2024.1.23-1", + "@exabyte-io/application-flavors.js": "https://github.com/Exabyte-io/application-flavors.git#513e4daf188c1ef1fcfe8195e2c90e289f616296", "@exabyte-io/code.js": "https://github.com/Exabyte-io/code.js.git#b3eaf74a11cf0b35a1f0bac32e74452fe0329953", "@exabyte-io/eslint-config": "^2022.11.17-0", "@exabyte-io/made.js": "^2024.1.8-0", @@ -70,7 +70,7 @@ "ts-node": "^10.9.2" }, "peerDependencies": { - "@exabyte-io/code.js": "https://github.com/Exabyte-io/code.js.git#b3eaf74a11cf0b35a1f0bac32e74452fe0329953", + "@exabyte-io/code.js": "*", "@exabyte-io/made.js": "*", "@exabyte-io/application-flavors.js": "*" }, diff --git a/src/application.ts b/src/application.ts index 79f1cc9..4bafa41 100644 --- a/src/application.ts +++ b/src/application.ts @@ -1,5 +1,4 @@ -// @ts-expect-error application-flavors.js is not typed -import { allApplications, getAppData, getAppTree } from "@exabyte-io/application-flavors.js"; +import { AllowedApplications, ApplicationTreeData, allApplications, getAppData, getAppTree } from "@exabyte-io/application-flavors.js"; import { NamedDefaultableInMemoryEntity } from "@exabyte-io/code.js/dist/entity"; import lodash from "lodash"; @@ -21,7 +20,8 @@ export function ApplicationMixin< constructor(...args: any[]) { const config = args[0] as ApplicationConfig; - if (!config || typeof config.name !== "string") throw new Error("Invalid application configuration object."); + if (!config || !config?.name) throw new Error("Invalid application configuration object."); + if (!allApplications.includes(config.name)) throw new Error(`Invalid application name: ${config.name}`); const staticConfig = getApplicationConfig(config); super({ ...staticConfig, ...config }); } @@ -38,7 +38,7 @@ export function ApplicationMixin< } static create(config: { - name: string, + name: AllowedApplications, version?: string, build?: string }) { @@ -50,7 +50,7 @@ export function ApplicationMixin< version = undefined, build = "Default" }: { - name: string, + name: AllowedApplications, version?: string, build?: string }) { @@ -81,6 +81,7 @@ export function ApplicationMixin< } getExecutableByName(name?: string) { + console.log(`getExecutableByName: ${name}`) return new Application.Executable( getExecutableConfig({ appName: this.prop("name"), @@ -123,6 +124,7 @@ export function ApplicationMixin< const tree = getAppTree(this.prop("name")); return Object.keys(tree) .filter((key) => { + // @ts-ignore const { supportedApplicationVersions } = tree[key]; return ( !supportedApplicationVersions || diff --git a/src/template.ts b/src/template.ts index dab6870..b6274e9 100644 --- a/src/template.ts +++ b/src/template.ts @@ -1,4 +1,3 @@ -// @ts-expect-error application-flavors.js is not typed import { allTemplates } from "@exabyte-io/application-flavors.js"; import { NamedInMemoryEntity, @@ -96,7 +95,7 @@ export function TemplateMixin< static fromFlavor(appName: string, execName: string, inputName: string): Template { const filtered = allTemplates.filter( - (temp: TemplateData) => + (temp) => temp.applicationName === appName && temp.executableName === execName && temp.name === inputName, diff --git a/src/tree.ts b/src/tree.ts index 587f41f..1b3768f 100644 --- a/src/tree.ts +++ b/src/tree.ts @@ -1,8 +1,35 @@ -// @ts-expect-error application-flavors.js is not typed -import { allApplications, getAppData, getAppTree } from "@exabyte-io/application-flavors.js"; +import { AllowedApplications, allApplications, getAppData, getAppTree } from "@exabyte-io/application-flavors.js"; import { getOneMatchFromObject } from "@exabyte-io/code.js/dist/utils"; -import { AppTree, ExecutableData } from "./types"; +import { ExecutableData } from "./types"; import { Constructor } from "@exabyte-io/code.js/dist/context"; +import { ApplicationData, ApplicationTree } from "@exabyte-io/application-flavors.js/lib/js/build_templates"; + +type AppTree = { + // application + [appName in AllowedApplications]: { + // version + defaultVersion: string + } & { + [version: string]: { + // build + [build: string]: { + build: string; + name: string; + summary: string; + shortName: string; + } + } + }; +} + +type AppArray = { + version: string; + build: string; + name: string; + summary: string; + shortName: string; + isDefault: boolean; +}[]; /** * @summary Return all applications as both a nested object of Applications and an array of config objects @@ -10,33 +37,25 @@ import { Constructor } from "@exabyte-io/code.js/dist/context"; * @returns containing applications and applicationConfigs */ export function getAllApplications(cls?: Constructor) { - const applicationsTree = {}; - // @ts-expect-error application-flavors is not typed - const applicationsArray = []; - allApplications.forEach((appName: string) => { - // @ts-ignore - applicationsTree[appName] = {}; - const { versions, defaultVersion, build = "Default", ...appData } = getAppData(appName); - // @ts-ignore - applicationsTree[appName].defaultVersion = defaultVersion; + const applicationsTree: AppTree = {} as AppTree; + const applicationsArray: AppArray = []; + allApplications.forEach((appName) => { + const { versions, defaultVersion, ...appData } = getAppData(appName); // @ts-ignore + applicationsTree[appName] = { defaultVersion }; versions.forEach((options) => { - const { version } = options; - // @ts-ignore + const { version, build = "Default" } = options; if (!(version in applicationsTree[appName])) applicationsTree[appName][version] = {}; const config = { ...appData, build, ...options }; if (cls) { - // @ts-ignore applicationsTree[appName][version][build] = new cls(config); applicationsArray.push(new cls(config)); } else { - // @ts-ignore applicationsTree[appName][version][build] = config; applicationsArray.push(config); } }); }); - // @ts-ignore return { applicationsTree, applicationsArray }; } @@ -48,14 +67,12 @@ export function getAllApplications(cls?: Constructor) { * @param build {String} the build to use (optional, defaults to Default) * @return {*} an application */ -// @ts-ignore applicationsTree is not typed -export function getApplication({ applicationsTree, name, version = null, build = "Default" }:{ - applicationsTree: object, - name: string, +export function getApplication({ applicationsTree, name, version, build = "Default" }:{ + applicationsTree: AppTree, + name: AllowedApplications, version?: string, build?: string, }) { - // @ts-ignore applicationsTree is not typed const app = applicationsTree[name]; const version_ = version || app.defaultVersion; if (!app[version_]) console.log(`Version ${version_} not available for ${name} !`); @@ -71,8 +88,8 @@ const { applicationsTree } = getAllApplications(); * @param build {String} * @returns {*} */ -export function getApplicationConfig({ name, version = undefined, build = "Default" }: { - name: string; +export function getApplicationConfig({ name, version, build = "Default" }: { + name: AllowedApplications; version?: string; build?: string; }) { @@ -90,18 +107,26 @@ export function getApplicationConfig({ name, version = undefined, build = "Defau * @param execName if not provided, find the executable with isDefault === true * @returns an executable config */ -export function getExecutableConfig({ appName, execName = undefined }: { appName: string, execName: string | undefined }): ExecutableData | undefined { - const appTree: AppTree = getAppTree(appName); - Object.entries(appTree).forEach(([name, exec]) => { - exec.name = name; - }); +export function getExecutableConfig({ appName, execName }: { appName: AllowedApplications, execName?: string }) { + const appTree = getAppTree(appName); + console.log(appTree) if (!execName) { console.log("No executable name provided, using default executable"); - return getOneMatchFromObject(appTree, "isDefault", true) as ExecutableData | undefined; + // iterate over properties of appTree and find the one with isDefault === true + Object.entries(appTree).forEach(([key, value]) => { + if (value.isDefault) { + console.log(`Found default executable: ${key}`); + execName = key; + } + }); + if (!execName) { + console.log(`No default executable found for application ${appName}`); + return undefined; + } } if (!appTree[execName]) { console.log(`Executable ${execName} not found for application ${appName}`); return undefined; } - return appTree[execName]; + return {...appTree[execName], name: execName}; } diff --git a/src/types/index.ts b/src/types/index.ts index eca5f84..f6532a1 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,3 +1,5 @@ +import { AllowedApplications } from "@exabyte-io/application-flavors.js"; + // TODO: remove these types once application-flavors is moved to TypeScript export type VersionData = { version: string; @@ -7,7 +9,7 @@ export type VersionData = { } export type ApplicationData = { - name: string; + name: AllowedApplications; shortName: string; summary: string; defaultVersion: string; @@ -16,10 +18,6 @@ export type ApplicationData = { export type ApplicationConfig = Omit & VersionData; -export type AppTree = { - [applicationName: string]: ExecutableData; -} - export type ExecutableData = { name?: string; isDefault: boolean; diff --git a/tests/application.test.ts b/tests/application.test.ts index 0d40280..346ea30 100644 --- a/tests/application.test.ts +++ b/tests/application.test.ts @@ -7,6 +7,8 @@ describe("Application", () => { const obj = { name: "espresso" }; it("can be created", () => { const app = new Application(obj); + console.log(app); + console.log(app.executables); expect(app.name).to.equal("espresso"); expect(app.executables.map((e) => e.name).includes("pw.x")).to.equal(true); });