@tremho/mist-lift 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +37 -0
- package/build/commands/actions/initQuestions.js +136 -0
- package/build/commands/actions/initQuestions.js.map +1 -0
- package/build/commands/actions/makePackageJson.js +2 -0
- package/build/commands/actions/makePackageJson.js.map +1 -0
- package/build/commands/actions/setupPackageJson.js +68 -0
- package/build/commands/actions/setupPackageJson.js.map +1 -0
- package/build/commands/build.js +191 -0
- package/build/commands/build.js.map +1 -0
- package/build/commands/builtin/ApiDocMaker.js +72 -0
- package/build/commands/builtin/ApiDocMaker.js.map +1 -0
- package/build/commands/builtin/BuiltInHandler.js +62 -0
- package/build/commands/builtin/BuiltInHandler.js.map +1 -0
- package/build/commands/builtin/DeployBuiltInZip.js +57 -0
- package/build/commands/builtin/DeployBuiltInZip.js.map +1 -0
- package/build/commands/builtin/StageWebrootZip.js +70 -0
- package/build/commands/builtin/StageWebrootZip.js.map +1 -0
- package/build/commands/builtin/prebuilt-zips/API.zip +0 -0
- package/build/commands/builtin/prebuilt-zips/FileServe.zip +0 -0
- package/build/commands/builtin/prebuilt-zips/Webroot.zip +0 -0
- package/build/commands/create.js +75 -0
- package/build/commands/create.js.map +1 -0
- package/build/commands/deploy.js +187 -0
- package/build/commands/deploy.js.map +1 -0
- package/build/commands/doctor.js +137 -0
- package/build/commands/doctor.js.map +1 -0
- package/build/commands/help.js +205 -0
- package/build/commands/help.js.map +1 -0
- package/build/commands/init.js +92 -0
- package/build/commands/init.js.map +1 -0
- package/build/commands/package.js +249 -0
- package/build/commands/package.js.map +1 -0
- package/build/commands/publish.js +344 -0
- package/build/commands/publish.js.map +1 -0
- package/build/commands/settings.js +95 -0
- package/build/commands/settings.js.map +1 -0
- package/build/commands/start.js +66 -0
- package/build/commands/start.js.map +1 -0
- package/build/commands/test.js +52 -0
- package/build/commands/test.js.map +1 -0
- package/build/commands/user.js +20 -0
- package/build/commands/user.js.map +1 -0
- package/build/expressRoutes/all.js +129 -0
- package/build/expressRoutes/all.js.map +1 -0
- package/build/expressRoutes/api.js +22 -0
- package/build/expressRoutes/api.js.map +1 -0
- package/build/expressRoutes/functionBinder.js +191 -0
- package/build/expressRoutes/functionBinder.js.map +1 -0
- package/build/lib/CaseUtils.js +57 -0
- package/build/lib/CaseUtils.js.map +1 -0
- package/build/lib/DirectoryUtils.js +37 -0
- package/build/lib/DirectoryUtils.js.map +1 -0
- package/build/lib/LiftConfig.js +83 -0
- package/build/lib/LiftConfig.js.map +1 -0
- package/build/lib/LiftVersion.js +117 -0
- package/build/lib/LiftVersion.js.map +1 -0
- package/build/lib/Tests/fileCompare.test.js +55 -0
- package/build/lib/Tests/fileCompare.test.js.map +1 -0
- package/build/lib/askQuestion.js +41 -0
- package/build/lib/askQuestion.js.map +1 -0
- package/build/lib/executeCommand.js +45 -0
- package/build/lib/executeCommand.js.map +1 -0
- package/build/lib/fileCompare.js +48 -0
- package/build/lib/fileCompare.js.map +1 -0
- package/build/lib/openAPI/ApiBuildCollector.js +58 -0
- package/build/lib/openAPI/ApiBuildCollector.js.map +1 -0
- package/build/lib/openAPI/WebrootFileSupport.js +44 -0
- package/build/lib/openAPI/WebrootFileSupport.js.map +1 -0
- package/build/lib/openAPI/openApiConstruction.js +203 -0
- package/build/lib/openAPI/openApiConstruction.js.map +1 -0
- package/build/lib/pathResolve.js +27 -0
- package/build/lib/pathResolve.js.map +1 -0
- package/build/lib/utils.js +76 -0
- package/build/lib/utils.js.map +1 -0
- package/build/lift.js +124 -0
- package/build/lift.js.map +1 -0
- package/package.json +69 -0
- package/src/commands/actions/initQuestions.ts +131 -0
- package/src/commands/actions/makePackageJson.ts +0 -0
- package/src/commands/actions/setupPackageJson.ts +36 -0
- package/src/commands/build.ts +165 -0
- package/src/commands/builtin/ApiDocMaker.ts +70 -0
- package/src/commands/builtin/BuiltInHandler.ts +51 -0
- package/src/commands/builtin/DeployBuiltInZip.ts +27 -0
- package/src/commands/builtin/StageWebrootZip.ts +39 -0
- package/src/commands/builtin/prebuilt-zips/API.zip +0 -0
- package/src/commands/builtin/prebuilt-zips/FileServe.zip +0 -0
- package/src/commands/builtin/prebuilt-zips/Webroot.zip +0 -0
- package/src/commands/create.ts +55 -0
- package/src/commands/deploy.ts +171 -0
- package/src/commands/doctor.ts +102 -0
- package/src/commands/help.ts +171 -0
- package/src/commands/init.ts +62 -0
- package/src/commands/package.ts +228 -0
- package/src/commands/publish.ts +350 -0
- package/src/commands/settings.ts +76 -0
- package/src/commands/start.ts +46 -0
- package/src/commands/test.ts +38 -0
- package/src/commands/user.ts +20 -0
- package/src/expressRoutes/all.ts +104 -0
- package/src/expressRoutes/api.ts +24 -0
- package/src/expressRoutes/functionBinder.ts +169 -0
- package/src/lib/CaseUtils.ts +68 -0
- package/src/lib/DirectoryUtils.ts +36 -0
- package/src/lib/LiftConfig.ts +83 -0
- package/src/lib/LiftVersion.ts +95 -0
- package/src/lib/Tests/dir1/file.1 +0 -0
- package/src/lib/Tests/dir1/file.2 +0 -0
- package/src/lib/Tests/dir2/file.1 +0 -0
- package/src/lib/Tests/fileCompare.test.ts +34 -0
- package/src/lib/askQuestion.ts +18 -0
- package/src/lib/executeCommand.ts +38 -0
- package/src/lib/fileCompare.ts +46 -0
- package/src/lib/openAPI/ApiBuildCollector.ts +47 -0
- package/src/lib/openAPI/WebrootFileSupport.ts +21 -0
- package/src/lib/openAPI/openApiConstruction.ts +202 -0
- package/src/lib/pathResolve.ts +32 -0
- package/src/lib/utils.ts +45 -0
- package/src/lift.ts +82 -0
- package/tsconfig.json +28 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import {gatherFunctionDefinitions} from "../../lib/openAPI/ApiBuildCollector";
|
|
2
|
+
import {buildOpenApi} from "../../lib/openAPI/openApiConstruction";
|
|
3
|
+
import {whiteBright} from "ansi-colors";
|
|
4
|
+
import {GetWebrootServePaths} from "../../lib/openAPI/WebrootFileSupport";
|
|
5
|
+
|
|
6
|
+
export async function MakePublicApiDoc
|
|
7
|
+
(
|
|
8
|
+
):Promise<Uint8Array>
|
|
9
|
+
{
|
|
10
|
+
const defs = gatherFunctionDefinitions();
|
|
11
|
+
return await buildOpenApi(defs)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function MakeBuiltinApiDoc
|
|
15
|
+
(
|
|
16
|
+
yamlFile:string
|
|
17
|
+
|
|
18
|
+
):Promise<Uint8Array>
|
|
19
|
+
{
|
|
20
|
+
const defs = gatherFunctionDefinitions()
|
|
21
|
+
addBuiltInDefinitions(defs)
|
|
22
|
+
return await buildOpenApi(defs, false, yamlFile) //, true)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function addBuiltInDefinitions(defs:any[])
|
|
26
|
+
{
|
|
27
|
+
// console.warn("NOT ADDING ANY BUILTIN API INTEGRATIONS")
|
|
28
|
+
// console.log("ADDING apiDef");
|
|
29
|
+
defs.push(apiDef);
|
|
30
|
+
// console.log("ADDING webrootDef");
|
|
31
|
+
defs.push(webrootDef);
|
|
32
|
+
|
|
33
|
+
// console.warn("Adding webroot literals");
|
|
34
|
+
// do just /docs and see how that goes
|
|
35
|
+
let fsdef = Object.assign({},fileServeDef); // copy
|
|
36
|
+
fsdef.name = "fileserve_docs"
|
|
37
|
+
fsdef.pathMap = "/docs/{path}"
|
|
38
|
+
defs.push(fsdef);
|
|
39
|
+
const roots = GetWebrootServePaths();
|
|
40
|
+
// console.log("roots", roots)
|
|
41
|
+
for(let root of roots)
|
|
42
|
+
{
|
|
43
|
+
if(root) {
|
|
44
|
+
let rootName = root;
|
|
45
|
+
while (rootName.indexOf("/") != -1) rootName = rootName.replace("/", "").toLowerCase().trim();
|
|
46
|
+
let fileserve = Object.assign({}, fileServeDef); // copy
|
|
47
|
+
fileserve.name = "fileserve_" + rootName
|
|
48
|
+
fileserve.pathMap = `${root}/{path}`
|
|
49
|
+
defs.push(fileserve);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const apiDef = {"name": "API", "description": "", "version": "1.0.0", "pathMap": "/api", "allowedMethods": "GET",
|
|
55
|
+
"logLevel": "Debug", "sessionRequired": false, "userRequired": false, "schemas": {}, "parameters": [],
|
|
56
|
+
"returns": { "200": {"type": "empty", "description": "successful response."}, "500": {"type": "string",
|
|
57
|
+
"description": "Error details"}}}
|
|
58
|
+
|
|
59
|
+
const fileServeDef = {"name": "FileServe", "description": "file service", "version":
|
|
60
|
+
"1.0.0", "pathMap": "",
|
|
61
|
+
"allowedMethods": "GET", "logLevel": "Debug", "sessionRequired": false, "userRequired": false,
|
|
62
|
+
"schemas": {}, "parameters": [{"name": "path", "in": "path"}],
|
|
63
|
+
"returns": {"200": {"type": "empty", "description": "successful response."},
|
|
64
|
+
"500": {"type": "string", "description": "Error details"}}}
|
|
65
|
+
|
|
66
|
+
const webrootDef = {"name": "Webroot", "description": "Serves files from the webroot /", "version": "1.0.0",
|
|
67
|
+
"pathMap": "/{path}", "allowedMethods": "get", "logLevel": "Debug", "sessionRequired": false, "userRequired": false,
|
|
68
|
+
"schemas": {}, "parameters": [{"name": "path", "in": "path"}],
|
|
69
|
+
"returns": {"200": {"type": "empty", "description": "successful response."},
|
|
70
|
+
"500": {"type": "string", "description": "Error details"}}}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {StageWebrootZip} from "./StageWebrootZip";
|
|
2
|
+
import {DeployBuiltInZip} from "./DeployBuiltInZip";
|
|
3
|
+
import {GetWebrootServePaths} from "../../lib/openAPI/WebrootFileSupport";
|
|
4
|
+
|
|
5
|
+
import fs from 'fs'
|
|
6
|
+
import path from 'path'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export async function DeployWebrootBuiltIn
|
|
10
|
+
(
|
|
11
|
+
)
|
|
12
|
+
{
|
|
13
|
+
const wrZip = await StageWebrootZip()
|
|
14
|
+
// console.log("Deploy Webroot Builtin from "+wrZip)
|
|
15
|
+
await DeployBuiltInZip("Webroot", wrZip)
|
|
16
|
+
// remove temp zip when done
|
|
17
|
+
fs.rmSync(wrZip, {recursive: true});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function DeployRootFileserves
|
|
21
|
+
(
|
|
22
|
+
)
|
|
23
|
+
{
|
|
24
|
+
// console.log("Deploy Root Fileserves")
|
|
25
|
+
// Get root paths
|
|
26
|
+
const roots = GetWebrootServePaths();
|
|
27
|
+
// for each, deploy under the name of each
|
|
28
|
+
const fileserveZip = path.join(__dirname, 'prebuilt-zips', 'FileServe.zip')
|
|
29
|
+
let all:Promise<any>[] = [];
|
|
30
|
+
for(let root of roots) {
|
|
31
|
+
root = root.trim()
|
|
32
|
+
let name = "fileserve_" + root;
|
|
33
|
+
while (name.indexOf("/") !== -1) {
|
|
34
|
+
name = name.replace('/', '');
|
|
35
|
+
}
|
|
36
|
+
all.push(DeployBuiltInZip(name, fileserveZip))
|
|
37
|
+
}
|
|
38
|
+
// console.log('wait all');
|
|
39
|
+
await Promise.all(all);
|
|
40
|
+
// console.log('all complete');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function DeployApiBuiltin
|
|
44
|
+
(
|
|
45
|
+
):Promise<any>
|
|
46
|
+
{
|
|
47
|
+
console.log("Deploy API Builtin")
|
|
48
|
+
// get the prebuilt zip location
|
|
49
|
+
const apiZip = path.join(__dirname, 'prebuilt-zips', 'API.zip')
|
|
50
|
+
await DeployBuiltInZip("api", apiZip)
|
|
51
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
import * as path from 'path'
|
|
3
|
+
import {deployPackage} from '../deploy'
|
|
4
|
+
|
|
5
|
+
export async function DeployBuiltInZip
|
|
6
|
+
(
|
|
7
|
+
name:string,
|
|
8
|
+
zipPath:string
|
|
9
|
+
)
|
|
10
|
+
{
|
|
11
|
+
// console.log(">> Deploying "+name)
|
|
12
|
+
await deployPackage(name, zipPath);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function DeployFileserve
|
|
16
|
+
(
|
|
17
|
+
root:string
|
|
18
|
+
)
|
|
19
|
+
{
|
|
20
|
+
// rootName is without slash
|
|
21
|
+
if(root) {
|
|
22
|
+
let rootName = root.replace("/", "")
|
|
23
|
+
let name = "fileserve_" + rootName
|
|
24
|
+
let zipPath = path.join(__dirname, 'prebuilt-zips', 'FileServe.zip')
|
|
25
|
+
await DeployBuiltInZip(name, zipPath)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {MakePublicApiDoc} from "./ApiDocMaker";
|
|
2
|
+
|
|
3
|
+
import * as ac from "ansi-colors"
|
|
4
|
+
import * as path from 'path'
|
|
5
|
+
import * as fs from 'fs'
|
|
6
|
+
import {executeCommand} from "../../lib/executeCommand";
|
|
7
|
+
import {resolvePaths} from "../../lib/pathResolve";
|
|
8
|
+
import {recurseDirectory} from "../../lib/DirectoryUtils";
|
|
9
|
+
import {FolderToZip, UnzipToFolder} from "../../lib/utils";
|
|
10
|
+
|
|
11
|
+
export async function StageWebrootZip
|
|
12
|
+
(
|
|
13
|
+
):Promise<string>
|
|
14
|
+
{
|
|
15
|
+
// console.log(">> staging webroot to zip")
|
|
16
|
+
const projectPaths = resolvePaths();
|
|
17
|
+
// make a public yaml
|
|
18
|
+
await MakePublicApiDoc(); // writes apidoc.yaml to docs
|
|
19
|
+
const builtinPath = path.join(__dirname, 'prebuilt-zips', 'Webroot.zip')
|
|
20
|
+
const exdir = path.join(projectPaths.basePath, '.package_temp');
|
|
21
|
+
await UnzipToFolder(builtinPath, exdir)
|
|
22
|
+
const webroot = path.join(projectPaths.basePath, 'webroot');
|
|
23
|
+
const packageTemp = path.join(projectPaths.basePath, '.package_temp')
|
|
24
|
+
const zipFilesPath = path.join(packageTemp, 'Webroot','__files__')
|
|
25
|
+
await recurseDirectory(webroot, (filepath, stats) => {
|
|
26
|
+
const relPath = filepath.substring(webroot.length)
|
|
27
|
+
if(stats.isDirectory()) {
|
|
28
|
+
fs.mkdirSync(zipFilesPath+relPath, {recursive: true})
|
|
29
|
+
} else {
|
|
30
|
+
fs.copyFileSync(filepath, zipFilesPath + relPath)
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
const webrootZip = path.join(projectPaths.basePath, 'a.zip')
|
|
34
|
+
|
|
35
|
+
await FolderToZip(path.join(packageTemp, 'Webroot'), webrootZip)
|
|
36
|
+
// return path to this zip
|
|
37
|
+
return webrootZip
|
|
38
|
+
|
|
39
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** Handles fucntion creation via the create command */
|
|
2
|
+
|
|
3
|
+
import * as fs from 'fs'
|
|
4
|
+
import * as path from 'path'
|
|
5
|
+
import * as ac from "ansi-colors"
|
|
6
|
+
import {resolvePaths} from "../lib/pathResolve";
|
|
7
|
+
import {camelCase, pascalCase} from "../lib/CaseUtils"
|
|
8
|
+
import {helpCreate} from "./help";
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/// Create command
|
|
12
|
+
export function doCreate(
|
|
13
|
+
funcName:string // name of function to create
|
|
14
|
+
)
|
|
15
|
+
{
|
|
16
|
+
if(!funcName) {
|
|
17
|
+
helpCreate()
|
|
18
|
+
return
|
|
19
|
+
} else {
|
|
20
|
+
|
|
21
|
+
console.log(ac.green.bold("Creating new function named ")+funcName)
|
|
22
|
+
|
|
23
|
+
const projectPaths = resolvePaths();
|
|
24
|
+
const funcPath = path.join(projectPaths.functionPath, funcName);
|
|
25
|
+
if(!fs.existsSync(funcPath)) fs.mkdirSync(funcPath)
|
|
26
|
+
const dataDir = path.join(__dirname, '..', '..', 'templateData');
|
|
27
|
+
|
|
28
|
+
const testdirname = camelCase(funcName) + '-tests';
|
|
29
|
+
if(!fs.existsSync(path.join(funcPath, testdirname))) fs.mkdirSync(path.join(funcPath, testdirname))
|
|
30
|
+
if(!fs.existsSync(path.join(funcPath, 'src'))) fs.mkdirSync(path.join(funcPath, 'src'))
|
|
31
|
+
|
|
32
|
+
let localsrc = fs.readFileSync(path.join(dataDir, 'function-local-ts')).toString();
|
|
33
|
+
while (localsrc.indexOf("$$FUNCTION_NAME$$") !== -1) {
|
|
34
|
+
localsrc = localsrc.replace("$$FUNCTION_NAME$$", funcName);
|
|
35
|
+
}
|
|
36
|
+
fs.writeFileSync(path.join(funcPath, 'src', 'local.ts'), localsrc);
|
|
37
|
+
let defsrc = fs.readFileSync(path.join(dataDir, 'function-definition-template')).toString();
|
|
38
|
+
while(defsrc.indexOf("$$FUNCTION_NAME$$") !== -1) {
|
|
39
|
+
defsrc = defsrc.replace("$$FUNCTION_NAME$$", funcName);
|
|
40
|
+
}
|
|
41
|
+
let defpathMap = "/"+funcName.toLowerCase();
|
|
42
|
+
defsrc = defsrc.replace("$$PATHMAP$$", defpathMap)
|
|
43
|
+
fs.writeFileSync(path.join(funcPath, 'src', 'definition.json'), defsrc);
|
|
44
|
+
let mainsrc = fs.readFileSync(path.join(dataDir, 'function-main-ts')).toString();
|
|
45
|
+
while(mainsrc.indexOf("$$TemplateName$$") !== -1) {
|
|
46
|
+
mainsrc = mainsrc.replace("$$TemplateName$$", funcName);
|
|
47
|
+
}
|
|
48
|
+
fs.writeFileSync(path.join(funcPath, 'src', 'main.ts'), mainsrc);
|
|
49
|
+
fs.copyFileSync(path.join(dataDir, 'function-test-template'), path.join(funcPath, testdirname, 'Sanity.test.ts'))
|
|
50
|
+
fs.copyFileSync(path.join(dataDir, 'function-runmain-mjs'), path.join(funcPath, 'runmain.mjs'));
|
|
51
|
+
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
|
|
2
|
+
import {
|
|
3
|
+
LambdaClient,
|
|
4
|
+
CreateFunctionCommand,
|
|
5
|
+
DeleteFunctionCommand,
|
|
6
|
+
AddPermissionCommand
|
|
7
|
+
} from "@aws-sdk/client-lambda";
|
|
8
|
+
|
|
9
|
+
import md5 from "md5";
|
|
10
|
+
|
|
11
|
+
import path from "path"
|
|
12
|
+
import fs, {Stats} from "fs"
|
|
13
|
+
import {resolvePaths} from "../lib/pathResolve"
|
|
14
|
+
|
|
15
|
+
import * as ac from "ansi-colors"
|
|
16
|
+
|
|
17
|
+
import {doTestAsync} from "./test"
|
|
18
|
+
import {recurseDirectory} from "../lib/DirectoryUtils"
|
|
19
|
+
import {getLiftVersion, getProjectName, getProjectVersion} from "../lib/LiftVersion"
|
|
20
|
+
import {executeCommand} from "../lib/executeCommand"
|
|
21
|
+
import {isNewerFile} from "../lib/fileCompare"
|
|
22
|
+
import {delay} from "../lib/utils"
|
|
23
|
+
import {doBuildAsync} from "./build";
|
|
24
|
+
import {doPackageAsync} from "./package";
|
|
25
|
+
import {Md5} from "@smithy/md5-js";
|
|
26
|
+
import {getAWSCredentials, getSettings, RuntimeType} from "../lib/LiftConfig";
|
|
27
|
+
|
|
28
|
+
let projectPaths:{basePath: string, buildPath: string, functionPath: string, packagePath: string, verified: boolean}
|
|
29
|
+
|
|
30
|
+
let deploymentRecord:any = {} // a map of last deployment times
|
|
31
|
+
|
|
32
|
+
// package then deploy
|
|
33
|
+
export async function doDeployAsync(
|
|
34
|
+
args:string[]
|
|
35
|
+
): Promise<number>
|
|
36
|
+
{
|
|
37
|
+
projectPaths = resolvePaths()
|
|
38
|
+
|
|
39
|
+
const deploymentRecordPath = path.join(projectPaths.basePath, '.deployed')
|
|
40
|
+
try { deploymentRecord = JSON.parse(fs.readFileSync(deploymentRecordPath).toString()) } catch {}
|
|
41
|
+
|
|
42
|
+
// the main package json that has all imports
|
|
43
|
+
const mainPkgJsonPath = path.join(projectPaths.packagePath)
|
|
44
|
+
const mainPkgSrc = fs.readFileSync(mainPkgJsonPath).toString()
|
|
45
|
+
const mainPkgJson = JSON.parse(mainPkgSrc)
|
|
46
|
+
|
|
47
|
+
const projectName = getProjectName()
|
|
48
|
+
const projectVersion = getProjectVersion()
|
|
49
|
+
const liftVersion = getLiftVersion()
|
|
50
|
+
|
|
51
|
+
const funcsToDeploy: string[] = []
|
|
52
|
+
const options: string[] = []
|
|
53
|
+
for (let arg of args) {
|
|
54
|
+
if (arg.charAt(0) == '-') {
|
|
55
|
+
options.push(arg.toLowerCase())
|
|
56
|
+
} else funcsToDeploy.push(arg)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (options.indexOf("--no-package") === -1) {
|
|
60
|
+
let ret = await doPackageAsync(args)
|
|
61
|
+
if (ret) return ret;
|
|
62
|
+
else await delay(2500);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if(options.indexOf("--clean") !== -1) {
|
|
66
|
+
deploymentRecord = {};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!funcsToDeploy.length) {
|
|
70
|
+
let firstDepth = 0
|
|
71
|
+
recurseDirectory(projectPaths.functionPath, (filepath, stats) => {
|
|
72
|
+
let depth = filepath.split(path.sep).length
|
|
73
|
+
if (!firstDepth) firstDepth = depth
|
|
74
|
+
if (stats.isDirectory() && depth == firstDepth) {
|
|
75
|
+
funcsToDeploy.push(path.basename(filepath))
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const all: Promise<any>[] = [];
|
|
81
|
+
let error = 0;
|
|
82
|
+
|
|
83
|
+
for (let funcName of funcsToDeploy) {
|
|
84
|
+
// console.log("Deploy "+funcName)
|
|
85
|
+
const zipFile = path.join(projectPaths.basePath, 'MistLift_Zips', funcName+".zip")
|
|
86
|
+
if(fs.existsSync(zipFile)) {
|
|
87
|
+
let zipTime = fs.statSync(zipFile).mtime;
|
|
88
|
+
if(zipTime.getTime() > (deploymentRecord[funcName] ?? 0)) {
|
|
89
|
+
await deployPackage(funcName);
|
|
90
|
+
deploymentRecord[funcName] = Date.now();
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
console.error("deploy: " +zipFile + ac.red.bold(` ${funcName} does not exist`))
|
|
94
|
+
return -1;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
try {fs.writeFileSync(deploymentRecordPath, JSON.stringify(deploymentRecord)) } catch {}
|
|
99
|
+
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
//------------
|
|
104
|
+
|
|
105
|
+
export async function deployPackage(funcName:string, zipFile?:string) {
|
|
106
|
+
// first off, anchor a base directory
|
|
107
|
+
zipFile ??= path.join(projectPaths.basePath, 'MistLift_Zips', funcName+".zip")
|
|
108
|
+
|
|
109
|
+
// funcname gets decorated with current instance identifier
|
|
110
|
+
var idsrc = md5((getProjectName()??"") + (getProjectVersion()??""))
|
|
111
|
+
var dFuncName = funcName + "_"+idsrc
|
|
112
|
+
|
|
113
|
+
// See if function exists
|
|
114
|
+
const client:any = new LambdaClient(getAWSCredentials());
|
|
115
|
+
const command:any = new DeleteFunctionCommand({
|
|
116
|
+
FunctionName: dFuncName
|
|
117
|
+
});
|
|
118
|
+
client.send(command).then((response:any) => {
|
|
119
|
+
}).catch((e:any) => {
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// console.log(ac.green.italic("deploying ")+ac.green.bold(funcName)+"...")
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
const response:any = await CreateCloudFunction(dFuncName, zipFile);
|
|
126
|
+
const parts = response.FunctionArn.split(":");
|
|
127
|
+
const principal = parts[4]
|
|
128
|
+
await AddPermissions(client, dFuncName, principal);
|
|
129
|
+
console.log(ac.green.bold(`Successfully deployed ${funcName}`));
|
|
130
|
+
}
|
|
131
|
+
catch(e:any) {
|
|
132
|
+
console.error(ac.red.bold.italic("Error deploying "+funcName), e);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async function CreateCloudFunction(
|
|
136
|
+
funcName:string,
|
|
137
|
+
zipFile:string
|
|
138
|
+
|
|
139
|
+
) : Promise<any>
|
|
140
|
+
{
|
|
141
|
+
|
|
142
|
+
const settings = getSettings();
|
|
143
|
+
const nodeRuntime:RuntimeType|undefined = settings.awsNodeRuntime
|
|
144
|
+
const serviceRole:string = settings.awsServiceRoleARN ?? ""
|
|
145
|
+
const zipFileBase64:Uint8Array = fs.readFileSync(zipFile);
|
|
146
|
+
const client:any = new LambdaClient(getAWSCredentials());
|
|
147
|
+
const command:any = new CreateFunctionCommand({
|
|
148
|
+
FunctionName: funcName,
|
|
149
|
+
Runtime: nodeRuntime,
|
|
150
|
+
Role: serviceRole,
|
|
151
|
+
Handler: 'runmain.handler',
|
|
152
|
+
Code: {
|
|
153
|
+
ZipFile: zipFileBase64
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
return await client.send(command); // response
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function AddPermissions(client:LambdaClient, funcName:string, principal:string):Promise<any>
|
|
160
|
+
{
|
|
161
|
+
const region = getSettings().awsPreferredRegion
|
|
162
|
+
const WSApi = "/"+funcName.toLowerCase();
|
|
163
|
+
const command:any = new AddPermissionCommand({
|
|
164
|
+
FunctionName: funcName,
|
|
165
|
+
StatementId: "InvokePermission",
|
|
166
|
+
Action: "lambda:invokeFunction",
|
|
167
|
+
Principal: "apigateway.amazonaws.com",
|
|
168
|
+
SourceArn: `arn:aws:execute-api:${region}:${principal}:${WSApi}`
|
|
169
|
+
});
|
|
170
|
+
return client.send(command);
|
|
171
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
|
|
2
|
+
import * as ac from "ansi-colors"
|
|
3
|
+
import {VersionInfo, getLiftVersion, getProjectVersion, getProjectName} from "../lib/LiftVersion";
|
|
4
|
+
import {executeCommand} from "../lib/executeCommand"
|
|
5
|
+
import {resolvePaths} from "../lib/pathResolve";
|
|
6
|
+
import {areSettingsAvailable} from "../lib/LiftConfig";
|
|
7
|
+
|
|
8
|
+
export async function doDoctor():Promise<boolean>
|
|
9
|
+
{
|
|
10
|
+
console.log(ac.blue.bold('Lift doctor'));
|
|
11
|
+
|
|
12
|
+
const liftVersion = getLiftVersion().toString()
|
|
13
|
+
const projectVersion = getProjectVersion().toString()
|
|
14
|
+
const projectName = getProjectName();
|
|
15
|
+
const typescriptVersion = await fetchTypescriptVersion()
|
|
16
|
+
const nodeVersion = await fetchNodeVersion()
|
|
17
|
+
const npmVersion = await fetchNpmVersion()
|
|
18
|
+
const gitVersion = await fetchGitVersion();
|
|
19
|
+
const settingsAvail = areSettingsAvailable();
|
|
20
|
+
|
|
21
|
+
console.log("Checking installed dependencies:")
|
|
22
|
+
let ok = report("MistLift", liftVersion, "0.1.0")
|
|
23
|
+
ok = ok && report("Typescript", typescriptVersion, "5.3.3")
|
|
24
|
+
ok = ok && report("Node", nodeVersion, "20.11.0")
|
|
25
|
+
ok = ok && report("Npm", npmVersion, "10.3.0")
|
|
26
|
+
report("Git", gitVersion, "2.0.0")
|
|
27
|
+
if(!settingsAvail) {
|
|
28
|
+
console.log("")
|
|
29
|
+
console.log(ac.yellow.dim.bold("Cloud Settings are not set. ")+ac.blue("run "+ac.bold("lift settings")))
|
|
30
|
+
}
|
|
31
|
+
if(!ok) {
|
|
32
|
+
console.log("")
|
|
33
|
+
console.log(ac.red.bold("System needs updates before MistLift can be used."));
|
|
34
|
+
} else {
|
|
35
|
+
console.log("")
|
|
36
|
+
console.log(ac.green.bold("Ready for MistLift"))
|
|
37
|
+
console.log("");
|
|
38
|
+
if(resolvePaths().verified) {
|
|
39
|
+
console.log(ac.blue.italic("Current project " + projectName + " " + projectVersion))
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return ok
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function versionTrim(vstr:string)
|
|
46
|
+
{
|
|
47
|
+
vstr = vstr.trim();
|
|
48
|
+
let i = -1;
|
|
49
|
+
while(++i < vstr.length) {
|
|
50
|
+
let c = vstr.charAt(i);
|
|
51
|
+
if(c >= '0' && c <= '9') break;
|
|
52
|
+
}
|
|
53
|
+
return vstr.substring(i);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function fetchTypescriptVersion()
|
|
57
|
+
{
|
|
58
|
+
const result = await executeCommand('tsc', ['-v'])
|
|
59
|
+
if(result.retcode) return "Typescript not found"
|
|
60
|
+
var vstr = versionTrim(result.stdStr);
|
|
61
|
+
return vstr;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function fetchNodeVersion()
|
|
65
|
+
{
|
|
66
|
+
const result = await executeCommand('node', ['-v'])
|
|
67
|
+
if(result.retcode) return "Node not found"
|
|
68
|
+
var vstr = versionTrim(result.stdStr);
|
|
69
|
+
return vstr;
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function fetchNpmVersion()
|
|
74
|
+
{
|
|
75
|
+
const result = await executeCommand('npm', ['-v'])
|
|
76
|
+
if(result.retcode) return "npm not found"
|
|
77
|
+
var vstr = versionTrim(result.stdStr);
|
|
78
|
+
return vstr;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function fetchGitVersion()
|
|
82
|
+
{
|
|
83
|
+
const result = await executeCommand('git', ['-v'])
|
|
84
|
+
if(result.retcode) return "Git not found"
|
|
85
|
+
var vstr = versionTrim(result.stdStr);
|
|
86
|
+
return vstr;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// compare to a minimum and report ok or error
|
|
90
|
+
|
|
91
|
+
function report(name:string, version:string, minStr:string):boolean
|
|
92
|
+
{
|
|
93
|
+
const ver = new VersionInfo(version);
|
|
94
|
+
const minVer = new VersionInfo(minStr);
|
|
95
|
+
let ok = (ver.isGreaterThan(minVer) || ver.equals(minVer))
|
|
96
|
+
if(ok) {
|
|
97
|
+
console.log(ac.green.bold("√ ")+ac.black.bold(name)+" "+ac.grey(version))
|
|
98
|
+
} else {
|
|
99
|
+
console.log(ac.red.bold("X ")+ac.black.bold(name)+ac.red.bold(" does not meet minimum version of ")+ac.blue(minStr))
|
|
100
|
+
}
|
|
101
|
+
return ok;
|
|
102
|
+
}
|