mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-04 06:19:44 +00:00
feat(marketplace): extract common components (#1338)
* feat(marketplace): extract common components * chore: fix service provide * feat(markdown): allow Observable content * chore: remove unnecessary module import * minor styling for marketplacee list * only show loading for marketplace show if version change * chore: get rid of unnecessary server request * chore: fix version switching Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { PackageState } from '@start9labs/shared'
|
||||
import { PackageState } from 'src/app/types/package-state'
|
||||
import { ConfigSpec } from 'src/app/pkg-config/config-types'
|
||||
import {
|
||||
DependencyErrorType,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { AbstractApiService } from '@start9labs/shared'
|
||||
import { Subject, Observable } from 'rxjs'
|
||||
import {
|
||||
Http,
|
||||
@@ -13,7 +14,10 @@ import { DataModel } from 'src/app/services/patch-db/data-model'
|
||||
import { RequestError } from '../http.service'
|
||||
import { map } from 'rxjs/operators'
|
||||
|
||||
export abstract class ApiService implements Source<DataModel>, Http<DataModel> {
|
||||
export abstract class ApiService
|
||||
extends AbstractApiService
|
||||
implements Source<DataModel>, Http<DataModel>
|
||||
{
|
||||
protected readonly sync$ = new Subject<Update<DataModel>>()
|
||||
|
||||
/** PatchDb Source interface. Post/Patch requests provide a source of patches to the db. */
|
||||
@@ -24,9 +28,6 @@ export abstract class ApiService implements Source<DataModel>, Http<DataModel> {
|
||||
.pipe(map(result => ({ result, jsonrpc: '2.0' })))
|
||||
}
|
||||
|
||||
// for getting static files: ex icons, instructions, licenses
|
||||
abstract getStatic(url: string): Promise<string>
|
||||
|
||||
// db
|
||||
|
||||
abstract getRevisions(since: number): Promise<RR.GetRevisionsRes>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { InstallProgress, pauseFor } from '@start9labs/shared'
|
||||
import { pauseFor } from '@start9labs/shared'
|
||||
import { ApiService } from './embassy-api.service'
|
||||
import { PatchOp, Update, Operation, RemoveOperation } from 'patch-db-client'
|
||||
import { PackageState } from '@start9labs/shared'
|
||||
import { PackageState } from 'src/app/types/package-state'
|
||||
import { InstallProgress } from 'src/app/types/install-progress'
|
||||
import {
|
||||
DataModel,
|
||||
DependencyErrorType,
|
||||
@@ -192,6 +193,8 @@ export class MockApiService extends ApiService {
|
||||
return Mock.MarketplacePkgsList
|
||||
} else if (path.startsWith('/package/v0/release-notes')) {
|
||||
return Mock.ReleaseNotes
|
||||
} else if (path.includes('instructions') || path.includes('license')) {
|
||||
return markdown
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PackageState } from '@start9labs/shared'
|
||||
import { PackageState } from 'src/app/types/package-state'
|
||||
import {
|
||||
DataModel,
|
||||
DependencyErrorType,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { WorkspaceConfig, PackageState } from '@start9labs/shared'
|
||||
import { WorkspaceConfig } from '@start9labs/shared'
|
||||
import { PackageState } from 'src/app/types/package-state'
|
||||
import {
|
||||
InterfaceDef,
|
||||
PackageDataEntry,
|
||||
|
||||
@@ -15,9 +15,9 @@ import { ServerInfo } from 'src/app/services/patch-db/data-model'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
import {
|
||||
catchError,
|
||||
finalize,
|
||||
map,
|
||||
shareReplay,
|
||||
startWith,
|
||||
switchMap,
|
||||
tap,
|
||||
} from 'rxjs/operators'
|
||||
@@ -56,11 +56,11 @@ export class MarketplaceService extends AbstractMarketplaceService {
|
||||
|
||||
constructor(
|
||||
private readonly api: ApiService,
|
||||
private readonly emver: Emver,
|
||||
private readonly patch: PatchDbService,
|
||||
private readonly config: ConfigService,
|
||||
private readonly loadingCtrl: LoadingController,
|
||||
private readonly errToast: ErrorToastService,
|
||||
private readonly emver: Emver,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
@@ -79,12 +79,17 @@ export class MarketplaceService extends AbstractMarketplaceService {
|
||||
|
||||
getPackage(id: string, version: string): Observable<MarketplacePkg> {
|
||||
const params = { ids: [{ id, version }] }
|
||||
|
||||
return this.init$.pipe(
|
||||
const fallback$ = this.init$.pipe(
|
||||
switchMap(({ url }) => from(this.getMarketplacePkgs(params, url))),
|
||||
map(pkgs => pkgs.find(pkg => pkg.manifest.id == id)),
|
||||
map(pkgs => this.findPackage(pkgs, id, version)),
|
||||
startWith(null),
|
||||
)
|
||||
|
||||
return this.getPackages().pipe(
|
||||
map(pkgs => this.findPackage(pkgs, id, version)),
|
||||
switchMap(pkg => (pkg ? of(pkg) : fallback$)),
|
||||
tap(pkg => {
|
||||
if (!pkg) {
|
||||
if (pkg === undefined) {
|
||||
throw new Error(`No results for ${id}${version ? ' ' + version : ''}`)
|
||||
}
|
||||
}),
|
||||
@@ -103,26 +108,6 @@ export class MarketplaceService extends AbstractMarketplaceService {
|
||||
)
|
||||
}
|
||||
|
||||
// async install(id: string, version?: string): Promise<void> {
|
||||
// const loader = await this.loadingCtrl.create({
|
||||
// spinner: 'lines',
|
||||
// message: 'Beginning Installation',
|
||||
// cssClass: 'loader',
|
||||
// })
|
||||
// loader.present()
|
||||
//
|
||||
// try {
|
||||
// await this.installPackage({
|
||||
// id,
|
||||
// 'version-spec': version ? `=${version}` : undefined,
|
||||
// })
|
||||
// } catch (e) {
|
||||
// this.errToast.present(e)
|
||||
// } finally {
|
||||
// loader.dismiss()
|
||||
// }
|
||||
// }
|
||||
|
||||
install(id: string, version?: string): Observable<unknown> {
|
||||
return defer(() =>
|
||||
from(
|
||||
@@ -161,6 +146,20 @@ export class MarketplaceService extends AbstractMarketplaceService {
|
||||
)
|
||||
}
|
||||
|
||||
getPackageMarkdown(type: string, pkgId: string): Observable<string> {
|
||||
return this.getMarketplace().pipe(
|
||||
switchMap(({ url }) =>
|
||||
from(
|
||||
this.api.marketplaceProxy<string>(
|
||||
`/package/v0/${type}/${pkgId}`,
|
||||
{},
|
||||
url,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
async getMarketplaceData(
|
||||
params: RR.GetMarketplaceDataReq,
|
||||
url: string,
|
||||
@@ -217,4 +216,18 @@ export class MarketplaceService extends AbstractMarketplaceService {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private findPackage(
|
||||
pkgs: readonly MarketplacePkg[],
|
||||
id: string,
|
||||
version: string,
|
||||
): MarketplacePkg | undefined {
|
||||
return pkgs.find(pkg => {
|
||||
const versionIsSame =
|
||||
version === '*' ||
|
||||
this.emver.compare(pkg.manifest.version, version) === 0
|
||||
|
||||
return pkg.manifest.id === id && versionIsSame
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { ActivatedRoute } from '@angular/router'
|
||||
import { ModalController } from '@ionic/angular'
|
||||
import { DependentInfo } from '@start9labs/shared'
|
||||
import { DependentInfo } from 'src/app/types/dependent-info'
|
||||
import { AppConfigPage } from 'src/app/modals/app-config/app-config.page'
|
||||
|
||||
@Injectable({
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { ConfigSpec } from 'src/app/pkg-config/config-types'
|
||||
import { InstallProgress, PackageState, Url } from '@start9labs/shared'
|
||||
import { Url } from '@start9labs/shared'
|
||||
import { MarketplaceManifest } from '@start9labs/marketplace'
|
||||
import { BasicInfo } from 'src/app/pages/developer-routes/developer-menu/form-info'
|
||||
import { PackageState } from 'src/app/types/package-state'
|
||||
import { InstallProgress } from 'src/app/types/install-progress'
|
||||
|
||||
export interface DataModel {
|
||||
'server-info': ServerInfo
|
||||
@@ -111,7 +113,7 @@ export interface CurrentDependencyInfo {
|
||||
'health-checks': string[] // array of health check IDs
|
||||
}
|
||||
|
||||
export interface Manifest extends MarketplaceManifest {
|
||||
export interface Manifest extends MarketplaceManifest<DependencyConfig> {
|
||||
main: ActionImpl
|
||||
'health-checks': Record<
|
||||
string,
|
||||
@@ -125,7 +127,11 @@ export interface Manifest extends MarketplaceManifest {
|
||||
migrations: Migrations
|
||||
actions: Record<string, Action>
|
||||
permissions: any // @TODO 0.3.1
|
||||
dependencies: DependencyInfo
|
||||
}
|
||||
|
||||
export interface DependencyConfig {
|
||||
check: ActionImpl
|
||||
'auto-configure': ActionImpl
|
||||
}
|
||||
|
||||
export interface ActionImpl {
|
||||
@@ -352,28 +358,3 @@ export interface DependencyErrorHealthChecksFailed {
|
||||
export interface DependencyErrorTransitive {
|
||||
type: DependencyErrorType.Transitive
|
||||
}
|
||||
|
||||
export interface DependencyInfo {
|
||||
[id: string]: DependencyEntry
|
||||
}
|
||||
|
||||
export interface DependencyEntry {
|
||||
version: string
|
||||
requirement:
|
||||
| {
|
||||
type: 'opt-in'
|
||||
how: string
|
||||
}
|
||||
| {
|
||||
type: 'opt-out'
|
||||
how: string
|
||||
}
|
||||
| {
|
||||
type: 'required'
|
||||
}
|
||||
description: string | null
|
||||
config: {
|
||||
check: ActionImpl
|
||||
'auto-configure': ActionImpl
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { isEmptyObject, PackageState } from '@start9labs/shared'
|
||||
import { isEmptyObject } from '@start9labs/shared'
|
||||
import { PackageState } from 'src/app/types/package-state'
|
||||
import {
|
||||
PackageDataEntry,
|
||||
PackageMainStatus,
|
||||
|
||||
Reference in New Issue
Block a user