@geekmidas/cloud 10.0.0-alpha.123 → 10.0.0-alpha.125

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geekmidas/cloud",
3
- "version": "10.0.0-alpha.123",
3
+ "version": "10.0.0-alpha.125",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -41,8 +41,8 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "lodash.snakecase": "~4.1.1",
44
- "@geekmidas/envkit": "10.0.0-alpha.123",
45
- "@geekmidas/manifest": "10.0.0-alpha.123"
44
+ "@geekmidas/envkit": "10.0.0-alpha.125",
45
+ "@geekmidas/manifest": "10.0.0-alpha.125"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/lodash.get": "~4.4.9",
@@ -58,10 +58,10 @@
58
58
  "@pulumi/aws": ">=7.47.0",
59
59
  "@pulumi/random": ">=4.21.2",
60
60
  "@pulumi/pulumi": ">=3.263.0",
61
- "@geekmidas/manifest": "^10.0.0-alpha.123",
62
- "@geekmidas/storage": "^10.0.0-alpha.123",
63
- "@geekmidas/events": "^10.0.0-alpha.123",
64
- "@geekmidas/db": "^10.0.0-alpha.123"
61
+ "@geekmidas/manifest": "^10.0.0-alpha.125",
62
+ "@geekmidas/storage": "^10.0.0-alpha.125",
63
+ "@geekmidas/events": "^10.0.0-alpha.125",
64
+ "@geekmidas/db": "^10.0.0-alpha.125"
65
65
  },
