@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.
Files changed (121) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +37 -0
  3. package/build/commands/actions/initQuestions.js +136 -0
  4. package/build/commands/actions/initQuestions.js.map +1 -0
  5. package/build/commands/actions/makePackageJson.js +2 -0
  6. package/build/commands/actions/makePackageJson.js.map +1 -0
  7. package/build/commands/actions/setupPackageJson.js +68 -0
  8. package/build/commands/actions/setupPackageJson.js.map +1 -0
  9. package/build/commands/build.js +191 -0
  10. package/build/commands/build.js.map +1 -0
  11. package/build/commands/builtin/ApiDocMaker.js +72 -0
  12. package/build/commands/builtin/ApiDocMaker.js.map +1 -0
  13. package/build/commands/builtin/BuiltInHandler.js +62 -0
  14. package/build/commands/builtin/BuiltInHandler.js.map +1 -0
  15. package/build/commands/builtin/DeployBuiltInZip.js +57 -0
  16. package/build/commands/builtin/DeployBuiltInZip.js.map +1 -0
  17. package/build/commands/builtin/StageWebrootZip.js +70 -0
  18. package/build/commands/builtin/StageWebrootZip.js.map +1 -0
  19. package/build/commands/builtin/prebuilt-zips/API.zip +0 -0
  20. package/build/commands/builtin/prebuilt-zips/FileServe.zip +0 -0
  21. package/build/commands/builtin/prebuilt-zips/Webroot.zip +0 -0
  22. package/build/commands/create.js +75 -0
  23. package/build/commands/create.js.map +1 -0
  24. package/build/commands/deploy.js +187 -0
  25. package/build/commands/deploy.js.map +1 -0
  26. package/build/commands/doctor.js +137 -0
  27. package/build/commands/doctor.js.map +1 -0
  28. package/build/commands/help.js +205 -0
  29. package/build/commands/help.js.map +1 -0
  30. package/build/commands/init.js +92 -0
  31. package/build/commands/init.js.map +1 -0
  32. package/build/commands/package.js +249 -0
  33. package/build/commands/package.js.map +1 -0
  34. package/build/commands/publish.js +344 -0
  35. package/build/commands/publish.js.map +1 -0
  36. package/build/commands/settings.js +95 -0
  37. package/build/commands/settings.js.map +1 -0
  38. package/build/commands/start.js +66 -0
  39. package/build/commands/start.js.map +1 -0
  40. package/build/commands/test.js +52 -0
  41. package/build/commands/test.js.map +1 -0
  42. package/build/commands/user.js +20 -0
  43. package/build/commands/user.js.map +1 -0
  44. package/build/expressRoutes/all.js +129 -0
  45. package/build/expressRoutes/all.js.map +1 -0
  46. package/build/expressRoutes/api.js +22 -0
  47. package/build/expressRoutes/api.js.map +1 -0
  48. package/build/expressRoutes/functionBinder.js +191 -0
  49. package/build/expressRoutes/functionBinder.js.map +1 -0
  50. package/build/lib/CaseUtils.js +57 -0
  51. package/build/lib/CaseUtils.js.map +1 -0
  52. package/build/lib/DirectoryUtils.js +37 -0
  53. package/build/lib/DirectoryUtils.js.map +1 -0
  54. package/build/lib/LiftConfig.js +83 -0
  55. package/build/lib/LiftConfig.js.map +1 -0
  56. package/build/lib/LiftVersion.js +117 -0
  57. package/build/lib/LiftVersion.js.map +1 -0
  58. package/build/lib/Tests/fileCompare.test.js +55 -0
  59. package/build/lib/Tests/fileCompare.test.js.map +1 -0
  60. package/build/lib/askQuestion.js +41 -0
  61. package/build/lib/askQuestion.js.map +1 -0
  62. package/build/lib/executeCommand.js +45 -0
  63. package/build/lib/executeCommand.js.map +1 -0
  64. package/build/lib/fileCompare.js +48 -0
  65. package/build/lib/fileCompare.js.map +1 -0
  66. package/build/lib/openAPI/ApiBuildCollector.js +58 -0
  67. package/build/lib/openAPI/ApiBuildCollector.js.map +1 -0
  68. package/build/lib/openAPI/WebrootFileSupport.js +44 -0
  69. package/build/lib/openAPI/WebrootFileSupport.js.map +1 -0
  70. package/build/lib/openAPI/openApiConstruction.js +203 -0
  71. package/build/lib/openAPI/openApiConstruction.js.map +1 -0
  72. package/build/lib/pathResolve.js +27 -0
  73. package/build/lib/pathResolve.js.map +1 -0
  74. package/build/lib/utils.js +76 -0
  75. package/build/lib/utils.js.map +1 -0
  76. package/build/lift.js +124 -0
  77. package/build/lift.js.map +1 -0
  78. package/package.json +69 -0
  79. package/src/commands/actions/initQuestions.ts +131 -0
  80. package/src/commands/actions/makePackageJson.ts +0 -0
  81. package/src/commands/actions/setupPackageJson.ts +36 -0
  82. package/src/commands/build.ts +165 -0
  83. package/src/commands/builtin/ApiDocMaker.ts +70 -0
  84. package/src/commands/builtin/BuiltInHandler.ts +51 -0
  85. package/src/commands/builtin/DeployBuiltInZip.ts +27 -0
  86. package/src/commands/builtin/StageWebrootZip.ts +39 -0
  87. package/src/commands/builtin/prebuilt-zips/API.zip +0 -0
  88. package/src/commands/builtin/prebuilt-zips/FileServe.zip +0 -0
  89. package/src/commands/builtin/prebuilt-zips/Webroot.zip +0 -0
  90. package/src/commands/create.ts +55 -0
  91. package/src/commands/deploy.ts +171 -0
  92. package/src/commands/doctor.ts +102 -0
  93. package/src/commands/help.ts +171 -0
  94. package/src/commands/init.ts +62 -0
  95. package/src/commands/package.ts +228 -0
  96. package/src/commands/publish.ts +350 -0
  97. package/src/commands/settings.ts +76 -0
  98. package/src/commands/start.ts +46 -0
  99. package/src/commands/test.ts +38 -0
  100. package/src/commands/user.ts +20 -0
  101. package/src/expressRoutes/all.ts +104 -0
  102. package/src/expressRoutes/api.ts +24 -0
  103. package/src/expressRoutes/functionBinder.ts +169 -0
  104. package/src/lib/CaseUtils.ts +68 -0
  105. package/src/lib/DirectoryUtils.ts +36 -0
  106. package/src/lib/LiftConfig.ts +83 -0
  107. package/src/lib/LiftVersion.ts +95 -0
  108. package/src/lib/Tests/dir1/file.1 +0 -0
  109. package/src/lib/Tests/dir1/file.2 +0 -0
  110. package/src/lib/Tests/dir2/file.1 +0 -0
  111. package/src/lib/Tests/fileCompare.test.ts +34 -0
  112. package/src/lib/askQuestion.ts +18 -0
  113. package/src/lib/executeCommand.ts +38 -0
  114. package/src/lib/fileCompare.ts +46 -0
  115. package/src/lib/openAPI/ApiBuildCollector.ts +47 -0
  116. package/src/lib/openAPI/WebrootFileSupport.ts +21 -0
  117. package/src/lib/openAPI/openApiConstruction.ts +202 -0
  118. package/src/lib/pathResolve.ts +32 -0
  119. package/src/lib/utils.ts +45 -0
  120. package/src/lift.ts +82 -0
  121. 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
+ }
@@ -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
+ }