@stacksjs/cloud 0.58.51 → 0.58.52

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/dist/index.js CHANGED
@@ -1,15 +1,4 @@
1
1
  // @bun
2
- var __defProp = Object.defineProperty;
3
- var __export = (target, all) => {
4
- for (var name in all)
5
- __defProp(target, name, {
6
- get: all[name],
7
- enumerable: true,
8
- configurable: true,
9
- set: (newValue) => all[name] = () => newValue
10
- });
11
- };
12
-
13
2
  // src/helpers.ts
14
3
  import {CloudFormation} from "@aws-sdk/client-cloudformation";
15
4
  import {CloudWatchLogsClient, DeleteLogGroupCommand, DescribeLogGroupsCommand} from "@aws-sdk/client-cloudwatch-logs";
@@ -21,7 +10,7 @@ import {Lambda} from "@aws-sdk/client-lambda";
21
10
  import {ContactType, Route53Domains} from "@aws-sdk/client-route-53-domains";
22
11
  import {ListBucketsCommand, S3} from "@aws-sdk/client-s3";
23
12
  import {config as config2} from "@stacksjs/config";
24
- import {err, handleError as handleError2, ok} from "@stacksjs/error-handling";
13
+ import {err, handleError, ok} from "@stacksjs/error-handling";
25
14
  import {log} from "@stacksjs/logging";
26
15
  import {path as p} from "@stacksjs/path";
27
16
  import {rimraf} from "@stacksjs/utils";
@@ -127,6 +116,7 @@ async function deleteJumpBox(stackName) {
127
116
  const jumpBoxId = await getJumpBoxInstanceId();
128
117
  if (!jumpBoxId)
129
118
  return err("Jump-box not found");
119
+ log.info(`Deleting jump-box ${jumpBoxId}...`);
130
120
  return await deleteEc2Instance(jumpBoxId, stackName);
131
121
  }
132
122
  async function deleteIamUsers() {
@@ -150,7 +140,7 @@ async function deleteIamUsers() {
150
140
  });
151
141
  await Promise.all(promises).catch((error) => {
152
142
  console.error(`Error deleting user: ${error}`);
153
- return err(handleError2("Error deleting Stacks IAM users", error));
143
+ return err(handleError("Error deleting Stacks IAM users", error));
154
144
  });
155
145
  return ok(`Stacks IAM users deleted for team ${teamName}`);
156
146
  }
@@ -168,39 +158,39 @@ async function deleteStacksBuckets() {
168
158
  log.info(`Finished listing bucket ${bucketName} objects`);
169
159
  if (objects.Contents) {
170
160
  log.info("Deleting bucket objects...");
171
- await Promise.all(objects.Contents.map((object) => s3.deleteObject({ Bucket: bucketName, Key: object.Key || "" }).catch((error) => handleError2(error))));
161
+ await Promise.all(objects.Contents.map((object) => s3.deleteObject({ Bucket: bucketName, Key: object.Key || "" }).catch((error) => handleError(error))));
172
162
  log.info(`Finished deleting objects from bucket ${bucketName}`);
173
163
  }
174
164
  log.info(`Deleting bucket ${bucketName} versions...`);
175
165
  try {
176
166
  const versions = await s3.listObjectVersions({ Bucket: bucketName });
177
167
  if (versions.Versions) {
178
- await Promise.all(versions.Versions.map((version) => s3.deleteObject({ Bucket: bucketName, Key: version.Key || "", VersionId: version.VersionId }))).catch((error) => handleError2(error));
168
+ await Promise.all(versions.Versions.map((version) => s3.deleteObject({ Bucket: bucketName, Key: version.Key || "", VersionId: version.VersionId }))).catch((error) => handleError(error));
179
169
  log.info(`Finished deleting versions from bucket ${bucketName}`);
180
170
  }
181
171
  log.info(`Deleting bucket ${bucketName} delete markers...`);
182
172
  if (versions.DeleteMarkers) {
183
- await Promise.all(versions.DeleteMarkers.map((marker) => s3.deleteObject({ Bucket: bucketName, Key: marker.Key || "", VersionId: marker.VersionId }))).catch((error) => handleError2(error));
173
+ await Promise.all(versions.DeleteMarkers.map((marker) => s3.deleteObject({ Bucket: bucketName, Key: marker.Key || "", VersionId: marker.VersionId }))).catch((error) => handleError(error));
184
174
  log.info(`Finished deleting delete markers from bucket ${bucketName}`);
185
175
  }
186
176
  const uploads = await s3.listMultipartUploads({ Bucket: bucketName });
187
177
  if (uploads.Uploads) {
188
178
  log.info("Aborting bucket multipart uploads...");
189
- await Promise.all(uploads.Uploads.map((upload) => s3.abortMultipartUpload({ Bucket: bucketName, Key: upload.Key || "", UploadId: upload.UploadId }))).catch((error) => handleError2(error));
179
+ await Promise.all(uploads.Uploads.map((upload) => s3.abortMultipartUpload({ Bucket: bucketName, Key: upload.Key || "", UploadId: upload.UploadId }))).catch((error) => handleError(error));
190
180
  log.info(`Finished aborting multipart uploads from bucket ${bucketName}`);
191
181
  }
192
- await s3.deleteBucket({ Bucket: bucketName }).catch((error) => handleError2(error));
182
+ await s3.deleteBucket({ Bucket: bucketName }).catch((error) => handleError(error));
193
183
  log.info(`Bucket ${bucketName} deleted`);
194
184
  } catch (error) {
195
185
  log.info(`Error listing bucket ${bucketName} versions`, error);
196
186
  }
197
187
  });
198
188
  await Promise.all(promises).catch((error) => {
199
- return err(handleError2("Error deleting stacks buckets", error));
189
+ return err(handleError("Error deleting stacks buckets", error));
200
190
  });
201
191
  return ok("Stacks buckets deleted");
202
192
  } catch (error) {
203
- return err(handleError2("Error deleting stacks buckets", error));
193
+ return err(handleError("Error deleting stacks buckets", error));
204
194
  }
205
195
  }
206
196
  async function deleteStacksFunctions() {
@@ -215,7 +205,7 @@ async function deleteStacksFunctions() {
215
205
  log.info("Function is replicated, skipping...");
216
206
  return ok("CloudFront is still deleting the some functions. Try again later.");
217
207
  }
218
- return err(handleError2("Error deleting stacks functions", error));
208
+ return err(handleError("Error deleting stacks functions", error));
219
209
  });
220
210
  return ok("Stacks functions deleted");
221
211
  }
@@ -231,7 +221,7 @@ async function deleteLogGroups() {
231
221
  }
232
222
  return ok("Log groups deleted");
233
223
  } catch (error) {
234
- return err(handleError2("Error deleting log groups", error));
224
+ return err(handleError("Error deleting log groups", error));
235
225
  }
236
226
  }