66
66
  "peerDependenciesMeta": {
67
67
  "@geekmidas/manifest": {
@@ -16,6 +16,7 @@ import {
16
16
  type ProvisionedManifest,
17
17
  provisionCompute,
18
18
  provisionerFor,
19
+ provisionProcessors,
19
20
  resolveEdges,
20
21
  subscribeConsumers,
21
22
  vpcFor,
@@ -556,6 +557,78 @@ describe('functions and crons', () => {
556
557
  });
557
558
  });
558
559
 
560
+ describe("a file server's processors", () => {
561
+ const stack = new App({
562
+ name: 'shop',
563
+ stage: 'production',
564
+ domain: 'example.com',
565
+ hostedZoneId: 'Z',
566
+ region: 'eu-west-1',
567
+ }).stack('media');
568
+ const argsOf = (component: unknown) =>
569
+ (component as { args: Record<string, any> }).args;
570
+
571
+ it('are Lambdas behind IAM-auth URLs, served through the router on their prefix', () => {
572
+ const media = { _id: 'Media', _type: 'sst.aws.Bucket' };
573
+ const router = { _id: 'MediaServer' };
574
+ const provisioned = {
575
+ Media: media,
576
+ MediaServer: router,
577
+ } as unknown as ProvisionedManifest;
578
+
579
+ const [thumbnails, pages] = provisionProcessors(
580
+ stack,
581
+ {
582
+ Media: { kind: 'objects', id: 'Media', provides: ['MEDIA_URL'] },
583
+ MediaServer: {
584
+ kind: 'file-server',
585
+ id: 'MediaServer',
586
+ of: 'Media',
587
+ processors: [
588
+ {
589
+ id: 'thumbnails',
590
+ handler: 'apps/api/.gkm/aws/processors/thumbnails.handler',
591
+ path: '/i/:width/*',
592
+ prefix: '/i/',
593
+ native: ['sharp'],
594
+ timeout: 15_000,
595
+ memorySize: 1536,
596
+ dependencies: [{ target: 'Media', kind: 'objects' }],
597
+ },
598
+ {
599
+ id: 'pages',
600
+ handler: 'apps/api/.gkm/aws/processors/pages.handler',
601
+ path: '/pdf/:page/*',
602
+ prefix: '/pdf/',
603
+ dependencies: [{ target: 'Media', kind: 'objects' }],
604
+ },
605
+ ],
606
+ },
607
+ } as never,
608
+ provisioned,
609
+ );
610
+
611
+ expect(thumbnails).toBeInstanceOf(Function);
612
+ expect(argsOf(thumbnails)).toMatchObject({
613
+ name: stack.logicalPrefixedName('MediaServerthumbnails'),
614
+ handler: 'apps/api/.gkm/aws/processors/thumbnails.handler',
615
+ link: [media],
616
+ timeout: '15 seconds',
617
+ memory: '1536 MB',
618
+ // Installed for the Lambda, never bundled.
619
+ nodejs: { install: ['sharp'] },
620
+ url: {
621
+ authorization: 'iam',
622
+ router: { instance: router, path: '/i' },
623
+ },
624
+ });
625
+ expect(argsOf(pages)).toMatchObject({
626
+ url: { router: { path: '/pdf' } },
627
+ });
628
+ expect(argsOf(pages).nodejs).toBeUndefined();
629
+ });
630
+ });
631
+
559
632
  describe('kinds provisioned elsewhere', () => {
560
633
  it('skips a worker, which is a process rather than a resource', () => {
561
634
  // A worker in the manifest used to throw UnknownDeclarationKind at synth,
@@ -839,6 +839,65 @@ export function provisionCompute(
839
839
  return crons;
840
840
  }
841
841
 
842
+ /**
843
+ * Every file server's processors: each a Lambda behind a function URL with
844
+ * IAM auth, served through the file server's router on its pattern's prefix
845
+ * — so the CDN signs each request (origin access control) and the URL cannot
846
+ * be called around the cache. Linked to the bucket it reads and what it
847
+ * depends on; its native packages installed for the Lambda, not bundled.
848
+ *
849
+ * After everything else, for the reason {@link provisionCompute} is.
850
+ */
851
+ export function provisionProcessors(
852
+ stack: StackType,
853
+ manifest: ConstructManifest,
854
+ provisioned: ProvisionedManifest,
855
+ ): Function[] {
856
+ const lambdas: Function[] = [];
857
+
858
+ for (const [id, declaration] of Object.entries(manifest)) {
859
+ if (declaration?.kind !== 'file-server') continue;
860
+ const router = provisioned[id];
861
+ if (!router) continue;
862
+
863
+ for (const processor of declaration.processors ?? []) {
864
+ const { link } = resolveEdges(processor.dependencies, provisioned);
865
+ const vpc = vpcFor(link);
866
+ const native = processor.native ?? [];
867
+ lambdas.push(
868
+ new Function(stack, `${id}${processor.id}`, {
869
+ name: stack.logicalPrefixedName(`${id}${processor.id}`),
870
+ handler: processor.handler,
871
+ link,
872
+ ...(vpc ? { vpc } : {}),
873
+ ...(processor.timeout !== undefined
874
+ ? {
875
+ timeout:
876
+ `${Math.ceil(processor.timeout / 1000)} seconds` as sst.aws.FunctionArgs['timeout'],
877
+ }
878
+ : {}),
879
+ ...(processor.memorySize !== undefined
880
+ ? {
881
+ memory:
882
+ `${processor.memorySize} MB` as sst.aws.FunctionArgs['memory'],
883
+ }
884
+ : {}),
885
+ ...(native.length ? { nodejs: { install: [...native] } } : {}),
886
+ url: {
887
+ authorization: 'iam',
888
+ router: {
889
+ instance: router as unknown as sst.aws.Router,
890
+ path: processor.prefix.replace(/\/$/, ''),
891
+ },
892
+ },
893
+ }),
894
+ );
895
+ }
896
+ }
897
+
898
+ return lambdas;
899
+ }
900
+
842
901
  /** A provisioned queue: what {@link subscribeConsumers} subscribes through. */
843
902
  interface Consumable {
844
903
  consume(consumer: {
@@ -1051,6 +1110,7 @@ export function fromManifest<
1051
1110
  // The functions and crons, each queue's one consumer and each surface's
1052
1111
  // endpoints, once everything they link to exists.
1053
1112
  provisionCompute(stack, manifest, provisioned);
1113
+ provisionProcessors(stack, manifest, provisioned);
1054
1114
  subscribeConsumers(manifest, provisioned);
1055
1115
  mountRoutes(manifest, provisioned);
1056
1116