├── images └── hero.png ├── .github ├── FUNDING.yml └── workflows │ └── issues.yml ├── client ├── libs │ └── blooddy_crypto.swc ├── src │ ├── com │ │ ├── apm │ │ │ ├── client │ │ │ │ ├── commands │ │ │ │ │ ├── project │ │ │ │ │ │ └── processes │ │ │ │ │ │ │ ├── data │ │ │ │ │ │ │ ├── EntitlementsDefault.xml │ │ │ │ │ │ │ ├── InfoAdditionsDefault.xml │ │ │ │ │ │ │ └── AndroidManifestDefault.xml │ │ │ │ │ │ │ ├── AndroidManifestMerge.as │ │ │ │ │ │ │ ├── AndroidManifestMergeProcess.as │ │ │ │ │ │ │ ├── ProjectConfigGetProcess.as │ │ │ │ │ │ │ ├── ValidatePackageCacheProcess.as │ │ │ │ │ │ │ ├── ProjectDefinitionCreateProcess.as │ │ │ │ │ │ │ ├── GenerateConfigAndroidProcess.as │ │ │ │ │ │ │ ├── IOSPlistMergeProcess.as │ │ │ │ │ │ │ ├── ProjectAddProcess.as │ │ │ │ │ │ │ ├── ValidateProjectParametersProcess.as │ │ │ │ │ │ │ ├── GenerateConfigIOSProcess.as │ │ │ │ │ │ │ └── ProjectConfigSetProcess.as │ │ │ │ │ ├── Command.as │ │ │ │ │ ├── packages │ │ │ │ │ │ ├── processes │ │ │ │ │ │ │ ├── PackagePublishProcess.as │ │ │ │ │ │ │ ├── PackageGenerateChecksumProcess.as │ │ │ │ │ │ │ ├── PackageDependenciesVerifyProcess.as │ │ │ │ │ │ │ ├── PackageDefinitionLoadProcess.as │ │ │ │ │ │ │ ├── UninstallConfigForPackageProcess.as │ │ │ │ │ │ │ ├── InstallLocalPackageProcess.as │ │ │ │ │ │ │ └── PackageExtractDefinitionProcess.as │ │ │ │ │ │ ├── utils │ │ │ │ │ │ │ └── ProjectDefinitionValidator.as │ │ │ │ │ │ ├── CreateCommand.as │ │ │ │ │ │ └── BuildCommand.as │ │ │ │ │ ├── general │ │ │ │ │ │ ├── HelpCommand.as │ │ │ │ │ │ ├── UpgradeCommand.as │ │ │ │ │ │ └── VersionCommand.as │ │ │ │ │ └── airsdk │ │ │ │ │ │ └── AIRSDKListCommand.as │ │ │ │ ├── Consts.as │ │ │ │ ├── io │ │ │ │ │ ├── utils │ │ │ │ │ │ └── ListOutput.as │ │ │ │ │ ├── IOColour.as │ │ │ │ │ └── IO.as │ │ │ │ ├── processes │ │ │ │ │ ├── Process.as │ │ │ │ │ ├── ProcessCallback.as │ │ │ │ │ ├── events │ │ │ │ │ │ └── ProcessEvent.as │ │ │ │ │ ├── generic │ │ │ │ │ │ ├── ChecksumProcess.as │ │ │ │ │ │ ├── ExtractZipProcess.as │ │ │ │ │ │ └── ChecksumAS3Process.as │ │ │ │ │ └── ProcessBase.as │ │ │ │ ├── events │ │ │ │ │ ├── APMEvent.as │ │ │ │ │ └── CommandEvent.as │ │ │ │ ├── config │ │ │ │ │ └── processes │ │ │ │ │ │ ├── DebugDelayProcess.as │ │ │ │ │ │ ├── LoadUserSettingsProcess.as │ │ │ │ │ │ ├── CheckNetworkProcess.as │ │ │ │ │ │ ├── LoadProjectDefinitionProcess.as │ │ │ │ │ │ └── LoadWindowsJavaHomeProcess.as │ │ │ │ ├── repositories │ │ │ │ │ ├── PackageResolverResult.as │ │ │ │ │ ├── RepositoryResolver.as │ │ │ │ │ └── processes │ │ │ │ │ │ └── RepositoryGetPackageVersionProcess.as │ │ │ │ └── analytics │ │ │ │ │ └── Analytics.as │ │ │ ├── data │ │ │ │ ├── project │ │ │ │ │ ├── ProjectApplicationProperties.as │ │ │ │ │ └── ProjectPackageDependency.as │ │ │ │ ├── packages │ │ │ │ │ ├── PackageLicense.as │ │ │ │ │ ├── RepositoryDefinition.as │ │ │ │ │ └── PackageIdentifier.as │ │ │ │ └── install │ │ │ │ │ ├── InstallPackageDataGroup.as │ │ │ │ │ └── InstallPackageData.as │ │ │ ├── remote │ │ │ │ ├── airsdk │ │ │ │ │ ├── events │ │ │ │ │ │ └── AIRSDKAPIEvent.as │ │ │ │ │ └── AIRSDKBuild.as │ │ │ │ ├── repository │ │ │ │ │ ├── Repository.as │ │ │ │ │ └── RepositoryQueryOptions.as │ │ │ │ ├── lib │ │ │ │ │ ├── events │ │ │ │ │ │ └── APIRequestEvent.as │ │ │ │ │ └── APIRequestQueue.as │ │ │ │ └── github │ │ │ │ │ └── GitHubAPI.as │ │ │ ├── utils │ │ │ │ ├── Checksum.as │ │ │ │ ├── WindowsShellPaths.as │ │ │ │ ├── JSONUtils.as │ │ │ │ └── DeployFileUtils.as │ │ │ └── SemVerRange.as │ │ └── apple │ │ │ └── plist │ │ │ ├── entries │ │ │ ├── PlistBooleanEntry.as │ │ │ ├── PlistStringEntry.as │ │ │ ├── PlistCommentEntry.as │ │ │ ├── PlistArrayEntry.as │ │ │ └── PlistDictEntry.as │ │ │ └── Plist.as │ ├── apm.xml │ ├── apm.bat │ ├── org │ │ └── as3commons │ │ │ ├── lang │ │ │ ├── INamed.as │ │ │ ├── IApplicationDomainAware.as │ │ │ ├── IEquals.as │ │ │ ├── ClassNotFoundError.as │ │ │ ├── ICloneable.as │ │ │ ├── IllegalArgumentError.as │ │ │ ├── IllegalStateError.as │ │ │ ├── IComparable.as │ │ │ ├── IIterator.as │ │ │ ├── StringBuffer.as │ │ │ ├── IDisposable.as │ │ │ ├── builder │ │ │ │ ├── ToStringBuilder.as │ │ │ │ └── ToStringStyle.as │ │ │ ├── util │ │ │ │ └── CloneUtils.as │ │ │ ├── DictionaryUtils.as │ │ │ └── SoftReference.as │ │ │ └── zip │ │ │ ├── IZipLibrary.as │ │ │ ├── IZipFile.as │ │ │ ├── IZip.as │ │ │ ├── ZipErrorEvent.as │ │ │ ├── ZipEvent.as │ │ │ └── utils │ │ │ └── ChecksumUtil.as │ ├── apm │ ├── airsdk │ │ ├── lib │ │ │ └── ADTConfig.as │ │ └── AIRSDKVersion.as │ └── APMConsoleApp.as ├── README.md └── apm.iml ├── version.config ├── .gitignore ├── LICENSE ├── README.md └── BUILDING.md /images/hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airsdk/apm/HEAD/images/hero.png -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [marchbold] 4 | -------------------------------------------------------------------------------- /client/libs/blooddy_crypto.swc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/airsdk/apm/HEAD/client/libs/blooddy_crypto.swc -------------------------------------------------------------------------------- /version.config: -------------------------------------------------------------------------------- 1 | #Tue, 11 Mar 2025 13:47:09 +1000 2 | 3 | version_major=2 4 | version_minor=2 5 | version_build=0 6 | version_preview= 7 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/project/processes/data/EntitlementsDefault.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /client/README.md: -------------------------------------------------------------------------------- 1 | 2 | # AIR Package Manager (`apm`) Client 3 | 4 | This is the source code for the APMConsoleApp client application. 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .metadata 2 | out 3 | .idea/libraries 4 | .idea/workspace.xml 5 | .idea/usage.statistics.xml 6 | .idea/tasks.xml 7 | .idea/shelf 8 | *.zip 9 | build.config -------------------------------------------------------------------------------- /client/src/com/apm/client/Consts.as: -------------------------------------------------------------------------------- 1 | package com.apm.client 2 | { 3 | public final class Consts 4 | { 5 | public static const VERSION : String = CONFIG::VERSION; 6 | } 7 | } -------------------------------------------------------------------------------- /client/src/apm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | airsdk.apm 4 | apm 5 | apm 6 | 0.0.1 7 | 8 | apm.swf 9 | false 10 | 11 | 12 | -------------------------------------------------------------------------------- /client/src/com/apm/client/io/utils/ListOutput.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 3/11/2025 4 | */ 5 | package com.apm.client.io.utils 6 | { 7 | public class ListOutput 8 | { 9 | 10 | 11 | public static function marker( isLast:Boolean = true ):String 12 | { 13 | return (isLast ? "└── " : "├── "); 14 | } 15 | 16 | 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /client/src/apm.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | chcp 65001>nul 3 | ::set WORKING_DIR=%cd% 4 | ::set SCRIPT_DIR=%~dp0 5 | ::set AIRDIR=%AIR_HOME% 6 | 7 | for /f "tokens=*" %%a in ('where adl.exe') do set ADL_DIR=%%a 8 | for %%a in (%ADL_DIR%) do set AIR_BIN_DIR=%%~dpa 9 | for %%a in (%AIR_BIN_DIR:~0,-1%) do set AIR_DIR=%%~dpa 10 | 11 | adl -profile extendedDesktop -nodebug -multi-instance -cmd "%~dp0\apm.xml" -- -workingdir "%cd%" -airdir "%AIR_DIR% " -uname "windows" %* 12 | 13 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/project/processes/data/InfoAdditionsDefault.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | UIDeviceFamily 5 | 6 | 1 7 | 2 8 | 9 | 10 | MinimumOSVersion 11 | 12.0 12 | 13 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /client/src/com/apm/data/project/ProjectApplicationProperties.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 20/2/2023 4 | */ 5 | package com.apm.data.project 6 | { 7 | public interface ProjectApplicationProperties 8 | { 9 | function get applicationId():String; 10 | function get applicationName():Object; 11 | function get applicationFilename():String; 12 | function get version():String; 13 | function get versionLabel():String; 14 | 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/project/processes/data/AndroidManifestDefault.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/project/processes/AndroidManifestMerge.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 31/8/2021 4 | */ 5 | package com.apm.client.commands.project.processes 6 | { 7 | 8 | public class AndroidManifestMerge 9 | { 10 | public static const MERGE_TOOL_VERSION:String = "31.9.0"; 11 | 12 | private static const MERGE_TOOL_FILENAME:String = "manifest-merger-@MERGE_TOOL_VERSION@.jar"; 13 | 14 | 15 | public static function get mergeToolFilename():String 16 | { 17 | return MERGE_TOOL_FILENAME 18 | .replace( /@MERGE_TOOL_VERSION@/g, MERGE_TOOL_VERSION ); 19 | } 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/INamed.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2011 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.lang { 17 | 18 | public interface INamed { 19 | function get name():String; 20 | function set name(value:String):void; 21 | } 22 | } -------------------------------------------------------------------------------- /.github/workflows/issues.yml: -------------------------------------------------------------------------------- 1 | name: 'Close stale issues and PR' 2 | on: 3 | schedule: 4 | - cron: '30 1 * * 2' 5 | 6 | jobs: 7 | stale: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/stale@v4 11 | with: 12 | stale-issue-label: 'stale' 13 | exempt-issue-labels: 'enhancement,bug,bug-air-sdk' 14 | stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days.' 15 | stale-pr-message: 'This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days.' 16 | close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.' 17 | days-before-stale: 60 18 | days-before-close: 5 19 | days-before-pr-close: -1 -------------------------------------------------------------------------------- /client/src/com/apm/client/processes/Process.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 28/5/2021 4 | */ 5 | package com.apm.client.processes 6 | { 7 | import flash.events.IEventDispatcher; 8 | 9 | 10 | public interface Process extends IEventDispatcher 11 | { 12 | //////////////////////////////////////////////////////// 13 | // FUNCTIONALITY 14 | // 15 | 16 | /** 17 | * Will set the current queue before start so the process can add additional processes if required. 18 | * 19 | * @param value 20 | */ 21 | function set processQueue( value:ProcessQueue ):void; 22 | 23 | 24 | /** 25 | * Will be called when the process should start running. 26 | * The process must dispatch a ProcessEvent.COMPLETE function when complete. 27 | */ 28 | function start( complete:Function=null, failure:Function=null ):void; 29 | 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /client/src/com/apm/client/processes/ProcessCallback.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 22/6/2021 4 | */ 5 | package com.apm.client.processes 6 | { 7 | 8 | public class ProcessCallback extends ProcessBase 9 | { 10 | //////////////////////////////////////////////////////// 11 | // CONSTANTS 12 | // 13 | 14 | private static const TAG:String = "ProcessCallback"; 15 | 16 | 17 | //////////////////////////////////////////////////////// 18 | // VARIABLES 19 | // 20 | 21 | private var _callback:Function; 22 | 23 | 24 | //////////////////////////////////////////////////////// 25 | // FUNCTIONALITY 26 | // 27 | 28 | public function ProcessCallback( callback:Function ) 29 | { 30 | super(); 31 | _callback = callback; 32 | } 33 | 34 | 35 | override public function start( completeCallback:Function=null, failureCallback:Function=null ):void 36 | { 37 | if (_callback != null) _callback(); 38 | complete(); 39 | } 40 | 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /client/src/com/apm/remote/airsdk/events/AIRSDKAPIEvent.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 7/6/2021 4 | */ 5 | package com.apm.remote.airsdk.events 6 | { 7 | import flash.events.Event; 8 | 9 | 10 | public class AIRSDKAPIEvent extends Event 11 | { 12 | //////////////////////////////////////////////////////// 13 | // CONSTANTS 14 | // 15 | 16 | private static const TAG:String = "AIRSDKAPIEvent"; 17 | 18 | 19 | //////////////////////////////////////////////////////// 20 | // VARIABLES 21 | // 22 | 23 | 24 | //////////////////////////////////////////////////////// 25 | // FUNCTIONALITY 26 | // 27 | 28 | 29 | public function AIRSDKAPIEvent( type:String, bubbles:Boolean = false, cancelable:Boolean = false ) 30 | { 31 | super( type, bubbles, cancelable ); 32 | } 33 | 34 | 35 | override public function clone():Event 36 | { 37 | return new AIRSDKAPIEvent( type, bubbles, cancelable ); 38 | } 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /client/src/com/apm/client/events/APMEvent.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 28/5/2021 4 | */ 5 | package com.apm.client.events 6 | { 7 | import flash.events.DataEvent; 8 | import flash.events.Event; 9 | 10 | 11 | public class APMEvent extends DataEvent 12 | { 13 | 14 | //////////////////////////////////////////////////////// 15 | // CONSTANTS 16 | // 17 | 18 | private static const TAG:String = "APMEvent"; 19 | 20 | 21 | //////////////////////////////////////////////////////// 22 | // VARIABLES 23 | // 24 | 25 | 26 | 27 | 28 | //////////////////////////////////////////////////////// 29 | // FUNCTIONALITY 30 | // 31 | 32 | 33 | public function APMEvent( type:String, bubbles:Boolean=false, cancelable:Boolean=false, data:String = "" ) 34 | { 35 | super( type, bubbles, cancelable, data ); 36 | } 37 | 38 | 39 | override public function clone():Event 40 | { 41 | return new APMEvent( type, bubbles, cancelable, data ); 42 | } 43 | 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /client/src/apm: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 3 | ADL=adl 4 | unameOut="$(uname -s)" 5 | case "${unameOut}" in 6 | Linux*) UNAME=linux;; 7 | Darwin*) UNAME=mac;; 8 | CYGWIN*) 9 | UNAME=cygwin 10 | AIR_HOME="$( echo "/${AIR_HOME}" | sed -e 's/\\/\//g' -e 's/://' -e 's/\/\//\//g' )" 11 | ;; 12 | MINGW*) 13 | UNAME=mingw 14 | AIR_HOME="$( echo "/${AIR_HOME}" | sed -e 's/\\/\//g' -e 's/://' -e 's/\/\//\//g' )" 15 | ADL=adl.exe 16 | ;; 17 | *) 18 | UNAME="UNKNOWN:${unameOut}" 19 | ;; 20 | esac 21 | 22 | # if AIR_HOME environment variable is set, look for "adl" in AIR_HOME/bin directory 23 | if [ -z "${ADL_DIR}" ] && [ ! -z "${AIR_HOME}" ]; then 24 | ADL_DIR="${AIR_HOME}/bin/" 25 | fi 26 | 27 | AIR_DIR="$(dirname "$(dirname "$(which "${ADL_DIR}/${ADL}")")")" 28 | 29 | "${ADL_DIR}"${ADL} -profile extendedDesktop -nodebug -multi-instance -cmd "${SCRIPT_DIR}/apm.xml" -- \ 30 | -workingdir "$( pwd )" \ 31 | -appdir "${SCRIPT_DIR}" \ 32 | -airdir "${AIR_DIR}" \ 33 | -uname "${UNAME}" \ 34 | "$@" 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 distriqt // airnativeextensions 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/IApplicationDomainAware.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2011 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.lang { 17 | 18 | import flash.system.ApplicationDomain; 19 | 20 | /** 21 | * Describes an object that needs a reference to an ApplicationDomain. 22 | * @author Roland Zwaga 23 | */ 24 | public interface IApplicationDomainAware { 25 | /** 26 | * @param value The specified ApplicationDomain instance. 27 | */ 28 | function set applicationDomain(value:ApplicationDomain):void; 29 | } 30 | } -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/IEquals.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.lang { 17 | 18 | /** 19 | * This interface should be implemented by all objects that wish to offer an "equals" method. 20 | * 21 | * @author Christophe Herreman 22 | */ 23 | public interface IEquals { 24 | 25 | /** 26 | * Indicates whether some other object is equal to this one. 27 | * 28 | * @param other the object to compare to this object for equality 29 | */ 30 | function equals(other:Object):Boolean; 31 | 32 | } 33 | } -------------------------------------------------------------------------------- /client/src/airsdk/lib/ADTConfig.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 5/10/2021 4 | */ 5 | package airsdk.lib 6 | { 7 | import com.apm.utils.FileUtils; 8 | 9 | import flash.filesystem.File; 10 | 11 | import org.as3commons.file.PropertiesFile; 12 | 13 | 14 | public class ADTConfig extends PropertiesFile 15 | { 16 | //////////////////////////////////////////////////////// 17 | // CONSTANTS 18 | // 19 | 20 | private static const TAG:String = "ADTConfig"; 21 | 22 | 23 | //////////////////////////////////////////////////////// 24 | // VARIABLES 25 | // 26 | 27 | 28 | //////////////////////////////////////////////////////// 29 | // FUNCTIONALITY 30 | // 31 | 32 | public function ADTConfig() 33 | { 34 | super(); 35 | } 36 | 37 | 38 | public static function load( file:File ):ADTConfig 39 | { 40 | var config:ADTConfig = null; 41 | if (file != null && file.exists) 42 | { 43 | var content:String = FileUtils.readFileContentAsString( file ); 44 | 45 | config = new ADTConfig(); 46 | config.parse( content ); 47 | } 48 | return config; 49 | } 50 | 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/ClassNotFoundError.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.lang { 17 | 18 | /** 19 | * Thrown when an application tries to retrieve a class by its name and 20 | * the corresponding class could not be found. 21 | * 22 | * @author Christophe Herreman 23 | */ 24 | public class ClassNotFoundError extends Error { 25 | 26 | /** 27 | * Creates a new ClassNotFoundError object. 28 | */ 29 | public function ClassNotFoundError( message:String = "") { 30 | super(message); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/ICloneable.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.lang { 17 | 18 | /** 19 | * Interface to be implemented by all classes that want to provide cloning functionality. 20 | * 21 | * @author Christophe Herreman 22 | */ 23 | public interface ICloneable { 24 | 25 | /** 26 | * Clones this object. Implementations should decide on a per class basis wether a deep or a shallow clone 27 | * will be done. 28 | * 29 | * @return a new object which is a clone of this object 30 | */ 31 | function clone():*; 32 | 33 | } 34 | } -------------------------------------------------------------------------------- /client/src/com/apm/client/config/processes/DebugDelayProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 4/6/2021 4 | */ 5 | package com.apm.client.config.processes 6 | { 7 | import com.apm.client.processes.ProcessBase; 8 | import com.apm.client.processes.events.ProcessEvent; 9 | 10 | import flash.utils.setTimeout; 11 | 12 | 13 | public class DebugDelayProcess extends ProcessBase 14 | { 15 | //////////////////////////////////////////////////////// 16 | // CONSTANTS 17 | // 18 | 19 | private static const TAG:String = "DebugDelayProcess"; 20 | 21 | 22 | //////////////////////////////////////////////////////// 23 | // VARIABLES 24 | // 25 | 26 | private var _delay:int; 27 | 28 | 29 | //////////////////////////////////////////////////////// 30 | // FUNCTIONALITY 31 | // 32 | 33 | public function DebugDelayProcess( delay:int = 2000 ) 34 | { 35 | _delay = delay; 36 | } 37 | 38 | 39 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 40 | { 41 | super.start( completeCallback, failureCallback ); 42 | setTimeout( complete, _delay ); 43 | } 44 | 45 | 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/IllegalArgumentError.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.lang { 17 | 18 | /** 19 | * Thrown to indicate that a method has been passed an illegal or 20 | * inappropriate argument. 21 | * 22 | * @author Christophe Herreman 23 | */ 24 | public class IllegalArgumentError extends Error { 25 | 26 | /** 27 | * Constructs a new IllegalArgumentError. 28 | * 29 | * @param message the detail message that describes the cause of the error 30 | */ 31 | public function IllegalArgumentError( message:String = "") { 32 | super(message); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/Command.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 18/5/2021 4 | */ 5 | package com.apm.client.commands 6 | { 7 | import com.apm.client.*; 8 | 9 | import flash.events.IEventDispatcher; 10 | 11 | 12 | public interface Command extends IEventDispatcher 13 | { 14 | //////////////////////////////////////////////////////// 15 | // FUNCTIONALITY 16 | // 17 | 18 | /** 19 | * Starts the command execution with the current core configuration 20 | */ 21 | function execute():void; 22 | 23 | 24 | /** 25 | * Sets the command line parameters passed for this command 26 | * 27 | * @param parameters 28 | */ 29 | function setParameters( parameters:Array ):void; 30 | 31 | 32 | function get name():String; 33 | 34 | function get category():String; 35 | 36 | function get description():String; 37 | 38 | function get usage():String; 39 | 40 | 41 | /** 42 | * Whether this command access the network, eg package repository api or the air sdk api 43 | */ 44 | function get requiresNetwork():Boolean; 45 | 46 | 47 | /** 48 | * Whether this command needs a project file 49 | */ 50 | function get requiresProject():Boolean; 51 | 52 | 53 | 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](images/hero.png) 2 | 3 | # AIR Package Manager (`apm`) 4 | 5 | The AIR Package Manager allows management of AIR libraries and extensions and assists in creation of the application descriptor. 6 | 7 | It is comprised of a repository server and a command line client. This repository forms the source of the command line client. 8 | 9 | The goals of `apm` are to: 10 | 11 | - be command line tool for macOS and Windows; 12 | - read from a repository of packages (ANEs and SWCs); 13 | - install (download) packages and dependencies; 14 | - update packages and dependencies; 15 | - assist in the creation of the application descriptor (particularly on iOS / Android to merge android manifest additions and iOS info additions / entitlements ); 16 | - assist in the management of properties and settings for an AIR application; 17 | - assist in the building of an AIR application; 18 | 19 | This project runs in combination with the [APM repository](https://github.com/airsdk/apm-repository) which aims to provide a repository server to be the store for packages. 20 | 21 | See the [wiki](https://github.com/airsdk/apm/wiki) for details. 22 | 23 | ## Get involved 24 | 25 | Have a look at the [contributing guidelines](https://github.com/airsdk/apm/blob/master/.github/CONTRIBUTING.md) to see how you can contribute to apm. 26 | -------------------------------------------------------------------------------- /client/src/com/apm/client/events/CommandEvent.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 28/5/2021 4 | */ 5 | package com.apm.client.events 6 | { 7 | import flash.events.Event; 8 | 9 | 10 | public class CommandEvent extends Event 11 | { 12 | //////////////////////////////////////////////////////// 13 | // CONSTANTS 14 | // 15 | 16 | private static const TAG:String = "CommandEvent"; 17 | 18 | 19 | /** 20 | * @eventType complete 21 | */ 22 | public static const COMPLETE : String = "complete"; 23 | 24 | 25 | /** 26 | * @eventType usage 27 | */ 28 | public static const PRINT_USAGE : String = "usage"; 29 | 30 | 31 | //////////////////////////////////////////////////////// 32 | // VARIABLES 33 | // 34 | 35 | 36 | public var data:* = null; 37 | 38 | 39 | //////////////////////////////////////////////////////// 40 | // FUNCTIONALITY 41 | // 42 | 43 | public function CommandEvent( type:String, data:*=null, bubbles:Boolean=false, cancelable:Boolean=false ) 44 | { 45 | super( type, bubbles, cancelable ); 46 | this.data = data; 47 | } 48 | 49 | 50 | override public function clone():Event 51 | { 52 | return new CommandEvent( type, data, bubbles, cancelable ); 53 | } 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /client/src/com/apm/client/processes/events/ProcessEvent.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 31/5/2021 4 | */ 5 | package com.apm.client.processes.events 6 | { 7 | import flash.events.DataEvent; 8 | import flash.events.Event; 9 | 10 | 11 | public class ProcessEvent extends DataEvent 12 | { 13 | //////////////////////////////////////////////////////// 14 | // CONSTANTS 15 | // 16 | 17 | private static const TAG:String = "ProcessEvent"; 18 | 19 | 20 | /** 21 | * 22 | * @eventType process_complete 23 | */ 24 | public static const COMPLETE : String = "process_complete"; 25 | 26 | 27 | /** 28 | * @eventType process_failed 29 | */ 30 | public static const FAILED : String = "process_failed"; 31 | 32 | 33 | 34 | //////////////////////////////////////////////////////// 35 | // VARIABLES 36 | // 37 | 38 | 39 | //////////////////////////////////////////////////////// 40 | // FUNCTIONALITY 41 | // 42 | 43 | 44 | public function ProcessEvent( type:String, data:String="", bubbles:Boolean = false, cancelable:Boolean = false ) 45 | { 46 | super( type, bubbles, cancelable, data ); 47 | } 48 | 49 | 50 | override public function clone():Event 51 | { 52 | return super.clone(); 53 | } 54 | 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /client/src/com/apm/remote/airsdk/AIRSDKBuild.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 7/6/2021 4 | */ 5 | package com.apm.remote.airsdk 6 | { 7 | import com.adobe.utils.DateUtil; 8 | 9 | 10 | /** 11 | * Data class representing a version of the AIR SDK retrieved from the API 12 | */ 13 | public class AIRSDKBuild 14 | { 15 | //////////////////////////////////////////////////////// 16 | // CONSTANTS 17 | // 18 | 19 | private static const TAG:String = "AIRSDKBuild"; 20 | 21 | 22 | //////////////////////////////////////////////////////// 23 | // VARIABLES 24 | // 25 | 26 | public var version:String; 27 | 28 | public var releaseDate:Date; 29 | 30 | public var urls:Object = {}; 31 | 32 | public var releaseNotes:Array = []; 33 | 34 | 35 | //////////////////////////////////////////////////////// 36 | // FUNCTIONALITY 37 | // 38 | 39 | public function AIRSDKBuild() 40 | { 41 | } 42 | 43 | 44 | public static function fromObject( data:Object ):AIRSDKBuild 45 | { 46 | var b:AIRSDKBuild = new AIRSDKBuild(); 47 | if (data.hasOwnProperty("name")) b.version = data["name"]; 48 | if (data.hasOwnProperty("released_date")) b.releaseDate = DateUtil.parseW3CDTF( data["released_date"] ); 49 | return b; 50 | } 51 | 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/IllegalStateError.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.lang { 17 | 18 | /** 19 | * Signals that a method has been invoked at an illegal or inappropriate time. In other words, the environment 20 | * or application is not in an appropriate state for the requested operation. 21 | * 22 | * @author Christophe Herreman 23 | */ 24 | public class IllegalStateError extends Error { 25 | 26 | /** 27 | * Constructs a new IllegalStateError. 28 | * 29 | * @param message the detail message that describes the cause of the error 30 | */ 31 | public function IllegalStateError( message:String = "") { 32 | super(message); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /client/src/org/as3commons/zip/IZipLibrary.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2012 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.zip { 17 | import flash.display.BitmapData; 18 | import flash.display.DisplayObject; 19 | import flash.events.IEventDispatcher; 20 | 21 | /** 22 | * 23 | * @author Roland Zwaga 24 | */ 25 | public interface IZipLibrary extends IEventDispatcher { 26 | function addZip(zip:IZip):void; 27 | function formatAsBitmapData(ext:String):void; 28 | function formatAsDisplayObject(ext:String):void; 29 | function getBitmapData(filename:String):BitmapData; 30 | function getDefinition(filename:String, definition:String):Object; 31 | function getDisplayObject(filename:String):DisplayObject; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /client/src/com/apm/remote/repository/Repository.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 15/9/2021 4 | */ 5 | package com.apm.remote.repository 6 | { 7 | import com.apm.SemVerRange; 8 | import com.apm.data.packages.PackageDefinitionFile; 9 | 10 | import flash.events.IEventDispatcher; 11 | 12 | public interface Repository extends IEventDispatcher 13 | { 14 | //////////////////////////////////////////////////////// 15 | // FUNCTIONALITY 16 | // 17 | 18 | function get name():String; 19 | 20 | 21 | function setName( name:String ):Repository; 22 | 23 | 24 | function checkConnection( callback:Function = null ):void; 25 | 26 | 27 | function search( query:String, options:RepositoryQueryOptions = null, callback:Function = null ):void; 28 | 29 | 30 | function getPackage( identifier:String, options:RepositoryQueryOptions = null, callback:Function = null ):void; 31 | 32 | 33 | function getPackageVersion( identifier:String, version:SemVerRange, options:RepositoryQueryOptions = null, callback:Function = null ):void; 34 | 35 | 36 | function logEvent( event:String, identifier:String, version:String, callback:Function = null ):void; 37 | 38 | 39 | function setToken( token:String ):Repository; 40 | 41 | 42 | function publish( packageDef:PackageDefinitionFile, callback:Function = null ):void; 43 | 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /client/src/com/apm/client/repositories/PackageResolverResult.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 15/9/2021 4 | */ 5 | package com.apm.client.repositories 6 | { 7 | import com.apm.SemVer; 8 | import com.apm.SemVerRange; 9 | import com.apm.client.APM; 10 | import com.apm.client.logging.Log; 11 | import com.apm.client.processes.ProcessQueue; 12 | import com.apm.client.repositories.processes.RepositoryGetPackageVersionProcess; 13 | import com.apm.data.packages.PackageDefinition; 14 | import com.apm.data.packages.RepositoryDefinition; 15 | import com.apm.remote.repository.RepositoryAPI; 16 | import com.apm.remote.repository.RepositoryQueryOptions; 17 | 18 | 19 | /** 20 | * This stores the result of a package resolution search 21 | */ 22 | public class PackageResolverResult 23 | { 24 | //////////////////////////////////////////////////////// 25 | // CONSTANTS 26 | // 27 | 28 | private static const TAG:String = "PackageResolver"; 29 | 30 | 31 | //////////////////////////////////////////////////////// 32 | // VARIABLES 33 | // 34 | 35 | 36 | public var resolvedPackage:PackageDefinition; 37 | 38 | 39 | 40 | //////////////////////////////////////////////////////// 41 | // FUNCTIONALITY 42 | // 43 | 44 | public function PackageResolverResult() 45 | { 46 | } 47 | 48 | 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /client/src/com/apple/plist/entries/PlistBooleanEntry.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 10/9/2021 4 | */ 5 | package com.apple.plist.entries 6 | { 7 | /** 8 | * 9 | */ 10 | public class PlistBooleanEntry extends PlistEntry 11 | { 12 | //////////////////////////////////////////////////////// 13 | // CONSTANTS 14 | // 15 | 16 | private static const TAG:String = "PlistStringEntry"; 17 | 18 | 19 | //////////////////////////////////////////////////////// 20 | // VARIABLES 21 | // 22 | 23 | private var _value:Boolean; 24 | 25 | 26 | //////////////////////////////////////////////////////// 27 | // FUNCTIONALITY 28 | // 29 | 30 | public function PlistBooleanEntry( key:String ) 31 | { 32 | super( key, "bool" ); 33 | } 34 | 35 | 36 | public function get value():Boolean 37 | { 38 | return _value; 39 | } 40 | 41 | 42 | public function set value( value:Boolean ):void 43 | { 44 | _value = value; 45 | } 46 | 47 | 48 | override public function equals( entry:PlistEntry ):Boolean 49 | { 50 | if (super.equals( entry )) 51 | { 52 | return (value == (entry as PlistBooleanEntry).value); 53 | } 54 | return false; 55 | } 56 | 57 | 58 | override public function valueXML():XML 59 | { 60 | return <{value ? "true" : "false"}/>; 61 | } 62 | 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /client/src/com/apm/remote/lib/events/APIRequestEvent.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 7/12/16 4 | */ 5 | package com.apm.remote.lib.events 6 | { 7 | import com.apm.remote.lib.APIRequest; 8 | 9 | import flash.events.Event; 10 | 11 | public class APIRequestEvent extends Event 12 | { 13 | //////////////////////////////////////////////////////// 14 | // CONSTANTS 15 | // 16 | 17 | public static const TAG : String = "APIRequestEvent"; 18 | 19 | public static const COMPLETE : String = "complete"; 20 | public static const STATUS : String = "status"; 21 | public static const ERROR : String = "error"; 22 | 23 | 24 | //////////////////////////////////////////////////////// 25 | // VARIABLES 26 | // 27 | 28 | 29 | public var request : APIRequest; 30 | 31 | public var data: *; 32 | 33 | 34 | //////////////////////////////////////////////////////// 35 | // FUNCTIONALITY 36 | // 37 | 38 | public function APIRequestEvent( type:String, request:APIRequest, data:*=null, bubbles:Boolean=false, cancelable:Boolean =false ) 39 | { 40 | super( type, bubbles, cancelable ); 41 | this.request = request; 42 | this.data = data; 43 | } 44 | 45 | 46 | override public function clone():Event 47 | { 48 | return new APIRequestEvent( type, request, data, bubbles, cancelable ); 49 | } 50 | 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/IComparable.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.lang { 17 | 18 | /** 19 | * Interface to be implemented by objects that need to be compared with others for ordering. 20 | * 21 | * @author Christophe Herreman 22 | */ 23 | public interface IComparable { 24 | 25 | /** 26 | * Compares this object with the specified object for order. Returns a negative integer, zero, or a positive 27 | * integer as this object is less than, equal to, or greater than the specified object. 28 | * 29 | * @param other the object to be compared 30 | * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. 31 | */ 32 | function compareTo(other:Object):int; 33 | 34 | } 35 | } -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/IIterator.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.lang { 17 | 18 | /** 19 | * Defines an interface for iterating over the values of an object. 20 | * 21 | * @author Andrew Lewisohn 22 | */ 23 | public interface IIterator { 24 | 25 | //-------------------------------------------------------------------------- 26 | // 27 | // Methods 28 | // 29 | //-------------------------------------------------------------------------- 30 | 31 | /** 32 | * Move the iterator to the first item. 33 | */ 34 | function first():void; 35 | 36 | /** 37 | * Move the iterator to the last item. 38 | */ 39 | function last():void; 40 | 41 | /** 42 | * Returns the value of the next key, or false if there are no more keys. 43 | */ 44 | function next():Object; 45 | } 46 | } -------------------------------------------------------------------------------- /client/src/com/apple/plist/entries/PlistStringEntry.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 10/9/2021 4 | */ 5 | package com.apple.plist.entries 6 | { 7 | /** 8 | * 9 | */ 10 | public class PlistStringEntry extends PlistEntry 11 | { 12 | //////////////////////////////////////////////////////// 13 | // CONSTANTS 14 | // 15 | 16 | private static const TAG:String = "PlistStringEntry"; 17 | 18 | 19 | //////////////////////////////////////////////////////// 20 | // VARIABLES 21 | // 22 | 23 | private var _value:String = ""; 24 | 25 | 26 | //////////////////////////////////////////////////////// 27 | // FUNCTIONALITY 28 | // 29 | 30 | public function PlistStringEntry( key:String ) 31 | { 32 | super( key, "string" ); 33 | } 34 | 35 | 36 | public function get value():String 37 | { 38 | return _value; 39 | } 40 | 41 | 42 | public function set value( value:String ):void 43 | { 44 | _value = value; 45 | } 46 | 47 | 48 | override public function equals( entry:PlistEntry ):Boolean 49 | { 50 | if (super.equals( entry )) 51 | { 52 | return (value.toLowerCase() == (entry as PlistStringEntry).value.toLowerCase()); 53 | } 54 | return false; 55 | } 56 | 57 | 58 | override public function valueXML():XML 59 | { 60 | return <{type}>{_value}; 61 | } 62 | 63 | 64 | } 65 | 66 | 67 | } 68 | -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/StringBuffer.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.lang { 17 | 18 | /** 19 | * @author Christophe Herreman 20 | */ 21 | public final class StringBuffer { 22 | 23 | private var _string:Array; 24 | 25 | /** 26 | * Creates a new StringBuffer. 27 | */ 28 | public function StringBuffer( string:String = "") { 29 | _string = (string ? [string] : []); 30 | } 31 | 32 | public function append(value:Object):StringBuffer { 33 | _string[_string.length] = value; 34 | return this; 35 | } 36 | 37 | public function removeEnd(value:Object):StringBuffer { 38 | _string = [StringUtils.removeEnd(toString(), value.toString())]; 39 | return this; 40 | } 41 | 42 | public function toString():String { 43 | return _string.join(''); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /client/src/com/apm/client/io/IOColour.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 22/10/2021 4 | */ 5 | package com.apm.client.io 6 | { 7 | 8 | public class IOColour 9 | { 10 | //////////////////////////////////////////////////////// 11 | // CONSTANTS 12 | // 13 | 14 | private static const TAG:String = "IOColour"; 15 | 16 | public static const NONE:String = "0"; 17 | 18 | public static const BLACK:String = "0;30"; 19 | public static const RED:String = "0;31"; 20 | public static const GREEN:String = "0;32"; 21 | public static const BROWN:String = "0;33"; 22 | public static const BLUE:String = "0;34"; 23 | public static const PURPLE:String = "0;35"; 24 | public static const CYAN:String = "0;36"; 25 | public static const LIGHT_GRAY:String = "0;37"; 26 | public static const DARK_GRAY:String = "1;30"; 27 | public static const LIGHT_RED:String = "1;31"; 28 | public static const LIGHT_GREEN:String = "1;32"; 29 | public static const YELLOW:String = "1;33"; 30 | public static const LIGHT_BLUE:String = "1;34"; 31 | public static const LIGHT_PURPLE:String = "1;35"; 32 | public static const LIGHT_CYAN:String = "1;36"; 33 | public static const WHITE:String = "1;37"; 34 | 35 | 36 | //////////////////////////////////////////////////////// 37 | // VARIABLES 38 | // 39 | 40 | 41 | //////////////////////////////////////////////////////// 42 | // FUNCTIONALITY 43 | // 44 | 45 | public function IOColour() 46 | { 47 | } 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /client/src/com/apm/data/packages/PackageLicense.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 30/7/2021 4 | */ 5 | package com.apm.data.packages 6 | { 7 | 8 | public class PackageLicense 9 | { 10 | //////////////////////////////////////////////////////// 11 | // CONSTANTS 12 | // 13 | 14 | private static const TAG:String = "PackageLicense"; 15 | 16 | 17 | //////////////////////////////////////////////////////// 18 | // VARIABLES 19 | // 20 | 21 | public var type:String = "none"; 22 | public var url:String = ""; 23 | public var isPublic:Boolean = false; 24 | 25 | 26 | //////////////////////////////////////////////////////// 27 | // FUNCTIONALITY 28 | // 29 | 30 | public function PackageLicense() 31 | { 32 | } 33 | 34 | 35 | public function toDescriptiveString():String 36 | { 37 | return "[" + (isPublic ? "public" : "private") + "] " + type + " :: " + url; 38 | } 39 | 40 | 41 | public function toObject():Object 42 | { 43 | return { 44 | type: type, 45 | url: url, 46 | "public": isPublic 47 | }; 48 | } 49 | 50 | 51 | public function fromObject( data:Object ):PackageLicense 52 | { 53 | if (data != null) 54 | { 55 | if (data.hasOwnProperty( "type" )) this.type = data[ "type" ]; 56 | if (data.hasOwnProperty( "url" )) this.url = data[ "url" ]; 57 | if (data.hasOwnProperty( "public" )) this.isPublic = data[ "public" ]; 58 | } 59 | return this; 60 | } 61 | 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /client/src/APMConsoleApp.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 18/5/2021 4 | */ 5 | package 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.events.APMEvent; 9 | 10 | import flash.desktop.NativeApplication; 11 | import flash.desktop.SystemIdleMode; 12 | import flash.display.Sprite; 13 | import flash.events.InvokeEvent; 14 | import flash.system.System; 15 | import flash.utils.setInterval; 16 | 17 | 18 | public class APMConsoleApp extends Sprite 19 | { 20 | //////////////////////////////////////////////////////// 21 | // CONSTANTS 22 | // 23 | 24 | private static const TAG:String = "APMConsoleApp"; 25 | 26 | 27 | //////////////////////////////////////////////////////// 28 | // VARIABLES 29 | // 30 | 31 | 32 | protected var apmContext:APM; 33 | 34 | //////////////////////////////////////////////////////// 35 | // FUNCTIONALITY 36 | // 37 | 38 | 39 | public function APMConsoleApp() 40 | { 41 | apmContext = new APM(); 42 | 43 | NativeApplication.nativeApplication.executeInBackground = true; 44 | NativeApplication.nativeApplication.systemIdleMode = SystemIdleMode.KEEP_AWAKE; 45 | NativeApplication.nativeApplication.idleThreshold = 86400; 46 | 47 | NativeApplication.nativeApplication.addEventListener( InvokeEvent.INVOKE, invokeHandler ); 48 | } 49 | 50 | 51 | private function invokeHandler( event:InvokeEvent ):void 52 | { 53 | apmContext.main( event.arguments ); 54 | } 55 | 56 | 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /client/src/com/apple/plist/entries/PlistCommentEntry.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 10/9/2021 4 | */ 5 | package com.apple.plist.entries 6 | { 7 | import mx.utils.UIDUtil; 8 | 9 | /** 10 | * 11 | */ 12 | public class PlistCommentEntry extends PlistEntry 13 | { 14 | //////////////////////////////////////////////////////// 15 | // CONSTANTS 16 | // 17 | 18 | private static const TAG:String = "PlistDictEntry"; 19 | 20 | 21 | //////////////////////////////////////////////////////// 22 | // VARIABLES 23 | // 24 | 25 | private var _value:String; 26 | 27 | //////////////////////////////////////////////////////// 28 | // FUNCTIONALITY 29 | // 30 | 31 | public function PlistCommentEntry() 32 | { 33 | super( generateUniqueIdentifier(), "comment" ); 34 | } 35 | 36 | 37 | private function generateUniqueIdentifier():String 38 | { 39 | return "comment-" + UIDUtil.createUID(); 40 | } 41 | 42 | 43 | public function get value():String 44 | { 45 | return _value; 46 | } 47 | 48 | 49 | public function set value( value:String ):void 50 | { 51 | _value = value; 52 | } 53 | 54 | 55 | override public function keyXML():XML 56 | { 57 | return new XML(); 58 | } 59 | 60 | 61 | override public function valueXML():XML 62 | { 63 | return new XML( value ); 64 | } 65 | 66 | 67 | override public function equals( entry:PlistEntry ):Boolean 68 | { 69 | if (super.equals( entry )) 70 | { 71 | return (value == (entry as PlistCommentEntry).value); 72 | } 73 | return false; 74 | } 75 | 76 | 77 | } 78 | 79 | 80 | } 81 | -------------------------------------------------------------------------------- /client/src/com/apm/data/packages/RepositoryDefinition.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 31/5/2021 4 | */ 5 | package com.apm.data.packages 6 | { 7 | 8 | public class RepositoryDefinition 9 | { 10 | //////////////////////////////////////////////////////// 11 | // CONSTANTS 12 | // 13 | 14 | private static const TAG:String = "RepositoryDefinition"; 15 | 16 | public static const TYPE_REMOTE:String = "remote"; 17 | public static const TYPE_LOCAL:String = "local"; 18 | 19 | 20 | //////////////////////////////////////////////////////// 21 | // VARIABLES 22 | // 23 | 24 | public var type:String = TYPE_REMOTE; 25 | public var name:String = ""; 26 | public var location:String = ""; 27 | 28 | 29 | //////////////////////////////////////////////////////// 30 | // FUNCTIONALITY 31 | // 32 | 33 | public function RepositoryDefinition() 34 | { 35 | } 36 | 37 | 38 | public function toObject():Object 39 | { 40 | return { 41 | type: type, 42 | name: name, 43 | location: location 44 | }; 45 | } 46 | 47 | 48 | public static function fromObject( data:Object ):RepositoryDefinition 49 | { 50 | var rep:RepositoryDefinition = new RepositoryDefinition(); 51 | 52 | if (data.hasOwnProperty("type")) rep.type = data.type; 53 | if (data.hasOwnProperty("name")) rep.name = data.name; 54 | if (data.hasOwnProperty("location")) rep.location = data.location; 55 | if (data.hasOwnProperty("url")) rep.location = data.location; 56 | 57 | // TODO:: 58 | 59 | return rep; 60 | } 61 | 62 | 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/project/processes/AndroidManifestMergeProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 23/8/2021 4 | */ 5 | package com.apm.client.commands.project.processes 6 | { 7 | import com.apm.client.processes.ProcessBase; 8 | import com.apm.client.processes.ProcessQueue; 9 | import com.apm.data.project.ApplicationDescriptor; 10 | 11 | 12 | public class AndroidManifestMergeProcess extends ProcessBase 13 | { 14 | //////////////////////////////////////////////////////// 15 | // CONSTANTS 16 | // 17 | 18 | private static const TAG:String = "AndroidManifestMergeProcess"; 19 | 20 | 21 | //////////////////////////////////////////////////////// 22 | // VARIABLES 23 | // 24 | 25 | private var _appDescriptor:ApplicationDescriptor; 26 | 27 | 28 | private var _subqueue:ProcessQueue; 29 | 30 | 31 | //////////////////////////////////////////////////////// 32 | // FUNCTIONALITY 33 | // 34 | 35 | public function AndroidManifestMergeProcess( appDescriptor:ApplicationDescriptor ) 36 | { 37 | _appDescriptor = appDescriptor; 38 | } 39 | 40 | 41 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 42 | { 43 | super.start( completeCallback, failureCallback ); 44 | 45 | _subqueue = new ProcessQueue(); 46 | _subqueue.addProcess( new AndroidManifestMergeDependencyCheckProcess() ); 47 | _subqueue.addProcess( new AndroidManifestMergeRunProcess( _appDescriptor ) ); 48 | _subqueue.start( complete, failure ); 49 | 50 | } 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/IDisposable.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2011 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.lang { 17 | 18 | /** 19 | * This describes an object that is able to release any resources it might hold a reference to. 20 | * @author Roland Zwaga 21 | * @docref container-documentation.html#disposing_managed_objects 22 | */ 23 | public interface IDisposable { 24 | 25 | // -------------------------------------------------------------------- 26 | // 27 | // Properties 28 | // 29 | // -------------------------------------------------------------------- 30 | 31 | /** 32 | * Returns true if the dispose() has already been invoked before. 33 | */ 34 | function get isDisposed():Boolean; 35 | 36 | // -------------------------------------------------------------------- 37 | // 38 | // Methods 39 | // 40 | // -------------------------------------------------------------------- 41 | 42 | /** 43 | * Release any resources that the current object might hold a reference to. 44 | */ 45 | function dispose():void; 46 | } 47 | } -------------------------------------------------------------------------------- /client/src/org/as3commons/zip/IZipFile.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2012 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.zip { 17 | import flash.utils.ByteArray; 18 | import flash.utils.IDataOutput; 19 | 20 | /** 21 | * 22 | * @author Roland Zwaga 23 | */ 24 | public interface IZipFile { 25 | function get content():ByteArray; 26 | function set content(data:ByteArray):void; 27 | function get date():Date; 28 | function set date(value:Date):void; 29 | function get filename():String; 30 | function set filename(value:String):void; 31 | function get sizeCompressed():uint; 32 | function get sizeUncompressed():uint; 33 | function get versionNumber():String; 34 | 35 | function getContentAsString(recompress:Boolean=true, charset:String="utf-8"):String; 36 | function serialize(stream:IDataOutput, includeAdler32:Boolean, centralDir:Boolean=false, centralDirOffset:uint=0):uint; 37 | function setContent(data:ByteArray, doCompress:Boolean=true):void; 38 | function setContentAsString(value:String, charset:String="utf-8", doCompress:Boolean=true):void; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /client/src/com/apm/utils/Checksum.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 22/6/2021 4 | */ 5 | package com.apm.utils 6 | { 7 | import by.blooddy.crypto.SHA256; 8 | 9 | import com.apm.client.processes.generic.ChecksumProcess; 10 | 11 | import flash.filesystem.File; 12 | import flash.filesystem.FileMode; 13 | import flash.filesystem.FileStream; 14 | import flash.utils.ByteArray; 15 | 16 | 17 | public class Checksum 18 | { 19 | //////////////////////////////////////////////////////// 20 | // CONSTANTS 21 | // 22 | 23 | private static const TAG:String = "Checksum"; 24 | 25 | 26 | //////////////////////////////////////////////////////// 27 | // VARIABLES 28 | // 29 | 30 | 31 | //////////////////////////////////////////////////////// 32 | // FUNCTIONALITY 33 | // 34 | 35 | public function Checksum() 36 | { 37 | } 38 | 39 | 40 | public static function sha256Checksum( f:File, callback:Function=null ):String 41 | { 42 | if (callback == null) 43 | { 44 | var data:ByteArray = new ByteArray(); 45 | 46 | var fs:FileStream = new FileStream(); 47 | fs.open( f, FileMode.READ ); 48 | fs.readBytes( data ); 49 | fs.close(); 50 | 51 | try 52 | { 53 | return SHA256.hashBytes( data ); 54 | } 55 | catch (e:Error) 56 | { 57 | } 58 | } 59 | else 60 | { 61 | var process:ChecksumProcess = new ChecksumProcess( f ); 62 | process.start( 63 | function( data:Object ):void 64 | { 65 | callback( data ); 66 | }, 67 | function( error:String ):void 68 | { 69 | callback( null ); 70 | }); 71 | } 72 | return null; 73 | } 74 | 75 | 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /client/src/com/apm/remote/github/GitHubAPI.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 28/6/2021 4 | */ 5 | package com.apm.remote.github 6 | { 7 | import com.apm.remote.lib.APIRequestQueue; 8 | 9 | import flash.net.URLRequest; 10 | import flash.net.URLRequestHeader; 11 | import flash.net.URLRequestMethod; 12 | 13 | 14 | public class GitHubAPI 15 | { 16 | //////////////////////////////////////////////////////// 17 | // CONSTANTS 18 | // 19 | 20 | private static const TAG:String = "GitHubAPI"; 21 | 22 | 23 | //////////////////////////////////////////////////////// 24 | // VARIABLES 25 | // 26 | 27 | 28 | private var _requestQueue:APIRequestQueue; 29 | 30 | private var _endpoint:String = "https://api.github.com"; 31 | 32 | private var _token:String = ""; 33 | 34 | 35 | //////////////////////////////////////////////////////// 36 | // FUNCTIONALITY 37 | // 38 | 39 | public function GitHubAPI() 40 | { 41 | _requestQueue = new APIRequestQueue(); 42 | } 43 | 44 | 45 | public function setToken( token:String ):GitHubAPI 46 | { 47 | this._token = token; 48 | return this; 49 | } 50 | 51 | 52 | public function call( query:String, callback:Function ):void 53 | { 54 | var headers:Array = []; 55 | headers.push( new URLRequestHeader( "Accept", "application/vnd.github.v3.raw" ) ); 56 | if (_token.length > 0) 57 | { 58 | headers.push( new URLRequestHeader( "Authorization", "token " + _token ) ); 59 | } 60 | 61 | var req:URLRequest = new URLRequest( _endpoint + query ); 62 | req.method = URLRequestMethod.GET; 63 | req.requestHeaders = headers; 64 | 65 | _requestQueue.add( req, "gh", callback ); 66 | } 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /client/src/com/apm/client/processes/generic/ChecksumProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 13/8/2021 4 | */ 5 | package com.apm.client.processes.generic 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.logging.Log; 9 | import com.apm.client.processes.ProcessBase; 10 | 11 | import flash.filesystem.File; 12 | 13 | 14 | public class ChecksumProcess extends ProcessBase 15 | { 16 | //////////////////////////////////////////////////////// 17 | // CONSTANTS 18 | // 19 | 20 | private static const TAG:String = "ChecksumProcess"; 21 | 22 | 23 | //////////////////////////////////////////////////////// 24 | // VARIABLES 25 | // 26 | 27 | private var _file:File; 28 | 29 | 30 | //////////////////////////////////////////////////////// 31 | // FUNCTIONALITY 32 | // 33 | 34 | public function ChecksumProcess( file:File ) 35 | { 36 | _file = file; 37 | } 38 | 39 | 40 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 41 | { 42 | super.start( completeCallback, failureCallback ); 43 | Log.d( TAG, "start: " + _file.name ); 44 | var subprocess:ProcessBase; 45 | if (APM.config.isMacOS) 46 | { 47 | subprocess = new ChecksumMacOSProcess( APM.instance, _file ); 48 | } 49 | else if (APM.config.isWindows) 50 | { 51 | subprocess = new ChecksumWindowsProcess( APM.instance, _file ); 52 | } 53 | else if (APM.config.isLinux) 54 | { 55 | subprocess = new ChecksumLinuxProcess( APM.instance, _file ); 56 | } 57 | else 58 | { 59 | subprocess = new ChecksumAS3Process( APM.instance, _file ); 60 | } 61 | subprocess.start( complete, failure ); 62 | } 63 | 64 | 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /client/src/com/apm/client/config/processes/LoadUserSettingsProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 28/5/2021 4 | */ 5 | package com.apm.client.config.processes 6 | { 7 | import com.apm.client.config.RunConfig; 8 | import com.apm.client.logging.Log; 9 | import com.apm.client.processes.ProcessBase; 10 | import com.apm.data.user.UserSettings; 11 | 12 | import flash.filesystem.File; 13 | 14 | 15 | /** 16 | * Process to load the user settings file (.apm_config) from the user home directory 17 | */ 18 | public class LoadUserSettingsProcess extends ProcessBase 19 | { 20 | //////////////////////////////////////////////////////// 21 | // CONSTANTS 22 | // 23 | 24 | private static const TAG:String = "LoadUserSettingsProcess"; 25 | 26 | 27 | //////////////////////////////////////////////////////// 28 | // VARIABLES 29 | // 30 | 31 | private var _config:RunConfig; 32 | 33 | 34 | //////////////////////////////////////////////////////// 35 | // FUNCTIONALITY 36 | // 37 | 38 | public function LoadUserSettingsProcess( config:RunConfig ) 39 | { 40 | _config = config; 41 | } 42 | 43 | 44 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 45 | { 46 | super.start( completeCallback, failureCallback ); 47 | Log.d( TAG, "start()" ); 48 | try 49 | { 50 | var f:File = new File( _config.homeDirectory + File.separator + UserSettings.DEFAULT_FILENAME ); 51 | try 52 | { 53 | _config.user.load( f ); 54 | } 55 | catch (e:Error) 56 | { 57 | Log.d( TAG, "User settings file doesn't exist" ); 58 | } 59 | } 60 | catch (e:Error) 61 | { 62 | Log.e( TAG, e ); 63 | } 64 | 65 | complete(); 66 | } 67 | 68 | 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /client/src/org/as3commons/zip/IZip.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2012 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.zip { 17 | import flash.events.IEventDispatcher; 18 | import flash.net.URLRequest; 19 | import flash.utils.ByteArray; 20 | import flash.utils.IDataOutput; 21 | 22 | /** 23 | * 24 | * @author Roland Zwaga 25 | */ 26 | public interface IZip extends IEventDispatcher { 27 | function get active():Boolean; 28 | 29 | function addFile(name:String, content:ByteArray=null, doCompress:Boolean=true):ZipFile; 30 | function addFileAt(index:uint, name:String, content:ByteArray=null, doCompress:Boolean=true):ZipFile; 31 | function addFileFromString(name:String, content:String, charset:String="utf-8", doCompress:Boolean=true):ZipFile; 32 | function addFileFromStringAt(index:uint, name:String, content:String, charset:String="utf-8", doCompress:Boolean=true):ZipFile; 33 | function close():void; 34 | function getFileAt(index:uint):IZipFile; 35 | function getFileByName(name:String):IZipFile; 36 | function getFileCount():uint; 37 | function load(request:URLRequest):void; 38 | function loadBytes(bytes:ByteArray):void; 39 | function removeFileAt(index:uint):IZipFile; 40 | function serialize(stream:IDataOutput, includeAdler32:Boolean=false):void; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /client/src/com/apm/client/repositories/RepositoryResolver.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 17/9/2021 4 | */ 5 | package com.apm.client.repositories 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.data.packages.RepositoryDefinition; 9 | import com.apm.remote.repository.LocalRepository; 10 | import com.apm.remote.repository.Repository; 11 | import com.apm.remote.repository.RepositoryAPI; 12 | 13 | 14 | public class RepositoryResolver 15 | { 16 | //////////////////////////////////////////////////////// 17 | // CONSTANTS 18 | // 19 | 20 | private static const TAG:String = "RepositoryResolver"; 21 | 22 | 23 | //////////////////////////////////////////////////////// 24 | // VARIABLES 25 | // 26 | 27 | 28 | 29 | 30 | //////////////////////////////////////////////////////// 31 | // FUNCTIONALITY 32 | // 33 | 34 | public function RepositoryResolver() 35 | { 36 | } 37 | 38 | 39 | public static function repositoryForSource( source:String = null ):Repository 40 | { 41 | if (source != null) 42 | { 43 | if (APM.config.projectDefinition) 44 | { 45 | for each (var repository:RepositoryDefinition in APM.config.projectDefinition.repositories) 46 | { 47 | if (repository.name == source) 48 | { 49 | switch (repository.type) 50 | { 51 | case RepositoryDefinition.TYPE_LOCAL: 52 | { 53 | return new LocalRepository( repository.location ) 54 | .setName( repository.name ); 55 | } 56 | 57 | case RepositoryDefinition.TYPE_REMOTE: 58 | { 59 | return new RepositoryAPI( repository.location ) 60 | .setName( repository.name ); 61 | } 62 | } 63 | } 64 | } 65 | } 66 | } 67 | return new RepositoryAPI( APM.config.getDefaultRemoteRepositoryEndpoint() ); 68 | } 69 | 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /client/src/com/apm/client/processes/generic/ExtractZipProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 28/5/2021 4 | */ 5 | package com.apm.client.processes.generic 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.processes.ProcessBase; 9 | 10 | import flash.filesystem.File; 11 | 12 | 13 | public class ExtractZipProcess extends ProcessBase 14 | { 15 | //////////////////////////////////////////////////////// 16 | // CONSTANTS 17 | // 18 | 19 | private static const TAG:String = "ExtractZipProcess"; 20 | 21 | 22 | //////////////////////////////////////////////////////// 23 | // VARIABLES 24 | // 25 | 26 | protected var _zipFile:File; 27 | protected var _outputDir:File; 28 | protected var _showOutputs:Boolean; 29 | 30 | 31 | //////////////////////////////////////////////////////// 32 | // FUNCTIONALITY 33 | // 34 | 35 | public function ExtractZipProcess( zipFile:File, outputDir:File, showOutputs:Boolean=true ) 36 | { 37 | _zipFile = zipFile; 38 | _outputDir = outputDir; 39 | _showOutputs = showOutputs; 40 | } 41 | 42 | 43 | override public function start( completeCallback:Function=null, failureCallback:Function=null ):void 44 | { 45 | super.start( completeCallback, failureCallback ); 46 | var subprocess:ProcessBase; 47 | if (APM.config.isMacOS) 48 | { 49 | subprocess = new ExtractZipMacOSProcess( _zipFile, _outputDir, _showOutputs ); 50 | } 51 | else if (APM.config.isWindows) 52 | { 53 | subprocess = new ExtractZipWindowsProcess( _zipFile, _outputDir, _showOutputs ); 54 | } 55 | else if (APM.config.isLinux) 56 | { 57 | subprocess = new ExtractZipLinuxProcess( _zipFile, _outputDir, _showOutputs ); 58 | } 59 | else 60 | { 61 | subprocess = new ExtractZipAS3Process( _zipFile, _outputDir, _showOutputs ); 62 | } 63 | subprocess.start( complete, failure ); 64 | } 65 | 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/builder/ToStringBuilder.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.lang.builder { 17 | 18 | import org.as3commons.lang.StringBuffer; 19 | 20 | /** 21 | * 22 | * @author Christophe Herreman 23 | */ 24 | public class ToStringBuilder { 25 | 26 | public static var defaultStyle:ToStringStyle = ToStringStyle.DEFAULT_STYLE; 27 | 28 | private var _object:Object; 29 | 30 | private var _style:ToStringStyle; 31 | 32 | private var _stringBuffer:StringBuffer; 33 | 34 | /** 35 | * Creates a new ToStringBuilder. 36 | * 37 | * @param object the object for which to build a "toString" 38 | * @param style the ToStringStyle 39 | */ 40 | public function ToStringBuilder( object:Object, style:ToStringStyle = null) { 41 | _object = object; 42 | _style = (style ? style : defaultStyle); 43 | _stringBuffer = new StringBuffer(); 44 | 45 | _style.appendBegin(_stringBuffer, _object); 46 | } 47 | 48 | /** 49 | * 50 | */ 51 | public function append(value:Object, fieldName:String = null):ToStringBuilder { 52 | _style.append(_stringBuffer, _object, value, fieldName); 53 | 54 | return this; 55 | } 56 | 57 | /** 58 | * 59 | */ 60 | public function toString():String { 61 | _style.appendEnd(_stringBuffer); 62 | return _stringBuffer.toString(); 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /client/src/com/apm/utils/WindowsShellPaths.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 24/11/2021 4 | */ 5 | package com.apm.utils 6 | { 7 | import com.apm.client.logging.Log; 8 | 9 | import flash.filesystem.File; 10 | 11 | 12 | public class WindowsShellPaths 13 | { 14 | //////////////////////////////////////////////////////// 15 | // CONSTANTS 16 | // 17 | 18 | private static const TAG:String = "WindowsShellPaths"; 19 | 20 | 21 | //////////////////////////////////////////////////////// 22 | // VARIABLES 23 | // 24 | 25 | 26 | //////////////////////////////////////////////////////// 27 | // FUNCTIONALITY 28 | // 29 | 30 | public function WindowsShellPaths() 31 | { 32 | } 33 | 34 | 35 | public static function getCmdInterpreter( env:Object = null ):File 36 | { 37 | try 38 | { 39 | if (env != null && env.hasOwnProperty( "COMSPEC" )) 40 | { 41 | var comspec:File = new File( env[ "COMSPEC" ] ); 42 | if (comspec.exists) 43 | return comspec; 44 | } 45 | 46 | // Try default location 47 | var cmd:File = new File( "C:\\WINDOWS\\System32\\cmd.exe" ); 48 | if (cmd.exists) 49 | return cmd; 50 | } 51 | catch (e:Error) 52 | { 53 | Log.e( TAG, e ); 54 | } 55 | return null; 56 | } 57 | 58 | 59 | public static function getPowershell( env:Object = null ):File 60 | { 61 | try 62 | { 63 | if (env != null && env.hasOwnProperty( "SYSTEMROOT" )) 64 | { 65 | var powershell:File = new File( env[ "SYSTEMROOT" ] + "\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" ); 66 | if (powershell.exists) 67 | return powershell; 68 | } 69 | 70 | var defaultLocation:File = new File( "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" ); 71 | if (defaultLocation.exists) 72 | return defaultLocation; 73 | } 74 | catch (e:Error) 75 | { 76 | Log.e( TAG, e ); 77 | } 78 | return null; 79 | } 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /client/src/com/apm/client/processes/ProcessBase.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 15/6/2021 4 | */ 5 | package com.apm.client.processes 6 | { 7 | import com.apm.client.processes.events.ProcessEvent; 8 | 9 | import flash.events.EventDispatcher; 10 | 11 | 12 | public class ProcessBase extends EventDispatcher implements Process 13 | { 14 | //////////////////////////////////////////////////////// 15 | // CONSTANTS 16 | // 17 | 18 | private static const TAG:String = "ProcessBase"; 19 | 20 | 21 | //////////////////////////////////////////////////////// 22 | // VARIABLES 23 | // 24 | 25 | protected var _queue:ProcessQueue; 26 | 27 | 28 | public function get processQueue():ProcessQueue { return _queue; } 29 | 30 | 31 | public function set processQueue( value:ProcessQueue ):void { _queue = value; } 32 | 33 | 34 | protected var _completeCallback:Function; 35 | protected var _failureCallback:Function; 36 | 37 | private var _finished:Boolean = false; 38 | 39 | 40 | 41 | //////////////////////////////////////////////////////// 42 | // FUNCTIONALITY 43 | // 44 | 45 | public function ProcessBase() 46 | { 47 | } 48 | 49 | 50 | public function start( completeCallback:Function = null, failureCallback:Function = null ):void 51 | { 52 | _completeCallback = completeCallback; 53 | _failureCallback = failureCallback; 54 | } 55 | 56 | 57 | protected function complete( data:Object = null ):void 58 | { 59 | if (!_finished) 60 | { 61 | _finished = true; 62 | if (_completeCallback) _completeCallback( data ); 63 | dispatchEvent( new ProcessEvent( ProcessEvent.COMPLETE ) ); 64 | } 65 | } 66 | 67 | 68 | protected function failure( error:String = "" ):void 69 | { 70 | if (!_finished) 71 | { 72 | _finished = true; 73 | if (_failureCallback) _failureCallback(); 74 | dispatchEvent( new ProcessEvent( ProcessEvent.FAILED, error ) ); 75 | } 76 | } 77 | 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/project/processes/ProjectConfigGetProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 22/10/2021 4 | */ 5 | package com.apm.client.commands.project.processes 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.processes.ProcessBase; 9 | import com.apm.data.project.ProjectDefinition; 10 | import com.apm.data.project.ProjectParameter; 11 | 12 | 13 | public class ProjectConfigGetProcess extends ProcessBase 14 | { 15 | //////////////////////////////////////////////////////// 16 | // CONSTANTS 17 | // 18 | 19 | private static const TAG:String = "ProjectConfigGetProcess"; 20 | 21 | 22 | //////////////////////////////////////////////////////// 23 | // VARIABLES 24 | // 25 | 26 | private var _paramName:String; 27 | 28 | 29 | //////////////////////////////////////////////////////// 30 | // FUNCTIONALITY 31 | // 32 | 33 | public function ProjectConfigGetProcess( paramName:String ) 34 | { 35 | _paramName = paramName; 36 | } 37 | 38 | 39 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 40 | { 41 | super.start( completeCallback, failureCallback ); 42 | 43 | var project:ProjectDefinition = APM.config.projectDefinition; 44 | if (project == null) 45 | { 46 | failure( "No project file found" ); 47 | return; 48 | } 49 | 50 | var param:ProjectParameter; 51 | if (_paramName == null) 52 | { 53 | // print all config 54 | for each (param in APM.config.projectDefinition.getConfiguration( APM.config.buildType )) 55 | { 56 | APM.io.writeValue( param.name, param.value ); 57 | } 58 | } 59 | else 60 | { 61 | param = project.getConfigurationParam( _paramName, APM.config.buildType ); 62 | if (param == null) 63 | { 64 | APM.io.writeError( "parameter", "not found" ); 65 | } 66 | else 67 | { 68 | APM.io.writeValue( param.name, param.value ); 69 | } 70 | } 71 | 72 | complete(); 73 | } 74 | 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /client/src/com/apm/client/io/IO.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 18/5/2021 4 | */ 5 | package com.apm.client.io 6 | { 7 | 8 | /** 9 | * This class handles all the output to the terminal particularly around 10 | * being able to display visual features such as spinners / progress bars 11 | * and handling input from the user (questions etc). 12 | */ 13 | public interface IO 14 | { 15 | //////////////////////////////////////////////////////// 16 | // FUNCTIONALITY 17 | // 18 | 19 | function get terminalControlSupported():Boolean; 20 | 21 | 22 | function set terminalControlSupported( value:Boolean ):void; 23 | 24 | 25 | function get colourSupported():Boolean; 26 | 27 | 28 | function set colourSupported( value:Boolean ):void; 29 | 30 | 31 | function set colourMode( value:String ):void; 32 | 33 | 34 | function writeLine( s:String, colour:String = null ):void; 35 | 36 | 37 | function writeValue( key:String, value:String ):void; 38 | 39 | 40 | function writeResult( success:Boolean, message:String ):void; 41 | 42 | 43 | function writeError( tag:String, message:String ):void; 44 | 45 | 46 | function out( s:String ):void; 47 | 48 | 49 | function input( s:String = null ):String; 50 | 51 | 52 | function question( question:String, defaultResponse:String = null ):String; 53 | 54 | 55 | function error( e:Error ):void; 56 | 57 | 58 | // 59 | // UI elements 60 | // 61 | 62 | function showSpinner( message:String = "" ):void; 63 | 64 | 65 | function updateSpinner( message:String = "" ):void; 66 | 67 | 68 | function stopSpinner( success:Boolean, message:String = "", removeSpinner:Boolean = false ):void; 69 | 70 | 71 | // 72 | // PROGRESS BAR 73 | // 74 | 75 | function showProgressBar( message:String = "" ):void; 76 | 77 | 78 | function updateProgressBar( progress:Number, message:String = "" ):void; 79 | 80 | 81 | function completeProgressBar( success:Boolean, message:String = "" ):void; 82 | 83 | 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /client/src/com/apm/client/config/processes/CheckNetworkProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 28/5/2021 4 | */ 5 | package com.apm.client.config.processes 6 | { 7 | import com.apm.client.config.RunConfig; 8 | import com.apm.client.logging.Log; 9 | import com.apm.client.processes.ProcessBase; 10 | 11 | import flash.events.HTTPStatusEvent; 12 | import flash.net.URLLoader; 13 | import flash.net.URLRequest; 14 | 15 | 16 | /** 17 | * Checks internet network connectivity 18 | */ 19 | public class CheckNetworkProcess extends ProcessBase 20 | { 21 | //////////////////////////////////////////////////////// 22 | // CONSTANTS 23 | // 24 | 25 | private static const TAG:String = "CheckNetworkProcess"; 26 | 27 | private static const DEFAULT_URL:String = "https://google.com"; 28 | 29 | 30 | //////////////////////////////////////////////////////// 31 | // VARIABLES 32 | // 33 | 34 | private var _config:RunConfig; 35 | 36 | private var _loader:URLLoader; 37 | 38 | private var _testUrl:String; 39 | 40 | 41 | //////////////////////////////////////////////////////// 42 | // FUNCTIONALITY 43 | // 44 | 45 | public function CheckNetworkProcess( config:RunConfig, testUrl:String = DEFAULT_URL ) 46 | { 47 | _config = config; 48 | _testUrl = testUrl; 49 | } 50 | 51 | 52 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 53 | { 54 | super.start( completeCallback, failureCallback ); 55 | Log.d( TAG, "start()" ); 56 | try 57 | { 58 | _loader = new URLLoader(); 59 | _loader.addEventListener( HTTPStatusEvent.HTTP_STATUS, statusHandler ); 60 | _loader.load( new URLRequest( _testUrl ) ); 61 | } 62 | catch (e:Error) 63 | { 64 | } 65 | } 66 | 67 | 68 | private function statusHandler( event:HTTPStatusEvent ):void 69 | { 70 | _config.hasNetwork = (event.status == 200); 71 | _loader.removeEventListener( HTTPStatusEvent.HTTP_STATUS, statusHandler ); 72 | _loader.close(); 73 | complete(); 74 | } 75 | 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /client/src/com/apple/plist/entries/PlistArrayEntry.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 10/9/2021 4 | */ 5 | package com.apple.plist.entries 6 | { 7 | import com.apple.plist.PlistUtils; 8 | 9 | 10 | /** 11 | * 12 | */ 13 | public class PlistArrayEntry extends PlistEntry 14 | { 15 | //////////////////////////////////////////////////////// 16 | // CONSTANTS 17 | // 18 | 19 | private static const TAG:String = "PlistStringEntry"; 20 | 21 | 22 | //////////////////////////////////////////////////////// 23 | // VARIABLES 24 | // 25 | 26 | 27 | //////////////////////////////////////////////////////// 28 | // FUNCTIONALITY 29 | // 30 | 31 | public function PlistArrayEntry( key:String ) 32 | { 33 | super( key, "array" ); 34 | } 35 | 36 | 37 | public function addEntry( entry:PlistEntry ):void 38 | { 39 | // Check if entry already exists 40 | for (var i:int = entries.length - 1; i >= 0; --i) 41 | { 42 | var e:PlistEntry = entries[ i ]; 43 | if (entry.equals( e )) 44 | { 45 | entries[ i ] = PlistUtils.mergeEntry( entry, e ); 46 | return; 47 | } 48 | } 49 | entries.push( entry ); 50 | } 51 | 52 | 53 | override public function equals( entry:PlistEntry ):Boolean 54 | { 55 | if (super.equals( entry )) 56 | { 57 | var arrayEntry:PlistArrayEntry = entry as PlistArrayEntry; 58 | 59 | if (arrayEntry.entries.length != entries.length) return false; 60 | 61 | for each (var e:PlistEntry in entries) 62 | { 63 | var foundMatch:Boolean = false; 64 | for each (var ae:PlistEntry in arrayEntry.entries) 65 | { 66 | foundMatch ||= ae.equals( e ); 67 | } 68 | if (!foundMatch) return false; 69 | } 70 | 71 | return true; 72 | } 73 | return false; 74 | } 75 | 76 | 77 | override public function valueXML():XML 78 | { 79 | var array:XML = ; 80 | for each (var entry:PlistEntry in entries) 81 | { 82 | array.appendChild( entry.valueXML() ); 83 | } 84 | return array; 85 | } 86 | 87 | } 88 | 89 | 90 | } 91 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/packages/processes/PackagePublishProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 15/6/2021 4 | */ 5 | package com.apm.client.commands.packages.processes 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.processes.ProcessBase; 9 | import com.apm.client.repositories.RepositoryResolver; 10 | import com.apm.data.packages.PackageDefinitionFile; 11 | import com.apm.remote.repository.Repository; 12 | import com.apm.remote.repository.RepositoryAPI; 13 | 14 | 15 | /** 16 | * Publishes a verified package to the package repository. 17 | */ 18 | public class PackagePublishProcess extends ProcessBase 19 | { 20 | //////////////////////////////////////////////////////// 21 | // CONSTANTS 22 | // 23 | 24 | private static const TAG:String = "PackagePublishProcess"; 25 | 26 | 27 | //////////////////////////////////////////////////////// 28 | // VARIABLES 29 | // 30 | 31 | private var _packageDefinition:PackageDefinitionFile; 32 | private var _repositoryAPI:Repository; 33 | 34 | 35 | //////////////////////////////////////////////////////// 36 | // FUNCTIONALITY 37 | // 38 | 39 | public function PackagePublishProcess( packageDefinition:PackageDefinitionFile ) 40 | { 41 | _packageDefinition = packageDefinition; 42 | } 43 | 44 | 45 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 46 | { 47 | super.start( completeCallback, failureCallback ); 48 | if (APM.config.user.publisherToken == null || APM.config.user.publisherToken.length == 0) 49 | { 50 | return failure( "No publisher token currently set" ); 51 | } 52 | 53 | APM.io.showSpinner( "Publish package" ); 54 | 55 | RepositoryResolver.repositoryForSource() 56 | .setToken( APM.config.user.publisherToken ) 57 | .publish( _packageDefinition, function ( success:Boolean, data:* ):void { 58 | APM.io.stopSpinner( success, "Package published" + (success ? "" : " ERROR: " + data) ); 59 | complete(); 60 | } ); 61 | 62 | } 63 | 64 | 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/project/processes/ValidatePackageCacheProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 29/9/2021 4 | */ 5 | package com.apm.client.commands.project.processes 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.logging.Log; 9 | import com.apm.client.processes.ProcessBase; 10 | import com.apm.data.project.ProjectDefinition; 11 | import com.apm.utils.ProjectPackageCache; 12 | 13 | import flash.filesystem.File; 14 | 15 | 16 | /** 17 | * This process does a quick check that the packages in the project definition 18 | * file are available in the package cache. 19 | */ 20 | public class ValidatePackageCacheProcess extends ProcessBase 21 | { 22 | //////////////////////////////////////////////////////// 23 | // CONSTANTS 24 | // 25 | 26 | private static const TAG:String = "ValidatePackageCacheProcess"; 27 | 28 | 29 | //////////////////////////////////////////////////////// 30 | // VARIABLES 31 | // 32 | 33 | 34 | //////////////////////////////////////////////////////// 35 | // FUNCTIONALITY 36 | // 37 | 38 | public function ValidatePackageCacheProcess() 39 | { 40 | } 41 | 42 | 43 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 44 | { 45 | super.start( completeCallback, failureCallback ); 46 | 47 | Log.d( TAG, "Validating packages in project definition are installed" ); 48 | 49 | var project:ProjectDefinition = APM.config.projectDefinition; 50 | if (project == null) 51 | { 52 | failure( "No project file found" ); 53 | return; 54 | } 55 | 56 | var packagesDir:File = new File( APM.config.packagesDirectory ); 57 | for (var i:int = 0; i < project.dependencies.length; i++) 58 | { 59 | if (!ProjectPackageCache.isPackageInstalled( 60 | project.dependencies[ i ].identifier, 61 | project.dependencies[ i ].version 62 | )) 63 | { 64 | failure( "Required package not installed: " + project.dependencies[ i ].toString() + " : run 'apm install'" ); 65 | return; 66 | } 67 | } 68 | 69 | complete(); 70 | } 71 | 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/util/CloneUtils.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.lang.util { 17 | import flash.utils.Dictionary; 18 | 19 | import org.as3commons.lang.Assert; 20 | import org.as3commons.lang.ICloneable; 21 | 22 | /** 23 | * Helper functions for working with ICloneable implementations. 24 | * @author Roland Zwaga 25 | */ 26 | public final class CloneUtils { 27 | 28 | /** 29 | * Loops over the specified Array of ICloneables and returns a 30 | * new Array populated with the ICloneable.clone() results. 31 | * @param cloneables The specified Array of ICloneables. 32 | * @return The specified new Array of ICloneable.clone() results. 33 | */ 34 | public static function cloneList(cloneables:Array):Array { 35 | Assert.notNull(cloneables, "cloneables argument must not be null"); 36 | var clone:Array = []; 37 | for each (var cloneable:ICloneable in cloneables) { 38 | clone[clone.length] = cloneable.clone(); 39 | } 40 | return clone; 41 | } 42 | 43 | /** 44 | * 45 | * @param dictionary 46 | * @return 47 | */ 48 | public static function cloneDictionary(dictionary:Dictionary):Dictionary { 49 | var clone:Dictionary = new Dictionary(); 50 | for (var keyValue:* in dictionary) { 51 | var value:* = dictionary[keyValue]; 52 | var key:* = (keyValue is ICloneable) ? ICloneable(keyValue) : keyValue; 53 | clone[key] = (value is ICloneable) ? ICloneable(value) : value; 54 | } 55 | return clone; 56 | } 57 | 58 | } 59 | } -------------------------------------------------------------------------------- /client/src/com/apm/remote/repository/RepositoryQueryOptions.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 30/9/2021 4 | */ 5 | package com.apm.remote.repository 6 | { 7 | import flash.net.URLVariables; 8 | 9 | 10 | public class RepositoryQueryOptions 11 | { 12 | //////////////////////////////////////////////////////// 13 | // CONSTANTS 14 | // 15 | 16 | private static const TAG:String = "RepositoryQueryOptions"; 17 | 18 | 19 | //////////////////////////////////////////////////////// 20 | // VARIABLES 21 | // 22 | 23 | 24 | private var _includePrerelease:Boolean = false; 25 | 26 | public function get includePrerelease():Boolean { return _includePrerelease; } 27 | public function set includePrerelease( value:Boolean ):void { _includePrerelease = value; } 28 | 29 | 30 | //////////////////////////////////////////////////////// 31 | // FUNCTIONALITY 32 | // 33 | 34 | public function RepositoryQueryOptions() 35 | { 36 | } 37 | 38 | 39 | public function setIncludePrerelease( includePrerelease:Boolean = true ):RepositoryQueryOptions 40 | { 41 | _includePrerelease = includePrerelease; 42 | return this; 43 | } 44 | 45 | 46 | public function toURLVariables():URLVariables 47 | { 48 | var vars:URLVariables = new URLVariables(); 49 | apply( vars ); 50 | return vars; 51 | } 52 | 53 | 54 | public function apply( variables:URLVariables ):URLVariables 55 | { 56 | variables["includePrerelease"] = includePrerelease; 57 | 58 | return variables; 59 | } 60 | 61 | 62 | // 63 | // 64 | // 65 | 66 | public static function fromParameters( parameters:Array ):RepositoryQueryOptions 67 | { 68 | var repoQueryOptions:RepositoryQueryOptions = null; 69 | if (parameters != null) 70 | { 71 | for (var i:int = parameters.length-1; i >= 0; --i) 72 | { 73 | var param:String = parameters[i]; 74 | if (param == "--include-prerelease") 75 | { 76 | parameters.removeAt( i ); 77 | if (repoQueryOptions == null) repoQueryOptions = new RepositoryQueryOptions(); 78 | repoQueryOptions.setIncludePrerelease(); 79 | } 80 | } 81 | } 82 | return repoQueryOptions; 83 | } 84 | 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/project/processes/ProjectDefinitionCreateProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 15/6/2021 4 | */ 5 | package com.apm.client.commands.project.processes 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.processes.ProcessBase; 9 | import com.apm.data.project.ProjectDefinition; 10 | 11 | import flash.filesystem.File; 12 | 13 | 14 | public class ProjectDefinitionCreateProcess extends ProcessBase 15 | { 16 | //////////////////////////////////////////////////////// 17 | // CONSTANTS 18 | // 19 | 20 | private static const TAG:String = "ProjectDefinitionCreateProcess"; 21 | 22 | 23 | //////////////////////////////////////////////////////// 24 | // VARIABLES 25 | // 26 | 27 | 28 | 29 | //////////////////////////////////////////////////////// 30 | // FUNCTIONALITY 31 | // 32 | 33 | public function ProjectDefinitionCreateProcess() 34 | { 35 | } 36 | 37 | 38 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 39 | { 40 | super.start( completeCallback, failureCallback ); 41 | if (APM.config.projectDefinition != null) 42 | { 43 | APM.io.writeLine( "Already have a config file " ); 44 | 45 | var response:String = APM.io.question( "Overwrite? Y/n", "n" ) 46 | if (response.toLowerCase() != "y") 47 | { 48 | complete(); 49 | return; 50 | } 51 | } 52 | 53 | APM.io.writeLine( "Creating new project definition file" ); 54 | 55 | var project:ProjectDefinition = new ProjectDefinition(); 56 | 57 | // 58 | // Walk through any questions 59 | 60 | project.applicationId = APM.io.question( "Application Identifier", "com.my.app" ); 61 | project.applicationName = APM.io.question( "Application Name", "My Application" ); 62 | project.version = APM.io.question( "Application Version", "1.0.0" ); 63 | 64 | project.applicationFilename = project.applicationName.replace( /\ /g, "" ); 65 | project.versionLabel = ""; 66 | 67 | // TODO:: Add whatever else we need here 68 | 69 | var projectFile:File = new File( APM.config.workingDirectory + File.separator + ProjectDefinition.DEFAULT_FILENAME ); 70 | project.save( projectFile ); 71 | 72 | complete(); 73 | } 74 | 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /client/src/com/apm/client/config/processes/LoadProjectDefinitionProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 28/5/2021 4 | */ 5 | package com.apm.client.config.processes 6 | { 7 | import com.apm.client.config.RunConfig; 8 | import com.apm.client.logging.Log; 9 | import com.apm.client.processes.ProcessBase; 10 | import com.apm.data.project.ProjectDefinition; 11 | import com.apm.data.project.ProjectLock; 12 | 13 | import flash.filesystem.File; 14 | 15 | 16 | public class LoadProjectDefinitionProcess extends ProcessBase 17 | { 18 | //////////////////////////////////////////////////////// 19 | // CONSTANTS 20 | // 21 | 22 | private static const TAG:String = "LoadProjectDefinitionProcess"; 23 | 24 | 25 | //////////////////////////////////////////////////////// 26 | // VARIABLES 27 | // 28 | 29 | 30 | private var _config:RunConfig; 31 | 32 | 33 | //////////////////////////////////////////////////////// 34 | // FUNCTIONALITY 35 | // 36 | 37 | public function LoadProjectDefinitionProcess( config:RunConfig ) 38 | { 39 | _config = config; 40 | } 41 | 42 | 43 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 44 | { 45 | super.start( completeCallback, failureCallback ); 46 | Log.d( TAG, "start()" ); 47 | try 48 | { 49 | var projectFile:File = new File( _config.workingDirectory + File.separator + ProjectDefinition.DEFAULT_FILENAME ); 50 | if (projectFile.exists) 51 | { 52 | Log.d( TAG, "found project file - loading ..." ); 53 | _config.projectDefinition = new ProjectDefinition() 54 | .load( projectFile ); 55 | } 56 | 57 | var lockFile:File = new File( _config.workingDirectory + File.separator + ProjectLock.DEFAULT_FILENAME ); 58 | if (lockFile.exists) 59 | { 60 | Log.d( TAG, "found project lock file - loading ..." ); 61 | _config.projectLock = new ProjectLock() 62 | .load( lockFile ); 63 | } 64 | 65 | complete(); 66 | } 67 | catch (e:Error) 68 | { 69 | Log.e( TAG, e ); 70 | if (e.errorID == 1132) // Invalid JSON parse 71 | { 72 | failure( "Could not parse project file, check the format is correct" ); 73 | } 74 | else 75 | { 76 | failure( e.message ); 77 | } 78 | } 79 | } 80 | 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/DictionaryUtils.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.lang { 17 | 18 | import flash.utils.Dictionary; 19 | 20 | /** 21 | * Contains utilities for working with Dictionaries. 22 | * 23 | * @author Christophe Herreman 24 | */ 25 | public final class DictionaryUtils { 26 | 27 | /** 28 | * Returns an array with the keys of the dictionary. 29 | * 30 | */ 31 | public static function getKeys(dictionary:Dictionary):Array { 32 | return ObjectUtils.getKeys(dictionary); 33 | } 34 | 35 | /** 36 | * Check whether the given dictionary contains the given key. 37 | * 38 | * @param dictionary the dictionary to check for a key 39 | * @param key the key to look up in the dictionary 40 | * @return true if the dictionary contains the given key, false if not 41 | */ 42 | public static function containsKey(dictionary:Dictionary, key:Object):Boolean { 43 | var result:Boolean = false; 44 | 45 | for (var k:*in dictionary) { 46 | if (key === k) { 47 | result = true; 48 | break; 49 | } 50 | } 51 | return result; 52 | } 53 | 54 | /** 55 | * Check whether the given dictionary contains the given value. 56 | * 57 | * @param dictionary the dictionary to check for a value 58 | * @param value the value to look up in the dictionary 59 | * @return true if the dictionary contains the given value, false if not 60 | */ 61 | public static function containsValue(dictionary:Dictionary, value:Object):Boolean { 62 | var result:Boolean = false; 63 | 64 | for each (var i:*in dictionary) { 65 | if (i === value) { 66 | result = true; 67 | break; 68 | } 69 | } 70 | return result; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/general/HelpCommand.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 18/5/2021 4 | */ 5 | package com.apm.client.commands.general 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.commands.Command; 9 | import com.apm.client.events.CommandEvent; 10 | import com.apm.client.events.CommandEvent; 11 | 12 | import flash.events.EventDispatcher; 13 | 14 | 15 | public class HelpCommand extends EventDispatcher implements Command 16 | { 17 | 18 | //////////////////////////////////////////////////////// 19 | // CONSTANTS 20 | // 21 | 22 | private static const TAG:String = "HelpCommand"; 23 | 24 | 25 | public static const NAME:String = "help"; 26 | 27 | 28 | //////////////////////////////////////////////////////// 29 | // VARIABLES 30 | // 31 | 32 | private var _parameters:Array; 33 | 34 | 35 | //////////////////////////////////////////////////////// 36 | // FUNCTIONALITY 37 | // 38 | 39 | public function HelpCommand() 40 | { 41 | super(); 42 | } 43 | 44 | 45 | public function setParameters( parameters:Array ):void 46 | { 47 | _parameters = parameters; 48 | } 49 | 50 | 51 | public function get name():String 52 | { 53 | return NAME; 54 | } 55 | 56 | 57 | public function get category():String 58 | { 59 | return ""; 60 | } 61 | 62 | 63 | public function get requiresNetwork():Boolean 64 | { 65 | return false; 66 | } 67 | 68 | 69 | public function get requiresProject():Boolean 70 | { 71 | return false; 72 | } 73 | 74 | 75 | public function get description():String 76 | { 77 | return "print apm usage information"; 78 | } 79 | 80 | 81 | public function get usage():String 82 | { 83 | return description + " \n" + 84 | "\n" + 85 | "apm help "; 86 | } 87 | 88 | 89 | public function execute():void 90 | { 91 | if (_parameters && _parameters.length > 0) 92 | { 93 | dispatchEvent( new CommandEvent( CommandEvent.PRINT_USAGE, _parameters.join("/") )); 94 | } 95 | else 96 | { 97 | dispatchEvent( new CommandEvent( CommandEvent.PRINT_USAGE )); 98 | } 99 | dispatchEvent( new CommandEvent( CommandEvent.COMPLETE, APM.CODE_OK )); 100 | } 101 | 102 | 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/SoftReference.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007-2009-2010 the original author or authors 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | package org.as3commons.lang { 23 | 24 | import flash.utils.Dictionary; 25 | 26 | /** 27 | * Class that fakes a soft (or weak) reference to an object by internally using 28 | * a Dictionary object with weak keys to hold the object reference. 29 | * @author Roland Zwaga 30 | */ 31 | public final class SoftReference { 32 | private var _dict:Dictionary; 33 | 34 | /** 35 | * Creates a new SoftReference instance. 36 | * @param value Optional object instance to be used as the current SoftReference value. 37 | */ 38 | public function SoftReference( value:Object = null) { 39 | super(); 40 | if (value != null) { 41 | this.value = value; 42 | } 43 | } 44 | 45 | /** 46 | * The instance for which a soft reference is held by the current SoftReference. 47 | */ 48 | public function get value():Object { 49 | if (_dict != null) { 50 | for (var obj:Object in _dict) { 51 | return obj; 52 | } 53 | } 54 | return null; 55 | } 56 | 57 | /** 58 | * @private 59 | */ 60 | public function set value(value:Object):void { 61 | _dict = new Dictionary(true); 62 | _dict[value] = true; 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /client/apm.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/project/processes/GenerateConfigAndroidProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 29/9/2021 4 | */ 5 | package com.apm.client.commands.project.processes 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.logging.Log; 9 | import com.apm.client.processes.ProcessBase; 10 | 11 | import flash.filesystem.File; 12 | import flash.filesystem.FileMode; 13 | import flash.filesystem.FileStream; 14 | import flash.utils.ByteArray; 15 | 16 | 17 | /** 18 | * Generates a AndroidManifest.xml file in the configuration directory 19 | * for the current project. 20 | */ 21 | public class GenerateConfigAndroidProcess extends ProcessBase 22 | { 23 | //////////////////////////////////////////////////////// 24 | // CONSTANTS 25 | // 26 | 27 | private static const TAG:String = "GenerateConfigAndroidProcess"; 28 | 29 | [Embed(source="data/AndroidManifestDefault.xml",mimeType="application/octet-stream")] 30 | private var AndroidManifestDefault:Class; 31 | 32 | private var ANDROID_MANIFEST_DEFAULT:String = (new AndroidManifestDefault() as ByteArray).toString(); 33 | 34 | 35 | //////////////////////////////////////////////////////// 36 | // VARIABLES 37 | // 38 | 39 | 40 | //////////////////////////////////////////////////////// 41 | // FUNCTIONALITY 42 | // 43 | 44 | public function GenerateConfigAndroidProcess() 45 | { 46 | } 47 | 48 | 49 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 50 | { 51 | super.start( completeCallback, failureCallback ); 52 | 53 | Log.d( TAG, "Generating default AndroidManifest.xml configuration" ); 54 | 55 | var configManifest:File = new File( APM.config.configDirectory ).resolvePath( "android/AndroidManifest.xml" ); 56 | if (configManifest.exists) 57 | { 58 | APM.io.writeResult( false, "Config AndroidManifest.xml already exists" ); 59 | } 60 | else 61 | { 62 | writeDefaultManifest( configManifest ); 63 | APM.io.writeResult( true, "Generated: " + configManifest.nativePath ); 64 | } 65 | complete(); 66 | } 67 | 68 | 69 | private function writeDefaultManifest( file:File ):void 70 | { 71 | var fs:FileStream = new FileStream(); 72 | fs.open( file, FileMode.WRITE ); 73 | fs.writeUTFBytes( ANDROID_MANIFEST_DEFAULT ); 74 | fs.close(); 75 | } 76 | 77 | 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /client/src/com/apm/client/processes/generic/ChecksumAS3Process.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 13/8/2021 4 | */ 5 | package com.apm.client.processes.generic 6 | { 7 | import by.blooddy.crypto.SHA256; 8 | import by.blooddy.crypto.events.ProcessEvent; 9 | 10 | import com.apm.client.APM; 11 | 12 | import com.apm.client.logging.Log; 13 | 14 | import com.apm.client.processes.ProcessBase; 15 | 16 | import flash.filesystem.File; 17 | import flash.filesystem.FileMode; 18 | import flash.filesystem.FileStream; 19 | import flash.utils.ByteArray; 20 | 21 | 22 | public class ChecksumAS3Process extends ProcessBase 23 | { 24 | //////////////////////////////////////////////////////// 25 | // CONSTANTS 26 | // 27 | 28 | private static const TAG:String = "ChecksumAS3Process"; 29 | 30 | 31 | //////////////////////////////////////////////////////// 32 | // VARIABLES 33 | // 34 | 35 | protected var _core:APM; 36 | protected var _file:File; 37 | private var _hash:SHA256; 38 | private var _data:ByteArray; 39 | 40 | 41 | //////////////////////////////////////////////////////// 42 | // FUNCTIONALITY 43 | // 44 | 45 | public function ChecksumAS3Process( core:APM, file:File ) 46 | { 47 | _core = core; 48 | _file = file; 49 | } 50 | 51 | 52 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 53 | { 54 | super.start( completeCallback, failureCallback ); 55 | Log.d( TAG, "start: " + _file.name ); 56 | _data = new ByteArray(); 57 | 58 | var fs:FileStream = new FileStream(); 59 | fs.open( _file, FileMode.READ ); 60 | fs.readBytes( _data ); 61 | fs.close(); 62 | 63 | try 64 | { 65 | _hash = new SHA256(); 66 | _hash.addEventListener( ProcessEvent.COMPLETE, hashCompleteHandler ); 67 | _hash.addEventListener( ProcessEvent.ERROR, hashErrorHandler ); 68 | _hash.hashBytes( _data ); 69 | } 70 | catch (e:Error) 71 | { 72 | } 73 | } 74 | 75 | 76 | private function hashCompleteHandler( event:ProcessEvent ):void 77 | { 78 | var result:String = event.data; 79 | 80 | _data.clear(); 81 | _data = null; 82 | 83 | complete( result ); 84 | } 85 | 86 | 87 | private function hashErrorHandler( event:ProcessEvent ):void 88 | { 89 | var error:Error = event.data; 90 | failure( error.message ); 91 | } 92 | 93 | 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/packages/utils/ProjectDefinitionValidator.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 18/6/2021 4 | */ 5 | package com.apm.client.commands.packages.utils 6 | { 7 | import com.apm.SemVer; 8 | import com.apm.data.install.InstallRequest; 9 | import com.apm.data.packages.PackageDependency; 10 | import com.apm.data.project.ProjectDefinition; 11 | import com.apm.data.packages.PackageIdentifier; 12 | 13 | 14 | public class ProjectDefinitionValidator 15 | { 16 | //////////////////////////////////////////////////////// 17 | // CONSTANTS 18 | // 19 | 20 | private static const TAG:String = "ProjectDefinitionValidator"; 21 | 22 | 23 | public static const NOT_INSTALLED : int = -1; 24 | public static const ALREADY_INSTALLED : int = 0; 25 | public static const UNKNOWN_LATEST_REQUESTED:int = 1; 26 | public static const HIGHER_VERSION_REQUESTED:int = 2; 27 | 28 | //////////////////////////////////////////////////////// 29 | // VARIABLES 30 | // 31 | 32 | 33 | //////////////////////////////////////////////////////// 34 | // FUNCTIONALITY 35 | // 36 | 37 | public function ProjectDefinitionValidator() 38 | { 39 | } 40 | 41 | 42 | public static function checkPackageAlreadyInstalled( project:ProjectDefinition, request:InstallRequest ):int 43 | { 44 | // Check package not already installed 45 | for (var i:int = 0; i < project.dependencies.length; i++) 46 | { 47 | if (PackageIdentifier.isEquivalent( request.packageIdentifier, project.dependencies[i].identifier )) 48 | { 49 | if (request.version == "latest") 50 | { 51 | return UNKNOWN_LATEST_REQUESTED; // Unknown as yet 52 | } 53 | else if (project.dependencies[i].version.greaterThanOrEqual( request.semVer )) 54 | { 55 | return ALREADY_INSTALLED; 56 | } 57 | else 58 | { 59 | // Upgrading ... 60 | return HIGHER_VERSION_REQUESTED; 61 | } 62 | } 63 | } 64 | return NOT_INSTALLED; 65 | } 66 | 67 | 68 | public static function getInstalledPackageDependency( project:ProjectDefinition, request:InstallRequest ):PackageDependency 69 | { 70 | for (var i:int = 0; i < project.dependencies.length; i++) 71 | { 72 | if (PackageIdentifier.isEquivalent( request.packageIdentifier, project.dependencies[ i ].identifier )) 73 | { 74 | return project.dependencies[ i ]; 75 | } 76 | } 77 | return null; 78 | } 79 | 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /client/src/com/apm/utils/JSONUtils.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 28/6/2021 4 | */ 5 | package com.apm.utils 6 | { 7 | 8 | public class JSONUtils 9 | { 10 | //////////////////////////////////////////////////////// 11 | // CONSTANTS 12 | // 13 | 14 | private static const TAG:String = "JSONUtils"; 15 | 16 | 17 | //////////////////////////////////////////////////////// 18 | // VARIABLES 19 | // 20 | 21 | 22 | //////////////////////////////////////////////////////// 23 | // FUNCTIONALITY 24 | // 25 | 26 | public function JSONUtils() 27 | { 28 | } 29 | 30 | 31 | public static function addMissingKeys( data:Object, keyOrder:Array ):Array 32 | { 33 | for (var key:String in data) 34 | { 35 | var hasKeyInOrder:Boolean = false; 36 | for each (var keyInOrder:String in keyOrder) 37 | { 38 | if (keyInOrder == key) 39 | { 40 | hasKeyInOrder = true; 41 | break; 42 | } 43 | } 44 | if (!hasKeyInOrder) keyOrder.push( key ); 45 | 46 | if (data[key] is Array) 47 | { 48 | for each (var o:Object in data[key]) 49 | { 50 | addMissingKeys( o, keyOrder ); 51 | } 52 | } 53 | else if (data[key] is Object) 54 | { 55 | addMissingKeys( data[key], keyOrder ); 56 | } 57 | } 58 | return keyOrder; 59 | } 60 | 61 | 62 | public static function getMissingKeys( data:Object, keyOrder:Array, missingKeys:Array=null ):Array 63 | { 64 | if (missingKeys == null) missingKeys = []; 65 | for (var key:String in data) 66 | { 67 | var hasKey:Boolean = false; 68 | for each (var keyInOrder:String in keyOrder) 69 | { 70 | if (keyInOrder == key) 71 | { 72 | hasKey = true; 73 | break; 74 | } 75 | } 76 | for each (var missingKey:String in missingKeys) 77 | { 78 | if (missingKey == key) 79 | { 80 | hasKey = true; 81 | break; 82 | } 83 | } 84 | if (!hasKey) missingKeys.push( key ); 85 | 86 | if (data[key] is Array) 87 | { 88 | for each (var o:Object in data[key]) 89 | { 90 | getMissingKeys( o, keyOrder, missingKeys ); 91 | } 92 | } 93 | else if (data[key] is Object) 94 | { 95 | getMissingKeys( data[key], keyOrder, missingKeys ); 96 | } 97 | } 98 | return missingKeys; 99 | } 100 | 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/general/UpgradeCommand.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 18/5/2021 4 | */ 5 | package com.apm.client.commands.general 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.commands.Command; 9 | import com.apm.client.events.CommandEvent; 10 | import com.apm.client.processes.ProcessQueue; 11 | import com.apm.client.processes.upgrade.UpgradeClientProcess; 12 | 13 | import flash.events.EventDispatcher; 14 | 15 | 16 | public class UpgradeCommand extends EventDispatcher implements Command 17 | { 18 | 19 | //////////////////////////////////////////////////////// 20 | // CONSTANTS 21 | // 22 | 23 | private static const TAG:String = "UpgradeCommand"; 24 | 25 | 26 | public static const NAME:String = "upgrade"; 27 | 28 | 29 | //////////////////////////////////////////////////////// 30 | // VARIABLES 31 | // 32 | 33 | private var _parameters:Array; 34 | private var _queue:ProcessQueue; 35 | 36 | 37 | //////////////////////////////////////////////////////// 38 | // FUNCTIONALITY 39 | // 40 | 41 | public function UpgradeCommand() 42 | { 43 | super(); 44 | _queue = new ProcessQueue(); 45 | } 46 | 47 | 48 | public function setParameters( parameters:Array ):void 49 | { 50 | _parameters = parameters; 51 | } 52 | 53 | 54 | public function get name():String 55 | { 56 | return NAME; 57 | } 58 | 59 | 60 | public function get category():String 61 | { 62 | return ""; 63 | } 64 | 65 | 66 | public function get requiresNetwork():Boolean 67 | { 68 | return true; 69 | } 70 | 71 | 72 | public function get requiresProject():Boolean 73 | { 74 | return false; 75 | } 76 | 77 | 78 | public function get description():String 79 | { 80 | return "print apm version information"; 81 | } 82 | 83 | 84 | public function get usage():String 85 | { 86 | return description + " \n" + 87 | "\n" + 88 | "apm upgrade checks for the latest version of apm and attempts to install it if available"; 89 | } 90 | 91 | 92 | public function execute():void 93 | { 94 | _queue.addProcess( new UpgradeClientProcess() ); 95 | _queue.start( function ():void { 96 | dispatchEvent( new CommandEvent( CommandEvent.COMPLETE, APM.CODE_OK ) ); 97 | } ); 98 | 99 | } 100 | 101 | 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/general/VersionCommand.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 18/5/2021 4 | */ 5 | package com.apm.client.commands.general 6 | { 7 | import com.apm.SemVer; 8 | import com.apm.client.APM; 9 | import com.apm.client.Consts; 10 | import com.apm.client.commands.Command; 11 | import com.apm.client.events.CommandEvent; 12 | 13 | import flash.events.EventDispatcher; 14 | 15 | 16 | public class VersionCommand extends EventDispatcher implements Command 17 | { 18 | 19 | //////////////////////////////////////////////////////// 20 | // CONSTANTS 21 | // 22 | 23 | private static const TAG:String = "VersionCommand"; 24 | 25 | 26 | public static const NAME:String = "version"; 27 | 28 | 29 | //////////////////////////////////////////////////////// 30 | // VARIABLES 31 | // 32 | 33 | private var _parameters:Array; 34 | 35 | 36 | //////////////////////////////////////////////////////// 37 | // FUNCTIONALITY 38 | // 39 | 40 | public function VersionCommand() 41 | { 42 | super(); 43 | } 44 | 45 | 46 | public function setParameters( parameters:Array ):void 47 | { 48 | _parameters = parameters; 49 | } 50 | 51 | 52 | public function get name():String 53 | { 54 | return NAME; 55 | } 56 | 57 | 58 | public function get category():String 59 | { 60 | return ""; 61 | } 62 | 63 | 64 | public function get requiresNetwork():Boolean 65 | { 66 | return false; 67 | } 68 | 69 | 70 | public function get requiresProject():Boolean 71 | { 72 | return false; 73 | } 74 | 75 | 76 | public function get description():String 77 | { 78 | return "print apm version information"; 79 | } 80 | 81 | 82 | public function get usage():String 83 | { 84 | return description + " \n" + 85 | "\n" + 86 | "apm -v print the basic apm version number \n" + 87 | "apm version print the version information about apm"; 88 | } 89 | 90 | 91 | public function execute():void 92 | { 93 | try 94 | { 95 | var version:SemVer = SemVer.fromString( Consts.VERSION ); 96 | APM.io.writeLine( "apm: v" + (version == null ? Consts.VERSION : version.toString()) ); 97 | } 98 | catch (e:Error) 99 | { 100 | } 101 | dispatchEvent( new CommandEvent( CommandEvent.COMPLETE, APM.CODE_OK )); 102 | } 103 | 104 | 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /client/src/com/apm/data/install/InstallPackageDataGroup.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 18/6/2021 4 | */ 5 | package com.apm.data.install 6 | { 7 | /** 8 | * 9 | */ 10 | public class InstallPackageDataGroup 11 | { 12 | //////////////////////////////////////////////////////// 13 | // CONSTANTS 14 | // 15 | 16 | private static const TAG:String = "InstallPackageDataGroup"; 17 | 18 | 19 | //////////////////////////////////////////////////////// 20 | // VARIABLES 21 | // 22 | 23 | public var versions:Vector.; 24 | 25 | 26 | //////////////////////////////////////////////////////// 27 | // FUNCTIONALITY 28 | // 29 | 30 | public function InstallPackageDataGroup() 31 | { 32 | versions = new Vector.(); 33 | } 34 | 35 | 36 | public function get packageIdentifier():String 37 | { 38 | if (length > 0) 39 | return versions[0].packageIdentifier; 40 | return ""; 41 | } 42 | 43 | 44 | public function get length():int 45 | { 46 | return versions.length; 47 | } 48 | 49 | 50 | public function addIfNotExists( data:InstallPackageData ):void 51 | { 52 | var exists:Boolean = false; 53 | for each (var p:InstallPackageData in versions) 54 | { 55 | exists ||= data.equals( p ); 56 | } 57 | if (!exists) 58 | { 59 | versions.push( data ); 60 | } 61 | } 62 | 63 | 64 | public function sortByVersion():void 65 | { 66 | sort( sortInstallPackageData ); 67 | } 68 | 69 | 70 | public function sort( compare:Function ):void 71 | { 72 | versions.sort( compare ); 73 | } 74 | 75 | 76 | private function sortInstallPackageData( a:InstallPackageData, b:InstallPackageData ):int 77 | { 78 | if (a.equals( b )) return 0; 79 | if (a.packageVersion.version.greaterThan( b.packageVersion.version )) 80 | return -1; 81 | return 1; 82 | } 83 | 84 | 85 | public static const sortFunction:Function = function ( a:InstallPackageDataGroup, 86 | b:InstallPackageDataGroup ):Number 87 | { 88 | try 89 | { 90 | var packageAIdentifier:String = a.packageIdentifier; 91 | var packageBIdentifier:String = b.packageIdentifier; 92 | 93 | if (packageAIdentifier < packageBIdentifier) 94 | return -1; 95 | else if (packageAIdentifier > packageBIdentifier) 96 | return 1; 97 | } 98 | catch (e:Error) 99 | { 100 | trace( e ); 101 | } 102 | return 0; 103 | }; 104 | 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /client/src/com/apple/plist/entries/PlistDictEntry.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 10/9/2021 4 | */ 5 | package com.apple.plist.entries 6 | { 7 | /** 8 | * 9 | */ 10 | public class PlistDictEntry extends PlistEntry 11 | { 12 | //////////////////////////////////////////////////////// 13 | // CONSTANTS 14 | // 15 | 16 | private static const TAG:String = "PlistDictEntry"; 17 | 18 | 19 | //////////////////////////////////////////////////////// 20 | // VARIABLES 21 | // 22 | 23 | 24 | //////////////////////////////////////////////////////// 25 | // FUNCTIONALITY 26 | // 27 | 28 | public function PlistDictEntry( key:String ) 29 | { 30 | super( key, "dict" ); 31 | } 32 | 33 | 34 | public function keys():Array 35 | { 36 | var keys:Array = []; 37 | for each (var entry:PlistEntry in entries) 38 | { 39 | keys.push( entry.key ); 40 | } 41 | return keys; 42 | } 43 | 44 | 45 | public function getEntry( key:String ):PlistEntry 46 | { 47 | for each (var entry:PlistEntry in entries) 48 | { 49 | if (entry.key == key) 50 | { 51 | return entry; 52 | } 53 | } 54 | return null; 55 | } 56 | 57 | 58 | public function removeEntry( key:String ):void 59 | { 60 | for (var i:int = entries.length - 1; i >= 0; --i) 61 | { 62 | if (entries[i].key == key) 63 | { 64 | entries.splice( i, 1 ); 65 | } 66 | } 67 | } 68 | 69 | 70 | public function addEntry( entry:PlistEntry ):void 71 | { 72 | entries.push( entry ); 73 | } 74 | 75 | 76 | override public function equals( entry:PlistEntry ):Boolean 77 | { 78 | if (super.equals( entry )) 79 | { 80 | var dictEntry:PlistDictEntry = entry as PlistDictEntry; 81 | 82 | if (dictEntry.keys().length != keys().length) return false; 83 | 84 | for each (var e:PlistEntry in entries) 85 | { 86 | var compEntry:PlistEntry = dictEntry.getEntry( e.key ); 87 | if (compEntry == null) return false; 88 | if (!compEntry.equals( e )) return false; 89 | } 90 | 91 | return true; 92 | } 93 | return false; 94 | } 95 | 96 | 97 | override public function valueXML():XML 98 | { 99 | var dict:XML = ; 100 | for each (var entry:PlistEntry in entries) 101 | { 102 | dict.appendChild( entry.keyXML() ); 103 | dict.appendChild( entry.valueXML() ); 104 | } 105 | return dict; 106 | } 107 | 108 | 109 | } 110 | 111 | 112 | } 113 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/project/processes/IOSPlistMergeProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 10/9/2021 4 | */ 5 | package com.apm.client.commands.project.processes 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.processes.ProcessBase; 9 | import com.apm.data.project.ProjectParameter; 10 | import com.apm.utils.FileUtils; 11 | import com.apple.plist.Plist; 12 | import com.apple.plist.PlistUtils; 13 | 14 | import flash.filesystem.File; 15 | 16 | 17 | public class IOSPlistMergeProcess extends ProcessBase 18 | { 19 | //////////////////////////////////////////////////////// 20 | // CONSTANTS 21 | // 22 | 23 | private static const TAG:String = "IOSPlistMergeProcess"; 24 | 25 | 26 | //////////////////////////////////////////////////////// 27 | // VARIABLES 28 | // 29 | 30 | private var _mergePlist:File; 31 | private var _currentPlist:File; 32 | 33 | 34 | //////////////////////////////////////////////////////// 35 | // FUNCTIONALITY 36 | // 37 | 38 | public function IOSPlistMergeProcess( mergePlist:File, currentPlist:File ) 39 | { 40 | _mergePlist = mergePlist; 41 | _currentPlist = currentPlist; 42 | } 43 | 44 | 45 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 46 | { 47 | super.start( completeCallback, failureCallback ); 48 | 49 | if (!_mergePlist.exists || !_currentPlist.exists) 50 | { 51 | failure( "Plist file doesn't exist" ); 52 | return; 53 | } 54 | 55 | try 56 | { 57 | // Insert configuration parameters into merge plist 58 | // Note: currentPlist should already have parameters 59 | var mergeContent:String = FileUtils.readFileContentAsString( _mergePlist ); 60 | for each (var param:ProjectParameter in APM.config.projectDefinition.getConfiguration( APM.config.buildType )) 61 | { 62 | var regex:RegExp = new RegExp( "\\$\\{" + param.name + "\\}", "g" ); 63 | mergeContent = mergeContent.replace( regex, param.value ); 64 | } 65 | 66 | mergeContent = mergeContent.replace( 67 | /\$\{applicationId\}/g, 68 | APM.config.projectDefinition.getApplicationId( APM.config.buildType ) 69 | ); 70 | 71 | // Load and merge plists 72 | var merge:Plist = new Plist( mergeContent ); 73 | var current:Plist = new Plist().load( _currentPlist ); 74 | 75 | var result:Plist = PlistUtils.merge( current, merge ); 76 | 77 | result.saveAsync( _currentPlist, complete ); 78 | } 79 | catch (e:Error) 80 | { 81 | failure( e.message ); 82 | } 83 | 84 | } 85 | 86 | 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /client/src/com/apm/client/repositories/processes/RepositoryGetPackageVersionProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 15/9/2021 4 | */ 5 | package com.apm.client.repositories.processes 6 | { 7 | import com.apm.SemVer; 8 | import com.apm.SemVerRange; 9 | import com.apm.client.logging.Log; 10 | import com.apm.client.processes.ProcessBase; 11 | import com.apm.client.repositories.PackageResolver; 12 | import com.apm.client.repositories.PackageResolverResult; 13 | import com.apm.data.packages.PackageDefinition; 14 | import com.apm.data.packages.PackageVersion; 15 | import com.apm.remote.repository.Repository; 16 | import com.apm.remote.repository.RepositoryQueryOptions; 17 | 18 | 19 | public class RepositoryGetPackageVersionProcess extends ProcessBase 20 | { 21 | //////////////////////////////////////////////////////// 22 | // CONSTANTS 23 | // 24 | 25 | private static const TAG:String = "RepositoryGetPackageVersionProcess"; 26 | 27 | 28 | //////////////////////////////////////////////////////// 29 | // VARIABLES 30 | // 31 | 32 | private var _result:PackageResolverResult; 33 | private var _repository:Repository; 34 | private var _identifier:String; 35 | private var _version:SemVerRange; 36 | private var _options:RepositoryQueryOptions; 37 | 38 | 39 | //////////////////////////////////////////////////////// 40 | // FUNCTIONALITY 41 | // 42 | 43 | public function RepositoryGetPackageVersionProcess( result:PackageResolverResult, repo:Repository, identifier:String, version:SemVerRange, options:RepositoryQueryOptions ) 44 | { 45 | _result = result; 46 | _repository = repo; 47 | _identifier = identifier; 48 | _version = version; 49 | _options = options; 50 | } 51 | 52 | 53 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 54 | { 55 | super.start( completeCallback, failureCallback ); 56 | try 57 | { 58 | _repository.getPackageVersion( 59 | _identifier, 60 | _version, 61 | _options, 62 | function ( success:Boolean, packageDefinition:PackageDefinition ):void 63 | { 64 | if (success) 65 | { 66 | if (_repository.name != null) 67 | { 68 | for each (var v:PackageVersion in packageDefinition.versions) 69 | { 70 | v.source = _repository.name; 71 | } 72 | } 73 | _result.resolvedPackage = packageDefinition; 74 | } 75 | complete(); 76 | } 77 | ); 78 | } 79 | catch (e:Error) 80 | { 81 | Log.e( TAG, e ); 82 | failure( e.message ); 83 | } 84 | } 85 | 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/packages/processes/PackageGenerateChecksumProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 15/6/2021 4 | */ 5 | package com.apm.client.commands.packages.processes 6 | { 7 | import by.blooddy.crypto.SHA256; 8 | import by.blooddy.crypto.events.ProcessEvent; 9 | 10 | import com.apm.client.APM; 11 | import com.apm.client.processes.ProcessBase; 12 | import com.apm.client.processes.generic.ChecksumProcess; 13 | import com.apm.data.packages.PackageDefinitionFile; 14 | 15 | import flash.filesystem.File; 16 | import flash.filesystem.FileMode; 17 | import flash.filesystem.FileStream; 18 | import flash.utils.ByteArray; 19 | import flash.utils.ByteArray; 20 | 21 | 22 | /** 23 | * Loads a PackageDefinitionFile from a File reference. 24 | *
25 | * This process is really just for delaying the load until a point in the queue 26 | * (generally when extracting a package from a zip). 27 | */ 28 | public class PackageGenerateChecksumProcess extends ProcessBase 29 | { 30 | //////////////////////////////////////////////////////// 31 | // CONSTANTS 32 | // 33 | 34 | private static const TAG:String = "PackageGenerateChecksumProcess"; 35 | 36 | 37 | //////////////////////////////////////////////////////// 38 | // VARIABLES 39 | // 40 | 41 | private var _packageDefinition:PackageDefinitionFile; 42 | private var _file:File; 43 | 44 | 45 | //////////////////////////////////////////////////////// 46 | // FUNCTIONALITY 47 | // 48 | 49 | public function PackageGenerateChecksumProcess( packageDefinition:PackageDefinitionFile, file:File ) 50 | { 51 | _packageDefinition = packageDefinition; 52 | _file = file; 53 | } 54 | 55 | 56 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 57 | { 58 | super.start( completeCallback, failureCallback ); 59 | APM.io.showSpinner( "Generating package checksum: " + _file.nativePath ); 60 | if (!_file.exists) 61 | { 62 | APM.io.stopSpinner( false, "Package doesn't exist: " + _file.nativePath ); 63 | return failure(); 64 | } 65 | 66 | 67 | var subprocess:ChecksumProcess = new ChecksumProcess( _file ); 68 | 69 | subprocess.start( 70 | function( data:Object ):void 71 | { 72 | var result:String = String(data); 73 | _packageDefinition.version.checksum = result; 74 | APM.io.stopSpinner( true, "Generated checksum: " + result ); 75 | complete(); 76 | }, 77 | function( error:String ):void 78 | { 79 | APM.io.stopSpinner( false, "ERROR: " + error ); 80 | failure(); 81 | }); 82 | 83 | } 84 | 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /client/src/com/apm/data/install/InstallPackageData.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 18/6/2021 4 | */ 5 | package com.apm.data.install 6 | { 7 | import com.apm.data.packages.PackageVersion; 8 | 9 | public class InstallPackageData 10 | { 11 | //////////////////////////////////////////////////////// 12 | // CONSTANTS 13 | // 14 | 15 | private static const TAG:String = "InstallPackageData"; 16 | 17 | 18 | //////////////////////////////////////////////////////// 19 | // VARIABLES 20 | // 21 | 22 | public var packageVersion:PackageVersion; 23 | public var request:InstallRequest; 24 | 25 | 26 | //////////////////////////////////////////////////////// 27 | // FUNCTIONALITY 28 | // 29 | 30 | public function InstallPackageData( 31 | packageVersion:PackageVersion = null, 32 | request:InstallRequest = null ) 33 | { 34 | this.packageVersion = packageVersion; 35 | this.request = request; 36 | } 37 | 38 | 39 | public function get packageIdentifier():String 40 | { 41 | if (packageVersion && packageVersion.packageDef) 42 | return packageVersion.packageDef.identifier; 43 | return ""; 44 | } 45 | 46 | 47 | public function equals( b:InstallPackageData ):Boolean 48 | { 49 | if (packageVersion.equals( b.packageVersion )) 50 | { 51 | return true; 52 | } 53 | return false; 54 | } 55 | 56 | 57 | public function fromObject( data:Object ):InstallPackageData 58 | { 59 | if (data != null) 60 | { 61 | if (data.hasOwnProperty( "packageVersion" )) this.packageVersion = new PackageVersion().fromObject( data.packageVersion ); 62 | if (data.hasOwnProperty( "request" )) this.request = new InstallRequest( null, null, null ).fromObject( 63 | data.request ); 64 | } 65 | return this; 66 | } 67 | 68 | 69 | public function toObject():Object 70 | { 71 | return { 72 | packageVersion: packageVersion.toObject( false, true ), 73 | request : request.toObject() 74 | } 75 | } 76 | 77 | 78 | public static const sortFunction:Function = function ( a:InstallPackageData, b:InstallPackageData ):Number 79 | { 80 | try 81 | { 82 | var packageAIdentifier:String = a.packageVersion.packageDef.identifier.toLowerCase(); 83 | var packageBIdentifier:String = b.packageVersion.packageDef.identifier.toLowerCase(); 84 | 85 | if (packageAIdentifier < packageBIdentifier) 86 | return -1; 87 | else if (packageAIdentifier > packageBIdentifier) 88 | return 1; 89 | } 90 | catch (e:Error) 91 | { 92 | trace( e ); 93 | } 94 | return 0; 95 | }; 96 | 97 | 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /client/src/com/apm/client/analytics/Analytics.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 6/8/2021 4 | */ 5 | package com.apm.client.analytics 6 | { 7 | import com.apm.client.repositories.RepositoryResolver; 8 | import com.apm.remote.repository.RepositoryAPI; 9 | 10 | 11 | /** 12 | * A really basic analytics implementation so we can display install stats on 13 | * the repository site. 14 | */ 15 | public class Analytics 16 | { 17 | //////////////////////////////////////////////////////// 18 | // CONSTANTS 19 | // 20 | 21 | private static const TAG:String = "Analytics"; 22 | 23 | 24 | //////////////////////////////////////////////////////// 25 | // SINGLETON REFERENCE 26 | // 27 | 28 | private static var _shouldCreateInstance:Boolean = false; 29 | private static var _instance:Analytics; 30 | public static function get instance():Analytics 31 | { 32 | if (_instance == null) 33 | { 34 | _shouldCreateInstance = true; 35 | _instance = new Analytics(); 36 | _shouldCreateInstance = false; 37 | } 38 | return _instance; 39 | } 40 | 41 | 42 | //////////////////////////////////////////////////////// 43 | // VARIABLES 44 | // 45 | 46 | 47 | //////////////////////////////////////////////////////// 48 | // FUNCTIONALITY 49 | // 50 | 51 | public function Analytics() 52 | { 53 | if (_shouldCreateInstance) 54 | { 55 | } 56 | else 57 | { 58 | throw new Error( "Use Analytics.instance to access the analytics functionality" ); 59 | } 60 | } 61 | 62 | 63 | public function install( identifier:String, version:String, source:String, callback:Function = null ):void 64 | { 65 | if (source == "file") 66 | { 67 | callback(); 68 | } 69 | else 70 | { 71 | RepositoryResolver.repositoryForSource( source ) 72 | .logEvent( "install", identifier, version, callback ); 73 | } 74 | } 75 | 76 | 77 | public function download( identifier:String, version:String, source:String, callback:Function = null ):void 78 | { 79 | if (source == "file") 80 | { 81 | callback(); 82 | } 83 | else 84 | { 85 | RepositoryResolver.repositoryForSource( source ) 86 | .logEvent( "download", identifier, version, callback ); 87 | } 88 | } 89 | 90 | 91 | public function uninstall( identifier:String, version:String, source:String, callback:Function = null ):void 92 | { 93 | if (source == "file") 94 | { 95 | callback(); 96 | } 97 | else 98 | { 99 | RepositoryResolver.repositoryForSource( source ) 100 | .logEvent( "uninstall", identifier, version, callback ); 101 | } 102 | } 103 | 104 | 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /client/src/org/as3commons/zip/ZipErrorEvent.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2012 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.zip 17 | { 18 | import flash.events.Event; 19 | 20 | /** 21 | * Zip dispatches ZipErrorEvent objects when it encounters 22 | * errors while parsing the ZIP archive. There is only one type 23 | * of ZipErrorEvent: ZipErrorEvent.PARSE_ERROR 24 | * 25 | * @author Claus Wahlers 26 | * @author Max Herkender 27 | */ 28 | public class ZipErrorEvent extends Event 29 | { 30 | /** 31 | * A human readable description of the kind of parse error. 32 | */ 33 | public var text:String; 34 | 35 | /** 36 | * Defines the value of the type property of a ZipErrorEvent object. 37 | */ 38 | public static const PARSE_ERROR:String = "parseError"; 39 | 40 | /** 41 | * Constructor 42 | * 43 | * @param type The type of the event. Event listeners can 44 | * access this information through the inherited type property. 45 | * There is only one type of ZipErrorEvent: 46 | * ZipErrorEvent.PARSE_ERROR. 47 | * 48 | * @param text A human readable description of the kind of parse 49 | * error. 50 | * 51 | * @param bubbles Determines whether the Event object participates 52 | * in the bubbling stage of the event flow. Event listeners can 53 | * access this information through the inherited bubbles property. 54 | * 55 | * @param cancelable Determines whether the Event object can be 56 | * canceled. Event listeners can access this information through 57 | * the inherited cancelable property. 58 | */ 59 | public function ZipErrorEvent( type:String, text:String = "", bubbles:Boolean = false, cancelable:Boolean = false) { 60 | this.text = text; 61 | super(type, bubbles, cancelable); 62 | } 63 | 64 | /** 65 | * Creates a copy of the ZipErrorEvent object and sets the value 66 | * of each property to match that of the original. 67 | * 68 | * @return A new ZipErrorEvent object with property values that 69 | * match those of the original. 70 | */ 71 | override public function clone():Event { 72 | return new ZipErrorEvent(type, text, bubbles, cancelable); 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /client/src/com/apm/data/project/ProjectPackageDependency.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 17/10/2025 4 | */ 5 | package com.apm.data.project 6 | { 7 | import com.apm.SemVerRange; 8 | import com.apm.data.packages.PackageDependency; 9 | 10 | public class ProjectPackageDependency extends PackageDependency 11 | { 12 | //////////////////////////////////////////////////////// 13 | // CONSTANTS 14 | // 15 | 16 | private static const TAG:String = "ProjectPackageDependency"; 17 | 18 | 19 | //////////////////////////////////////////////////////// 20 | // VARIABLES 21 | // 22 | 23 | public var delayLoad:String = "none"; 24 | 25 | 26 | //////////////////////////////////////////////////////// 27 | // FUNCTIONALITY 28 | // 29 | 30 | public function ProjectPackageDependency() 31 | { 32 | } 33 | 34 | 35 | override public function toObject( forceObjectOutput:Boolean = false ):Object 36 | { 37 | if (_singleLineOutput && !forceObjectOutput) 38 | { 39 | return identifier + ":" + version.toString(); 40 | } 41 | else 42 | { 43 | var o:Object = { 44 | id : identifier, 45 | version: version.toString() 46 | }; 47 | if (source != null) o.source = source; 48 | if (delayLoad != "none") o.delayLoad = delayLoad; 49 | return o; 50 | } 51 | } 52 | 53 | 54 | override public function fromObject( data:Object ):PackageDependency 55 | { 56 | if (data != null) 57 | { 58 | if (data is String) 59 | { 60 | var line:String = String( data ); 61 | // single line format com.package.example:1.0.0 62 | // single line format com.package.example@1.0.0 63 | this._singleLineOutput = true; 64 | if (line.indexOf( ":" ) > 0) 65 | { 66 | this.identifier = line.substring( 0, line.indexOf( ":" ) ); 67 | this.version = SemVerRange.fromString( line.substring( line.indexOf( ":" ) + 1 ) ); 68 | } 69 | else if (line.indexOf( "@" ) > 0) 70 | { 71 | this.identifier = line.substring( 0, line.indexOf( "@" ) ); 72 | this.version = SemVerRange.fromString( line.substring( line.indexOf( "@" ) + 1 ) ); 73 | } 74 | else 75 | { 76 | this.identifier = line; 77 | this.version = null; 78 | } 79 | } 80 | else 81 | { 82 | if (data.hasOwnProperty( "id" )) this.identifier = data["id"]; 83 | if (data.hasOwnProperty( "version" )) this.version = SemVerRange.fromString( data["version"] ); 84 | if (data.hasOwnProperty( "source" )) this.source = data["source"]; 85 | if (data.hasOwnProperty( "package" )) this.identifier = data["package"].identifier; 86 | if (data.hasOwnProperty( "delayLoad" )) this.delayLoad = data["delayLoad"]; 87 | } 88 | } 89 | return this; 90 | } 91 | 92 | //////////////////////////////////////////////////////// 93 | // EVENT HANDLERS 94 | // 95 | 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/project/processes/ProjectAddProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 16/6/2023 4 | */ 5 | package com.apm.client.commands.project.processes 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.processes.ProcessBase; 9 | import com.apm.data.project.ProjectDefinition; 10 | import com.apm.data.common.Platform; 11 | 12 | public class ProjectAddProcess extends ProcessBase 13 | { 14 | //////////////////////////////////////////////////////// 15 | // CONSTANTS 16 | // 17 | 18 | private static const TAG:String = "PackageSetProcess"; 19 | 20 | 21 | //////////////////////////////////////////////////////// 22 | // VARIABLES 23 | // 24 | 25 | 26 | private var _paramName:String; 27 | private var _paramValue:String; 28 | 29 | 30 | //////////////////////////////////////////////////////// 31 | // FUNCTIONALITY 32 | // 33 | 34 | public function ProjectAddProcess( paramName:String, paramValue:String ) 35 | { 36 | _paramName = paramName; 37 | _paramValue = paramValue; 38 | } 39 | 40 | 41 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 42 | { 43 | super.start( completeCallback, failureCallback ); 44 | 45 | var project:ProjectDefinition = APM.config.projectDefinition; 46 | if (project == null) 47 | { 48 | failure( "No project file found" ); 49 | return; 50 | } 51 | 52 | if (_paramName == null) 53 | { 54 | failure( "No parameter name specified" ); 55 | return; 56 | } 57 | else if (_paramValue == null) 58 | { 59 | var value:String = APM.io.question( "Add", _paramName ); 60 | addProjectValue( project, _paramName, value ) 61 | } 62 | else 63 | { 64 | addProjectValue( project, _paramName, _paramValue ) 65 | } 66 | 67 | project.save(); 68 | complete(); 69 | } 70 | 71 | 72 | private function addProjectValue( project:ProjectDefinition, name:String, value:String ):void 73 | { 74 | switch (_paramName) 75 | { 76 | case "platforms": 77 | { 78 | var platformName:String = value.toLowerCase(); 79 | if (!Platform.isKnownPlatformName(platformName)) 80 | { 81 | APM.io.writeError( name, "Invalid platform name" ); 82 | return; 83 | } 84 | 85 | for each (var platform:Platform in project.platforms) 86 | { 87 | if (platform.name == platformName) 88 | { 89 | APM.io.writeError( name, "This value already exists" ); 90 | return; 91 | } 92 | } 93 | 94 | project.platforms.push( new Platform( platformName, true ) ); 95 | break; 96 | } 97 | default: 98 | { 99 | APM.io.writeError( name, "This parameter is not an array or is invalid" ); 100 | } 101 | } 102 | } 103 | 104 | 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/packages/processes/PackageDependenciesVerifyProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 15/6/2021 4 | */ 5 | package com.apm.client.commands.packages.processes 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.logging.Log; 9 | import com.apm.client.processes.ProcessBase; 10 | import com.apm.client.repositories.PackageResolver; 11 | import com.apm.data.packages.PackageDefinition; 12 | import com.apm.data.packages.PackageDefinitionFile; 13 | import com.apm.data.packages.PackageDependency; 14 | 15 | 16 | /** 17 | * Verifies the dependencies for a package structure in the specified path. 18 | *
19 | * The process will check the dependencies for the package exist in the package repository and fail if not. 20 | */ 21 | public class PackageDependenciesVerifyProcess extends ProcessBase 22 | { 23 | //////////////////////////////////////////////////////// 24 | // CONSTANTS 25 | // 26 | 27 | private static const TAG:String = "PackageDependenciesVerifyProcess"; 28 | 29 | 30 | //////////////////////////////////////////////////////// 31 | // VARIABLES 32 | // 33 | 34 | private var _dependency:PackageDependency; 35 | 36 | 37 | //////////////////////////////////////////////////////// 38 | // FUNCTIONALITY 39 | // 40 | 41 | public function PackageDependenciesVerifyProcess( dependency:PackageDependency ) 42 | { 43 | _dependency = dependency; 44 | } 45 | 46 | 47 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 48 | { 49 | super.start( completeCallback, failureCallback ); 50 | APM.io.showSpinner( "Checking dependency: " + _dependency.toString() ); 51 | 52 | if (_dependency.identifier == null || _dependency.identifier.length == 0 || _dependency.version == null) 53 | { 54 | failure( "INVALID DEPENDENCY [" + _dependency.toString() + "] - check your dependencies in the " + PackageDefinitionFile.DEFAULT_FILENAME ); 55 | } 56 | 57 | PackageResolver.instance.getPackageVersion( 58 | _dependency.identifier, 59 | _dependency.version, 60 | _dependency.source, 61 | null, 62 | function ( success:Boolean, packageDef:PackageDefinition ):void 63 | { 64 | Log.d( TAG, "success: " + success ); 65 | if (success) 66 | { 67 | Log.d( TAG, "package: " + packageDef.toDescriptiveString() ); 68 | } 69 | 70 | if (success && packageDef != null && packageDef.versions.length > 0) 71 | { 72 | APM.io.stopSpinner( true, "VERIFIED: " + _dependency.toString() ); 73 | complete(); 74 | } 75 | else 76 | { 77 | APM.io.stopSpinner( false, "Could not verify: " + _dependency.toString() ); 78 | failure( "INVALID DEPENDENCY [" + _dependency.toString() + "] - check your dependencies in the " + PackageDefinitionFile.DEFAULT_FILENAME ); 79 | } 80 | } 81 | ); 82 | 83 | } 84 | 85 | 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/project/processes/ValidateProjectParametersProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 29/9/2021 4 | */ 5 | package com.apm.client.commands.project.processes 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.logging.Log; 9 | import com.apm.client.processes.ProcessBase; 10 | import com.apm.data.common.Platform; 11 | import com.apm.data.common.PlatformConfiguration; 12 | import com.apm.data.common.PlatformParameter; 13 | import com.apm.data.project.ProjectDefinition; 14 | import com.apm.data.project.ProjectParameter; 15 | 16 | /** 17 | * This process does a quick check that the packages in the project definition 18 | * file are available in the package cache. 19 | */ 20 | public class ValidateProjectParametersProcess extends ProcessBase 21 | { 22 | //////////////////////////////////////////////////////// 23 | // CONSTANTS 24 | // 25 | 26 | private static const TAG:String = "ValidateProjectParametersProcess"; 27 | 28 | 29 | //////////////////////////////////////////////////////// 30 | // VARIABLES 31 | // 32 | 33 | 34 | //////////////////////////////////////////////////////// 35 | // FUNCTIONALITY 36 | // 37 | 38 | public function ValidateProjectParametersProcess() 39 | { 40 | } 41 | 42 | 43 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 44 | { 45 | super.start( completeCallback, failureCallback ); 46 | 47 | Log.d( TAG, "Validating parameters in project definition" ); 48 | 49 | var project:ProjectDefinition = APM.config.projectDefinition; 50 | if (project == null) 51 | { 52 | failure( "No project file found" ); 53 | return; 54 | } 55 | 56 | var isValid:Boolean = true; 57 | for each (var param:ProjectParameter in project.getConfiguration( APM.config.buildType )) 58 | { 59 | if (!param.isValid( project.platforms )) 60 | { 61 | isValid = false; 62 | APM.io.writeError( "validation", "Parameter not valid: " + param.name + "=" + param.value ); 63 | ProjectConfigDescribeProcess.describeParameter( param ); 64 | APM.io.writeLine( "" ); 65 | } 66 | } 67 | 68 | for each (var platform:String in Platform.ALL_PLATFORMS) 69 | { 70 | if (!project.shouldIncludePlatform( platform )) continue; 71 | var platformConfig:PlatformConfiguration = project.getPlatformConfiguration( platform ); 72 | if (platformConfig == null) continue; 73 | for each (var platformParam:PlatformParameter in platformConfig.parameters) 74 | { 75 | if (!platformParam.isValid()) 76 | { 77 | isValid = false; 78 | APM.io.writeError( "validation", "Platform parameter not valid: " + platformParam.name + "=" + platformParam.value ); 79 | APM.io.writeLine( "" ); 80 | } 81 | } 82 | } 83 | 84 | if (!isValid) 85 | { 86 | failure( "Invalid project configuration parameters" ); 87 | return; 88 | } 89 | 90 | complete(); 91 | } 92 | 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/packages/processes/PackageDefinitionLoadProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 15/6/2021 4 | */ 5 | package com.apm.client.commands.packages.processes 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.processes.ProcessBase; 9 | import com.apm.data.packages.PackageDefinitionFile; 10 | 11 | import flash.filesystem.File; 12 | import flash.filesystem.FileMode; 13 | import flash.filesystem.FileStream; 14 | 15 | 16 | /** 17 | * Loads a PackageDefinitionFile from a File reference. 18 | *
19 | * This process is really just for delaying the load until a point in the queue 20 | * (generally when extracting a package from a zip). 21 | */ 22 | public class PackageDefinitionLoadProcess extends ProcessBase 23 | { 24 | //////////////////////////////////////////////////////// 25 | // CONSTANTS 26 | // 27 | 28 | private static const TAG:String = "PackageDefinitionLoadProcess"; 29 | 30 | 31 | //////////////////////////////////////////////////////// 32 | // VARIABLES 33 | // 34 | 35 | private var _packageDefinition:PackageDefinitionFile; 36 | private var _file:File; 37 | 38 | 39 | //////////////////////////////////////////////////////// 40 | // FUNCTIONALITY 41 | // 42 | 43 | public function PackageDefinitionLoadProcess( packageDefinition:PackageDefinitionFile, file:File ) 44 | { 45 | _packageDefinition = packageDefinition; 46 | _file = file; 47 | } 48 | 49 | 50 | override public function start( completeCallback:Function=null, failureCallback:Function=null ):void 51 | { 52 | super.start( completeCallback, failureCallback ); 53 | APM.io.showSpinner( "Loading package definition file: " + _file.nativePath ); 54 | if (!_file.exists) 55 | { 56 | APM.io.stopSpinner( false, "Package definition file doesn't exist: " + _file.nativePath ); 57 | return failure(); 58 | } 59 | 60 | _packageDefinition.load( _file ); 61 | 62 | 63 | // Load README.md if available 64 | var readmeFile:File = _packageDefinition.sourceFile.parent.resolvePath("README.md"); 65 | if (readmeFile.exists) 66 | { 67 | var readmeFileStream:FileStream = new FileStream(); 68 | readmeFileStream.open( readmeFile, FileMode.READ ); 69 | _packageDefinition.readme = readmeFileStream.readUTFBytes( readmeFileStream.bytesAvailable ); 70 | readmeFileStream.close(); 71 | } 72 | 73 | 74 | // Load CHANGELOG.md if available 75 | var changelogFile:File = _packageDefinition.sourceFile.parent.resolvePath("CHANGELOG.md"); 76 | if (changelogFile.exists) 77 | { 78 | var changelogFileStream:FileStream = new FileStream(); 79 | changelogFileStream.open( changelogFile, FileMode.READ ); 80 | _packageDefinition.changelog = changelogFileStream.readUTFBytes( changelogFileStream.bytesAvailable ); 81 | changelogFileStream.close(); 82 | } 83 | 84 | APM.io.stopSpinner( true, "Package definition file loaded" ); 85 | complete(); 86 | } 87 | 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/packages/CreateCommand.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 18/5/2021 4 | */ 5 | package com.apm.client.commands.packages 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.commands.Command; 9 | import com.apm.client.commands.packages.processes.PackageDefinitionCreateProcess; 10 | import com.apm.client.commands.packages.processes.ViewPackageProcess; 11 | import com.apm.client.events.CommandEvent; 12 | import com.apm.client.processes.ProcessQueue; 13 | 14 | import flash.events.EventDispatcher; 15 | 16 | 17 | public class CreateCommand extends EventDispatcher implements Command 18 | { 19 | 20 | //////////////////////////////////////////////////////// 21 | // CONSTANTS 22 | // 23 | 24 | private static const TAG:String = "CreateCommand"; 25 | 26 | public static const NAME:String = "create"; 27 | 28 | 29 | 30 | //////////////////////////////////////////////////////// 31 | // VARIABLES 32 | // 33 | 34 | private var _parameters:Array; 35 | private var _queue:ProcessQueue; 36 | 37 | 38 | //////////////////////////////////////////////////////// 39 | // FUNCTIONALITY 40 | // 41 | 42 | public function CreateCommand() 43 | { 44 | super(); 45 | _queue = new ProcessQueue(); 46 | } 47 | 48 | 49 | public function setParameters( parameters:Array ):void 50 | { 51 | _parameters = parameters; 52 | } 53 | 54 | 55 | public function get name():String 56 | { 57 | return NAME; 58 | } 59 | 60 | 61 | public function get category():String 62 | { 63 | return ""; 64 | } 65 | 66 | 67 | public function get requiresNetwork():Boolean 68 | { 69 | return false; 70 | } 71 | 72 | 73 | public function get requiresProject():Boolean 74 | { 75 | return false; 76 | } 77 | 78 | 79 | public function get description():String 80 | { 81 | return "create a package template for a new package in the repository"; 82 | } 83 | 84 | 85 | public function get usage():String 86 | { 87 | return description + "\n" + 88 | "\n" + 89 | "apm create creates a template package in the current directory\n" + 90 | "apm create creates a template package in the sub-directory\n"; 91 | } 92 | 93 | 94 | public function execute():void 95 | { 96 | var name:String = ""; 97 | if (_parameters != null && _parameters.length > 0) 98 | { 99 | name = _parameters[0]; 100 | } 101 | 102 | _queue.addProcess( new PackageDefinitionCreateProcess( name )); 103 | 104 | _queue.start( 105 | function ():void 106 | { 107 | dispatchEvent( new CommandEvent( CommandEvent.COMPLETE, APM.CODE_OK )); 108 | }, 109 | function ( message:String ):void 110 | { 111 | dispatchEvent( new CommandEvent( CommandEvent.COMPLETE, APM.CODE_ERROR )); 112 | } 113 | ); 114 | } 115 | 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /BUILDING.md: -------------------------------------------------------------------------------- 1 | # Building APM 2 | 3 | Before attempting to modify the code, have a look at the [contributing guidelines](https://github.com/airsdk/apm/blob/efb0b6ab357448dcf3e6cb27b684be6e1ac6dac7/.github/CONTRIBUTING.md). 4 | 5 | APM is built using the AIR SDK. See the documentation at [airsdk.dev](https://airsdk.dev) to setup the AIR SDK on your machine. 6 | 7 | The command line utility output used by `apm` was only introduced recently in AIR so you need to ensure you have at least version 33.1.1.554 of the AIR SDK installed. 8 | 9 | ## AIR IDE 10 | 11 | You can use any AIR IDE to develop this project. The `client` directory is the root of the application source tree. It contains the following key directories: 12 | 13 | - `src`: All actionscript source code for `apm`; 14 | - `libs`: SWC's used by `apm`; 15 | 16 | You should add the src directory as a source code directory and the libs directory as a swc directory to whatever IDE you are using. Set the output to an `out` directory underneath `client` to keep your build inline with the ant script. 17 | 18 | ## Ant 19 | 20 | We have provided an ant build script `build.xml` that can be used to build the project. 21 | 22 | Make a copy of the `build.config.example` file as `build.config` in your checkout. Edit the file and point the `air.sdk` property to the location of the AIR SDK on your machine. eg 23 | 24 | ``` 25 | air.sdk = /Users/marchbold/sdks/air/AIR_33.1.1.554 26 | ``` 27 | 28 | Run the bootstrap command to download the ant contrib utilities used by the build script: 29 | 30 | ``` 31 | ant bootstrap 32 | ``` 33 | 34 | Then you should be able to run ant to build `apm`: 35 | 36 | ``` 37 | ❯ ant 38 | Buildfile: /Users/marchbold/work/distriqt/airsdk/apm/source/build.xml 39 | 40 | version_write: 41 | [copy] Copying 1 file to /Users/marchbold/work/distriqt/airsdk/apm/source/client/src/com/apm/client 42 | 43 | build: 44 | [echo] Building apm... 45 | [mxmlc] Loading configuration: /Users/marchbold/work/sdks/air/current/frameworks/air-config.xml 46 | [mxmlc] 47 | [mxmlc] 48 | [mxmlc] 63502 bytes written to /Users/marchbold/work/distriqt/airsdk/apm/source/client/out/apm.swf in 1.604 seconds 49 | [mxmlc] 50 | [echo] Copying apm scripts... 51 | [copy] Copying 3 files to /Users/marchbold/work/distriqt/airsdk/apm/source/client/out 52 | [echo] done 53 | 54 | BUILD SUCCESSFUL 55 | Total time: 2 seconds 56 | ``` 57 | 58 | The output of this is the `client/out` directory. It should contain 4 files: 59 | 60 | ``` 61 | - apm 62 | - apm.bat 63 | - apm.swf 64 | - apm.xml 65 | ``` 66 | 67 | The first two files are the launch scripts for macOS and Windows respectively. `apm.xml` is the application descriptor for the `apm` utility. 68 | 69 | ## Testing 70 | 71 | In order to test your local build, set the `AIR_TOOLS` environment variable that you would have set during installation of `apm` to point to the `client/out` directory. Or you can just run apm from the `client/out` directory directly. 72 | 73 | Once you set this you should be able to run `apm` in your terminal and reference your locally built version. 74 | -------------------------------------------------------------------------------- /client/src/org/as3commons/zip/ZipEvent.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2012 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.zip 17 | { 18 | import flash.events.Event; 19 | 20 | /** 21 | * Zip dispatches ZipEvent objects when a file contained in the 22 | * ZIP archive has finished loading and can be accessed. There is 23 | * only one type of ZipEvent: ZipErrorEvent.FILE_LOADED. 24 | * 25 | * @author Claus Wahlers 26 | * @author Max Herkender 27 | */ 28 | public class ZipEvent extends Event 29 | { 30 | /** 31 | * The file that has finished loading. 32 | */ 33 | public var file:ZipFile; 34 | 35 | /** 36 | * Defines the value of the type property of a ZipEvent object. 37 | */ 38 | public static const FILE_LOADED:String = "fileLoaded"; 39 | 40 | /** 41 | * Constructor 42 | * 43 | * @param type The type of the event. Event listeners can 44 | * access this information through the inherited type property. 45 | * There is only one type of ZipEvent: 46 | * ZipEvent.PARSE_ERROR. 47 | * 48 | * @param file The file that has finished loading. 49 | * 50 | * @param bubbles Determines whether the Event object participates 51 | * in the bubbling stage of the event flow. Event listeners can 52 | * access this information through the inherited bubbles property. 53 | * 54 | * @param cancelable Determines whether the Event object can be 55 | * canceled. Event listeners can access this information through 56 | * the inherited cancelable property. 57 | */ 58 | public function ZipEvent( type:String, file:ZipFile = null, bubbles:Boolean = false, cancelable:Boolean = false) { 59 | super(type, bubbles, cancelable); 60 | this.file = file; 61 | } 62 | 63 | /** 64 | * Creates a copy of the ZipEvent object and sets the value 65 | * of each property to match that of the original. 66 | * 67 | * @return A new ZipEvent object with property values that 68 | * match those of the original. 69 | */ 70 | override public function clone():Event { 71 | return new ZipEvent(type, file, bubbles, cancelable); 72 | } 73 | 74 | /** 75 | * TODO 76 | * 77 | * @return String 78 | */ 79 | override public function toString():String { 80 | return "[ZipEvent type=\"" + type + "\" filename=\"" + file.filename + "\" bubbles=" + bubbles + " cancelable=" + cancelable + " eventPhase=" + eventPhase + "]"; 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /client/src/com/apm/client/config/processes/LoadWindowsJavaHomeProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 28/5/2021 4 | */ 5 | package com.apm.client.config.processes 6 | { 7 | import com.apm.client.config.RunConfig; 8 | import com.apm.client.logging.Log; 9 | import com.apm.client.processes.ProcessBase; 10 | 11 | import flash.desktop.NativeProcess; 12 | import flash.desktop.NativeProcessStartupInfo; 13 | import flash.events.IOErrorEvent; 14 | import flash.events.NativeProcessExitEvent; 15 | import flash.events.ProgressEvent; 16 | import flash.filesystem.File; 17 | 18 | 19 | public class LoadWindowsJavaHomeProcess extends ProcessBase 20 | { 21 | //////////////////////////////////////////////////////// 22 | // CONSTANTS 23 | // 24 | 25 | private static const TAG:String = "LoadWindowsJavaHomeProcess"; 26 | 27 | 28 | //////////////////////////////////////////////////////// 29 | // VARIABLES 30 | // 31 | 32 | private var _config:RunConfig; 33 | private var _data:String = ""; 34 | 35 | 36 | //////////////////////////////////////////////////////// 37 | // FUNCTIONALITY 38 | // 39 | 40 | public function LoadWindowsJavaHomeProcess( config:RunConfig ) 41 | { 42 | _config = config; 43 | } 44 | 45 | 46 | private function isJavaHomeValid():Boolean 47 | { 48 | try 49 | { 50 | if (_config.env[ "JAVA_HOME" ] == null) return false; 51 | if (_config.getJava().exists) 52 | return true; 53 | } 54 | catch (e:Error) 55 | { 56 | } 57 | return false; 58 | } 59 | 60 | 61 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 62 | { 63 | super.start( completeCallback, failureCallback ); 64 | Log.d( TAG, "start()" ); 65 | 66 | if (!isJavaHomeValid()) 67 | { 68 | var javaBinPath:String = "bin\\java.exe"; 69 | var javaHome:String = null; 70 | 71 | // Try to locate a java install 72 | // Normally have a directory "Java/jdkx.x.x_x" 73 | // - so iterate over subdirectories checking for the java exe 74 | 75 | var javaDirectoryCandidates:Array = [ 76 | new File( "C:\\Program Files\\Java" ), 77 | new File( "C:\\Program Files (x86)\\Java" ) 78 | ]; 79 | 80 | for each (var candidate:File in javaDirectoryCandidates) 81 | { 82 | if (candidate.exists && candidate.getDirectoryListing().length > 0) 83 | { 84 | for each (var javaCandidate:File in candidate.getDirectoryListing()) 85 | { 86 | if (javaCandidate.resolvePath( javaBinPath ).exists) 87 | { 88 | javaHome = javaCandidate.nativePath; 89 | break; 90 | } 91 | } 92 | } 93 | } 94 | 95 | if (javaHome != null) 96 | { 97 | _config.env[ "JAVA_HOME" ] = javaHome; 98 | } 99 | complete(); 100 | 101 | 102 | } 103 | else 104 | { 105 | complete(); 106 | } 107 | } 108 | 109 | 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/airsdk/AIRSDKListCommand.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 18/5/2021 4 | */ 5 | package com.apm.client.commands.airsdk 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.commands.Command; 9 | import com.apm.client.events.CommandEvent; 10 | import com.apm.remote.airsdk.AIRSDKAPI; 11 | import com.apm.remote.airsdk.AIRSDKBuild; 12 | 13 | import flash.events.EventDispatcher; 14 | 15 | import flash.globalization.DateTimeFormatter; 16 | 17 | 18 | public class AIRSDKListCommand extends EventDispatcher implements Command 19 | { 20 | 21 | //////////////////////////////////////////////////////// 22 | // CONSTANTS 23 | // 24 | 25 | private static const TAG:String = "AIRSDKListCommand"; 26 | 27 | 28 | public static const NAME:String = "airsdk/list"; 29 | 30 | 31 | //////////////////////////////////////////////////////// 32 | // VARIABLES 33 | // 34 | 35 | private var _parameters:Array; 36 | 37 | private var _airsdkAPI:AIRSDKAPI; 38 | 39 | 40 | //////////////////////////////////////////////////////// 41 | // FUNCTIONALITY 42 | // 43 | 44 | public function AIRSDKListCommand() 45 | { 46 | super(); 47 | 48 | _airsdkAPI = new AIRSDKAPI(); 49 | } 50 | 51 | 52 | public function setParameters( parameters:Array ):void 53 | { 54 | _parameters = parameters; 55 | } 56 | 57 | 58 | public function get name():String 59 | { 60 | return NAME; 61 | } 62 | 63 | 64 | public function get category():String 65 | { 66 | return ""; 67 | } 68 | 69 | 70 | public function get requiresNetwork():Boolean 71 | { 72 | return true; 73 | } 74 | 75 | 76 | public function get requiresProject():Boolean 77 | { 78 | return false; 79 | } 80 | 81 | 82 | public function get description():String 83 | { 84 | return "lists available AIR SDK versions"; 85 | } 86 | 87 | 88 | public function get usage():String 89 | { 90 | return description + "\n" + 91 | "\n" + 92 | "apm airsdk list lists available AIR SDK versions\n" 93 | } 94 | 95 | 96 | public function execute():void 97 | { 98 | APM.io.showSpinner( "Retrieving AIR SDK list" ); 99 | 100 | _airsdkAPI.getReleases( function ( success:Boolean, builds:Array, message:String ):void { 101 | if (success) 102 | { 103 | APM.io.stopSpinner( true, "Downloaded AIR SDK list" ); 104 | 105 | var dtf:DateTimeFormatter = new DateTimeFormatter( "en-US" ); 106 | dtf.setDateTimePattern( "yyyy-MM-dd" ); 107 | for each (var build:AIRSDKBuild in builds) 108 | { 109 | APM.io.writeLine( " - " + build.version + "[" + dtf.format( build.releaseDate ) + "]" ); 110 | } 111 | } 112 | else 113 | { 114 | APM.io.stopSpinner( false, "ERROR: Could not get list" ); 115 | } 116 | dispatchEvent( new CommandEvent( CommandEvent.COMPLETE, APM.CODE_OK )); 117 | } ); 118 | 119 | } 120 | 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/packages/processes/UninstallConfigForPackageProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 15/6/2021 4 | */ 5 | package com.apm.client.commands.packages.processes 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.data.packages.PackageIdentifier; 9 | import com.apm.data.packages.PackageParameter; 10 | import com.apm.utils.DeployFileUtils; 11 | import com.apm.utils.FileUtils; 12 | import com.apm.utils.PackageFileUtils; 13 | import com.apm.client.logging.Log; 14 | import com.apm.client.processes.ProcessBase; 15 | import com.apm.data.packages.PackageDefinitionFile; 16 | import com.apm.utils.ProjectPackageCache; 17 | 18 | import flash.filesystem.File; 19 | import flash.html.script.Package; 20 | 21 | 22 | /** 23 | * This process removes any unused project config params associated with an AIR package 24 | * - it does not remove any related dependencies 25 | * - it only removes config params that isn't related to other packages 26 | */ 27 | public class UninstallConfigForPackageProcess extends ProcessBase 28 | { 29 | //////////////////////////////////////////////////////// 30 | // CONSTANTS 31 | // 32 | 33 | private static const TAG:String = "UninstallConfigForPackageProcess"; 34 | 35 | 36 | //////////////////////////////////////////////////////// 37 | // VARIABLES 38 | // 39 | 40 | private var _packageDefinition:PackageDefinitionFile; 41 | 42 | 43 | //////////////////////////////////////////////////////// 44 | // FUNCTIONALITY 45 | // 46 | 47 | public function UninstallConfigForPackageProcess( packageDefinition:PackageDefinitionFile ) 48 | { 49 | super(); 50 | _packageDefinition = packageDefinition; 51 | } 52 | 53 | 54 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 55 | { 56 | super.start( completeCallback, failureCallback ); 57 | APM.io.showSpinner( "Removing config for package : " + _packageDefinition.packageDef.identifier ); 58 | 59 | var paramsToRemove:Vector. = new Vector.(); 60 | 61 | var packages:Vector. = ProjectPackageCache.getPackages(); 62 | for each (var param:PackageParameter in _packageDefinition.version.parameters) 63 | { 64 | var shouldRemove:Boolean = true; 65 | for each (var packageDef:PackageDefinitionFile in packages) 66 | { 67 | if (packageDef.packageDef.equals( _packageDefinition.packageDef )) continue; 68 | for each (var packageParam:PackageParameter in packageDef.version.parameters) 69 | { 70 | if (packageParam.name == param.name) shouldRemove = false; 71 | } 72 | } 73 | 74 | if (shouldRemove) paramsToRemove.push( param ); 75 | } 76 | 77 | for each (var removeParam:PackageParameter in paramsToRemove) 78 | { 79 | APM.config.projectDefinition.removePackageParameter( removeParam.name ); 80 | } 81 | 82 | APM.io.stopSpinner( true, "Removed config for package : " + _packageDefinition.packageDef.identifier ); 83 | complete(); 84 | } 85 | 86 | 87 | 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /client/src/org/as3commons/lang/builder/ToStringStyle.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.lang.builder { 17 | 18 | import flash.utils.getQualifiedClassName; 19 | 20 | import org.as3commons.lang.ObjectUtils; 21 | import org.as3commons.lang.StringBuffer; 22 | 23 | /** 24 | * @author Christophe Herreman 25 | */ 26 | public class ToStringStyle { 27 | 28 | public static const DEFAULT_STYLE:ToStringStyle = new ToStringStyle(); 29 | 30 | public var useShortClassName:Boolean = true; 31 | 32 | public var contentBegin:String = "["; 33 | 34 | public var contentEnd:String = "]"; 35 | 36 | public var fieldSeparator:String = ","; 37 | 38 | public var fieldNameValueSeparator:String = "="; 39 | 40 | /** 41 | * 42 | */ 43 | public function ToStringStyle() { 44 | } 45 | 46 | /** 47 | * 48 | */ 49 | public function appendBegin(buffer:StringBuffer, object:Object):ToStringStyle { 50 | appendClassName(buffer, object); 51 | appendContentBegin(buffer); 52 | return this; 53 | } 54 | 55 | /** 56 | * 57 | */ 58 | public function append(buffer:StringBuffer, object:Object, value:Object, fieldName:String):ToStringStyle { 59 | if (fieldName) { 60 | buffer.append(fieldName + fieldNameValueSeparator + value + fieldSeparator); 61 | } else { 62 | buffer.append(value + fieldSeparator); 63 | } 64 | 65 | return this; 66 | } 67 | 68 | /** 69 | * 70 | */ 71 | public function appendEnd(buffer:StringBuffer):ToStringStyle { 72 | // remove the last field separator 73 | var string:String = buffer.toString(); 74 | 75 | if (buffer.toString().lastIndexOf(fieldSeparator) == (string.length - 1)) { 76 | buffer.removeEnd(fieldSeparator); 77 | } 78 | 79 | appendContentEnd(buffer); 80 | 81 | return this; 82 | } 83 | 84 | private function appendContentBegin(buffer:StringBuffer):ToStringStyle { 85 | buffer.append(contentBegin); 86 | return this; 87 | } 88 | 89 | private function appendContentEnd(buffer:StringBuffer):ToStringStyle { 90 | buffer.append(contentEnd); 91 | return this; 92 | } 93 | 94 | private function appendClassName(buffer:StringBuffer, object:Object):ToStringStyle { 95 | if (useShortClassName) { 96 | buffer.append(ObjectUtils.getClassName(object)); 97 | } else { 98 | buffer.append(getQualifiedClassName(object)); 99 | } 100 | return this; 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/project/processes/GenerateConfigIOSProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 29/9/2021 4 | */ 5 | package com.apm.client.commands.project.processes 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.logging.Log; 9 | import com.apm.client.processes.ProcessBase; 10 | 11 | import flash.filesystem.File; 12 | import flash.filesystem.FileMode; 13 | import flash.filesystem.FileStream; 14 | import flash.utils.ByteArray; 15 | 16 | 17 | /** 18 | * Generates an InfoAdditions.xml and Entitlements.xml file in the configuration directory 19 | * for the current project. 20 | */ 21 | public class GenerateConfigIOSProcess extends ProcessBase 22 | { 23 | //////////////////////////////////////////////////////// 24 | // CONSTANTS 25 | // 26 | 27 | private static const TAG:String = "GenerateConfigIOSProcess"; 28 | 29 | [Embed(source="data/InfoAdditionsDefault.xml",mimeType="application/octet-stream")] 30 | private var InfoAdditionsDefault:Class; 31 | 32 | [Embed(source="data/EntitlementsDefault.xml",mimeType="application/octet-stream")] 33 | private var EntitlementsDefault:Class; 34 | 35 | private var INFO_ADDITIONS_DEFAULT:String = (new InfoAdditionsDefault() as ByteArray).toString(); 36 | 37 | private var ENTITLEMENTS_DEFAULT:String = (new EntitlementsDefault() as ByteArray).toString(); 38 | 39 | 40 | //////////////////////////////////////////////////////// 41 | // VARIABLES 42 | // 43 | 44 | 45 | //////////////////////////////////////////////////////// 46 | // FUNCTIONALITY 47 | // 48 | 49 | public function GenerateConfigIOSProcess() 50 | { 51 | } 52 | 53 | 54 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 55 | { 56 | super.start( completeCallback, failureCallback ); 57 | 58 | Log.d( TAG, "Generating default iOS configuration" ); 59 | 60 | var configInfoAdditions:File = new File( APM.config.configDirectory ).resolvePath( "ios/InfoAdditions.xml" ); 61 | if (configInfoAdditions.exists) 62 | { 63 | APM.io.writeResult( false, "Config InfoAdditions.xml already exists" ); 64 | } 65 | else 66 | { 67 | writeContentToFile( INFO_ADDITIONS_DEFAULT, configInfoAdditions ); 68 | APM.io.writeResult( true, "Generated: " + configInfoAdditions.nativePath ); 69 | } 70 | 71 | var configEntitlements:File = new File( APM.config.configDirectory ).resolvePath( "ios/Entitlements.xml" ); 72 | if (configEntitlements.exists) 73 | { 74 | APM.io.writeResult( false, "Config Entitlements.xml already exists" ); 75 | } 76 | else 77 | { 78 | writeContentToFile( ENTITLEMENTS_DEFAULT, configEntitlements ); 79 | APM.io.writeResult( true, "Generated: " + configEntitlements.nativePath ); 80 | } 81 | 82 | complete(); 83 | } 84 | 85 | 86 | private function writeContentToFile( content:String, file:File ):void 87 | { 88 | var fs:FileStream = new FileStream(); 89 | fs.open( file, FileMode.WRITE ); 90 | fs.writeUTFBytes( content ); 91 | fs.close(); 92 | } 93 | 94 | 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /client/src/com/apm/utils/DeployFileUtils.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 13/7/2021 4 | */ 5 | package com.apm.utils 6 | { 7 | import com.apm.client.commands.packages.utils.*; 8 | import com.apm.client.config.RunConfig; 9 | 10 | import flash.filesystem.File; 11 | 12 | 13 | public class DeployFileUtils 14 | { 15 | //////////////////////////////////////////////////////// 16 | // CONSTANTS 17 | // 18 | 19 | private static const TAG:String = "DeployFileUtils"; 20 | 21 | 22 | //////////////////////////////////////////////////////// 23 | // VARIABLES 24 | // 25 | 26 | 27 | //////////////////////////////////////////////////////// 28 | // FUNCTIONALITY 29 | // 30 | 31 | public function DeployFileUtils() 32 | { 33 | } 34 | 35 | 36 | public static const DEPLOY_OPTIONS:Object = {}; 37 | 38 | { 39 | DEPLOY_OPTIONS[ PackageFileUtils.AIRPACKAGE_ANE_DIR ] = "aneDir"; 40 | DEPLOY_OPTIONS[ PackageFileUtils.AIRPACKAGE_SWC_DIR ] = "swcDir"; 41 | DEPLOY_OPTIONS[ PackageFileUtils.AIRPACKAGE_SRC_DIR ] = "srcDir"; 42 | DEPLOY_OPTIONS[ PackageFileUtils.AIRPACKAGE_ASSETS ] = "assetsDir"; 43 | DEPLOY_OPTIONS[ ProjectPackageCache.PACKAGE_CACHE_DIR ] = "packageCacheDir"; 44 | DEPLOY_OPTIONS[ "config" ] = "configDir"; 45 | } 46 | 47 | 48 | public static const DEFAULT_DIRS:Object = {}; 49 | 50 | { 51 | DEFAULT_DIRS[ PackageFileUtils.AIRPACKAGE_ANE_DIR ] = "ane"; 52 | DEFAULT_DIRS[ PackageFileUtils.AIRPACKAGE_SWC_DIR ] = "libs"; 53 | DEFAULT_DIRS[ PackageFileUtils.AIRPACKAGE_SRC_DIR ] = "libs_src"; 54 | DEFAULT_DIRS[ PackageFileUtils.AIRPACKAGE_ASSETS ] = "assets"; 55 | DEFAULT_DIRS[ ProjectPackageCache.PACKAGE_CACHE_DIR ] = ProjectPackageCache.PACKAGE_CACHE_DIR; 56 | DEFAULT_DIRS[ "config" ] = "config"; 57 | } 58 | 59 | 60 | public static function getDeployLocation( config:RunConfig, dirName:String ):File 61 | { 62 | var deployDirForType:File; 63 | var working:File = new File( config.workingDirectory ); 64 | var option:String = DEPLOY_OPTIONS.hasOwnProperty( dirName ) ? DEPLOY_OPTIONS[ dirName ] : dirName; 65 | if (config.projectDefinition != null && config.projectDefinition.deployOptions.hasOwnProperty( option )) 66 | { 67 | var deployPathForType:String = config.projectDefinition.deployOptions[ option ]; 68 | deployDirForType = FileUtils.getSourceForPath( deployPathForType ); 69 | } 70 | else 71 | { 72 | switch (dirName) 73 | { 74 | case PackageFileUtils.AIRPACKAGE_ANE_DIR: 75 | case PackageFileUtils.AIRPACKAGE_SWC_DIR: 76 | case PackageFileUtils.AIRPACKAGE_SRC_DIR: 77 | case PackageFileUtils.AIRPACKAGE_ASSETS: 78 | case ProjectPackageCache.PACKAGE_CACHE_DIR: 79 | case "config": 80 | deployDirForType = working.resolvePath( DEFAULT_DIRS[ dirName ] ); 81 | break; 82 | 83 | case PackageFileUtils.AIRPACKAGE_PLATFORMS: // Should not be deployed 84 | default: 85 | return null; 86 | } 87 | } 88 | if (!deployDirForType.exists) deployDirForType.createDirectory(); 89 | return deployDirForType; 90 | } 91 | 92 | 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /client/src/com/apm/data/packages/PackageIdentifier.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 13/8/2021 4 | */ 5 | package com.apm.data.packages 6 | { 7 | 8 | 9 | /** 10 | * Utilities for comparing package identifiers 11 | */ 12 | public class PackageIdentifier 13 | { 14 | //////////////////////////////////////////////////////// 15 | // CONSTANTS 16 | // 17 | 18 | private static const TAG:String = "PackageIdentifier"; 19 | 20 | 21 | //////////////////////////////////////////////////////// 22 | // VARIABLES 23 | // 24 | 25 | 26 | //////////////////////////////////////////////////////// 27 | // FUNCTIONALITY 28 | // 29 | 30 | public function PackageIdentifier() 31 | { 32 | } 33 | 34 | 35 | /** 36 | * Checks whether 2 package identifiers are equivalent. 37 | *
38 | * This takes into account variants of packages so "com.package" and "com.package-variant" will 39 | * return true as being the same package. 40 | * 41 | * @param identifierA Package identifier of the first package 42 | * @param identifierB Package identifier of the second package 43 | * 44 | * @return true if the packages are considered equivalent, ie same package or variant of the package 45 | */ 46 | public static function isEquivalent( identifierA:String, identifierB:String ):Boolean 47 | { 48 | if (identifierA == null || identifierB == null) return false; 49 | if (identifierA.toLowerCase() == identifierB.toLowerCase()) return true; 50 | return identifierWithoutVariant( identifierA ).toLowerCase() == 51 | identifierWithoutVariant( identifierB ).toLowerCase(); 52 | } 53 | 54 | 55 | /** 56 | * Removes the "variant" from a package identifier and returns the identifier 57 | * 58 | * @param identifier The complete package identifier 59 | * 60 | * @return The package identifier with no variant 61 | */ 62 | public static function identifierWithoutVariant( identifier:String ):String 63 | { 64 | if (identifier.indexOf( "-" ) > 0) 65 | { 66 | return identifier.substring( 0, identifier.indexOf( "-" ) ); 67 | } 68 | return identifier; 69 | } 70 | 71 | 72 | /** 73 | * Returns the "variant" from the package identifier 74 | * 75 | * @param identifier The complete package identifier 76 | * 77 | * @return 78 | */ 79 | public static function variantFromIdentifier( identifier:String ):String 80 | { 81 | if (identifier.indexOf( "-" ) > 0) 82 | { 83 | return identifier.substring( identifier.indexOf( "-" ) + 1 ); 84 | } 85 | return ""; 86 | } 87 | 88 | 89 | /** 90 | * Checks the identifier is valid 91 | * 92 | * @param identifier The complete package identifier 93 | * 94 | * @return 95 | */ 96 | public static function isValid( identifier:String ):Boolean 97 | { 98 | var pattern:RegExp = /^([A-Za-z]{1}[A-Za-z\d_]*\.)*[A-Za-z][A-Za-z\d_]*$/i; 99 | 100 | var result:Object = pattern.exec( identifierWithoutVariant( identifier ) ); 101 | return result != null; 102 | } 103 | 104 | 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/packages/processes/InstallLocalPackageProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 15/6/2021 4 | */ 5 | package com.apm.client.commands.packages.processes 6 | { 7 | import com.apm.client.processes.ProcessBase; 8 | import com.apm.client.processes.ProcessQueue; 9 | import com.apm.data.install.InstallData; 10 | import com.apm.data.install.InstallRequest; 11 | import com.apm.data.packages.PackageDefinitionFile; 12 | import com.apm.data.packages.PackageDependency; 13 | 14 | import flash.filesystem.File; 15 | 16 | /** 17 | * This process is to request the package and assemble the listed dependencies 18 | */ 19 | public class InstallLocalPackageProcess extends ProcessBase 20 | { 21 | //////////////////////////////////////////////////////// 22 | // CONSTANTS 23 | // 24 | 25 | private static const TAG:String = "InstallQueryPackageProcess"; 26 | 27 | 28 | //////////////////////////////////////////////////////// 29 | // VARIABLES 30 | // 31 | 32 | private var _packageFile:File; 33 | private var _installData:InstallData; 34 | private var _failIfInstalled:Boolean; 35 | 36 | 37 | //////////////////////////////////////////////////////// 38 | // FUNCTIONALITY 39 | // 40 | 41 | public function InstallLocalPackageProcess( 42 | packageFile:File, 43 | data:InstallData, 44 | failIfInstalled:Boolean = true ) 45 | { 46 | super(); 47 | _packageFile = packageFile; 48 | _installData = data; 49 | _failIfInstalled = failIfInstalled; 50 | } 51 | 52 | 53 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 54 | { 55 | super.start( completeCallback, failureCallback ); 56 | 57 | var packageDefinitionFile:PackageDefinitionFile = new PackageDefinitionFile(); 58 | var packageDir:File = new File(); 59 | 60 | var subqueue:ProcessQueue = new ProcessQueue(); 61 | subqueue.addProcess( new PackageExtractDefinitionProcess( packageDefinitionFile, _packageFile ) ); 62 | subqueue.start( 63 | function ():void 64 | { 65 | var request:InstallRequest = new InstallRequest( 66 | packageDefinitionFile.packageDef.identifier, 67 | packageDefinitionFile.version.version.toString(), 68 | "file", 69 | null, 70 | true, 71 | _packageFile 72 | ); 73 | 74 | _installData.request = request; 75 | _installData.addPackage( packageDefinitionFile.version, request ); 76 | 77 | // Queue dependencies for install 78 | for each (var dep:PackageDependency in packageDefinitionFile.dependencies) 79 | { 80 | _queue.addProcess( 81 | new InstallQueryPackageProcess( 82 | _installData, 83 | new InstallRequest( 84 | dep.identifier, 85 | dep.version.toString(), 86 | dep.source, 87 | packageDefinitionFile.version ) 88 | ) ); 89 | } 90 | complete(); 91 | }, 92 | function ( error:String ):void 93 | { 94 | failure( error ); 95 | } 96 | ) 97 | 98 | } 99 | 100 | 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /client/src/org/as3commons/zip/utils/ChecksumUtil.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2012 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.as3commons.zip.utils { 17 | import flash.utils.ByteArray; 18 | 19 | /** 20 | * @author Claus Wahlers 21 | * @author Max Herkender 22 | */ 23 | public final class ChecksumUtil { 24 | /** 25 | * @private 26 | */ 27 | private static var crcTable:Array = makeCRCTable(); 28 | 29 | /** 30 | * @private 31 | */ 32 | private static function makeCRCTable():Array { 33 | var table:Array = []; 34 | var i:uint; 35 | var j:uint; 36 | var c:uint; 37 | for (i = 0; i < 256; i++) { 38 | c = i; 39 | for (j = 0; j < 8; j++) { 40 | if (c & 1) { 41 | c = 0xEDB88320 ^ (c >>> 1); 42 | } else { 43 | c >>>= 1; 44 | } 45 | } 46 | table.push(c); 47 | } 48 | return table; 49 | } 50 | 51 | /** 52 | * Calculates a CRC-32 checksum over a ByteArray 53 | * 54 | * @see http://www.w3.org/TR/PNG/#D-CRCAppendix 55 | * 56 | * @param data 57 | * @param len 58 | * @param start 59 | * @return CRC-32 checksum 60 | */ 61 | public static function CRC32(data:ByteArray, start:uint=0, len:uint=0):uint { 62 | if (start >= data.length) { 63 | start = data.length; 64 | } 65 | if (len == 0) { 66 | len = data.length - start; 67 | } 68 | if (len + start > data.length) { 69 | len = data.length - start; 70 | } 71 | var i:uint; 72 | var c:uint = 0xffffffff; 73 | for (i = start; i < len; i++) { 74 | c = uint(crcTable[(c ^ data[i]) & 0xff]) ^ (c >>> 8); 75 | } 76 | return (c ^ 0xffffffff); 77 | } 78 | 79 | /** 80 | * Calculates an Adler-32 checksum over a ByteArray 81 | * 82 | * @see http://en.wikipedia.org/wiki/Adler-32#Example_implementation 83 | * 84 | * @param data 85 | * @param len 86 | * @param start 87 | * @return Adler-32 checksum 88 | */ 89 | public static function Adler32(data:ByteArray, start:uint=0, len:uint=0):uint { 90 | if (start >= data.length) { 91 | start = data.length; 92 | } 93 | if (len == 0) { 94 | len = data.length - start; 95 | } 96 | if (len + start > data.length) { 97 | len = data.length - start; 98 | } 99 | var i:uint = start; 100 | var a:uint = 1; 101 | var b:uint = 0; 102 | while (i < (start + len)) { 103 | a = (a + data[i]) % 65521; 104 | b = (a + b) % 65521; 105 | i++; 106 | } 107 | return (b << 16) | a; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /client/src/com/apm/SemVerRange.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 4/6/2021 4 | */ 5 | package com.apm 6 | { 7 | 8 | public class SemVerRange extends SemVer 9 | { 10 | //////////////////////////////////////////////////////// 11 | // CONSTANTS 12 | // 13 | 14 | private static const TAG:String = "SemVer"; 15 | 16 | // public static const DEFAULT:SemVer = new SemVer( "0.0.0" ); 17 | 18 | private var FORMAT:RegExp = /^([x0-9]*)(\.([x0-9]*))?(\.([x0-9]*))?(-(alpha|beta|rc)(\.(\d|[1-9]\d*))?)?$/; 19 | 20 | 21 | //////////////////////////////////////////////////////// 22 | // VARIABLES 23 | // 24 | 25 | 26 | //////////////////////////////////////////////////////// 27 | // FUNCTIONALITY 28 | // 29 | 30 | public function SemVerRange( version:String ) 31 | { 32 | super( version, FORMAT ); 33 | } 34 | 35 | 36 | public static function fromString( version:String ):SemVerRange 37 | { 38 | try 39 | { 40 | if (version != null) 41 | { 42 | return new SemVerRange( version ); 43 | } 44 | } 45 | catch (e:Error) 46 | { 47 | } 48 | return null; 49 | } 50 | 51 | 52 | /** 53 | * Returns true if this instance represents a range of potential versions. 54 | *
55 | * This is true if the version contains an "x" 56 | * 57 | * @return 58 | */ 59 | public function isRange():Boolean 60 | { 61 | return _major == "x" || _minor == "x" || _patch == "x"; 62 | } 63 | 64 | 65 | override public function toString():String 66 | { 67 | return _major + "." + _minor + "." + _patch + 68 | ( 69 | (_preview == null) ? "" : ("-" + _preview + 70 | (_previewNum == 0 ? "" : ("." + _previewNum))) 71 | ) 72 | ; 73 | } 74 | 75 | 76 | // 77 | // Comparisons 78 | // 79 | 80 | override public function equals( v:SemVer ):Boolean 81 | { 82 | if (v == null) return false; 83 | 84 | if (major == v.major 85 | && minor == v.minor 86 | && patch == v.patch) 87 | { 88 | return true; 89 | } 90 | 91 | // TODO preview info 92 | return false; 93 | } 94 | 95 | 96 | override public function greaterThanOrEqual( v:SemVer ):Boolean 97 | { 98 | if (equals( v )) return true; 99 | return greaterThan( v ); 100 | } 101 | 102 | 103 | override public function greaterThan( v:SemVer ):Boolean 104 | { 105 | if (equals( v )) return false; 106 | if (major > v.major) 107 | { 108 | return true; 109 | } 110 | else if (major == v.major) 111 | { 112 | if (minor > v.minor) 113 | { 114 | return true; 115 | } 116 | else if (minor == v.minor) 117 | { 118 | if (patch > v.patch) return true; 119 | // TODO preview info ... 120 | } 121 | } 122 | return false; 123 | } 124 | 125 | 126 | override public function lessThan( v:SemVer ):Boolean 127 | { 128 | return !greaterThanOrEqual( v ); 129 | } 130 | 131 | 132 | override public function lessThanOrEqual( v:SemVer ):Boolean 133 | { 134 | if (equals( v )) return true; 135 | return lessThan( v ); 136 | } 137 | 138 | 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /client/src/com/apm/remote/lib/APIRequestQueue.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 7/12/16 4 | */ 5 | package com.apm.remote.lib 6 | { 7 | import com.apm.remote.lib.events.APIRequestEvent; 8 | 9 | import flash.events.EventDispatcher; 10 | import flash.net.URLRequest; 11 | import flash.utils.setTimeout; 12 | 13 | 14 | public class APIRequestQueue extends EventDispatcher 15 | { 16 | //////////////////////////////////////////////////////// 17 | // CONSTANTS 18 | // 19 | 20 | public static const TAG : String = "APIRequestQueue"; 21 | 22 | 23 | //////////////////////////////////////////////////////// 24 | // VARIABLES 25 | // 26 | 27 | private var _queue : Vector.; 28 | 29 | private var _currentRequest : APIRequest; 30 | 31 | 32 | //////////////////////////////////////////////////////// 33 | // FUNCTIONALITY 34 | // 35 | 36 | public function APIRequestQueue() 37 | { 38 | _queue = new Vector.(); 39 | } 40 | 41 | 42 | public function add( request:URLRequest, id:String, callback:Function=null, maxAttempts:int=2 ):void 43 | { 44 | _queue.push( new APIRequest( request, id, callback, maxAttempts ) ); 45 | checkQueue(); 46 | } 47 | 48 | 49 | private function checkQueue():void 50 | { 51 | if (_queue.length > 0) 52 | { 53 | if (_currentRequest == null) 54 | { 55 | _currentRequest = _queue.shift(); 56 | _currentRequest.addEventListener( APIRequestEvent.COMPLETE, request_completeHandler ); 57 | _currentRequest.addEventListener( APIRequestEvent.STATUS, request_statusHandler ); 58 | _currentRequest.addEventListener( APIRequestEvent.ERROR, request_errorHandler ); 59 | _currentRequest.start(); 60 | } 61 | } 62 | } 63 | 64 | 65 | private function completeRequest():void 66 | { 67 | var request:APIRequest = _currentRequest; 68 | if (request != null) 69 | { 70 | request.dispose(); 71 | request.removeEventListener( APIRequestEvent.COMPLETE, request_completeHandler ); 72 | request.removeEventListener( APIRequestEvent.STATUS, request_statusHandler ); 73 | request.removeEventListener( APIRequestEvent.ERROR, request_errorHandler ); 74 | } 75 | _currentRequest = null; 76 | 77 | checkQueue(); 78 | 79 | if (request != null) 80 | { 81 | request.triggerCallback(); 82 | } 83 | } 84 | 85 | 86 | 87 | //////////////////////////////////////////////////////// 88 | // EVENT HANDLERS 89 | // 90 | 91 | private function request_completeHandler( event:APIRequestEvent ):void 92 | { 93 | dispatchEvent( event.clone() ); 94 | completeRequest(); 95 | } 96 | 97 | 98 | private function request_statusHandler( event:APIRequestEvent ):void 99 | { 100 | dispatchEvent( event.clone() ); 101 | } 102 | 103 | 104 | private function request_errorHandler( event:APIRequestEvent ):void 105 | { 106 | if (_currentRequest.attemptCount < _currentRequest.maxAttempts) 107 | { 108 | setTimeout( function():void { 109 | _currentRequest.start(); 110 | }, 500 * _currentRequest.attemptCount ); 111 | } 112 | else 113 | { 114 | dispatchEvent( event.clone() ); 115 | completeRequest(); 116 | } 117 | } 118 | 119 | 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /client/src/airsdk/AIRSDKVersion.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 28/8/2021 4 | */ 5 | package airsdk 6 | { 7 | import com.apm.utils.FileUtils; 8 | 9 | import flash.filesystem.File; 10 | 11 | 12 | /** 13 | * Specialised SemVer style version handler for the AIR SDK with 4 version numbers (XX.Y.Z.BBB) 14 | */ 15 | public class AIRSDKVersion 16 | { 17 | //////////////////////////////////////////////////////// 18 | // CONSTANTS 19 | // 20 | 21 | private static const TAG:String = "AIRSDKVersion"; 22 | 23 | private var FORMAT:RegExp = /^(\d|[0-9]\d*)\.(\d|[0-9]\d*)\.(\d|[0-9]\d*)\.(\d|[0-9]\d*)?$/; 24 | 25 | 26 | //////////////////////////////////////////////////////// 27 | // VARIABLES 28 | // 29 | 30 | private var _major:int = 0; 31 | private var _minor:int = 0; 32 | private var _patch:int = 0; 33 | private var _build:int = 0; 34 | 35 | 36 | public function get major():int { return _major; } 37 | 38 | 39 | public function get minor():int { return _minor; } 40 | 41 | 42 | public function get patch():int { return _patch; } 43 | 44 | 45 | public function get build():int { return _build; } 46 | 47 | 48 | //////////////////////////////////////////////////////// 49 | // FUNCTIONALITY 50 | // 51 | 52 | public function AIRSDKVersion( version:String ) 53 | { 54 | var results:Array = FORMAT.exec( version ); 55 | if (results != null) 56 | { 57 | for (var i:int = 0; i < results.length; i++) 58 | { 59 | switch (i) 60 | { 61 | case 1: 62 | _major = results[ i ]; 63 | break; 64 | case 2: 65 | _minor = results[ i ]; 66 | break; 67 | case 3: 68 | if (results[ i ] != undefined) _patch = results[ i ]; 69 | break; 70 | case 4: 71 | if (results[ i ] != undefined) _build = results[ i ]; 72 | break; 73 | } 74 | } 75 | } 76 | else 77 | { 78 | throw new Error( "Invalid AIR SDK version format" ) 79 | } 80 | } 81 | 82 | 83 | public static function fromString( version:String ):AIRSDKVersion 84 | { 85 | try 86 | { 87 | if (version != null) 88 | { 89 | return new AIRSDKVersion( version ); 90 | } 91 | } 92 | catch (e:Error) 93 | { 94 | } 95 | return null; 96 | } 97 | 98 | 99 | public function toString():String 100 | { 101 | return _major + "." + _minor + "." + _patch + "." + _build; 102 | } 103 | 104 | 105 | public function getNamespace():String 106 | { 107 | return "http://ns.adobe.com/air/application/" + _major + "." + _minor; 108 | } 109 | 110 | 111 | public static function fromAIRSDKDescription( file:File ):AIRSDKVersion 112 | { 113 | try 114 | { 115 | if (file.exists) 116 | { 117 | var airSDKDescriptionString:String = FileUtils.readFileContentAsString( file ); 118 | var airSDKDescription:XML = new XML( airSDKDescriptionString ); 119 | var versionString:String = airSDKDescription.version.text() + "." + airSDKDescription.build.text(); 120 | var version:AIRSDKVersion = new AIRSDKVersion( versionString ); 121 | return version; 122 | } 123 | } 124 | catch (e:Error) 125 | { 126 | trace( e ); 127 | } 128 | return null; 129 | } 130 | 131 | 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /client/src/com/apple/plist/Plist.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 10/9/2021 4 | */ 5 | package com.apple.plist 6 | { 7 | import com.apple.plist.entries.PlistDictEntry; 8 | 9 | import flash.events.Event; 10 | import flash.filesystem.File; 11 | import flash.filesystem.FileMode; 12 | import flash.filesystem.FileStream; 13 | 14 | 15 | /** 16 | * 17 | */ 18 | public class Plist extends PlistDictEntry 19 | { 20 | //////////////////////////////////////////////////////// 21 | // CONSTANTS 22 | // 23 | 24 | private static const TAG:String = "Plist"; 25 | 26 | private static const EMPTY_PLIST:String = 27 | "\n" + 28 | "\n" + 29 | "\n" + 30 | "\n" + 31 | "\n" + 32 | "\n" + 33 | ""; 34 | 35 | 36 | //////////////////////////////////////////////////////// 37 | // VARIABLES 38 | // 39 | 40 | 41 | 42 | //////////////////////////////////////////////////////// 43 | // FUNCTIONALITY 44 | // 45 | 46 | public function Plist( content:String = EMPTY_PLIST ) 47 | { 48 | super(""); 49 | loadPlistXMLString( content ); 50 | } 51 | 52 | 53 | 54 | // 55 | // LOADING / SAVING 56 | // 57 | 58 | 59 | public function loadPlistXMLString( xmlString:String ):void 60 | { 61 | var xml:XML = new XML( xmlString ); 62 | // process entries 63 | try 64 | { 65 | var dict:XML = xml.children()[0]; 66 | processEntries( dict ); 67 | } 68 | catch (e:Error) 69 | { 70 | } 71 | } 72 | 73 | 74 | public function toXML():XML 75 | { 76 | var xml:XML = new XML( EMPTY_PLIST ); 77 | xml.dict = valueXML(); 78 | return xml; 79 | } 80 | 81 | 82 | public function load( plistFile:File ):Plist 83 | { 84 | if (!plistFile.exists) 85 | { 86 | throw new Error( "plist file does not exist" ); 87 | } 88 | 89 | var fs:FileStream = new FileStream(); 90 | fs.open( plistFile, FileMode.READ ); 91 | var content:String = fs.readUTFBytes( fs.bytesAvailable ); 92 | fs.close(); 93 | 94 | loadPlistXMLString( content ); 95 | 96 | return this; 97 | } 98 | 99 | 100 | public function save( plistFile:File ):void 101 | { 102 | var data:String = toXML().toXMLString(); 103 | 104 | var fileStream:FileStream = new FileStream(); 105 | fileStream.open( plistFile, FileMode.WRITE ); 106 | fileStream.writeUTFBytes( data ); 107 | fileStream.close(); 108 | } 109 | 110 | 111 | public function saveAsync( plistFile:File, complete:Function = null ):void 112 | { 113 | var data:String = toXML().toXMLString(); 114 | 115 | var fileStream:FileStream = new FileStream(); 116 | fileStream.addEventListener( Event.CLOSE, function ( event:Event ):void { 117 | event.currentTarget.removeEventListener( event.type, arguments.callee ); 118 | if (complete != null) 119 | { 120 | complete(); 121 | } 122 | } ); 123 | 124 | fileStream.openAsync( plistFile, FileMode.WRITE ); 125 | fileStream.writeUTFBytes( data ); 126 | fileStream.close(); 127 | } 128 | 129 | 130 | } 131 | 132 | 133 | } 134 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/packages/processes/PackageExtractDefinitionProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 16/9/2021 4 | */ 5 | package com.apm.client.commands.packages.processes 6 | { 7 | import com.apm.client.logging.Log; 8 | import com.apm.client.processes.ProcessBase; 9 | import com.apm.data.packages.PackageDefinitionFile; 10 | import com.apm.utils.FileUtils; 11 | 12 | import flash.filesystem.File; 13 | import flash.filesystem.FileMode; 14 | import flash.filesystem.FileStream; 15 | import flash.utils.ByteArray; 16 | 17 | import org.as3commons.zip.IZipFile; 18 | import org.as3commons.zip.Zip; 19 | 20 | 21 | /** 22 | * Extracts the package definition from an airpackage file. 23 | *
24 | * 25 | * i.e. unzip the supplied File and load the package.json 26 | * into the supplied PackageDefinitionFile instance. 27 | */ 28 | public class PackageExtractDefinitionProcess extends ProcessBase 29 | { 30 | //////////////////////////////////////////////////////// 31 | // CONSTANTS 32 | // 33 | 34 | private static const TAG:String = "PackageExtractDefinitionProcess"; 35 | 36 | 37 | //////////////////////////////////////////////////////// 38 | // VARIABLES 39 | // 40 | 41 | private var _packageDefinition:PackageDefinitionFile; 42 | private var _packageFile:File; 43 | 44 | 45 | //////////////////////////////////////////////////////// 46 | // FUNCTIONALITY 47 | // 48 | 49 | public function PackageExtractDefinitionProcess( packageDefinition:PackageDefinitionFile, packageFile:File ) 50 | { 51 | _packageDefinition = packageDefinition; 52 | _packageFile = packageFile; 53 | } 54 | 55 | 56 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 57 | { 58 | super.start( completeCallback, failureCallback ); 59 | try 60 | { 61 | if (!_packageFile.exists) 62 | { 63 | failure( "Package file does not exist: " + _packageFile.nativePath ); 64 | return; 65 | } 66 | 67 | if (!FileUtils.tmpDirectory.exists) FileUtils.tmpDirectory.createDirectory(); 68 | var tmpPackageDefFile:File = FileUtils.tmpDirectory.resolvePath( _packageFile.name + ".json" ); 69 | 70 | var sourceBytes:ByteArray = new ByteArray(); 71 | 72 | var sourceStream:FileStream = new FileStream(); 73 | sourceStream.open( _packageFile, FileMode.READ ); 74 | sourceStream.readBytes( sourceBytes ); 75 | sourceStream.close(); 76 | 77 | var zip:Zip = new Zip(); 78 | zip.loadBytes( sourceBytes ); 79 | 80 | var zipFile:IZipFile = zip.getFileByName( PackageDefinitionFile.DEFAULT_FILENAME ); 81 | if (zipFile == null) 82 | { 83 | failure( "Package file invalid format (missing package.json): " + _packageFile.nativePath ); 84 | return; 85 | } 86 | 87 | var fs:FileStream = new FileStream(); 88 | fs.open( tmpPackageDefFile, FileMode.WRITE ); 89 | fs.writeBytes( zipFile.content ); 90 | fs.close(); 91 | 92 | _packageDefinition.load( tmpPackageDefFile ); 93 | 94 | tmpPackageDefFile.deleteFile(); 95 | 96 | complete(); 97 | } 98 | catch (e:Error) 99 | { 100 | Log.e( TAG, e ); 101 | failure( e.message ); 102 | } 103 | } 104 | 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/packages/BuildCommand.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 18/5/2021 4 | */ 5 | package com.apm.client.commands.packages 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.commands.Command; 9 | import com.apm.client.commands.packages.processes.PackageContentCreateProcess; 10 | import com.apm.client.commands.packages.processes.PackageContentVerifyProcess; 11 | import com.apm.client.commands.packages.processes.PackageDependenciesVerifyProcess; 12 | import com.apm.client.commands.packages.processes.ViewPackageProcess; 13 | import com.apm.client.events.CommandEvent; 14 | import com.apm.client.processes.ProcessQueue; 15 | 16 | import flash.events.EventDispatcher; 17 | 18 | import flash.filesystem.File; 19 | 20 | 21 | public class BuildCommand extends EventDispatcher implements Command 22 | { 23 | 24 | //////////////////////////////////////////////////////// 25 | // CONSTANTS 26 | // 27 | 28 | private static const TAG:String = "BuildCommand"; 29 | 30 | public static const NAME:String = "build"; 31 | 32 | 33 | 34 | //////////////////////////////////////////////////////// 35 | // VARIABLES 36 | // 37 | 38 | private var _parameters:Array; 39 | private var _queue:ProcessQueue; 40 | 41 | 42 | //////////////////////////////////////////////////////// 43 | // FUNCTIONALITY 44 | // 45 | 46 | public function BuildCommand() 47 | { 48 | super(); 49 | _queue = new ProcessQueue(); 50 | } 51 | 52 | 53 | public function setParameters( parameters:Array ):void 54 | { 55 | _parameters = parameters; 56 | } 57 | 58 | 59 | public function get name():String 60 | { 61 | return NAME; 62 | } 63 | 64 | 65 | public function get category():String 66 | { 67 | return ""; 68 | } 69 | 70 | 71 | public function get requiresNetwork():Boolean 72 | { 73 | return false; 74 | } 75 | 76 | 77 | public function get requiresProject():Boolean 78 | { 79 | return false; 80 | } 81 | 82 | 83 | public function get description():String 84 | { 85 | return "build a package directory into an airpackage"; 86 | } 87 | 88 | 89 | public function get usage():String 90 | { 91 | return description + "\n" + 92 | "\n" + 93 | "apm build build a package in the current directory\n" + 94 | "apm build build a package in a directory named \n"; 95 | } 96 | 97 | 98 | public function execute():void 99 | { 100 | var path:String = ""; 101 | if (_parameters != null && _parameters.length > 0) 102 | { 103 | path = _parameters[0]; 104 | } 105 | 106 | APM.io.writeLine( "Building package" ); 107 | 108 | var packageDir:File = new File( APM.config.workingDirectory + File.separator + path ); 109 | 110 | _queue.addProcess( new PackageContentVerifyProcess( packageDir, false )); 111 | _queue.addProcess( new PackageContentCreateProcess( packageDir )); 112 | 113 | _queue.start( 114 | function ():void 115 | { 116 | dispatchEvent( new CommandEvent( CommandEvent.COMPLETE, APM.CODE_OK )); 117 | }, 118 | function ( message:String ):void 119 | { 120 | dispatchEvent( new CommandEvent( CommandEvent.COMPLETE, APM.CODE_ERROR )); 121 | } 122 | ); 123 | } 124 | 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /client/src/com/apm/client/commands/project/processes/ProjectConfigSetProcess.as: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Michael Archbold (https://michaelarchbold.com) 3 | * @created 22/10/2021 4 | */ 5 | package com.apm.client.commands.project.processes 6 | { 7 | import com.apm.client.APM; 8 | import com.apm.client.processes.ProcessBase; 9 | import com.apm.data.packages.PackageDefinitionFile; 10 | import com.apm.data.packages.PackageParameter; 11 | import com.apm.data.project.ProjectDefinition; 12 | import com.apm.data.project.ProjectParameter; 13 | import com.apm.utils.ProjectPackageCache; 14 | 15 | public class ProjectConfigSetProcess extends ProcessBase 16 | { 17 | //////////////////////////////////////////////////////// 18 | // CONSTANTS 19 | // 20 | 21 | private static const TAG:String = "ProjectConfigGetProcess"; 22 | 23 | 24 | //////////////////////////////////////////////////////// 25 | // VARIABLES 26 | // 27 | 28 | 29 | private var _paramName:String; 30 | private var _paramValue:String; 31 | 32 | 33 | //////////////////////////////////////////////////////// 34 | // FUNCTIONALITY 35 | // 36 | 37 | public function ProjectConfigSetProcess( paramName:String, paramValue:String ) 38 | { 39 | _paramName = paramName; 40 | _paramValue = paramValue; 41 | } 42 | 43 | 44 | override public function start( completeCallback:Function = null, failureCallback:Function = null ):void 45 | { 46 | super.start( completeCallback, failureCallback ); 47 | 48 | var project:ProjectDefinition = APM.config.projectDefinition; 49 | if (project == null) 50 | { 51 | failure( "No project file found" ); 52 | return; 53 | } 54 | 55 | if (_paramName == null) 56 | { 57 | // set all config 58 | for each (var p:ProjectParameter in APM.config.projectDefinition.getConfiguration( APM.config.buildType )) 59 | { 60 | _queue.addProcess( new ProjectConfigSetProcess( p.name, null ) ); 61 | } 62 | } 63 | else if (_paramValue == null) 64 | { 65 | var param:ProjectParameter = project.getConfigurationParam( _paramName, APM.config.buildType ); 66 | var paramPackage:PackageDefinitionFile = ProjectPackageCache.getPackage( _paramName ); 67 | 68 | if (param != null) 69 | { 70 | APM.io.writeLine( "" ); 71 | ProjectConfigDescribeProcess.describeParameter( param ); 72 | ProjectConfigDescribeProcess.listParameter( param ); 73 | 74 | var value:String = APM.io.question( "Set", param.value ); 75 | if (value != null && value.length > 0 && value != param.value) 76 | { 77 | project.setConfigurationParamValue( _paramName, value, APM.config.buildType ); 78 | project.save(); 79 | } 80 | 81 | } 82 | else if (paramPackage != null) 83 | { 84 | if (paramPackage.version != null && paramPackage.version.parameters.length > 0) 85 | { 86 | for each (var pp:PackageParameter in paramPackage.version.parameters) 87 | { 88 | _queue.addProcess( new ProjectConfigSetProcess( pp.name, null ) ); 89 | } 90 | } 91 | else 92 | { 93 | APM.io.writeError( _paramName, "No configuration parameters required" ); 94 | } 95 | } 96 | } 97 | else 98 | { 99 | project.setConfigurationParamValue( _paramName, _paramValue, APM.config.buildType ); 100 | project.save(); 101 | } 102 | 103 | complete(); 104 | } 105 | 106 | } 107 | 108 | } 109 | --------------------------------------------------------------------------------