237
227
  async function deleteParameterStore() {
@@ -244,7 +234,7 @@ async function deleteParameterStore() {
244
234
  return ok("No stacks parameters found");
245
235
  const promises = stacksParameters.map((param) => ssm.deleteParameter({ Name: param.Name || "" }));
246
236
  await Promise.all(promises).catch((error) => {
247
- return err(handleError2("Error deleting parameter store", error));
237
+ return err(handleError("Error deleting parameter store", error));
248
238
  });
249
239
  return ok("Parameter store deleted");
250
240
  }
@@ -255,7 +245,7 @@ async function deleteCdkRemnants() {
255
245
  p.cloudPath("cdk.context.json")
256
246
  ]));
257
247
  } catch (error) {
258
- return err(handleError2("Error deleting CDK remnants", error));
248
+ return err(handleError("Error deleting CDK remnants", error));
259
249
  }
260
250
  }
261
251
  async function hasBeenDeployed() {
@@ -264,7 +254,7 @@ async function hasBeenDeployed() {
264
254
  const response = await s3.send(new ListBucketsCommand({}));
265
255
  return ok(response.Buckets?.some((bucket) => bucket.Name?.includes(config2.app.name?.toLocaleLowerCase() || "stacks")) || false);
266
256
  } catch (error) {
267
- return err(handleError2("Error checking if the app has been deployed", error));
257
+ return err(handleError("Error checking if the app has been deployed", error));
268
258
  }
269
259
  }
