WebPack Update
This commit is contained in:
		
							parent
							
								
									1238a1ff7c
								
							
						
					
					
						commit
						f8edbdd581
					
				|  | @ -119,7 +119,7 @@ export class PageHandler | ||||||
|   private _maxPreloadingDurationMS:number = 2000;  |   private _maxPreloadingDurationMS:number = 2000;  | ||||||
|    |    | ||||||
|   private static _localHost = "http://localhost:8080"; |   private static _localHost = "http://localhost:8080"; | ||||||
|   private static _localNetworkRegexPattern = /^(http:\/\/\d\d\d\.\d\d\d\.\d\d\d\.\d\d\d?:XXXX)/ |   private static _localNetworkRegexPattern = /^(http:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}?:XXXX)/ | ||||||
|   private static _localNetworkRegex = RegExpUtility.createRegExp( this._localNetworkRegexPattern, "XXXX", 8080 + "" ); |   private static _localNetworkRegex = RegExpUtility.createRegExp( this._localNetworkRegexPattern, "XXXX", 8080 + "" ); | ||||||
|   private _isHTMLMode:boolean = false; |   private _isHTMLMode:boolean = false; | ||||||
|   private _fileLocation:string = ""; |   private _fileLocation:string = ""; | ||||||
|  | @ -186,17 +186,25 @@ export class PageHandler | ||||||
|   get isLocalNetwork() |   get isLocalNetwork() | ||||||
|   { |   { | ||||||
|     let adress = this.trimmedLocation; |     let adress = this.trimmedLocation; | ||||||
|  | 
 | ||||||
|  |     // console.log( "Checking adress for localhost", adress, PageHandler._localHost, PageHandler._localNetworkRegex );
 | ||||||
|      |      | ||||||
|     if ( adress.startsWith( PageHandler._localHost ) ) |     if ( adress.startsWith( PageHandler._localHost ) ) | ||||||
|     { |     { | ||||||
|  |       console.log( "Is starting with localhost" ); | ||||||
|       return true; |       return true; | ||||||
|     } |     } | ||||||
|  |      | ||||||
|  |     // console.log( "Not starting with localhost" );
 | ||||||
| 
 | 
 | ||||||
|     if ( PageHandler._localNetworkRegex.test( adress ) ) |     if ( PageHandler._localNetworkRegex.test( adress ) ) | ||||||
|     { |     { | ||||||
|  |       // console.log( "Is starting with localhost regex" );
 | ||||||
|       return true; |       return true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // console.log( "Not starting with localhost regex" );
 | ||||||
|  | 
 | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -234,7 +242,7 @@ export class PageHandler | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|       console.log( "LOADING PAGE DATA FROM JSON" ); |       console.log( "LOADING PAGE DATA FROM JSON", this.isLocalNetwork, pagesPath ); | ||||||
|       let pagesData = await Loader.loadJSON<PagesJSON>( pagesPath ); |       let pagesData = await Loader.loadJSON<PagesJSON>( pagesPath ); | ||||||
|       pages = pagesData.pages; |       pages = pagesData.pages; | ||||||
|     }  |     }  | ||||||
|  |  | ||||||
|  | @ -0,0 +1,86 @@ | ||||||
|  | import { JSDOM } from "jsdom"; | ||||||
|  | 
 | ||||||
|  | export class DOMShim | ||||||
|  | { | ||||||
|  |   private static _instance:DOMShim = null; | ||||||
|  |    | ||||||
|  | 
 | ||||||
|  |   static get $():DOMShim | ||||||
|  |   { | ||||||
|  |     if ( this._instance ) | ||||||
|  |     { | ||||||
|  |       return this._instance | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     this._instance = new DOMShim(); | ||||||
|  |     return this._instance; | ||||||
|  |   }  | ||||||
|  | 
 | ||||||
|  |   private _applied = false; | ||||||
|  |   private _jsDOM:JSDOM; | ||||||
|  | 
 | ||||||
|  |   constructor() | ||||||
|  |   { | ||||||
|  |     this._apply(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   setDocument( html:string ) | ||||||
|  |   { | ||||||
|  |     this._jsDOM = new JSDOM( html ); | ||||||
|  |     ( global as any ).window   = this._jsDOM.window; | ||||||
|  |     ( global as any ).document = this._jsDOM.window.document; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   get jsdom(){ return this._jsDOM; } | ||||||
|  |    | ||||||
|  |   private _apply() | ||||||
|  |   { | ||||||
|  |     if ( this._applied ) | ||||||
|  |     { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     this._addHTMLNodeDefinition(); | ||||||
|  |     this._addDOMParser();     | ||||||
|  | 
 | ||||||
|  |     this._applied = true; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  |   private _addHTMLNodeDefinition() | ||||||
|  |   { | ||||||
|  |     ( global as any ).Node =  | ||||||
|  |     { | ||||||
|  |       ELEMENT_NODE: 1, | ||||||
|  |       ATTRIBUTE_NODE: 2, | ||||||
|  |       TEXT_NODE:3, | ||||||
|  |       CDATA_SECTION_NODE:4, | ||||||
|  |       PROCESSING_INSTRUCTION_NODE:7, | ||||||
|  |       COMMENT_NODE:8, | ||||||
|  |       DOCUMENT_NODE:9, | ||||||
|  |       DOCUMENT_TYPE_NODE:10, | ||||||
|  |       DOCUMENT_FRAGMENT_NODE:11 | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   private _addDOMParser() | ||||||
|  |   { | ||||||
|  |     DOMParserShim.implementation = ( html:string, type:string = "html" )=> | ||||||
|  |     { | ||||||
|  |       return new JSDOM( html, {contentType:type} ).window.document; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     global.DOMParser = DOMParserShim; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export class DOMParserShim | ||||||
|  | {   | ||||||
|  |   static implementation:( html:string, type:string )=>Document; | ||||||
|  |   parseFromString( html:string, type:string ):Document | ||||||
|  |   { | ||||||
|  |     return DOMParserShim.implementation( html, type ); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,373 @@ | ||||||
|  | import { promises as fs } from "fs"; | ||||||
|  | import * as path from "path"; | ||||||
|  | 
 | ||||||
|  | import { RJLog } from "../log/RJLog"; | ||||||
|  | import { PathReference } from "./PathReference"; | ||||||
|  | import { DOMShim } from "../DOMShim"; | ||||||
|  | import { DateMath } from "../../browser/date/DateMath"; | ||||||
|  | 
 | ||||||
|  | export class Files | ||||||
|  | { | ||||||
|  |   static parentPath( filePath:string ) | ||||||
|  |   { | ||||||
|  |     return path.dirname( filePath ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async forAllIn( filePath:string, filter:(p:PathReference)=>Promise<boolean> = null, action:(p:PathReference)=>Promise<void> = null ):Promise<PathReference[]> | ||||||
|  |   { | ||||||
|  |     let files = await fs.readdir( filePath ); | ||||||
|  | 
 | ||||||
|  |     let root = new PathReference( filePath ); | ||||||
|  |     let pathReferences = files.map( f => root.createRelative( f ) ); | ||||||
|  | 
 | ||||||
|  |     if ( filter ) | ||||||
|  |     {  | ||||||
|  |       let filteredPaths = []; | ||||||
|  | 
 | ||||||
|  |       for ( let p of pathReferences ) | ||||||
|  |       { | ||||||
|  |         if ( await filter( p ) ) | ||||||
|  |         { | ||||||
|  |           filteredPaths.push( p ); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       pathReferences = filteredPaths; | ||||||
|  | 
 | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     for ( let p of pathReferences ) | ||||||
|  |     { | ||||||
|  |       let isDirectory = await p.isDirectory(); | ||||||
|  | 
 | ||||||
|  |       if ( isDirectory ) | ||||||
|  |       { | ||||||
|  |         await this.forAllIn( p.absolutePath, filter, action ); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if ( action ) | ||||||
|  |     { | ||||||
|  |       for ( let p of pathReferences ) | ||||||
|  |       { | ||||||
|  |         await action( p ); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return Promise.resolve( pathReferences ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async forDirectChildrenIn( filePath:string, filter:(p:PathReference)=>Promise<boolean> = null, action:(p:PathReference)=>Promise<void> = null ):Promise<PathReference[]> | ||||||
|  |   { | ||||||
|  |     let files = await fs.readdir( filePath ); | ||||||
|  | 
 | ||||||
|  |     let root = new PathReference( filePath ); | ||||||
|  |     let pathReferences = files.map( f => root.createRelative( f ) ); | ||||||
|  | 
 | ||||||
|  |     if ( filter ) | ||||||
|  |     {  | ||||||
|  |       let filteredPaths = []; | ||||||
|  | 
 | ||||||
|  |       for ( let p of pathReferences ) | ||||||
|  |       { | ||||||
|  |         if ( await filter( p ) ) | ||||||
|  |         { | ||||||
|  |           filteredPaths.push( p ); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       pathReferences = filteredPaths; | ||||||
|  | 
 | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     if ( action ) | ||||||
|  |     { | ||||||
|  |       for ( let p of pathReferences ) | ||||||
|  |       { | ||||||
|  |         await action( p ); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return Promise.resolve( pathReferences ); | ||||||
|  | 
 | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   static joinPaths( pathFragments:string[] ) | ||||||
|  |   { | ||||||
|  |     return path.join.apply( path, pathFragments ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async existsIn( directoryPath:string, fileName:string ):Promise<boolean> | ||||||
|  |   { | ||||||
|  |     let combinedPath = Files.joinPaths( [ directoryPath, fileName ] ); | ||||||
|  |     let result = await Files.exists( combinedPath ); | ||||||
|  | 
 | ||||||
|  |     return Promise.resolve( result ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async getStatistics( filePath:string ) | ||||||
|  |   { | ||||||
|  |     return fs.stat( filePath ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async getModificationDate( filePath:string ):Promise<Date> | ||||||
|  |   { | ||||||
|  |     let stats = await this.getStatistics( filePath ); | ||||||
|  | 
 | ||||||
|  |     if ( ! stats ) | ||||||
|  |     { | ||||||
|  |       return Promise.resolve( null ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return new Date( stats.mtimeMs ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async isNewerThan( filePath:string, date:Date ):Promise<boolean> | ||||||
|  |   { | ||||||
|  |     let mDate = await this.getModificationDate( filePath ); | ||||||
|  | 
 | ||||||
|  |     return Promise.resolve( DateMath.isAfter( mDate, date ) ); | ||||||
|  |   }  | ||||||
|  | 
 | ||||||
|  |   static async isDirectory( filePath:string ):Promise<boolean> | ||||||
|  |   { | ||||||
|  |     try | ||||||
|  |     { | ||||||
|  |       let stats = await fs.stat( filePath );   | ||||||
|  |        | ||||||
|  |       return Promise.resolve( stats !== null && stats !== undefined && stats.isDirectory() ); | ||||||
|  |     } | ||||||
|  |     catch( e ) | ||||||
|  |     { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return Promise.resolve( false );     | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async isFile( filePath:string ):Promise<boolean> | ||||||
|  |   { | ||||||
|  |     try | ||||||
|  |     { | ||||||
|  |       let stats = await fs.stat( filePath );   | ||||||
|  |        | ||||||
|  |       return Promise.resolve( stats !== null && stats !== undefined && stats.isFile() ); | ||||||
|  |     } | ||||||
|  |     catch( e ) | ||||||
|  |     { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return Promise.resolve( false );     | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async isSymbolicLink( filePath:string ):Promise<boolean> | ||||||
|  |   { | ||||||
|  |     try | ||||||
|  |     { | ||||||
|  |       let stats = await fs.stat( filePath );   | ||||||
|  |        | ||||||
|  |       return Promise.resolve( stats !== null && stats !== undefined && stats.isSymbolicLink() ); | ||||||
|  |     } | ||||||
|  |     catch( e ) | ||||||
|  |     { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return Promise.resolve( false );     | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async exists( filePath:string ):Promise<boolean> | ||||||
|  |   { | ||||||
|  |     try | ||||||
|  |     { | ||||||
|  |       let stats = await fs.stat( filePath );   | ||||||
|  |        | ||||||
|  |       return Promise.resolve( stats !== null && stats !== undefined ); | ||||||
|  |     } | ||||||
|  |     catch( e ) | ||||||
|  |     { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return Promise.resolve( false );     | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async ensureDirectoryExists( path:string ):Promise<void> | ||||||
|  |   { | ||||||
|  |     let exists = await Files.exists( path ); | ||||||
|  | 
 | ||||||
|  |     if ( exists ) | ||||||
|  |     { | ||||||
|  |       return Promise.resolve(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     await fs.mkdir( path, { recursive: true } ); | ||||||
|  | 
 | ||||||
|  |     return Promise.resolve(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async ensureParentDirectoryExists( filePath:string ):Promise<void> | ||||||
|  |   { | ||||||
|  |     let path = Files.parentPath( filePath ); | ||||||
|  |     let exists = await Files.exists( path ); | ||||||
|  | 
 | ||||||
|  |     if ( exists ) | ||||||
|  |     { | ||||||
|  |       return Promise.resolve(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     await fs.mkdir( path ); | ||||||
|  | 
 | ||||||
|  |     return Promise.resolve(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async deleteFile( filePath:string ):Promise<boolean> | ||||||
|  |   { | ||||||
|  |     try | ||||||
|  |     { | ||||||
|  |       await fs.unlink( filePath ); | ||||||
|  |     } | ||||||
|  |     catch( e )  | ||||||
|  |     { | ||||||
|  |       return Promise.resolve( false ); | ||||||
|  |     }  | ||||||
|  | 
 | ||||||
|  |     return Promise.resolve( true ); | ||||||
|  |      | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  |   static async loadUTF8( filePath:string ):Promise<string> | ||||||
|  |   { | ||||||
|  |     try | ||||||
|  |     { | ||||||
|  |       let data = await fs.readFile( filePath ); | ||||||
|  |       let stringData = data.toString(); | ||||||
|  |       return Promise.resolve( stringData ); | ||||||
|  |     } | ||||||
|  |     catch ( exception ) | ||||||
|  |     {  | ||||||
|  |       RJLog.log( exception ); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     return Promise.resolve( null ); | ||||||
|  | 
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  | 
 | ||||||
|  |   static async moveFile( oldPath:string, newPath:string ) | ||||||
|  |   { | ||||||
|  |     try | ||||||
|  |     { | ||||||
|  |       await fs.rename( oldPath, newPath ); | ||||||
|  |     } | ||||||
|  |     catch ( e ) | ||||||
|  |     { | ||||||
|  |       await fs.copyFile( oldPath, newPath ); | ||||||
|  |       await fs.unlink( oldPath ); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async loadJSON<T>( filePath:string ):Promise<T> | ||||||
|  |   { | ||||||
|  |     let text = await Files.loadUTF8( filePath ); | ||||||
|  | 
 | ||||||
|  |     if ( text === null ) | ||||||
|  |     { | ||||||
|  |       return Promise.resolve( null ); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     try | ||||||
|  |     { | ||||||
|  |       let jsonObject = JSON.parse( text ); | ||||||
|  | 
 | ||||||
|  |       return Promise.resolve( jsonObject as T ); | ||||||
|  |     } | ||||||
|  |     catch ( exception ) | ||||||
|  |     { | ||||||
|  |       RJLog.log( exception ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return Promise.resolve( null ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async saveUTF8( filePath:string, text:string ):Promise<boolean> | ||||||
|  |   { | ||||||
|  |     try | ||||||
|  |     { | ||||||
|  |       await fs.writeFile( filePath, text ); | ||||||
|  |       return Promise.resolve( true ); | ||||||
|  |     } | ||||||
|  |     catch ( exception ) | ||||||
|  |     {  | ||||||
|  |       RJLog.log( exception ); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     return Promise.resolve( false ); | ||||||
|  | 
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async saveJSON<T>( filePath:string, data:T ):Promise<boolean> | ||||||
|  |   { | ||||||
|  |     try | ||||||
|  |     { | ||||||
|  |       let jsonData = JSON.stringify( data ); | ||||||
|  |       let result = await Files.saveUTF8( filePath, jsonData ); | ||||||
|  | 
 | ||||||
|  |       return Promise.resolve( result ); | ||||||
|  |     } | ||||||
|  |     catch( e )  | ||||||
|  |     { | ||||||
|  |       RJLog.log( e ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |     return Promise.resolve( false ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async saveXML( filePath:string, rootElement:Element ):Promise<void> | ||||||
|  |   { | ||||||
|  |     let domShim = DOMShim.$;   | ||||||
|  | 
 | ||||||
|  |     let nodeName = rootElement.nodeName; | ||||||
|  |     let xmlHeader = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>` + "\n"; | ||||||
|  |     let serializedXML = `${xmlHeader}<${nodeName}>${rootElement.innerHTML}</${nodeName}>` ; | ||||||
|  | 
 | ||||||
|  |     //RJLog.log( rootElement, serializedXML );
 | ||||||
|  | 
 | ||||||
|  |     await Files.saveUTF8( filePath, serializedXML ); | ||||||
|  | 
 | ||||||
|  |     return Promise.resolve(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async loadXML( filePath:string ):Promise<Document> | ||||||
|  |   { | ||||||
|  |     let domShim = DOMShim.$;  | ||||||
|  | 
 | ||||||
|  |     let stringData = await Files.loadUTF8( filePath ); | ||||||
|  |     let parser = new DOMParser(); | ||||||
|  |     let xmlDoc = parser.parseFromString( stringData, "text/xml" ); | ||||||
|  |     return xmlDoc; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async loadHTML( filePath:string ):Promise<Document> | ||||||
|  |   { | ||||||
|  |     let domShim = DOMShim.$;  | ||||||
|  | 
 | ||||||
|  |     let stringData = await Files.loadUTF8( filePath ); | ||||||
|  |     let parser = new DOMParser(); | ||||||
|  |     let xmlDoc = parser.parseFromString( stringData, "text/html" ); | ||||||
|  |     return xmlDoc; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static async saveHTML( filePath:string, rootElement:Element ):Promise<void> | ||||||
|  |   { | ||||||
|  |     let domShim = DOMShim.$;   | ||||||
|  | 
 | ||||||
|  |     await Files.saveUTF8( filePath, rootElement.outerHTML ); | ||||||
|  | 
 | ||||||
|  |     return Promise.resolve(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | export class FilesSync | ||||||
|  | { | ||||||
|  |    | ||||||
|  | } | ||||||
|  | @ -0,0 +1,26 @@ | ||||||
|  | import { PathReference } from "./PathReference" | ||||||
|  | 
 | ||||||
|  | export type PathReferenceFilter = (p:PathReference)=>Promise<boolean>; | ||||||
|  | 
 | ||||||
|  | export class PathFilter | ||||||
|  | { | ||||||
|  |   static get HTML() | ||||||
|  |   { | ||||||
|  |     return PathFilter.forFileExtension( ".html" ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static get JSON() | ||||||
|  |   { | ||||||
|  |     return PathFilter.forFileExtension( ".json" ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static forFileExtension( extension:string ):PathReferenceFilter | ||||||
|  |   { | ||||||
|  |     let filter = ( p:PathReference )=> | ||||||
|  |     { | ||||||
|  |       return p.isFileWithExtension( extension ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return filter; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,151 @@ | ||||||
|  | 
 | ||||||
|  | import { RegExpUtility } from "../../browser/text/RegExpUtitlity"; | ||||||
|  | import { Files } from "./Files"; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export class PathReference | ||||||
|  | { | ||||||
|  |   _parentReference:PathReference; | ||||||
|  |   _relative:boolean; | ||||||
|  |   _path:string; | ||||||
|  |   _cachedAbsolutePath:string; | ||||||
|  | 
 | ||||||
|  |   constructor( absolutePath:string ) | ||||||
|  |   { | ||||||
|  |     this._path = RegExpUtility.normalizePath( absolutePath ); | ||||||
|  |     this._relative = false; | ||||||
|  |     this._parentReference = null;     | ||||||
|  |   }   | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   createRelative( path:string ) | ||||||
|  |   { | ||||||
|  |     path = RegExpUtility.normalizePath( path ); | ||||||
|  |     let link = new PathReference( path ); | ||||||
|  |     link._relative = true; | ||||||
|  |     link._parentReference = this; | ||||||
|  | 
 | ||||||
|  |     return link; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   createRelativeFromAbsolute( otherAbsolutePath:string, isFile:boolean ) | ||||||
|  |   { | ||||||
|  |     otherAbsolutePath = RegExpUtility.normalizePath( otherAbsolutePath ); | ||||||
|  | 
 | ||||||
|  |     if ( ! isFile ) | ||||||
|  |     { | ||||||
|  |       let relativePath = RegExpUtility.createRelativeDirectoryPath( this.absolutePath, otherAbsolutePath ); | ||||||
|  |       return this.createRelative( relativePath ) | ||||||
|  |     }  | ||||||
|  | 
 | ||||||
|  |     let filePath   = RegExpUtility.fileNameOrLastPath( otherAbsolutePath ); | ||||||
|  |     let parentPath = RegExpUtility.parentPath( otherAbsolutePath );     | ||||||
|  |      | ||||||
|  |     let relativePath = RegExpUtility.createRelativeDirectoryPath( this.absolutePath, parentPath ); | ||||||
|  |     relativePath = RegExpUtility.join( relativePath, filePath ); | ||||||
|  | 
 | ||||||
|  |     return this.createRelative( relativePath ) | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   get isRelative() | ||||||
|  |   { | ||||||
|  |     return this._relative; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   get relativePath() | ||||||
|  |   { | ||||||
|  |     return this._path; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   get fileName() | ||||||
|  |   { | ||||||
|  |     return RegExpUtility.fileNameOrLastPath( this._path ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   get fileNameWithoutExtension() | ||||||
|  |   { | ||||||
|  |     return RegExpUtility.trimFileTypeExtension( this.fileName ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   pathEndsWith( extension:string ) | ||||||
|  |   { | ||||||
|  |     return this._path.toLowerCase().endsWith( extension.toLowerCase() ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   async isFileWithExtension( extension:string ) | ||||||
|  |   { | ||||||
|  |     if ( ! this.pathEndsWith( extension ) ) | ||||||
|  |     { | ||||||
|  |       return false; | ||||||
|  |     }  | ||||||
|  | 
 | ||||||
|  |     return this.isFile(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   get absolutePath() | ||||||
|  |   { | ||||||
|  |     if ( ! this._relative ) | ||||||
|  |     { | ||||||
|  |       return this._path; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if ( this._cachedAbsolutePath ) | ||||||
|  |     { | ||||||
|  |       return this._cachedAbsolutePath; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     let cachedAbsolutePath = RegExpUtility.join( this._parentReference.absolutePath, this._path ); | ||||||
|  |     cachedAbsolutePath = RegExpUtility.resolvePath( cachedAbsolutePath ); | ||||||
|  | 
 | ||||||
|  |     this._cachedAbsolutePath = cachedAbsolutePath; | ||||||
|  | 
 | ||||||
|  |     return this._cachedAbsolutePath; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   async exists():Promise<boolean> | ||||||
|  |   { | ||||||
|  |     return Files.exists( this.absolutePath ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   async isFile():Promise<boolean> | ||||||
|  |   { | ||||||
|  |     return Files.isFile( this.absolutePath ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   async isDirectory():Promise<boolean> | ||||||
|  |   { | ||||||
|  |     return Files.isDirectory( this.absolutePath ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   async isSymbolicLink():Promise<boolean> | ||||||
|  |   { | ||||||
|  |     return Files.isSymbolicLink( this.absolutePath ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   async loadUTF8() | ||||||
|  |   { | ||||||
|  |     return Files.loadUTF8( this.absolutePath ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   async loadHTML() | ||||||
|  |   { | ||||||
|  |     return Files.loadHTML( this.absolutePath ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   async saveHTML( rootElement:Element ) | ||||||
|  |   { | ||||||
|  |     return Files.saveHTML( this.absolutePath, rootElement ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   async loadXML() | ||||||
|  |   { | ||||||
|  |     return Files.loadXML( this.absolutePath ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   async loadJSON<T>() | ||||||
|  |   { | ||||||
|  |     return Files.loadJSON<T>( this.absolutePath ); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -1,8 +1,8 @@ | ||||||
| { | { | ||||||
|   "compilerOptions": { |   "compilerOptions": { | ||||||
|     "target": "ESNext", |      | ||||||
|     "module": "CommonJS", |     "module": "es2022",  | ||||||
|     "lib": ["ESNext"], |     "target": "es2015", | ||||||
|     "moduleResolution": "Node", |     "moduleResolution": "Node", | ||||||
|     "types": ["node"] |     "types": ["node"] | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -2,23 +2,100 @@ | ||||||
| import * as fs from "fs"; | import * as fs from "fs"; | ||||||
| import * as path from "path"; | import * as path from "path"; | ||||||
| import { RJLog } from "../log/RJLog"; | import { RJLog } from "../log/RJLog"; | ||||||
|  | import { spawn } from "child_process"; | ||||||
| 
 | 
 | ||||||
| export class PagesInfo | export class PagesInfo | ||||||
| { | { | ||||||
|   pages:string[] = []; |   pages:string[] = []; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | export class PHPServerSettings | ||||||
|  | { | ||||||
|  |   phpPaths:string[] = [ "D:\\apps\\php\\php.exe", "C:\\apps\\php\\php.exe" ]; | ||||||
|  |   relativeWebPath:string; | ||||||
|  |   routerPath:string; | ||||||
|  |   port:number = 8081; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| export class PHPPagesBuilder | export class PHPPagesBuilder | ||||||
| { | { | ||||||
|   inputDir:string; |   inputDir:string; | ||||||
|   outputDir:string; |   outputDir:string; | ||||||
| 
 | 
 | ||||||
|   constructor( source:string, build:string )  |   static hasServer = false; | ||||||
|  | 
 | ||||||
|  |   constructor( source:string, build:string, settings:PHPServerSettings )  | ||||||
|   { |   { | ||||||
|     this.inputDir = source;  |     this.inputDir = source;  | ||||||
|     this.outputDir = build; |     this.outputDir = build; | ||||||
|  | 
 | ||||||
|  |     this.startServer( settings ); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   startServer( settings:PHPServerSettings ) | ||||||
|  |   { | ||||||
|  |     if ( settings == null ) | ||||||
|  |     { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if ( PHPPagesBuilder.hasServer ) | ||||||
|  |     { | ||||||
|  |       return; | ||||||
|  |     }   | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     PHPPagesBuilder.hasServer = true; | ||||||
|  | 
 | ||||||
|  |     let phpPath = PHPPagesBuilder.getPHPPath( settings ); | ||||||
|  | 
 | ||||||
|  |     if ( ! phpPath ) | ||||||
|  |     { | ||||||
|  |       RJLog.error( "PHP was not found!"); | ||||||
|  |       RJLog.error( "Ensure PHP is installed and the paths in the settings are configured correctly."); | ||||||
|  |       RJLog.log( "PHP paths from settings of '" + process.argv[ 2 ] + "': "); | ||||||
|  |       RJLog.log( '"' + settings.phpPaths.join( ", " ) + '"' ); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     let workdingDir = process.cwd(); | ||||||
|  |    | ||||||
|  |     let webPath = path.join( workdingDir, settings.relativeWebPath ); | ||||||
|  |     let routerPath = path.join( webPath, "_router_.php" ); | ||||||
|  | 
 | ||||||
|  |     let port = settings.port; | ||||||
|  |     let spawnedProcess = spawn( phpPath,["-S", "0.0.0.0:" + port, routerPath, "-t", webPath ] ); | ||||||
|  | 
 | ||||||
|  |     spawnedProcess.stdout.on( "data", data => { console.log( data + "" ); }  ); | ||||||
|  | 
 | ||||||
|  |     spawnedProcess.stderr.on( "data", data => { console.log( data + "" ); }  ); | ||||||
|  | 
 | ||||||
|  |     spawnedProcess.on( 'error', (error) => { | ||||||
|  |         console.log(`error: ${error.message}`); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     spawnedProcess.on( "close", code => { | ||||||
|  |         console.log(`child process exited with code ${code}`); | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static getPHPPath( settings:PHPServerSettings ) | ||||||
|  |   { | ||||||
|  |     for ( let path of settings.phpPaths ) | ||||||
|  |     { | ||||||
|  |       let exists = fs.existsSync( path ); | ||||||
|  |        | ||||||
|  |       if ( exists ) | ||||||
|  |       { | ||||||
|  |         RJLog.log( "Starting php server from:", path ); | ||||||
|  |         return path; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return null; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|   filterFiles( fileName:string )  |   filterFiles( fileName:string )  | ||||||
|   { |   { | ||||||
|     if ( fileName.startsWith( "__" ) ) |     if ( fileName.startsWith( "__" ) ) | ||||||
|  |  | ||||||
|  | @ -0,0 +1,127 @@ | ||||||
|  | 
 | ||||||
|  | import * as fs from "fs"; | ||||||
|  | import * as path from "path"; | ||||||
|  | import { RJLog } from "../log/RJLog"; | ||||||
|  | import { Files } from "../files/Files"; | ||||||
|  | import { PathReference } from "../files/PathReference"; | ||||||
|  | 
 | ||||||
|  | export class TemplatesInfo | ||||||
|  | { | ||||||
|  |   templates:string[] = []; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export class TemplatesIndexBuilder | ||||||
|  | { | ||||||
|  |   inputDir:string; | ||||||
|  |   outputDir:string; | ||||||
|  | 
 | ||||||
|  |   constructor( source:string, build:string )  | ||||||
|  |   { | ||||||
|  |     this.inputDir = source;  | ||||||
|  |     this.outputDir = build; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   filterFiles( fileName:string )  | ||||||
|  |   { | ||||||
|  |     if ( fileName.startsWith( "__" ) ) | ||||||
|  |     { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     return fileName.endsWith( ".html" ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   apply( compiler:any )  | ||||||
|  |   { | ||||||
|  |     compiler.hooks.afterCompile.tapAsync( "TemplatesIndexBuilder",  | ||||||
|  |       async ( compilation:any, callback:any ) =>  | ||||||
|  |       { | ||||||
|  |         await Files.forAllIn( this.inputDir, null,  | ||||||
|  |           async ( p:PathReference ) => | ||||||
|  |           { | ||||||
|  |             if ( await p.isDirectory() ) | ||||||
|  |             { | ||||||
|  |               return Promise.resolve(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             let fileName = p.fileName; | ||||||
|  | 
 | ||||||
|  |             if ( ! this.filterFiles( fileName ) ) | ||||||
|  |             {  | ||||||
|  |               return Promise.resolve(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             compilation.fileDependencies.add( p.absolutePath ); | ||||||
|  | 
 | ||||||
|  |             return Promise.resolve(); | ||||||
|  |           } | ||||||
|  |         );          | ||||||
|  | 
 | ||||||
|  |         callback(); | ||||||
|  | 
 | ||||||
|  |       } | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     compiler.hooks.emit.tapAsync( "TemplatesIndexBuilder",  | ||||||
|  |       async ( compilation:any, callback:any ) =>  | ||||||
|  |       { | ||||||
|  |         let templates = new TemplatesInfo();         | ||||||
|  |         let templatesPathReference = new PathReference( path.resolve( this.inputDir ) ); | ||||||
|  | 
 | ||||||
|  |         // RJLog.log( templatesPathReference.absolutePath );
 | ||||||
|  | 
 | ||||||
|  |         await Files.forAllIn( templatesPathReference.absolutePath, null,  | ||||||
|  |           async ( p:PathReference ) => | ||||||
|  |           { | ||||||
|  |             if ( await p.isDirectory() ) | ||||||
|  |             { | ||||||
|  |               return Promise.resolve(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             let fileName = p.fileName; | ||||||
|  | 
 | ||||||
|  |             if ( ! this.filterFiles( fileName ) ) | ||||||
|  |             {  | ||||||
|  |               return Promise.resolve(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             let absoluteFilePath = p.absolutePath; | ||||||
|  |             let inputRelativePath = templatesPathReference.createRelativeFromAbsolute( absoluteFilePath, true ); | ||||||
|  | 
 | ||||||
|  |             // RJLog.log( "Abs to Rel", absoluteFilePath, inputRelativePath.relativePath );
 | ||||||
|  |             let outputFileName = path.join( this.outputDir, inputRelativePath.relativePath ); | ||||||
|  | 
 | ||||||
|  |             templates.templates.push( inputRelativePath.relativePath ); | ||||||
|  | 
 | ||||||
|  |             let content = fs.readFileSync( p.absolutePath, "utf-8" ); | ||||||
|  | 
 | ||||||
|  |             // RJLog.log( "Adding", p.absolutePath, outputFileName );
 | ||||||
|  |             compilation.assets[ outputFileName ] =  | ||||||
|  |             { | ||||||
|  |               source: () => content, | ||||||
|  |               size: () => content.length, | ||||||
|  |             }; | ||||||
|  |                | ||||||
|  | 
 | ||||||
|  |             return Promise.resolve(); | ||||||
|  |           } | ||||||
|  |         );          | ||||||
|  | 
 | ||||||
|  |         let templatesPath = path.join( this.outputDir, "index.json" ); | ||||||
|  | 
 | ||||||
|  |         let templatesJSON = JSON.stringify( templates, null, "  " ); | ||||||
|  | 
 | ||||||
|  |         compilation.assets[ templatesPath ] =  | ||||||
|  |         { | ||||||
|  |           source: () => templatesJSON, | ||||||
|  |           size: () => templatesJSON.length, | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         callback(); | ||||||
|  | 
 | ||||||
|  |         return Promise.resolve(); | ||||||
|  |       } | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	 Josef
						Josef