11/* eslint-disable @typescript-eslint/no-var-requires */
22
3- import { DeployModule } from "./DeployModule" ;
4- import { loadDeployManifest , loadDeployManifestExt } from "../project" ;
5- import { CacheDirectory } from "../CacheDirectory" ;
6- import { Logger } from "../logging" ;
3+ import {
4+ DeployStep ,
5+ DeployModule ,
6+ DeployPackage ,
7+ DeployJob ,
8+ DeployJobResult
9+ } from "." ;
10+ import {
11+ loadDeployManifest ,
12+ loadDeployManifestExt ,
13+ CacheDirectory ,
14+ Logger
15+ } from ".." ;
716
817import { DeployManifest } from "@polywrap/polywrap-manifest-types-js" ;
9- import { Schema as JsonSchema } from "jsonschema" ;
18+ import { Schema as JsonSchema , validate } from "jsonschema" ;
1019import path from "path" ;
11- import nodePath from "path " ;
20+ import fs from "fs " ;
1221
1322interface DeployerConfig {
1423 cache : CacheDirectory ;
1524 logger : Logger ;
1625 defaultModulesCached : boolean ;
1726}
1827
28+ type DeployManifestJob = DeployManifest [ "jobs" ] [ number ] ;
29+ type DeployManifestStep = DeployManifestJob [ "steps" ] [ number ] ;
30+
1931export class Deployer {
2032 public static cacheLayout = {
2133 root : "deploy/" ,
@@ -43,13 +55,95 @@ export class Deployer {
4355 ) : Promise < Deployer > {
4456 const deployManifest = await loadDeployManifest ( manifest , logger ) ;
4557 const cache = new CacheDirectory ( {
46- rootDir : nodePath . dirname ( manifest ) ,
58+ rootDir : path . dirname ( manifest ) ,
4759 subDir : Deployer . cacheLayout . root ,
4860 } ) ;
4961 return new Deployer ( deployManifest , cache , logger ) ;
5062 }
5163
52- public async getDeployModule (
64+ public async run ( ) : Promise < DeployJobResult [ ] > {
65+ const allStepsFromAllJobs = Object . entries ( this . manifest . jobs ) . flatMap (
66+ ( [ jobName , job ] ) => {
67+ return job . steps . map ( ( step ) => ( {
68+ jobName,
69+ ...step ,
70+ } ) ) ;
71+ }
72+ ) ;
73+
74+ const packageNames = [
75+ ...new Set ( allStepsFromAllJobs . map ( ( step ) => step . package ) ) ,
76+ ] ;
77+
78+ this . _sanitizePackages ( packageNames ) ;
79+
80+ await this . _cacheDeployModules ( packageNames ) ;
81+
82+ const packageMapEntries = await Promise . all (
83+ packageNames . map ( async ( packageName ) => {
84+ const deployerPackage = await this . _getDeployModule ( packageName ) ;
85+ return [ packageName , deployerPackage ] ;
86+ } )
87+ ) ;
88+
89+ const packageMap = Object . fromEntries ( packageMapEntries ) ;
90+
91+ const stepToPackageMap : Record <
92+ string ,
93+ DeployPackage & { jobName : string }
94+ > = { } ;
95+
96+ for ( const step of allStepsFromAllJobs ) {
97+ stepToPackageMap [ step . name ] = {
98+ ...packageMap [ step . package ] ,
99+ jobName : step . jobName ,
100+ } ;
101+ }
102+
103+ this . _validateManifestWithExts ( this . manifest , stepToPackageMap ) ;
104+
105+ const jobs = Object . entries ( this . manifest . jobs ) . map ( ( [ jobName , job ] ) => {
106+ const steps : DeployStep [ ] = job . steps . map ( ( step ) => {
107+ return new DeployStep ( {
108+ name : step . name ,
109+ uriOrStepResult : step . uri ,
110+ deployModule : stepToPackageMap [ step . name ] . deployModule ,
111+ config : step . config ?? { } ,
112+ } ) ;
113+ } ) ;
114+
115+ return new DeployJob ( {
116+ name : jobName ,
117+ steps,
118+ config : job . config ?? { } ,
119+ logger : this . _config . logger ,
120+ } ) ;
121+ } ) ;
122+
123+ return await Promise . all ( jobs . map ( ( job ) => job . run ( ) ) ) ;
124+ }
125+
126+ private _sanitizePackages ( packages : string [ ] ) {
127+ const unrecognizedPackages : string [ ] = [ ] ;
128+
129+ const availableDeployers = fs . readdirSync (
130+ path . join ( __dirname , ".." , "defaults" , "deploy-modules" )
131+ ) ;
132+
133+ packages . forEach ( ( p ) => {
134+ if ( ! availableDeployers . includes ( p ) ) {
135+ unrecognizedPackages . push ( p ) ;
136+ }
137+ } ) ;
138+
139+ if ( unrecognizedPackages . length ) {
140+ throw new Error (
141+ `Unrecognized packages: ${ unrecognizedPackages . join ( ", " ) } `
142+ ) ;
143+ }
144+ }
145+
146+ private async _getDeployModule (
53147 moduleName : string
54148 ) : Promise < {
55149 deployModule : DeployModule ;
@@ -77,7 +171,7 @@ export class Deployer {
77171 } ;
78172 }
79173
80- public async cacheDeployModules ( modules : string [ ] ) : Promise < void > {
174+ private async _cacheDeployModules ( modules : string [ ] ) : Promise < void > {
81175 if ( this . _config . defaultModulesCached ) {
82176 return ;
83177 }
@@ -94,4 +188,42 @@ export class Deployer {
94188
95189 this . _config . defaultModulesCached = true ;
96190 }
191+
192+ private _validateManifestWithExts (
193+ deployManifest : DeployManifest ,
194+ stepToPackageMap : Record < string , DeployPackage & { jobName : string } >
195+ ) {
196+ const errors = Object . entries ( stepToPackageMap ) . flatMap (
197+ ( [ stepName , step ] ) => {
198+ const jobEntry = Object . entries ( deployManifest . jobs ) . find (
199+ ( [ jobName ] ) => jobName === step . jobName
200+ ) as [ string , DeployManifestJob ] ;
201+
202+ const job = jobEntry [ 1 ] ;
203+
204+ const stepToValidate = job . steps . find (
205+ ( s ) => s . name === stepName
206+ ) as DeployManifestStep ;
207+
208+ return step . manifestExt
209+ ? validate (
210+ {
211+ ...job . config ,
212+ ...stepToValidate . config ,
213+ } ,
214+ step . manifestExt
215+ ) . errors
216+ : [ ] ;
217+ }
218+ ) ;
219+
220+ if ( errors . length ) {
221+ throw new Error (
222+ [
223+ `Validation errors encountered while sanitizing DeployManifest format ${ deployManifest . format } ` ,
224+ ...errors . map ( ( error ) => error . toString ( ) ) ,
225+ ] . join ( "\n" )
226+ ) ;
227+ }
228+ }
97229}
0 commit comments