270
260
  async function getJumpBoxInstanceProfileName() {
@@ -488,729 +478,10 @@ class AiStack {
488
478
  // src/cloud/cdn.ts
489
479
  import {Duration as Duration2, Fn, CfnOutput as Output2, aws_cloudfront as cloudfront, aws_cloudfront_origins as origins, aws_route53 as route53, aws_route53_targets as targets} from "aws-cdk-lib";
490
480
  import {config as config6} from "@stacksjs/config";
491
-
492
- // /home/runner/work/stacks/stacks/storage/framework/core/storage/src/files.ts
493
- import {detectIndent, detectNewline} from "@stacksjs/strings";
494
- import {dirname, join as join2, path as p2} from "@stacksjs/path";
495
-
496
- // /home/runner/work/stacks/stacks/storage/framework/core/arrays/src/helpers.ts
497
- import {clamp} from "@stacksjs/utils";
498
- // /home/runner/work/stacks/stacks/storage/framework/core/arrays/src/contains.ts
499
- function contains(needle, haystack) {
500
- return haystack.some((hay) => needle.includes(hay));
501
- }
502
- // /home/runner/work/stacks/stacks/storage/framework/core/storage/src/fs.ts
503
- import {mkdirSync, writeFileSync} from "fs";
504
- import * as fs from "fs-extra";
505
- import {pathExists as existsSync} from "fs-extra";
506
- async function exists(path2) {
507
- return await existsSync(path2);
508
- }
509
-
510
- // /home/runner/work/stacks/stacks/storage/framework/core/storage/src/files.ts
511
- async function readJsonFile(name, cwd) {
512
- const file = await readTextFile(name, cwd);
513
- const data = JSON.parse(file.data);
514
- const indent = detectIndent(file.data).indent;
515
- const newline = detectNewline(file.data);
516
- return { ...file, data, indent, newline };
517
- }
518
- async function readPackageJson(name, cwd) {
519
- const file = await readJsonFile(name, cwd);
520
- return file.data;
521
- }
522
- async function writeFile(path3, data) {
523
- if (typeof path3 === "string") {
524
- const dirPath = dirname(path3);
525
- if (!await existsSync(dirPath))
526
- await createFolder(dirPath);
527
- return await Bun.write(Bun.file(path3), data);
528
- }
529
- return await Bun.write(path3, data);
530
- }
531
- async function writeJsonFile(file) {
532
- let json = JSON.stringify(file.data, undefined, file.indent);
533
- if (file.newline)
534
- json += file.newline;
535
- return writeTextFile({ ...file, data: json });
536
- }
537
- function readTextFile(name, cwd) {
538
- return new Promise((resolve, reject) => {
539
- let filePath;
540
- if (cwd)
541
- filePath = join2(cwd, name);
542
- else
543
- filePath = name;
544
- fs.readFile(filePath, "utf8", (err2, text) => {
545
- if (err2) {
546
- reject(err2);
547
- } else {
548
- resolve({
549
- path: filePath,
550
- data: text
551
- });
552
- }
553
- });
554
- });
555
- }
556
- async function writeTextFile(file) {
557
- return await Bun.write(file.path, file.data);
558
- }
559
- function isFile(path3) {
560
- return fs.existsSync(path3);
561
- }
562
- function doesExist(path3) {
563
- return !isFile(path3) || !isFolder(path3);
564
- }
565
- function doesNotExist(path3) {
566
- return !isFile(path3) && !isFolder(path3);
567
- }
568
- function hasFiles(folder) {
569
- try {
570
- return fs.readdirSync(folder).length > 0;
571
- } catch (err2) {
572
- return false;
573
- }
574
- }
575
- function hasComponents() {
576
- return hasFiles(p2.componentsPath());
577
- }
578
- function hasFunctions() {
579
- return hasFiles(p2.functionsPath());
580
- }
581
- function deleteFiles(dir, exclude = []) {
582
- if (fs.existsSync(dir)) {
583
- fs.readdirSync(dir).forEach((file) => {
584
- const p3 = join2(dir, file);
585
- if (fs.statSync(p3).isDirectory()) {
586
- if (fs.readdirSync(p3).length === 0)
587
- fs.rmSync(p3, { recursive: true, force: true });
588
- else
589
- deleteFiles(p3, exclude);
590
- } else if (!contains(p3, exclude)) {
591
- fs.rmSync(p3);
592
- }
593
- });
594
- }
595
- }
596
- function getFiles(dir, exclude = []) {
597
- let results = [];
598
- const list = fs.readdirSync(dir);
599
- list.forEach((file) => {
600
- file = join2(dir, file);
601
- const stat = fs.statSync(file);
602
- if (stat && stat.isDirectory())
603
- results = results.concat(getFiles(file, exclude));
604
- else if (!contains(file, exclude))
605
- results.push(file);
606
- });
607
- return results;
608
- }
609
- function put(path3, contents) {
610
- const dirPath = dirname(path3);
611
- if (!fs.existsSync(dirPath))
612
- fs.mkdirSync(dirPath, { recursive: true });
613
- fs.writeFileSync(path3, contents, "utf-8");
614
- }
615
- async function get(path3) {
616
- return Bun.file(path3).text();
617
- }
618
- var files = {
619
- readJsonFile,
620
- readPackageJson,
621
- readTextFile,
622
- writeJsonFile,
623
- writeTextFile,
624
- isFile,
625
- hasFiles,
626
- hasComponents,
627
- hasFunctions,
628
- deleteFiles,
629
- getFiles,
630
- put,
631
- get
632
- };
633
- // /home/runner/work/stacks/stacks/storage/framework/core/storage/src/folders.ts
634
- import {join as join3} from "@stacksjs/path";
635
- function isFolder2(path4) {
636
- try {
637
- return fs.statSync(path4).isDirectory();
638
- } catch {
639
- return false;
640
- }
641
- }
642
- function isDirectory(path4) {
643
- return isFolder2(path4);
644
- }
645
- function isDir(path4) {
646
- return isFolder2(path4);
647
- }
648
- function doesFolderExist(path4) {
649
- return fs.existsSync(path4);
650
- }
651
- function createFolder2(dir) {
652
- return new Promise((resolve, reject) => {
653
- fs.mkdirs(dir, (err2) => {
654
- if (err2)
655
- reject(err2);
656
- else
657
- resolve();
658
- });
659
- });
660
- }
661
- function getFolders(dir) {
662
- return fs.readdirSync(dir).filter((file) => {
663
- return fs.statSync(join3(dir, file)).isDirectory();
664
- });
665
- }
666
- var folders = {
667
- isFolder: isFolder2,
668
- doesFolderExist,
669
- createFolder: createFolder2,
670
- getFolders
671
- };
672
- // /home/runner/work/stacks/stacks/storage/framework/core/storage/src/hash.ts
673
- import {path as p3} from "@stacksjs/path";
674
- // /home/runner/work/stacks/stacks/storage/framework/core/storage/src/helpers.ts
675
- import {fileURLToPath} from "url";
676
- import {dirname as dirname2} from "@stacksjs/path";
677
- function updateConfigFile(filePath, newConfig) {
678
- return new Promise((resolve, reject) => {
679
- const config5 = JSON.parse(fs.readFileSync(filePath, "utf8"));
680
- for (const key in newConfig)
681
- config5[key] = newConfig[key];
682
- try {
683
- fs.writeFileSync(filePath, JSON.stringify(config5, null, 2));
684
- resolve();
685
- } catch (error) {
686
- reject(error);
687
- }
688
- });
689
- }
690
- var __dirname = "/home/runner/work/stacks/stacks/storage/framework/core/storage/src";
691
- var _dirname = typeof __dirname !== "undefined" ? __dirname : dirname2(fileURLToPath(import.meta.url));
692
- var helpers3 = {
693
- _dirname,
694
- updateConfigFile
695
- };
696
- // /home/runner/work/stacks/stacks/storage/framework/core/storage/src/copy.ts
697
- import {join as join4} from "@stacksjs/path";
698
- function copy(src, dest, exclude = []) {
699
- if (Array.isArray(src)) {
700
- src.forEach((file) => {
701
- copy(file, dest, exclude);
702
- });
703
- } else {
704
- if (fs.statSync(src).isDirectory())
705
- copyFolder(src, dest, exclude);
706
- else
707
- copyFile(src, dest);
708
- }
709
- }
710
- function copyFile(src, dest) {
711
- fs.copyFileSync(src, dest);
712
- }
713
- function copyFolder(src, dest, exclude = []) {
714
- if (!fs.existsSync(dest))
715
- fs.mkdirSync(dest, { recursive: true });
716
- if (fs.existsSync(src)) {
717
- fs.readdirSync(src).forEach((file) => {
718
- if (!contains(join4(src, file), exclude)) {
719
- const srcPath = join4(src, file);
720
- const destPath = join4(dest, file);
721
- if (fs.statSync(srcPath).isDirectory())
722
- copyFolder(srcPath, destPath, exclude);
723
- else
724
- fs.copyFileSync(srcPath, destPath);
725
- }
726
- });
727
- }
728
- }
729
- // /home/runner/work/stacks/stacks/storage/framework/core/storage/src/glob.ts
730
- import {default as default2} from "fast-glob";
731
- // /home/runner/work/stacks/stacks/storage/framework/core/storage/src/delete.ts
732
- import {err as err2, ok as ok2} from "@stacksjs/error-handling";
733
- import {italic, log as log2} from "@stacksjs/cli";
734
- function deleteFolder(path7) {
735
- return new Promise((resolve, reject) => {
736
- try {
737
- if (isFolder2(path7)) {
738
- fs.rmSync(path7, { recursive: true, force: true });
739
- return resolve(ok2(`Deleted ${path7}`));
740
- }
741
- return resolve(ok2(`Path ${path7} was not a directory`));
742
- } catch (error) {
743
- return reject(err2(error));
744
- }
745
- });
746
- }
747
- async function isDirectoryEmpty(path7) {
748
- return new Promise((resolve, reject) => {
749
- try {
750
- if (fs.statSync(path7).isDirectory()) {
751
- if (fs.readdirSync(path7).length === 0)
752
- return resolve(ok2(true));
753
- else
754
- return resolve(ok2(false));
755
- }
756
- return resolve(ok2(false));
757
- } catch (error) {
758
- return reject(err2(error));
759
- }
760
- });
761
- }
762
- async function deleteEmptyFolder(path7) {
763
- return new Promise((resolve, reject) => {
764
- try {
765
- if (fs.statSync(path7).isDirectory()) {
766
- if (fs.readdirSync(path7).length === 0) {
767
- fs.rmSync(path7, { recursive: true, force: true });
768
- return resolve(ok2(`Deleted ${path7}`));
769
- } else {
770
- return resolve(ok2(`Path ${path7} was not empty`));
771
- }
772
- }
773
- return resolve(ok2(`Path ${path7} was not a directory`));
774
- } catch (error) {
775
- return reject(err2(error));
776
- }
777
- });
778
- }
779
- async function deleteEmptyFolders(dir) {
780
- try {
781
- if (!fs.existsSync(dir))
782
- return ok2(`Path ${dir} does not exist`);
783
- const files3 = fs.readdirSync(dir);
784
- for (const file of files3) {
785
- const p4 = join(dir, file);
786
- if (isFolder2(p4)) {
787
- if (fs.readdirSync(p4).length === 0)
788
- fs.rmSync(p4, { recursive: true, force: true });
789
- else
790
- await deleteEmptyFolders(p4);
791
- }
792
- }
793
- return ok2(`Deleted empty folders located in ${dir}`);
794
- } catch (error) {
795
- return err2(error);
796
- }
797
- }
798
- function deleteFile(path7) {
799
- return new Promise((resolve, reject) => {
800
- try {
801
- if (isFile(path7)) {
802
- fs.rmSync(path7, { recursive: true, force: true });
803
- return resolve(ok2(`Deleted ${path7}`));
804
- }
805
- return resolve(ok2(`Path ${path7} was not a file`));
806
- } catch (error) {
807
- return reject(err2(error));
808
- }
809
- });
810
- }
811
- async function deleteGlob(path7) {
812
- if (!path7.includes("*"))
813
- return err2(handleError(`Path ${path7} does not contain a glob`));
814
- const directories = await default2([path7], { onlyDirectories: true });
815
- for (const directory of directories) {
816
- const result = await deleteFolder(directory);
817
- if (result.isErr()) {
818
- log2.error(result.error);
819
- return result;
820
- }
821
- log2.info(`Deleted ${italic(directory)}`);
822
- }
823
- return ok2(`Deleted ${directories.length} directories`);
824
- }
825
- async function del(path7) {
826
- if (isFile(path7))
827
- return await deleteFile(path7);
828
- if (isFolder2(path7))
829
- return await deleteFolder(path7);
830
- if (path7.includes("*"))
831
- return await deleteGlob(path7);
832
- return err2(handleError(`Path ${path7} cannot be deleted due to an unhandled condition. Please report this issue.`));
833
- }
834
- // /home/runner/work/stacks/stacks/storage/framework/core/storage/src/zip.ts
835
- import {runCommand} from "@stacksjs/cli";
836
- async function zip(from, to, options) {
837
- const toPath = to || "archive.zip";
838
- const fromPath = Array.isArray(from) ? from.join(" ") : from;
839
- if (Array.isArray(from))
840
- return runCommand(`zip -r ${toPath} ${fromPath}`, options);
841
- return runCommand(`zip -r ${to} ${from}`, options);
842
- }
843
- async function unzip(paths) {
844
- if (Array.isArray(paths))
845
- return runCommand(`unzip ${paths.join(" ")}`);
846
- return runCommand(`unzip ${paths}`);
847
- }
848
- function archive(paths) {
849
- return zip(paths);
850
- }
851
- function unarchive(paths) {
852
- return unzip(paths);
853
- }
854
- function compress(paths) {
855
- return zip(paths);
856
- }
857
- function decompress(paths) {
858
- return unzip(paths);
859
- }
860
- function gzipSync(data, options) {
861
- return Bun.gzipSync(data, options);
862
- }
863
- function gunzipSync(data) {
864
- return Bun.gunzipSync(data);
865
- }
866
- function deflateSync(data, options) {
867
- return Bun.deflateSync(data, options);
868
- }
869
- function inflateSync(data) {
870
- return Bun.inflateSync(data);
871
- }
872
- // /home/runner/work/stacks/stacks/storage/framework/core/storage/src/storage.ts
873
- var exports_storage = {};
874
- __export(exports_storage, {
875
- zip: () => {
876
- {
877
- return zip;
878
- }
879
- },
880
- writeTextFile: () => {
881
- {
882
- return writeTextFile;
883
- }
884
- },
885
- writeJsonFile: () => {
886
- {
887
- return writeJsonFile;
888
- }
889
- },
890
- writeFileSync: () => {
891
- {
892
- return writeFileSync;
893
- }
894
- },
895
- writeFile: () => {
896
- {
897
- return writeFile;
898
- }
899
- },
900
- updateConfigFile: () => {
901
- {
902
- return updateConfigFile;
903
- }
904
- },
905
- unzip: () => {
906
- {
907
- return unzip;
908
- }
909
- },
910
- unarchive: () => {
911
- {
912
- return unarchive;
913
- }
914
- },
915
- setVisibility: () => {
916
- {
917
- return setVisibility;
918
- }
919
- },
920
- rename: () => {
921
- {
922
- return rename;
923
- }
924
- },
925
- readTextFile: () => {
926
- {
927
- return readTextFile;
928
- }
929
- },
930
- readPackageJson: () => {
931
- {
932
- return readPackageJson;
933
- }
934
- },
935
- readJsonFile: () => {
936
- {
937
- return readJsonFile;
938
- }
939
- },
940
- put: () => {
941
- {
942
- return put;
943
- }
944
- },
945
- move: () => {
946
- {
947
- return move2;
948
- }
949
- },
950
- mkdirSync: () => {
951
- {
952
- return mkdirSync;
953
- }
954
- },
955
- isFolder: () => {
956
- {
957
- return isFolder2;
958
- }
959
- },
960
- isFile: () => {
961
- {
962
- return isFile;
963
- }
964
- },
965
- isDirectoryEmpty: () => {
966
- {
967
- return isDirectoryEmpty;
968
- }
969
- },
970
- isDirectory: () => {
971
- {
972
- return isDirectory;
973
- }
974
- },
975
- isDir: () => {
976
- {
977
- return isDir;
978
- }
979
- },
980
- inflateSync: () => {
981
- {
982
- return inflateSync;
983
- }
984
- },
985
- helpers: () => {
986
- {
987
- return helpers3;
988
- }
989
- },
990
- hasFunctions: () => {
991
- {
992
- return hasFunctions;
993
- }
994
- },
995
- hasFiles: () => {
996
- {
997
- return hasFiles;
998
- }
999
- },
1000
- hasComponents: () => {
1001
- {
1002
- return hasComponents;
1003
- }
1004
- },
1005
- gzipSync: () => {
1006
- {
1007
- return gzipSync;
1008
- }
1009
- },
1010
- gunzipSync: () => {
1011
- {
1012
- return gunzipSync;
1013
- }
1014
- },
1015
- getFolders: () => {
1016
- {
1017
- return getFolders;
1018
- }
1019
- },
1020
- getFiles: () => {
1021
- {
1022
- return getFiles;
1023
- }
1024
- },
1025
- get: () => {
1026
- {
1027
- return get;
1028
- }
1029
- },
1030
- fs: () => {
1031
- {
1032
- return fs;
1033
- }
1034
- },
1035
- folders: () => {
1036
- {
1037
- return folders;
1038
- }
1039
- },
1040
- files: () => {
1041
- {
1042
- return files;
1043
- }
1044
- },
1045
- existsSync: () => {
1046
- {
1047
- return existsSync;
1048
- }
1049
- },
1050
- exists: () => {
1051
- {
1052
- return exists;
1053
- }
1054
- },
1055
- doesNotExist: () => {
1056
- {
1057
- return doesNotExist;
1058
- }
1059
- },
1060
- doesFolderExist: () => {
1061
- {
1062
- return doesFolderExist;
1063
- }
1064
- },
1065
- doesExist: () => {
1066
- {
1067
- return doesExist;
1068
- }
1069
- },
1070
- deleteGlob: () => {
1071
- {
1072
- return deleteGlob;
1073
- }
1074
- },
1075
- deleteFolder: () => {
1076
- {
1077
- return deleteFolder;
1078
- }
1079
- },
1080
- deleteFiles: () => {
1081
- {
1082
- return deleteFiles;
1083
- }
1084
- },
1085
- deleteFile: () => {
1086
- {
1087
- return deleteFile;
1088
- }
1089
- },
1090
- deleteEmptyFolders: () => {
1091
- {
1092
- return deleteEmptyFolders;
1093
- }
1094
- },
1095
- deleteEmptyFolder: () => {
1096
- {
1097
- return deleteEmptyFolder;
1098
- }
1099
- },
1100
- del: () => {
1101
- {
1102
- return del;
1103
- }
1104
- },
1105
- deflateSync: () => {
1106
- {
1107
- return deflateSync;
1108
- }
1109
- },
1110
- decompress: () => {
1111
- {
1112
- return decompress;
1113
- }
1114
- },
1115
- createFolder: () => {
1116
- {
1117
- return createFolder2;
1118
- }
1119
- },
1120
- copyFolder: () => {
1121
- {
1122
- return copyFolder;
1123
- }
1124
- },
1125
- copyFile: () => {
1126
- {
1127
- return copyFile;
1128
- }
1129
- },
1130
- copy: () => {
1131
- {
1132
- return copy;
1133
- }
1134
- },
1135
- compress: () => {
1136
- {
1137
- return compress;
1138
- }
1139
- },
1140
- archive: () => {
1141
- {
1142
- return archive;
1143
- }
1144
- },
1145
- _dirname: () => {
1146
- {
1147
- return _dirname;
1148
- }
1149
- }
1150
- });
1151
-
1152
- // /home/runner/work/stacks/stacks/storage/framework/core/storage/src/move.ts
1153
- import {err as err3, ok as ok3} from "@stacksjs/error-handling";
1154
- import {log as log3} from "@stacksjs/logging";
1155
- import {path as path8} from "@stacksjs/path";
1156
- async function move2(src, dest, options) {
1157
- try {
1158
- if (Array.isArray(src)) {
1159
- const operations = src.map(async (file) => {
1160
- const from2 = file;
1161
- const to2 = path8.resolve(dest, path8.basename(file));
1162
- const result2 = await rename(from2, to2, options);
1163
- if (result2.isErr()) {
1164
- log3.error(result2.error);
1165
- return err3(handleError(result2.error.message, result2.error));
1166
- }
1167
- });
1168
- await Promise.all(operations);
1169
- return ok3({ message: "Files moved successfully" });
1170
- }
1171
- const from = src;
1172
- const to = dest;
1173
- const result = await rename(from, to, options);
1174
- if (result.isErr()) {
1175
- log3.error(result.error);
1176
- return err3(handleError(result.error));
1177
- }
1178
- return ok3({ message: "File moved successfully" });
1179
- } catch (error) {
1180
- return err3(handleError(error));
1181
- }
1182
- }
1183
- async function rename(from, to, options) {
1184
- return new Promise((resolve, reject) => {
1185
- try {
1186
- const dir = path8.dirname(to);
1187
- if (!fs.existsSync(dir))
1188
- fs.mkdirSync(dir, { recursive: true });
1189
- if (!fs.existsSync(from))
1190
- return reject(err3(new Error(`File or directory does not exist: ${from}`)));
1191
- if (fs.existsSync(to)) {
1192
- if (!options?.overwrite)
1193
- return reject(err3(new Error(`File or directory already exists: ${to}`)));
1194
- fs.unlinkSync(to);
1195
- }
1196
- fs.renameSync(from, to);
1197
- return resolve(ok3({ message: "File moved successfully" }));
1198
- } catch (error) {
1199
- if (error.code === "ENOENT")
1200
- log3.error("File or directory does not exist\n\n", error);
1201
- else
1202
- log3.error(error);
1203
- return reject(err3(new Error(error)));
1204
- }
1205
- });
1206
- }
1207
- // /home/runner/work/stacks/stacks/storage/framework/core/storage/src/visibility.ts
1208
- function setVisibility() {
1209
- return "wip";
1210
- }
1211
- // src/cloud/cdn.ts
1212
- import {path as p4} from "@stacksjs/path";
481
+ import {hasFiles} from "@stacksjs/storage";
482
+ import {path as p2} from "@stacksjs/path";
1213
483
  import {env as env2} from "@stacksjs/env";
484
+ import * as kinesis from "aws-cdk-lib/aws-kinesis";
1214
485
 
1215
486
  class CdnStack {
1216
487
  distribution;
@@ -1218,6 +489,7 @@ class CdnStack {
1218
489
  cdnCachePolicy;
1219
490
  apiCachePolicy;
1220
491
  vanityUrl;
492
+ realtimeLogConfig;
1221
493
  props;
1222
494
  constructor(scope, props) {
1223
495
  this.props = props;
@@ -1230,6 +502,28 @@ class CdnStack {
1230
502
  maxTtl: config6.cloud.cdn?.maxTtl ? Duration2.seconds(config6.cloud.cdn.maxTtl) : undefined,
1231
503
  cookieBehavior: this.getCookieBehavior(config6.cloud.cdn?.cookieBehavior)
1232
504
  });
505
+ const logStream = new kinesis.Stream(scope, "StacksCdnRealtimeLogStream", {
506
+ streamName: "StacksCdnRealtimeLogStream",
507
+ retentionPeriod: Duration2.days(1),
508
+ shardCount: 1,
509
+ encryption: kinesis.StreamEncryption.UNENCRYPTED
510
+ });
511
+ this.realtimeLogConfig = new cloudfront.RealtimeLogConfig(scope, "StacksRealTimeLogConfig", {
512
+ endPoints: [
513
+ cloudfront.Endpoint.fromKinesisStream(logStream)
514
+ ],
515
+ fields: [
516
+ "timestamp",
517
+ "c-ip",
518
+ "cs-method",
519
+ "cs-uri-stem",
520
+ "cs-uri-query",
521
+ "cs-referer",
522
+ "cs-user-agent",
523
+ "sc-status"
524
+ ],
525
+ samplingRate: 100
526
+ });
1233
527
  this.distribution = new cloudfront.Distribution(scope, "Cdn", {
1234
528
  domainNames: [props.domain],
1235
529
  defaultRootObject: "index.html",
@@ -1257,7 +551,8 @@ class CdnStack {
1257
551
  allowedMethods: this.allowedMethods(),
1258
552
  cachedMethods: this.cachedMethods(),
1259
553
  viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
1260
- cachePolicy: this.cdnCachePolicy
554
+ cachePolicy: this.cdnCachePolicy,
555
+ realtimeLogConfig: this.realtimeLogConfig
1261
556
  },
1262
557
  additionalBehaviors: this.additionalBehaviors(scope, props),
1263
558
  errorResponses: [
@@ -1351,10 +646,10 @@ class CdnStack {
1351
646
  return config6.cloud.api?.deploy;
1352
647
  }
1353
648
  apiBehaviorOptions(scope, props) {
1354
- const hostname = Fn.select(2, Fn.split("/", props.webServerUrl.url));
1355
- const origin = (path10 = "/api") => {
649
+ const hostname = `api.${props.domain}`;
650
+ const origin = () => {
1356
651
  return new origins.HttpOrigin(hostname, {
1357
- originPath: path10,
652
+ originPath: "/",
1358
653
  protocolPolicy: cloudfront.OriginProtocolPolicy.HTTPS_ONLY
1359
654
  });
1360
655
  };
@@ -1365,15 +660,17 @@ class CdnStack {
1365
660
  allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL,
1366
661
  cachedMethods: cloudfront.CachedMethods.CACHE_GET_HEAD_OPTIONS,
1367
662
  cachePolicy: this.setApiCachePolicy(scope),
1368
- viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS
663
+ viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
664
+ realtimeLogConfig: this.realtimeLogConfig
1369
665
  },
1370
666
  "/api/*": {
1371
- origin: origin("/api/*"),
667
+ origin: origin(),
1372
668
  compress: true,
1373
669
  allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL,
1374
670
  cachedMethods: cloudfront.CachedMethods.CACHE_GET_HEAD_OPTIONS,
1375
671
  cachePolicy: this.apiCachePolicy,
1376
- viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS
672
+ viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
673
+ realtimeLogConfig: this.realtimeLogConfig
1377
674
  }
1378
675
  };
1379
676
  }
@@ -1388,7 +685,8 @@ class CdnStack {
1388
685
  allowedMethods: this.allowedMethodsFromString(config6.cloud.cdn?.allowedMethods),
1389
686
  cachedMethods: this.cachedMethodsFromString(config6.cloud.cdn?.cachedMethods),
1390
687
  viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
1391
- cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED
688
+ cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
689
+ realtimeLogConfig: this.realtimeLogConfig
1392
690
  },
1393
691
  "/docs/*": {
1394
692
  origin: new origins.S3Origin(props.publicBucket, {
@@ -1399,7 +697,8 @@ class CdnStack {
1399
697
  allowedMethods: this.allowedMethodsFromString(config6.cloud.cdn?.allowedMethods),
1400
698
  cachedMethods: this.cachedMethodsFromString(config6.cloud.cdn?.cachedMethods),
1401
699
  viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
1402
- cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED
700
+ cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
701
+ realtimeLogConfig: this.realtimeLogConfig
1403
702
  }
1404
703
  };
1405
704
  }
@@ -1423,7 +722,8 @@ class CdnStack {
1423
722
  compress: false,
1424
723
  allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL,
1425
724
  viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
1426
- cachePolicy: aiCachePolicy
725
+ cachePolicy: aiCachePolicy,
726
+ realtimeLogConfig: this.realtimeLogConfig
1427
727
  },
1428
728
  "/ai/summary": {
1429
729
  origin: new origins.HttpOrigin(summaryHostname, {
@@ -1433,7 +733,8 @@ class CdnStack {
1433
733
  compress: false,
1434
734
  allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL,
1435
735
  viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
1436
- cachePolicy: aiCachePolicy
736
+ cachePolicy: aiCachePolicy,
737
+ realtimeLogConfig: this.realtimeLogConfig
1437
738
  }
1438
739
  };
1439
740
  }
@@ -1455,7 +756,8 @@ class CdnStack {
1455
756
  cookieBehavior: cloudfront.CacheCookieBehavior.none(),
1456
757
  headerBehavior: cloudfront.CacheHeaderBehavior.none(),
1457
758
  queryStringBehavior: cloudfront.CacheQueryStringBehavior.none()
1458
- })
759
+ }),
760
+ realtimeLogConfig: this.realtimeLogConfig
1459
761
  }
1460
762
  };
1461
763
  }
@@ -1466,13 +768,14 @@ class CdnStack {
1466
768
  return config6.cloud.cli;
1467
769
  }
1468
770
  shouldDeployDocs() {
1469
- return hasFiles(p4.projectPath("docs"));
771
+ return hasFiles(p2.projectPath("docs"));
1470
772
  }
1471
773
  additionalBehaviors(scope, props) {
1472
774
  let behaviorOptions = {};
1473
775
  if (this.shouldDeployApi()) {
1474
776
  const keysToRemove = ["_HANDLER", "_X_AMZN_TRACE_ID", "AWS_REGION", "AWS_EXECUTION_ENV", "AWS_LAMBDA_FUNCTION_NAME", "AWS_LAMBDA_FUNCTION_MEMORY_SIZE", "AWS_LAMBDA_FUNCTION_VERSION", "AWS_LAMBDA_INITIALIZATION_TYPE", "AWS_LAMBDA_LOG_GROUP_NAME", "AWS_LAMBDA_LOG_STREAM_NAME", "AWS_ACCESS_KEY", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN", "AWS_LAMBDA_RUNTIME_API", "LAMBDA_TASK_ROOT", "LAMBDA_RUNTIME_DIR", "_"];
1475
777
  keysToRemove.forEach((key) => delete env2[key]);
778
+ behaviorOptions = this.apiBehaviorOptions(scope, props);
1476
779
  }
1477
780
  if (this.shouldDeployDocs() && !config6.app.docMode) {
1478
781
  behaviorOptions = {
@@ -1563,13 +866,19 @@ class DnsStack {
1563
866
  zone: this.zone,
1564
867
  target: route532.RecordTarget.fromAlias(new targets2.BucketWebsiteTarget(wwwBucket))
1565
868
  });
869
+ new route532.ARecord(scope, "StoreAliasRecord", {
870
+ recordName: `store.${props.domain}`,
871
+ zone: this.zone,
872
+ target: route532.RecordTarget.fromIpAddresses("137.66.37.136")
873
+ });
1566
874
  }
1567
875
  }
1568
876
 
1569
877
  // src/cloud/docs.ts
1570
878
  import {AssetHashType, CfnOutput as Output4, RemovalPolicy as RemovalPolicy2, aws_lambda as lambda3} from "aws-cdk-lib";
1571
879
  import {config as config8} from "@stacksjs/config";
1572
- import {path as p5} from "@stacksjs/path";
880
+ import {path as p3} from "@stacksjs/path";
881
+ import {storage as storage3} from "@stacksjs/storage";
1573
882
  import {originRequestFunctionHash} from "@stacksjs/utils";
1574
883
 
1575
884
  class DocsStack {
@@ -1581,14 +890,14 @@ class DocsStack {
1581
890
  description: "The Stacks Origin Request function that prettifies URLs",
1582
891
  runtime: lambda3.Runtime.NODEJS_18_X,
1583
892
  handler: "dist/origin-request.handler",
1584
- code: lambda3.Code.fromAsset(p5.corePath("cloud/dist.zip"), {
893
+ code: lambda3.Code.fromAsset(p3.corePath("cloud/dist.zip"), {
1585
894
  assetHash: originRequestFunctionHash,
1586
895
  assetHashType: AssetHashType.CUSTOM
1587
896
  })
1588
897
  });
1589
898
  const cfnOriginRequestFunction = this.originRequestFunction.node.defaultChild;
1590
899
  cfnOriginRequestFunction.applyRemovalPolicy(RemovalPolicy2.RETAIN);
1591
- if (!config8.app.docMode && exports_storage.hasFiles(p5.projectPath("docs"))) {
900
+ if (!config8.app.docMode && storage3.hasFiles(p3.projectPath("docs"))) {
1592
901
  new Output4(scope, "DocsUrl", {
1593
902
  value: `https://${props.domain}/${docsPrefix}`,
1594
903
  description: "The URL of the deployed documentation"
@@ -1749,7 +1058,7 @@ class SecurityStack {
1749
1058
  },
1750
1059
  rules: this.getFirewallRules()
1751
1060
  };
1752
- this.firewall = new wafv2.CfnWebACL(scope, "WebFirewall", options);
1061
+ this.firewall = new wafv2.CfnWebACL(scope, "StacksWebFirewall", options);
1753
1062
  Tags2.of(this.firewall).add("Name", "waf-cloudfront", { priority: 300 });
1754
1063
  Tags2.of(this.firewall).add("Purpose", "CloudFront", { priority: 300 });
1755
1064
  Tags2.of(this.firewall).add("CreatedBy", "CloudFormation", { priority: 300 });
@@ -2317,26 +1626,26 @@ class PermissionsStack {
2317
1626
  }
2318
1627
 
2319
1628
  // src/cloud/compute.ts
2320
- import {Duration as Duration6, CfnOutput as Output6, RemovalPolicy as RemovalPolicy8, aws_ec2 as ec23, aws_ecs as ecs, aws_secretsmanager as secretsmanager} from "aws-cdk-lib";
2321
- import {path as p6} from "@stacksjs/path";
1629
+ import {Duration as Duration6, CfnOutput as Output6, RemovalPolicy as RemovalPolicy8, aws_ec2 as ec23, aws_ecs as ecs, aws_route53 as route535, aws_route53_targets as route53Targets, aws_secretsmanager as secretsmanager} from "aws-cdk-lib";
1630
+ import {path as p4} from "@stacksjs/path";
2322
1631
  import {env as env6} from "@stacksjs/env";
2323
1632
  import {LogGroup} from "aws-cdk-lib/aws-logs";
2324
1633
  import * as elbv2 from "aws-cdk-lib/aws-elasticloadbalancingv2";
2325
1634
 
2326
1635
  class ComputeStack {
2327
1636
  lb;
2328
- apiServer;
2329
- apiServerUrl;
1637
+ cluster;
1638
+ taskDefinition;
2330
1639
  constructor(scope, props) {
2331
1640
  const vpc = props.vpc;
2332
1641
  const fileSystem = props.fileSystem;
2333
1642
  if (!fileSystem)
2334
1643
  throw new Error("The file system is missing. Please make sure it was created properly.");
2335
- const cluster = new ecs.Cluster(scope, "StacksCluster", {
1644
+ this.cluster = new ecs.Cluster(scope, "StacksCluster", {
2336
1645
  clusterName: `${props.slug}-${props.appEnv}-web-server-cluster`,
2337
1646
  vpc
2338
1647
  });
2339
- const taskDefinition = new ecs.FargateTaskDefinition(scope, "TaskDefinition", {
1648
+ this.taskDefinition = new ecs.FargateTaskDefinition(scope, "TaskDefinition", {
2340
1649
  family: `${props.appName}-${props.appEnv}-api`,
2341
1650
  memoryLimitMiB: 512,
2342
1651
  cpu: 256,
@@ -2344,18 +1653,18 @@ class ComputeStack {
2344
1653
  cpuArchitecture: ecs.CpuArchitecture.ARM64
2345
1654
  }
2346
1655
  });
2347
- const container = taskDefinition.addContainer("WebServerContainer", {
1656
+ const container = this.taskDefinition.addContainer("WebServerContainer", {
2348
1657
  containerName: `${props.appName}-${props.appEnv}-api`,
2349
- image: ecs.ContainerImage.fromAsset(p6.frameworkPath("server")),
1658
+ image: ecs.ContainerImage.fromAsset(p4.frameworkPath("server")),
2350
1659
  logging: new ecs.AwsLogDriver({
2351
- streamPrefix: `${props.appName}-${props.appEnv}-web`,
1660
+ streamPrefix: `${props.appName}-${props.appEnv}-web-server-logs`,
2352
1661
  logGroup: new LogGroup(scope, "StacksApiLogs", {
2353
- logGroupName: "/ecs/stacks-api",
1662
+ logGroupName: "/aws/ecs/stacks-api",
2354
1663
  removalPolicy: RemovalPolicy8.DESTROY
2355
1664
  })
2356
1665
  }),
2357
1666
  healthCheck: {
2358
- command: ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"],
1667
+ command: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"],
2359
1668
  interval: Duration6.seconds(10),
2360
1669
  timeout: Duration6.seconds(5),
2361
1670
  retries: 3,
@@ -2377,8 +1686,8 @@ class ComputeStack {
2377
1686
  description: "Access to the public facing load balancer"
2378
1687
  });
2379
1688
  serviceSecurityGroup.addIngressRule(publicLoadBalancerSG, ec23.Port.allTraffic(), "Ingress from the public ALB");
2380
- serviceSecurityGroup.addIngressRule(publicLoadBalancerSG, ec23.Port.allTraffic(), "Ingress from the public ALB");
2381
1689
  this.lb = new elbv2.ApplicationLoadBalancer(scope, "ApplicationLoadBalancer", {
1690
+ http2Enabled: true,
2382
1691
  loadBalancerName: `${props.appName}-${props.appEnv}-alb`,
2383
1692
  vpc,
2384
1693
  vpcSubnets: {
@@ -2391,14 +1700,20 @@ class ComputeStack {
2391
1700
  idleTimeout: Duration6.seconds(30),
2392
1701
  securityGroup: publicLoadBalancerSG
2393
1702
  });
1703
+ new route535.ARecord(scope, "ApiDomainAliasRecord", {
1704
+ zone: props.zone,
1705
+ recordName: "api",
1706
+ target: route535.RecordTarget.fromAlias(new route53Targets.LoadBalancerTarget(this.lb))
1707
+ });
2394
1708
  const serviceTargetGroup = new elbv2.ApplicationTargetGroup(scope, "ServiceTargetGroup", {
1709
+ targetGroupName: `${props.appName}-${props.appEnv}-api-tg`,
2395
1710
  vpc,
2396
1711
  targetType: elbv2.TargetType.IP,
2397
1712
  protocol: elbv2.ApplicationProtocol.HTTP,
2398
1713
  port: 3000,
2399
1714
  healthCheck: {
2400
1715
  interval: Duration6.seconds(6),
2401
- path: "/",
1716
+ path: "/api/health",
2402
1717
  protocol: elbv2.Protocol.HTTP,
2403
1718
  timeout: Duration6.seconds(5),
2404
1719
  healthyThresholdCount: 2,
@@ -2407,9 +1722,9 @@ class ComputeStack {
2407
1722
  });
2408
1723
  const service = new ecs.FargateService(scope, "StacksApiService", {
2409
1724
  serviceName: `${props.appName}-${props.appEnv}-api-service`,
2410
- cluster,
2411
- taskDefinition,
2412
- desiredCount: 2,
1725
+ cluster: this.cluster,
1726
+ taskDefinition: this.taskDefinition,
1727
+ desiredCount: 1,
2413
1728
  assignPublicIp: true,
2414
1729
  maxHealthyPercent: 200,
2415
1730
  vpcSubnets: vpc.selectSubnets({
@@ -2421,13 +1736,18 @@ class ComputeStack {
2421
1736
  });
2422
1737
  service.attachToApplicationTargetGroup(serviceTargetGroup);
2423
1738
  publicLoadBalancerSG.addIngressRule(ec23.Peer.anyIpv4(), ec23.Port.allTraffic());
1739
+ this.lb.addListener("HttpsListener", {
1740
+ port: 443,
1741
+ certificates: [props.certificate],
1742
+ defaultAction: elbv2.ListenerAction.forward([serviceTargetGroup])
1743
+ });
2424
1744
  this.lb.addListener("HttpListener", {
2425
1745
  port: 80,
2426
1746
  defaultAction: elbv2.ListenerAction.forward([serviceTargetGroup])
2427
1747
  });
2428
1748
  props.fileSystem.connections.allowFromAnyIpv4(ec23.Port.tcp(2049));
2429
1749
  const volumeName = `${props.slug}-${props.appEnv}-efs`;
2430
- taskDefinition.addVolume({
1750
+ this.taskDefinition.addVolume({
2431
1751
  name: volumeName,
2432
1752
  efsVolumeConfiguration: {
2433
1753
  fileSystemId: props.fileSystem.fileSystemId
@@ -2473,6 +1793,43 @@ class ComputeStack {
2473
1793
  }
2474
1794
  }
2475
1795
 
1796
+ // src/cloud/queue.ts
1797
+ import {aws_ec2 as ec24} from "aws-cdk-lib";
1798
+ import {Rule, Schedule} from "aws-cdk-lib/aws-events";
1799
+ import {EcsTask} from "aws-cdk-lib/aws-events-targets";
1800
+
1801
+ class QueueStack {
1802
+ constructor(scope, props) {
1803
+ const rule = new Rule(scope, "Rule", {
1804
+ ruleName: `${props.appName}-${props.appEnv}-queue`,
1805
+ schedule: Schedule.cron({ minute: "*", hour: "*", month: "*", weekDay: "*", year: "*" })
1806
+ });
1807
+ rule.addTarget(new EcsTask({
1808
+ cluster: props.cluster,
1809
+ taskDefinition: props.taskDefinition,
1810
+ containerOverrides: [
1811
+ {
1812
+ containerName: `${props.appName}-${props.appEnv}-api`,
1813
+ environment: [
1814
+ {
1815
+ name: "QUEUE_WORKER",
1816
+ value: "true"
1817
+ },
1818
+ {
1819
+ name: "JOB",
1820
+ value: "DummyJob.ts"
1821
+ }
1822
+ ]
1823
+ }
1824
+ ],
1825
+ retryAttempts: 3,
1826
+ subnetSelection: {
1827
+ subnetType: ec24.SubnetType.PUBLIC
1828
+ }
1829
+ }));
1830
+ }
1831
+ }
1832
+
2476
1833
  // src/cloud/index.ts
2477
1834
  class Cloud extends Stack2 {
2478
1835
  constructor(scope, id, props) {
@@ -2482,7 +1839,7 @@ class Cloud extends Stack2 {
2482
1839
  ...props,
2483
1840
  zone: dns2.zone
2484
1841
  });
2485
- const storage4 = new StorageStack(this, {
1842
+ const storage5 = new StorageStack(this, {
2486
1843
  ...props,
2487
1844
  kmsKey: security2.kmsKey
2488
1845
  });
@@ -2512,27 +1869,31 @@ class Cloud extends Stack2 {
2512
1869
  zone: dns2.zone,
2513
1870
  certificate: security2.certificate
2514
1871
  });
1872
+ new QueueStack(this, {
1873
+ ...props,
1874
+ cluster: api.cluster,
1875
+ taskDefinition: api.taskDefinition
1876
+ });
2515
1877
  }
2516
1878
  const ai2 = new AiStack(this, props);
2517
- const cli4 = new CliStack(this, props);
1879
+ const cli2 = new CliStack(this, props);
2518
1880
  const cdn2 = new CdnStack(this, {
2519
1881
  ...props,
2520
- publicBucket: storage4.publicBucket,
2521
- logBucket: storage4.logBucket,
1882
+ publicBucket: storage5.publicBucket,
1883
+ logBucket: storage5.logBucket,
2522
1884
  certificate: security2.certificate,
2523
1885
  firewall: security2.firewall,
2524
1886
  originRequestFunction: docs2.originRequestFunction,
2525
1887
  zone: dns2.zone,
2526
- cliSetupUrl: cli4.cliSetupUrl,
1888
+ cliSetupUrl: cli2.cliSetupUrl,
2527
1889
  askAiUrl: ai2.askAiUrl,
2528
1890
  summarizeAiUrl: ai2.summarizeAiUrl,
2529
- webServer: api?.apiServer,
2530
- webServerUrl: api?.apiServerUrl
1891
+ lb: api?.lb
2531
1892
  });
2532
1893
  new DeploymentStack(this, {
2533
1894
  ...props,
2534
- publicBucket: storage4.publicBucket,
2535
- privateBucket: storage4.privateBucket,
1895
+ publicBucket: storage5.publicBucket,
1896
+ privateBucket: storage5.privateBucket,
2536
1897
  cdn: cdn2.distribution
2537
1898
  });
2538
1899
  }
@@ -2577,7 +1938,7 @@ var request = new Request;
2577
1938
  import {extname} from "path";
2578
1939
  import {URL} from "url";
2579
1940
  async function serverResponse(req) {
2580
- console.log("serverResponse", req);
1941
+ console.log("serverResponse", JSON.stringify(req));
2581
1942
  const routesList = await route.getRoutes();
2582
1943
  const url = new URL(req.url);
2583
1944
  const foundRoute = routesList.find((route2) => {
@@ -2585,7 +1946,7 @@ async function serverResponse(req) {
2585
1946
  return pattern.test(url.pathname);
2586
1947
  });
2587
1948
  if (!foundRoute)
2588
- return new Response("Not found", { status: 404 });
1949
+ return new Response("Pretty 404 page coming soon", { status: 404 });
2589
1950
  addRouteParamsAndQuery(url, foundRoute);
2590
1951
  executeMiddleware(foundRoute);
2591
1952
  return execute(foundRoute, req, { statusCode: foundRoute?.statusCode });
@@ -2688,32 +2049,32 @@ class Router {
2688
2049
  paramNames: []
2689
2050
  });
2690
2051
  }
2691
- get(path14, callback) {
2692
- this.addRoute("GET", path14, callback, 200);
2052
+ get(path7, callback) {
2053
+ this.addRoute("GET", path7, callback, 200);
2693
2054
  return this;
2694
2055
  }
2695
- post(path14, callback) {
2696
- this.addRoute("POST", path14, callback, 201);
2056
+ post(path7, callback) {
2057
+ this.addRoute("POST", path7, callback, 201);
2697
2058
  return this;
2698
2059
  }
2699
- view(path14, callback) {
2700
- this.addRoute("GET", path14, callback, 200);
2060
+ view(path7, callback) {
2061
+ this.addRoute("GET", path7, callback, 200);
2701
2062
  return this;
2702
2063
  }
2703
- redirect(path14, callback, _status) {
2704
- this.addRoute("GET", path14, callback, 302);
2064
+ redirect(path7, callback, _status) {
2065
+ this.addRoute("GET", path7, callback, 302);
2705
2066
  return this;
2706
2067
  }
2707
- delete(path14, callback) {
2708
- this.addRoute("DELETE", path14, callback, 204);
2068
+ delete(path7, callback) {
2069
+ this.addRoute("DELETE", path7, callback, 204);
2709
2070
  return this;
2710
2071
  }
2711
- patch(path14, callback) {
2712
- this.addRoute("PATCH", path14, callback, 202);
2072
+ patch(path7, callback) {
2073
+ this.addRoute("PATCH", path7, callback, 202);
2713
2074
  return this;
2714
2075
  }
2715
- put(path14, callback) {
2716
- this.addRoute("PUT", path14, callback, 202);
2076
+ put(path7, callback) {
2077
+ this.addRoute("PUT", path7, callback, 202);
2717
2078
  return this;
2718
2079
  }
2719
2080
  group(options, callback) {