@tremho/mist-lift 2.2.8 → 2.4.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 (66) hide show
  1. package/README.md +9 -1
  2. package/build/commands/actions/updateDeployedPermissions.js +109 -0
  3. package/build/commands/actions/updateDeployedPermissions.js.map +1 -0
  4. package/build/commands/builtin/ApiDocMaker.js +18 -10
  5. package/build/commands/builtin/ApiDocMaker.js.map +1 -1
  6. package/build/commands/builtin/BuiltInHandler.js +6 -3
  7. package/build/commands/builtin/BuiltInHandler.js.map +1 -1
  8. package/build/commands/builtin/ExportWebroot.js +242 -0
  9. package/build/commands/builtin/ExportWebroot.js.map +1 -0
  10. package/build/commands/builtin/StageWebrootZip.js +10 -6
  11. package/build/commands/builtin/StageWebrootZip.js.map +1 -1
  12. package/build/commands/builtin/prebuilt-zips/API.zip +0 -0
  13. package/build/commands/builtin/prebuilt-zips/FileServe.zip +0 -0
  14. package/build/commands/builtin/prebuilt-zips/Webroot.zip +0 -0
  15. package/build/commands/builtin/webroot-export/s3webroot.js +117 -0
  16. package/build/commands/builtin/webroot-export/s3webroot.js.map +1 -0
  17. package/build/commands/deploy.js +6 -4
  18. package/build/commands/deploy.js.map +1 -1
  19. package/build/commands/package.js +31 -1
  20. package/build/commands/package.js.map +1 -1
  21. package/build/commands/publish.js +40 -13
  22. package/build/commands/publish.js.map +1 -1
  23. package/build/commands/start.js +2 -1
  24. package/build/commands/start.js.map +1 -1
  25. package/build/commands/update.js +1 -0
  26. package/build/commands/update.js.map +1 -1
  27. package/build/expressRoutes/all.js +1 -0
  28. package/build/expressRoutes/all.js.map +1 -1
  29. package/build/expressRoutes/functionBinder.js +159 -17
  30. package/build/expressRoutes/functionBinder.js.map +1 -1
  31. package/build/lib/DirectoryUtils.js +2 -1
  32. package/build/lib/DirectoryUtils.js.map +1 -1
  33. package/build/lib/IdSrc.js +29 -5
  34. package/build/lib/IdSrc.js.map +1 -1
  35. package/build/lib/TypeCheck.js +1204 -0
  36. package/build/lib/TypeCheck.js.map +1 -0
  37. package/build/lib/executeCommand.js +1 -1
  38. package/build/lib/executeCommand.js.map +1 -1
  39. package/build/lib/openAPI/openApiConstruction.js +238 -54
  40. package/build/lib/openAPI/openApiConstruction.js.map +1 -1
  41. package/build/lift.js +1 -1
  42. package/build/lift.js.map +1 -1
  43. package/package.json +5 -2
  44. package/src/commands/actions/updateDeployedPermissions.ts +80 -0
  45. package/src/commands/builtin/ApiDocMaker.ts +17 -10
  46. package/src/commands/builtin/BuiltInHandler.ts +7 -2
  47. package/src/commands/builtin/ExportWebroot.ts +195 -0
  48. package/src/commands/builtin/StageWebrootZip.ts +13 -5
  49. package/src/commands/builtin/prebuilt-zips/API.zip +0 -0
  50. package/src/commands/builtin/prebuilt-zips/FileServe.zip +0 -0
  51. package/src/commands/builtin/prebuilt-zips/Webroot.zip +0 -0
  52. package/src/commands/builtin/webroot-export/s3webroot.ts +78 -0
  53. package/src/commands/deploy.ts +6 -4
  54. package/src/commands/package.ts +33 -2
  55. package/src/commands/publish.ts +37 -12
  56. package/src/commands/start.ts +2 -1
  57. package/src/commands/update.ts +1 -0
  58. package/src/expressRoutes/all.ts +1 -0
  59. package/src/expressRoutes/functionBinder.ts +152 -16
  60. package/src/lib/DirectoryUtils.ts +2 -1
  61. package/src/lib/IdSrc.ts +17 -4
  62. package/src/lib/TypeCheck.ts +1168 -0
  63. package/src/lib/executeCommand.ts +1 -1
  64. package/src/lib/openAPI/openApiConstruction.ts +225 -41
  65. package/src/lift.ts +1 -1
  66. package/templateData/function-main-ts +8 -1
@@ -0,0 +1,80 @@
1
+ import * as ac from 'ansi-colors'
2
+
3
+ import path from 'path'
4
+ import fs from 'fs'
5
+ import { recurseDirectory } from '../../lib/DirectoryUtils'
6
+ import { decoratedName, getAccountId } from '../../lib/IdSrc'
7
+ import { getAWSCredentials, getSettings } from '../../lib/LiftConfig'
8
+ import { resolvePaths } from '../../lib/pathResolve'
9
+ import { LambdaClient, AddPermissionCommand } from '@aws-sdk/client-lambda'
10
+
11
+ // let projectPaths: { basePath: string, buildPath: string, functionPath: string, packagePath: string, verified: boolean }
12
+
13
+ export default async function updateDeployedPermissions (apiId: string): Promise<boolean | number | undefined> {
14
+ const projectPaths = resolvePaths()
15
+ if (!projectPaths.verified) {
16
+ console.log(ac.bold.magenta('current directory is not at project root'))
17
+ return -1
18
+ }
19
+
20
+ const funcsToDeploy: string[] = []
21
+ let firstDepth = 0
22
+ recurseDirectory(projectPaths.functionPath, (filepath, stats) => {
23
+ const depth = filepath.split(path.sep).length
24
+ if (firstDepth === 0) firstDepth = depth
25
+ if (stats.isDirectory() && depth === firstDepth) {
26
+ funcsToDeploy.push(path.basename(filepath))
27
+ }
28
+ return false
29
+ })
30
+
31
+ const accountId: string = await getAccountId()
32
+ const region: string = getSettings().awsPreferredRegion ?? ''
33
+
34
+ const client = new LambdaClient(getAWSCredentials())
35
+
36
+ for (const funcName of funcsToDeploy) {
37
+ // read the def file and get the method from there
38
+ const defPath = path.join(projectPaths.functionPath, funcName, 'src', 'definition.json')
39
+ const def = JSON.parse(fs.readFileSync(defPath).toString())
40
+ const method: string = def.method
41
+ const pathMap: string = def.pathMap
42
+
43
+ const arn = generateSourceArnForApiGateway(region, accountId, apiId, method, pathMap)
44
+ const dname = decoratedName(funcName)
45
+ console.log(ac.grey.italic('update permissions for resource ' + arn))
46
+ const command: any = new AddPermissionCommand({
47
+ FunctionName: dname,
48
+ StatementId: 'InvokePermission',
49
+ Action: 'lambda:invokeFunction',
50
+ Principal: 'apigateway.amazonaws.com',
51
+ SourceArn: arn
52
+ })
53
+ await client.send(command)
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Generates the correct SourceArn to authorize API Gateway to invoke a Lambda function.
59
+ *
60
+ * @param region - The AWS region, e.g., 'us-west-1'
61
+ * @param accountId - Your AWS account ID
62
+ * @param apiId - The API Gateway ID, e.g., 'sfr7yltmc3'
63
+ * @param method - The HTTP method, e.g., 'POST'
64
+ * @param routePath - The API route path, e.g., '/upstart/{artistId}/{id}'
65
+ * @returns The complete SourceArn string
66
+ */
67
+ export function generateSourceArnForApiGateway (
68
+ region: string,
69
+ accountId: string,
70
+ apiId: string,
71
+ method: string,
72
+ routePath: string
73
+ ): string {
74
+ // Clean leading slashes and replace path params with wildcards
75
+ const cleanedPath = routePath
76
+ .replace(/^\/+/, '') // remove leading slashes
77
+ .replace(/{[^}]+}/g, '*') // replace path params with *
78
+
79
+ return `arn:aws:execute-api:${region}:${accountId}:${apiId}/*/${method.toUpperCase()}/${cleanedPath}`
80
+ }
@@ -5,6 +5,7 @@ import { GetWebrootServePaths } from '../../lib/openAPI/WebrootFileSupport'
5
5
  import path from 'path'
6
6
  // import * as ac from 'ansi-colors'
7
7
  import { decoratedName } from '../../lib/IdSrc'
8
+ import { getWebrootSettings } from './ExportWebroot'
8
9
 
9
10
  export async function MakePublicApiDoc
10
11
  (
@@ -22,29 +23,32 @@ export async function MakeBuiltinApiDoc
22
23
  const defs = gatherFunctionDefinitions()
23
24
  // console.log(ac.gray.dim('>> after gatherfunctions'), defs)
24
25
  // console.log(ac.gray.dim('>>> addBuiltInDefinitions '))
25
- addBuiltInDefinitions(defs)
26
+ const wrs = await getWebrootSettings()
27
+ const withWebroot = (wrs.webrootMethod ?? 'SELF') === 'SELF'
28
+ // console.log("wrs.webrootMethod=",wrs.webrootMethod)
29
+ addBuiltInDefinitions(defs, withWebroot)
26
30
  // console.log(ac.gray.dim('>> after addBuiltIns'), defs)
27
31
  // console.log(ac.gray.dim('>>> buildOpenApi '))
28
- return await buildOpenApi(defs, false, yamlFile) //, true)
32
+ return await buildOpenApi(defs, true, true, yamlFile)
29
33
  }
30
34
 
31
- export function addBuiltInDefinitions (defs: any[]): void {
35
+ export function addBuiltInDefinitions (defs: any[], withWebroot: boolean): void {
32
36
  // console.warn("NOT ADDING ANY BUILTIN API INTEGRATIONS")
33
37
  // console.log("ADDING apiDef");
34
38
  // console.log(ac.gray.dim('>>>> pushing apiDef '), apiDef)
35
39
  defs.push(apiDef)
40
+ // console.log("withWebroot = "+withWebroot)
36
41
  // console.log(ac.gray.dim('>>>> pushing webrootDef '), webrootDef)
37
- defs.push(webrootDef)
42
+ defs.push(webrootDef) // we need to do this to support index or anything else.
38
43
 
39
44
  // console.log(ac.gray.dim('>>>> Adding webroot literals '))
40
45
  // console.warn("Adding webroot literals");
41
46
  // do just /docs and see how that goes
42
- /*
43
- const fsdef = Object.assign({}, fileServeDef) // copy
44
- fsdef.name = decoratedName('fileserve_docs')
45
- fsdef.pathMap = '/docs/{path}'
46
- defs.push(fsdef)
47
- */
47
+ // const fsdef = Object.assign({}, fileServeDef) // copy
48
+ // fsdef.name = decoratedName('fileserve_docs')
49
+ // fsdef.pathMap = '/docs/{path}'
50
+ // defs.push(fsdef)
51
+ // }
48
52
  const roots = GetWebrootServePaths()
49
53
  // console.log("roots", roots)
50
54
  // console.log(ac.gray.dim('>>>> roots here: '), roots)
@@ -55,6 +59,9 @@ export function addBuiltInDefinitions (defs: any[]): void {
55
59
  let rootName = rootPath
56
60
  // console.log(ac.gray.dim('>> rootName = '+rootName))
57
61
  while (rootName.includes('/')) rootName = rootName.replace('/', '').toLowerCase().trim()
62
+ // TODO: Trying to exclude here seems to remove our ability to get anything from root (webroot, should be there already)
63
+ // console.log('fileserve '+ rootName)
64
+ // if(!withWebroot && rootName !== 'docs') continue; // only copy docs for non-self export types
58
65
  // console.log(ac.gray.dim('>> past stupid error = '+rootName))
59
66
  const fileserve = Object.assign({}, fileServeDef) // copy
60
67
  fileserve.name = decoratedName('fileserve_' + rootName)
@@ -9,11 +9,16 @@ import path from 'path'
9
9
 
10
10
  export async function DeployWebrootBuiltIn
11
11
  (
12
+ externalizedFolders: boolean = true
12
13
  ): Promise<void> {
13
14
  // console.warn(">> DeployWebrootBuiltIn")
15
+ // const withRoot = externalizedFolders
16
+ // const withFolders = true
14
17
  const wrZip = await StageWebrootZip()
15
- // console.log(">> Deploy Webroot Builtin from "+wrZip)
16
- await DeployBuiltInZip('Webroot', wrZip)
18
+ const wrName = decoratedName('Webroot')
19
+ // console.log(">> Deploy Webroot Builtin from "+wrZip+" as "+wrName)
20
+
21
+ await DeployBuiltInZip(wrName, wrZip)
17
22
  // remove temp zip when done
18
23
  // console.warn("a.zip is left behind")
19
24
  fs.rmSync(wrZip, { recursive: true })
@@ -0,0 +1,195 @@
1
+ import * as path from 'path'
2
+ import * as fs from 'fs'
3
+ import * as ac from 'ansi-colors'
4
+ import { resolvePaths } from '../../lib/pathResolve'
5
+ import { recurseDirectory } from '../../lib/DirectoryUtils'
6
+ // import { isNewer } from '../../lib/fileCompare'
7
+ import { executeCommand } from '../../lib/executeCommand'
8
+ // import { mkdirSync } from 'fs'
9
+ import { DeployRootFileserves, DeployWebrootBuiltIn } from './BuiltInHandler'
10
+ // import { ServiceSettingsData } from '@tremho/inverse-y'
11
+ import { exportWebrootToS3, getS3Prefix } from './webroot-export/s3webroot'
12
+
13
+ /*
14
+ Here we want to handle exporting the webroot to other serving sources according to configuration.
15
+
16
+ - Read the config options
17
+ - enumerate the webroot and find recent changes
18
+ - write these file paths to a temp file
19
+ - per config, call the handler that will do this
20
+ - to S3
21
+ - to script
22
+ later:
23
+ - to Blob ?
24
+ -
25
+
26
+ */
27
+
28
+ /*
29
+ Script will be called with comma delimited list of files as arg 1, and options (string) as arg2
30
+ */
31
+ export class WebrootScriptOptions {
32
+ public scriptName = '' // name of script to call (relative to project root)
33
+ public options = '' // options passed as second parameter to script (see comment above)
34
+ }
35
+ export class WebrootS3Options {
36
+ public unused = '' // empty (lint)
37
+ }
38
+ export class WebrootDefaultOptions {
39
+ public unused = '' // empty (lint)
40
+ }
41
+
42
+ export type WebrootOptions = WebrootDefaultOptions | WebrootScriptOptions | WebrootS3Options
43
+
44
+ /*
45
+ For non-SELF types, only the files *not* in subdirectories will be packaged to the deployed webroot
46
+ */
47
+ export enum WebrootExportType {
48
+ SELF = 'SELF', // Webroot is packaged and deployed per existing implementation, including all subdirectories
49
+ SCRIPT = 'SCRIPT', // a build-time script is called to copy all updated files to their target
50
+ S3 = 'S3' // built-in function (instead of script) is called for an S3 target
51
+ }
52
+
53
+ /*
54
+ This is what webrootConfig.json looks like
55
+ */
56
+ export class WebrootExportConfig {
57
+ public type: WebrootExportType = WebrootExportType.SELF
58
+ public options: WebrootOptions = new WebrootDefaultOptions()
59
+ }
60
+
61
+ let basePath = ''
62
+
63
+ /**
64
+ * Exports the webroot according to configuration
65
+ */
66
+ export async function ExportWebroot (): Promise<any> {
67
+ const projectPaths = resolvePaths()
68
+ basePath = projectPaths.basePath
69
+ const webrootConfig = readWebrootConfig(path.join(basePath, 'webrootConfig.json'))
70
+ // console.log(">> ExportWebroot", {webrootConfig})
71
+
72
+ const fla = await getUpdatedExportFileList()
73
+ switch (webrootConfig.type) {
74
+ case WebrootExportType.SELF:
75
+ await exportSelf()
76
+ break
77
+ case WebrootExportType.S3:
78
+ await exportWebrootToS3(fla, webrootConfig.options as WebrootS3Options)
79
+ break
80
+ case WebrootExportType.SCRIPT:
81
+ await exportScript(fla, webrootConfig.options as WebrootScriptOptions)
82
+ break
83
+ default: {
84
+ throw new Error(`UNSUPPORTED WEBROOT EXPORT ${WebrootExportType[webrootConfig.type]}`)
85
+ }
86
+ }
87
+ }
88
+ export async function getWebrootSettings (): Promise<{ webrootMethod: string, webrootBaseUrl: string }> {
89
+ const projectPaths = resolvePaths()
90
+ basePath = projectPaths.basePath
91
+ const webrootConfig = readWebrootConfig(path.join(basePath, 'webrootConfig.json'))
92
+ let baseUrl = ''
93
+ switch (webrootConfig.type) {
94
+ case WebrootExportType.SELF:
95
+ baseUrl = ''
96
+ break
97
+ case WebrootExportType.S3:
98
+ baseUrl = await getS3Prefix()
99
+ break
100
+ case WebrootExportType.SCRIPT: {
101
+ const options = webrootConfig.options as WebrootScriptOptions
102
+ const scriptPath = path.join(basePath, options.scriptName)
103
+ const out = await executeCommand(scriptPath, ['--prefix'], basePath, false)
104
+ baseUrl = out.stdStr.trim()
105
+ break
106
+ }
107
+ default: {
108
+ const unreachable: never = webrootConfig.type
109
+ throw new Error(`UNSUPPORTED WEBROOT EXPORT ${unreachable}`)
110
+ }
111
+ }
112
+ return {
113
+ webrootMethod: webrootConfig.type.toString(),
114
+ webrootBaseUrl: baseUrl
115
+ }
116
+ }
117
+
118
+ let warned = false
119
+ function readWebrootConfig (configPath: string): WebrootExportConfig {
120
+ let conf = new WebrootExportConfig()
121
+ let content = ''
122
+ // console.log("... reading from "+configPath)
123
+ try {
124
+ // console.log(" >> readWebrootConfig")
125
+ content = fs.readFileSync(configPath).toString()
126
+ conf = JSON.parse(content)
127
+ } catch (e: any) {
128
+ if (!warned) {
129
+ warned = true
130
+ console.error(ac.yellow.bold('Warning: Failed to read or parse ' + configPath))
131
+ console.warn(ac.yellow.bold.dim("Falling back to 'self' publish mode"))
132
+ }
133
+ }
134
+
135
+ return conf
136
+ }
137
+
138
+ async function exportSelf (): Promise<void> {
139
+ // zip up everything
140
+ // console.log(">> exportSelf")
141
+ // console.log(" >> deployWebrootBuiltIn")
142
+ await DeployWebrootBuiltIn(false)
143
+ // console.log(" >> deployRootFileserves")
144
+ await DeployRootFileserves()
145
+ }
146
+
147
+ async function exportScript (fla: string[], options: WebrootScriptOptions) {
148
+ // console.log(">> exportScript")
149
+ // console.log(" >> DeployWebrootBuiltIn")
150
+ // await DeployWebrootBuiltIn(true)
151
+ console.log(ac.bold.green(`calling webroot exportScript ${options.scriptName}`))
152
+ // console.log("files", fla)
153
+ const fl = fla.join(',')
154
+ const args = [fl]
155
+ // args.unshift(options.options)
156
+ // console.log("args", args)
157
+
158
+ const scriptPath = path.join(basePath, options.scriptName)
159
+ // console.log("Executing script", scriptPath)
160
+ await executeCommand(scriptPath, args, basePath, true)
161
+ }
162
+
163
+ async function getUpdatedExportFileList (): Promise<string[]> {
164
+ // console.log(">> getUpdatedExportFileList")
165
+ // find the last published time from .published file
166
+ let lastPublished = 0
167
+ try {
168
+ const pubjson = JSON.parse(fs.readFileSync(path.join(basePath, '.published')).toString())
169
+ lastPublished = pubjson.time
170
+ // console.log("last published ", lastPublished)
171
+ } catch (e: any) {
172
+ console.warn(ac.yellow.italic.dim('no .published information available - full export'))
173
+ }
174
+ const outbin: string[] = []
175
+ // enumerate at webroot and files from all non-root directories
176
+ const folder = path.join(basePath, 'webroot')
177
+ const rootpathsteps = folder.split(path.sep).length
178
+ const enumerating = true
179
+
180
+ function gatherFiles (filepath: string, stats: fs.Stats): boolean {
181
+ // console.log(filepath, {steps:filepath.split(path.sep).length, rootpathsteps, isDir:stats.isDirectory()})
182
+ if (filepath.split(path.sep).length > rootpathsteps + 1) {
183
+ // console.log({filepath, mtime:stats.mtime.getTime(), lastPublished})
184
+ if (stats.mtime.getTime() >= lastPublished) {
185
+ filepath = '+' + filepath
186
+ // console.log("will update "+filepath)
187
+ }
188
+ outbin.push(filepath)
189
+ }
190
+ return false
191
+ }
192
+ // console.log("recursing folder ", folder)
193
+ await recurseDirectory(folder, gatherFiles)
194
+ return outbin
195
+ }
@@ -11,6 +11,8 @@ import { rmSync } from 'fs'
11
11
 
12
12
  export async function StageWebrootZip
13
13
  (
14
+ withRoot: boolean = true,
15
+ withFolders: boolean = true
14
16
  ): Promise<string> {
15
17
  // console.log(">>>> staging webroot to zip")
16
18
  const projectPaths = resolvePaths()
@@ -43,6 +45,7 @@ export async function StageWebrootZip
43
45
  await fs.mkdirSync(zipFilesPath)
44
46
 
45
47
  // todo: read the redirects.json file
48
+ // todo: Document as deprecated
46
49
  let redirected: string[] = []
47
50
  try {
48
51
  const redir = JSON.parse(fs.readFileSync(path.join(webroot, 'redirects.json')).toString())
@@ -55,13 +58,18 @@ export async function StageWebrootZip
55
58
  // console.log(">>>> enumerating "+webroot)
56
59
  await recurseDirectory(webroot, (filepath, stats) => {
57
60
  const relPath = filepath.substring(webroot.length)
58
- if (stats.isDirectory()) {
61
+ if (stats.isDirectory() && withFolders) {
59
62
  fs.mkdirSync(zipFilesPath + relPath, { recursive: true })
60
63
  } else {
61
- // console.log(ac.grey.dim('>> considering ' + relPath))
62
- if (!redirected.includes(relPath.substring(1))) {
63
- // console.log(ac.grey.dim('>> copying...'))
64
- fs.copyFileSync(filepath, zipFilesPath + relPath) // copy only if not in redirected list
64
+ if (
65
+ (relPath.includes(path.sep) && withFolders) ||
66
+ ((!relPath.includes(path.sep)) && withRoot)
67
+ ) {
68
+ // TODO: Deprecate redirection. we'll continue to supoort it here, though for now
69
+ if (!redirected.includes(relPath.substring(1))) {
70
+ // console.log(ac.grey.dim('>> copying...'))
71
+ fs.copyFileSync(filepath, zipFilesPath + relPath) // copy only if not in redirected list
72
+ }
65
73
  }
66
74
  }
67
75
  return false
@@ -0,0 +1,78 @@
1
+ import { S3Client } from '@aws-sdk/client-s3'
2
+ import { s3ListObjects, s3CreateBucket, s3UploadFile, s3Delete, S3ActionsLog } from '@tremho/basic-s3-actions'
3
+ import * as fs from 'fs'
4
+ import * as ac from 'ansi-colors'
5
+ import { WebrootS3Options, WebrootScriptOptions } from '../ExportWebroot'
6
+ import { DeployRootFileserves, DeployWebrootBuiltIn } from '../BuiltInHandler'
7
+
8
+ export async function exportWebrootToS3 (exportFileList: string[], options?: WebrootS3Options) {
9
+ const bucketName = determineBucketName()
10
+ console.log(ac.green.bold('webroot export to s3 bucket name ' + bucketName))
11
+ let existing: string[] = []
12
+ try {
13
+ // console.log("fetching existing")
14
+ existing = await getExistingDeployedFileList(bucketName)
15
+ } catch (e: any) {
16
+ console.log(ac.blue.italic('creating webroot bucket ' + bucketName))
17
+ await s3CreateBucket(bucketName, true)
18
+ // console.log("bucket created")
19
+ }
20
+
21
+ console.log(ac.blue.italic('Deploying base webroot handling'))
22
+ await DeployWebrootBuiltIn(true)
23
+ await DeployRootFileserves()
24
+
25
+ // console.log("existing ", existing)
26
+
27
+ let update = false
28
+ for (let file of exportFileList) {
29
+ update = (file.charAt(0) == '+')
30
+ if (update) file = file.substring(1)
31
+ const i = file.indexOf('/webroot/') + 9
32
+ const sfile = file.substring(i)
33
+ if (!sfile) continue
34
+ if (sfile.substring(0, 4) === 'docs') continue // keep these in self-serve only
35
+ const xi = existing.indexOf(sfile)
36
+ let disp = 'created'
37
+ if (xi !== -1) {
38
+ existing.splice(xi, 1)
39
+ disp = 'updated'
40
+ }
41
+ if (update) {
42
+ // console.log(sfile+"...")
43
+ try {
44
+ await s3UploadFile(bucketName, file, sfile)
45
+ console.log(ac.green.italic(`${disp} ${sfile}`))
46
+ } catch (e: any) {
47
+ break
48
+ }
49
+ }
50
+ }
51
+ for (const leftover of existing) {
52
+ await s3Delete(bucketName, leftover)
53
+ console.log(ac.green.italic(`deleted ${leftover}`))
54
+ }
55
+ }
56
+
57
+ function determineBucketName () {
58
+ let pkg: any = {}
59
+ try {
60
+ pkg = JSON.parse(fs.readFileSync('./package.json').toString())
61
+ } catch (e: any) {
62
+ console.error(ac.bold.red('Failed to read package.json ' + e.message))
63
+ }
64
+ return (pkg.author + '-' + pkg.name).toLowerCase()
65
+ }
66
+
67
+ async function getExistingDeployedFileList (bucketName: string) {
68
+ // S3ActionsLog.setMinimumLevel('Console', 'trace')
69
+ // S3ActionsLog.Debug("Getting bucket list for "+bucketName)
70
+ const list = await s3ListObjects(bucketName)
71
+ // S3ActionsLog.setMinimumLevel('Console', 'error')
72
+ return list
73
+ }
74
+
75
+ export function getS3Prefix () {
76
+ const name = determineBucketName()
77
+ return `https://${name}.s3.us-west-1.amazonaws.com/`
78
+ }
@@ -106,11 +106,11 @@ export async function deployPackage (
106
106
  try {
107
107
  def = JSON.parse(fs.readFileSync(defFile).toString())
108
108
  } catch (e: any) {
109
- // hack for assigning a definition -- the defs from ApiDocMaker don't appear here
110
- if (funcName === 'Webroot') {
109
+ // hack for assigning a definition -- the defs from the MistBuiltIn def file don't appear here
110
+ if (funcName.includes('Webroot')) {
111
111
  def.name = 'Webroot'
112
112
  def.timeoutSeconds = 8
113
- def.memorySize = 256
113
+ def.memorySize = 8192
114
114
  }
115
115
  }
116
116
  const timeout: number = def.timeoutSeconds ?? 0 // zero will mean default (3 seconds on AWS)
@@ -135,7 +135,9 @@ export async function deployPackage (
135
135
  const response: any = await CreateCloudFunction(dFuncName, zipFile, timeout, memorySize)
136
136
  const parts = response.FunctionArn.split(':')
137
137
  const principal = parts[4]
138
- await AddPermissions(client, dFuncName, principal)
138
+ if (dFuncName.includes('Webroot') || dFuncName.includes('FileServe')) {
139
+ await AddPermissions(client, dFuncName, principal)
140
+ }
139
141
  let deployMsg: string = `Successfully deployed ${funcName}`
140
142
  // console.log(ac.gray.dim('>> deploy trace 1'))
141
143
  if (memorySize > 0 || timeout > 0) {
@@ -11,6 +11,8 @@ import { executeCommand } from '../lib/executeCommand'
11
11
  import { isNewerFile } from '../lib/fileCompare'
12
12
  import { doBuildAsync } from './build'
13
13
  import { FolderToZip } from '../lib/utils'
14
+ import { getWebrootSettings } from './builtin/ExportWebroot'
15
+ import { getServiceSettings, setAws, setWebroot } from '@tremho/inverse-y'
14
16
 
15
17
  // test then package
16
18
  export async function doPackageAsync (
@@ -123,6 +125,8 @@ async function packageFunction (funcName: string): Promise<number> {
123
125
  // - write out new package.json to workPath
124
126
  // console.log("writing package.json", pkgjson)
125
127
  fs.writeFileSync(path.join(workPath, 'package.json'), JSON.stringify(pkgjson, null, 2))
128
+
129
+ const webrootExport = await getWebrootSettings()
126
130
  // - execute npm i at workpath, create node_modules
127
131
  await executeCommand('npm i', [], workPath).then(() => {
128
132
  // copy the lambda function
@@ -148,10 +152,37 @@ async function packageFunction (funcName: string): Promise<number> {
148
152
  const runmainPath = path.join(workPath, 'runmain.mjs')
149
153
  fs.writeFileSync(runmainPath, fs.readFileSync(templatePath))
150
154
 
155
+ // put svcsettings.json into place
156
+
157
+ // Get publish Url from existing .published file (if any).
158
+ // If we haven't published before, we won't have this, but I think that's okay for now at least
159
+
160
+ try {
161
+ // console.log("creating service settings file")
162
+ const pubsrc = path.join(workPath, '..', '.published')
163
+ let pubInfo: any = {}
164
+ // console.log("checking pubsrc at ", pubsrc)
165
+ if (fs.existsSync(pubsrc)) {
166
+ // console.log("found it")
167
+ pubInfo = JSON.parse(fs.readFileSync(pubsrc).toString())
168
+ // console.log({pubInfo})
169
+ }
170
+ const publishUrl = pubInfo.url ?? '/'
171
+
172
+ const stage = publishUrl.substring(publishUrl.lastIndexOf('/') + 1)
173
+ setWebroot(webrootExport.webrootMethod, webrootExport.webrootBaseUrl)
174
+ setAws(stage, publishUrl)
175
+ // console.log("getServiceSettings", getServiceSettings())
176
+ const settingsFile = path.join(projectPaths.basePath, '.package_temp', 'svcsettings.json')
177
+ fs.writeFileSync(settingsFile, JSON.stringify(getServiceSettings()))
178
+ // if (fs.existsSync(settingsFile)) console.log("file confirmed at ", settingsFile)
179
+ } catch (e: any) {
180
+ console.error(e)
181
+ }
182
+ // console.log("push to zip stack ", {zipFile})
151
183
  all.push(FolderToZip(workPath, zipFile))
152
- // console.log("now zip it")
153
184
  })
154
-
185
+ // console.log("all", {all})
155
186
  return await Promise.all(all).then(() => {
156
187
  return error
157
188
  })