@alzulejos/laranja-docs 0.2.4

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.
@@ -0,0 +1,193 @@
1
+ ---
2
+ title: CLI commands
3
+ description: Every laranja command and flag.
4
+ order: 1
5
+ ---
6
+
7
+ # CLI commands
8
+
9
+ ```
10
+ laranja <command> [project-dir] [flags]
11
+ ```
12
+
13
+ `project-dir` defaults to the current directory, so most of the time you just run
14
+ `laranja deploy`. Run `laranja --help` for a summary.
15
+
16
+ > **Most commands need your account.** `plan`, `deploy`, and `eject` build your
17
+ > template on the laranja server, so they need a `LARANJA_API_KEY` and a
18
+ > `projectId` in your config. Run [`laranja init`](#init) once to sign in and link
19
+ > a project; the key is stored in `~/.laranja/auth.json` so you don't re-export
20
+ > it. Your **source code never leaves your machine** — only a description of your
21
+ > infrastructure does
22
+ > (see [how it works](../getting-started/how-it-works.md)).
23
+
24
+ ## Global flags
25
+
26
+ | Flag | Applies to | Description |
27
+ |---|---|---|
28
+ | `--stage`, `-s <name>` | deploy, plan, destroy, logs, eject | Target [stage](../guides/stages-and-environments.md); overrides `config.stage`. |
29
+ | `--verbose`, `-v` | deploy | Stream full CDK/CloudFormation output instead of the compact UI. |
30
+ | `--strict` | deploy | Fail if any [`env()`](../guides/environment-variables.md#values-from-your-environment--env) value is unset (default: warn). |
31
+
32
+ ---
33
+
34
+ ## `init`
35
+
36
+ Sign in and scaffold a `laranja.config.ts` in the project directory.
37
+
38
+ ```bash
39
+ laranja init
40
+ ```
41
+
42
+ `init` prompts for your **laranja API key** (from the dashboard) and validates it
43
+ against the server before writing anything, then stores it in
44
+ `~/.laranja/auth.json` so later commands don't need it re-exported. It then lets
45
+ you **pick or create a dashboard project** and fills the scaffolded config's
46
+ `name` and `projectId` for you. Edit the file afterwards to set your `region`,
47
+ `env`, and `compute`. See the [config reference](./config-file.md).
48
+
49
+ ---
50
+
51
+ ## `logout`
52
+
53
+ Remove the stored API key (`~/.laranja/auth.json`).
54
+
55
+ ```bash
56
+ laranja logout
57
+ ```
58
+
59
+ After this, commands that talk to the server (`init`, `plan`, `deploy`, `eject`)
60
+ need `LARANJA_API_KEY` in the environment again, or another `laranja init`.
61
+
62
+ ---
63
+
64
+ ## `plan`
65
+
66
+ Preview what a deploy would do — laranja synthesizes your template on the server,
67
+ diffs it against the stack **currently deployed** in your AWS account, and prints
68
+ your app's resources tagged **created / changed / unchanged**. Nothing is applied.
69
+
70
+ ```bash
71
+ laranja plan
72
+ laranja plan --stage prod
73
+ ```
74
+
75
+ ```
76
+ Plan for "my-api-dev"
77
+
78
+ = http HTTP 2 routes → proxy Lambda + Function URL
79
+ + daily Cron Lambda + EventBridge rule
80
+ ~ emails Queue SQS + consumer Lambda
81
+
82
+ 8 AWS resources +3 created ~2 changed =3 unchanged
83
+ ```
84
+
85
+ `+` is new, `~` changed, `=` unchanged. The bottom line tallies the underlying
86
+ AWS resources.
87
+
88
+ `plan` needs `LARANJA_API_KEY` (run [`laranja init`](#init) first) to synthesize,
89
+ and a working **AWS credential chain** to read your live stack. It is
90
+ **read-only** — it never creates a deployment or counts against your deploy limit.
91
+
92
+ | Flag | Description |
93
+ |---|---|
94
+ | `--stage`, `-s` | Target stage. |
95
+
96
+ ---
97
+
98
+ ## `deploy`
99
+
100
+ Deploy into your AWS account using your **local** AWS credentials. The template is
101
+ synthesized on the laranja server first, then applied with your own credentials —
102
+ so deploy needs both `LARANJA_API_KEY` (run [`laranja init`](#init) first) and a
103
+ working AWS credential chain.
104
+
105
+ ```bash
106
+ laranja deploy
107
+ laranja deploy --stage prod
108
+ laranja deploy --verbose
109
+ ```
110
+
111
+ - The first deploy to a new account/region prompts to **bootstrap** (a one-time
112
+ setup in your account).
113
+ - On success it prints your outputs — the HTTPS URL, queue URLs, and the cron
114
+ jobs deployed.
115
+
116
+ | Flag | Description |
117
+ |---|---|
118
+ | `--stage`, `-s` | Target stage. |
119
+ | `--verbose`, `-v` | Stream full CDK output. |
120
+ | `--strict` | Fail the deploy if any [`env()`](../guides/environment-variables.md#values-from-your-environment--env) value is unset. By default these are deployed with a warning. |
121
+
122
+ ---
123
+
124
+ ## `destroy`
125
+
126
+ Tear down the deployed stack and all its resources. Prompts for confirmation.
127
+
128
+ ```bash
129
+ laranja destroy
130
+ laranja destroy --stage prod
131
+ ```
132
+
133
+ > Targets the stack for the resolved stage — make sure `--stage` matches the
134
+ > environment you intend to remove.
135
+
136
+ | Flag | Description |
137
+ |---|---|
138
+ | `--stage`, `-s` | Target stage. |
139
+
140
+ ---
141
+
142
+ ## `logs`
143
+
144
+ Tail CloudWatch logs for your deployed functions. The live stack is the source of
145
+ truth — no local state needed.
146
+
147
+ ```bash
148
+ laranja logs # interactive picker (TTY)
149
+ laranja logs sendEmail # tail a specific function by name
150
+ laranja logs --all # tail every function, multiplexed
151
+ laranja logs --no-follow # print recent history and exit
152
+ laranja logs --since 30m # history look-back window
153
+ laranja logs --stage prod # functions for the prod stack
154
+ ```
155
+
156
+ | Flag / arg | Description |
157
+ |---|---|
158
+ | `<name>` (positional) | Function to tail (matched against its short label or full name). |
159
+ | `--all` | Tail every function in the stack, multiplexed. |
160
+ | `--no-follow` | Print the recent history window and exit (no live tail). |
161
+ | `--since <dur>` | History look-back, e.g. `30s`, `15m`, `1h`, `2d` (default `1h`). |
162
+ | `--stage`, `-s` | Target stage. |
163
+
164
+ Both a directory and a function name can be passed as positionals —
165
+ `laranja logs ./app sendEmail` works.
166
+
167
+ ---
168
+
169
+ ## `eject`
170
+
171
+ Generate a standalone, owned **CDK project** from your app and stop — for when
172
+ you've outgrown the abstraction and want full control. **Paid feature.**
173
+
174
+ ```bash
175
+ laranja eject
176
+ laranja eject --force # overwrite an existing ./infra
177
+ laranja eject --stage prod
178
+ ```
179
+
180
+ The CDK project is generated **on the laranja server** (which gates the paid
181
+ entitlement) and written to `./infra` — a complete project you own and run
182
+ yourself (`cd infra && npm install && npm run deploy`). Requires `LARANJA_API_KEY`
183
+ and a `projectId`; if your account can't eject, the server returns a clear error.
184
+
185
+ | Flag | Description |
186
+ |---|---|
187
+ | `--force` | Overwrite an existing `infra/` directory. |
188
+ | `--stage`, `-s` | Target stage (baked into the generated project). |
189
+
190
+ ## Related
191
+
192
+ - [Stages & environments](../guides/stages-and-environments.md)
193
+ - [How it works](../getting-started/how-it-works.md)
@@ -0,0 +1,114 @@
1
+ ---
2
+ title: Config file
3
+ description: Every field in laranja.config.ts, with defaults and behavior.
4
+ order: 2
5
+ ---
6
+
7
+ # `laranja.config.ts`
8
+
9
+ Every project has a `laranja.config.ts` at its root that `export default`s a
10
+ config object. It's a TypeScript module (loaded via `tsx`), so you get full type
11
+ checking and can compute values if you need to.
12
+
13
+ ```ts
14
+ import type { LaranjaConfig } from "@alzulejos/laranja-decorators";
15
+
16
+ const config: LaranjaConfig = {
17
+ name: "my-api",
18
+ // From your laranja dashboard — identifies this project on the server.
19
+ projectId: "proj_…",
20
+ region: "us-east-1",
21
+ env: { LOG_LEVEL: "info" },
22
+ // Default compute for every function (the HTTP proxy + each cron/queue).
23
+ compute: { memory: 256, timeout: 30 },
24
+ };
25
+
26
+ export default config;
27
+ ```
28
+
29
+ The config stays minimal because the HTTP app is declared in code with the
30
+ [`http()`](./decorators-and-markers.md#http) marker — there's no config field for
31
+ it. For a deploy with no HTTP app, just omit the marker (see
32
+ [workers-only deployments](../guides/http-apps.md#workers-only-deployments)). Run
33
+ [`laranja init`](./commands.md#init) to scaffold this file — it fills in
34
+ `name` and `projectId` from the dashboard project you pick.
35
+
36
+ ## Fields
37
+
38
+ | Field | Required | Default | Description |
39
+ |---|---|---|---|
40
+ | `name` | ✅ | — | App name. Used for the CloudFormation stack and all resource names. |
41
+ | `region` | | `AWS_REGION` / `AWS_DEFAULT_REGION` | AWS region to deploy to. |
42
+ | `stage` | | `"dev"` | Deployment stage. Part of the stack + resource names and injected as the `STAGE` env var. Override per-run with [`--stage`](../guides/stages-and-environments.md). |
43
+ | `profile` | | — | AWS named profile to deploy with. |
44
+ | `framework` | | _auto-detected_ | Override framework detection (e.g. `"express"`). |
45
+ | `env` | | `{}` | Plain environment variables injected into every Lambda. See [Environment variables](../guides/environment-variables.md). |
46
+ | `compute` | | `{ memory: 256, timeout: 30 }` | Default memory (MB) and timeout (s) for **every** function. See [compute](#compute). |
47
+ | `resources` | | `{}` | Per-resource overrides keyed by resource id (`http`, or a cron/queue id). See [resources](#resources). |
48
+ | `projectId` | ✅ | — | Project id from the laranja dashboard. Required by the server-side build (`plan`/`deploy`/`eject`); `laranja init` fills it in. |
49
+ | `provider` | | `"aws"` | Target cloud. Only `"aws"` is implemented today. |
50
+
51
+ ### `name`
52
+
53
+ Drives the stack name (`‹name›-‹stage›`) and every resource name
54
+ (`‹name›-‹fn›-‹stage›`). Choose something short and stable — renaming it after a
55
+ deploy creates a _new_ stack rather than renaming the old one.
56
+
57
+ ### `region` and `profile`
58
+
59
+ `region` falls back to `AWS_REGION`, then `AWS_DEFAULT_REGION`. If none is set,
60
+ the CLI errors with a clear message. `profile` selects a named profile from your
61
+ AWS credentials file; otherwise the default credential chain is used.
62
+
63
+ ### `stage`
64
+
65
+ The default is `"dev"`. It's part of resource names and is injected into every
66
+ Lambda as `process.env.STAGE`. The [`--stage`](../guides/stages-and-environments.md)
67
+ flag overrides it per command — the recommended way to drive multiple
68
+ environments from one config.
69
+
70
+ ### `compute`
71
+
72
+ The default **memory** (MB) and **timeout** (seconds) applied to every function —
73
+ the HTTP proxy and each cron/queue consumer. The scaffold sets
74
+ `{ memory: 256, timeout: 30 }`:
75
+
76
+ ```ts
77
+ const config: LaranjaConfig = {
78
+ name: "my-api",
79
+ projectId: "proj_…",
80
+ compute: { memory: 512, timeout: 20 },
81
+ };
82
+ ```
83
+
84
+ ### `resources`
85
+
86
+ Per-resource overrides, keyed by **resource id** — `http` for the proxy, or the
87
+ [`id`](./decorators-and-markers.md#cron) of a cron/queue. Each entry
88
+ merges field-by-field on top of `compute`, and queue/cron entries also accept
89
+ their kind-specific knobs (e.g. a queue's `visibilityTimeout`). An unknown id is
90
+ a hard error, so a typo can't silently no-op:
91
+
92
+ ```ts
93
+ const config: LaranjaConfig = {
94
+ name: "my-api",
95
+ projectId: "proj_…",
96
+ compute: { memory: 256, timeout: 30 },
97
+ resources: {
98
+ http: { memory: 512 }, // beefier proxy
99
+ cleanup: { timeout: 60 }, // a slow cron by its id
100
+ emails: { visibilityTimeout: 180 }, // a queue by its name/id
101
+ },
102
+ };
103
+ ```
104
+
105
+ ### Workers-only deployments
106
+
107
+ To deploy only your workers (`@Cron` / `@Queue`) with no HTTP app — for teams
108
+ whose API is hosted elsewhere — simply don't add an `http()` marker. No flag is
109
+ needed. See [workers-only deployments](../guides/http-apps.md#workers-only-deployments).
110
+
111
+ ## Related
112
+
113
+ - [Environment variables](../guides/environment-variables.md)
114
+ - [Stages & environments](../guides/stages-and-environments.md)
@@ -0,0 +1,310 @@
1
+ ---
2
+ title: Decorators & markers
3
+ description: API reference for @Cron, @Queue, cron, queue, getQueue, and http.
4
+ order: 3
5
+ ---
6
+
7
+ # Decorators & markers
8
+
9
+ All of these are imported from `@alzulejos/laranja-decorators`. They are **static markers**
10
+ — the [scanner](../getting-started/how-it-works.md#1-scan) reads them at build time to
11
+ shape your infrastructure. At runtime they are near-no-ops (they don't wrap or
12
+ intercept your functions), so they're safe to leave in place.
13
+
14
+ ```bash
15
+ npm install @alzulejos/laranja-decorators
16
+ ```
17
+
18
+ The schedule builders [`rate`](../guides/schedules.md#ratevalue-unit) and
19
+ [`every`](../guides/schedules.md#everyunit) are re-exported here too, so you can
20
+ import them alongside `@Cron`. For `@nestjs/schedule` compatibility, the
21
+ `CronExpression` enum, `@Interval`, and `@Timeout` are re-exported as well — so a
22
+ Nest app can repoint its import at `@alzulejos/laranja-decorators` unchanged.
23
+
24
+ ---
25
+
26
+ ## `@Cron`
27
+
28
+ Schedules a class method. Each `@Cron` becomes [its own Lambda + EventBridge
29
+ rule](./what-gets-deployed.md#cron--lambda--eventbridge-rule).
30
+
31
+ ```ts
32
+ function Cron(schedule: ScheduleInput): MethodDecorator
33
+ function Cron(options: CronOptions): MethodDecorator
34
+ function Cron(expression: string, options?: NestCronOptions): MethodDecorator // @nestjs/schedule form
35
+ ```
36
+
37
+ ```ts
38
+ import { Cron, rate, CronExpression } from "@alzulejos/laranja-decorators";
39
+
40
+ export class Jobs {
41
+ @Cron(rate(5, "minutes"))
42
+ async refreshCache() {}
43
+
44
+ @Cron({ schedule: "cron(0 12 * * ? *)", id: "daily-report" })
45
+ async report() {}
46
+
47
+ // @nestjs/schedule style — a node-cron string or CronExpression, translated for you
48
+ @Cron("0 3 * * *", { name: "nightly", timeZone: "Europe/Lisbon" })
49
+ async nightly() {}
50
+
51
+ @Cron(CronExpression.EVERY_30_MINUTES)
52
+ async sweep() {}
53
+ }
54
+ ```
55
+
56
+ **`CronOptions`** (laranja form)
57
+
58
+ | Field | Type | Description |
59
+ |---|---|---|
60
+ | `schedule` | `ScheduleInput` | A [`rate()`/`every()`](../guides/schedules.md) result, a `Schedule`, or a raw string. |
61
+ | `id` | `string` _(optional)_ | Stable logical id. Defaults to `‹Class›-‹method›`; also drives the Lambda name. |
62
+
63
+ **`NestCronOptions`** (the second argument in the `@nestjs/schedule` form)
64
+
65
+ | Field | Type | Description |
66
+ |---|---|---|
67
+ | `name` | `string` _(optional)_ | Used as the resource `id`. |
68
+ | `timeZone` | `string` _(optional)_ | IANA timezone the schedule is evaluated in. |
69
+
70
+ See [Schedules → node-cron expressions](../guides/schedules.md#node-cron-expressions-nestjsschedule-compatibility)
71
+ for the accepted syntax and what's rejected. Nest providers resolve through DI —
72
+ declare your module with [`workers()`](#workers).
73
+
74
+ ---
75
+
76
+ ## `cron()` marker
77
+
78
+ Function-style counterpart to `@Cron`, for codebases that don't use classes.
79
+ Registers a standalone exported function on a schedule.
80
+
81
+ ```ts
82
+ function cron(schedule: ScheduleInput, handler: JobHandler): void
83
+ function cron(options: CronOptions, handler: JobHandler): void
84
+ ```
85
+
86
+ ```ts
87
+ import { cron, rate } from "@alzulejos/laranja-decorators";
88
+
89
+ export async function refreshCache() {}
90
+
91
+ cron(rate(5, "minutes"), refreshCache);
92
+ cron({ schedule: rate(1, "hour"), id: "hourly-sync" }, refreshCache);
93
+ ```
94
+
95
+ The function's name becomes the resource id unless you pass an explicit `id`.
96
+
97
+ ---
98
+
99
+ ## `@Interval`
100
+
101
+ `@nestjs/schedule`-compatible. Runs a method every _N_ milliseconds; laranja
102
+ lowers it to a `rate(...)`, so the interval must be a whole number of minutes
103
+ (EventBridge's 1-minute floor).
104
+
105
+ ```ts
106
+ function Interval(milliseconds: number): MethodDecorator
107
+ function Interval(name: string, milliseconds: number): MethodDecorator
108
+ ```
109
+
110
+ ```ts
111
+ import { Interval } from "@alzulejos/laranja-decorators";
112
+
113
+ export class Jobs {
114
+ @Interval(300000) // every 5 minutes
115
+ async poll() {}
116
+ }
117
+ ```
118
+
119
+ ---
120
+
121
+ ## `@Timeout`
122
+
123
+ Re-exported for `@nestjs/schedule` source compatibility, but a one-shot timer
124
+ relative to process start has no serverless equivalent — laranja **rejects it at
125
+ build time** with a clear message. Use [`@Cron`](#cron) or [`@Interval`](#interval)
126
+ instead.
127
+
128
+ ---
129
+
130
+ ## `@Queue`
131
+
132
+ Consumes messages from an SQS queue. Each `@Queue` becomes [an SQS queue +
133
+ consumer Lambda](./what-gets-deployed.md#queue--sqs-queue--consumer-lambda).
134
+ The handler is called once per message with the JSON-parsed body.
135
+
136
+ ```ts
137
+ function Queue(options: QueueOptions): MethodDecorator
138
+ ```
139
+
140
+ ```ts
141
+ import { Queue } from "@alzulejos/laranja-decorators";
142
+
143
+ export class Workers {
144
+ @Queue({ name: "emails", batchSize: 10 })
145
+ async sendEmail(body: unknown) {}
146
+
147
+ @Queue({ name: "orders.fifo", fifo: true })
148
+ async processOrder(body: unknown) {}
149
+ }
150
+ ```
151
+
152
+ **`QueueOptions`**
153
+
154
+ | Field | Type | Default | Description |
155
+ |---|---|---|---|
156
+ | `name` | `string` | _required_ | Queue name. A `.fifo` suffix marks a FIFO queue. |
157
+ | `batchSize` | `number` | `10` | Max messages per consumer invocation. |
158
+ | `fifo` | `boolean` | `false` | Force a FIFO queue (or end `name` with `.fifo`). When set, laranja appends `.fifo` to `name` if you left it off. |
159
+
160
+ ---
161
+
162
+ ## `queue()` marker
163
+
164
+ Function-style counterpart to `@Queue`.
165
+
166
+ ```ts
167
+ function queue(options: QueueOptions, handler: JobHandler): void
168
+ ```
169
+
170
+ ```ts
171
+ import { queue } from "@alzulejos/laranja-decorators";
172
+
173
+ export async function sendEmail(body: unknown) {}
174
+
175
+ queue({ name: "emails", batchSize: 10 }, sendEmail);
176
+ ```
177
+
178
+ ---
179
+
180
+ ## `getQueue()`
181
+
182
+ The queue **producer** — get a handle to a declared queue and `.send()` messages
183
+ to it. The counterpart to the [`@Queue`](#queue) / [`queue()`](#queue-marker)
184
+ consumers. Unlike the markers, this does real work at runtime (a single SQS
185
+ `SendMessage`); laranja injects the queue URL and grants `sqs:SendMessage` to
186
+ every function, so there's nothing to configure.
187
+
188
+ ```ts
189
+ function getQueue(name: string): LaranjaQueue
190
+
191
+ interface LaranjaQueue {
192
+ readonly url: string;
193
+ send(payload: unknown, options?: SendOptions): Promise<{ messageId?: string }>;
194
+ }
195
+ ```
196
+
197
+ ```ts
198
+ import { getQueue } from "@alzulejos/laranja-decorators";
199
+
200
+ await getQueue("emails").send({ to, subject });
201
+ await getQueue("orders.fifo").send(order, { groupId: order.customerId });
202
+ ```
203
+
204
+ `payload` is JSON-serialized (strings are sent as-is). `name` is the queue's
205
+ declared `name`; a send to an undeclared queue throws.
206
+
207
+ **`SendOptions`**
208
+
209
+ | Field | Type | Applies to | Description |
210
+ |---|---|---|---|
211
+ | `groupId` | `string` | FIFO (**required**) | `MessageGroupId` — orders messages within a group. A FIFO send throws without it. |
212
+ | `dedupId` | `string` | FIFO | `MessageDeduplicationId` — only needed when content-based dedup is off. |
213
+ | `delaySeconds` | `number` | Standard | Delay (0–900s) before the message becomes visible. Ignored by FIFO. |
214
+
215
+ See [Queues → Sending messages](../guides/queues.md#sending-messages).
216
+
217
+ ---
218
+
219
+ ## `http()`
220
+
221
+ Marks the HTTP app (the proxy target) in code — the only way to declare one.
222
+ Export the result so the scanner can find it.
223
+
224
+ ```ts
225
+ function http<T>(app: T): T
226
+ ```
227
+
228
+ ```ts
229
+ import express from "express";
230
+ import { http } from "@alzulejos/laranja-decorators";
231
+
232
+ const app = express();
233
+ export default http(app); // or: export const api = http(app);
234
+ ```
235
+
236
+ It returns its argument untouched — purely a static marker. Omit it for a
237
+ [workers-only](../guides/http-apps.md#workers-only-deployments) deployment.
238
+
239
+ For **NestJS**, wrap your async `bootstrap` factory (which `return`s the app)
240
+ instead of an app instance — see [HTTP apps → NestJS](../guides/http-apps.md#nestjs):
241
+
242
+ ```ts
243
+ export default http(bootstrap); // bootstrap: () => Promise<INestApplication>
244
+ ```
245
+
246
+ ---
247
+
248
+ ## `workers()`
249
+
250
+ **NestJS only.** Declares the module laranja builds a dependency-injection
251
+ context from, so class-based [`@Cron`](#cron) / [`@Queue`](#queue) providers
252
+ resolve their injected dependencies at runtime (via
253
+ `NestFactory.createApplicationContext`) instead of a bare `new`. The DI
254
+ counterpart to [`http()`](#http); export it so the scanner can find it.
255
+
256
+ ```ts
257
+ function workers<T>(module: T): T
258
+ ```
259
+
260
+ ```ts
261
+ import { workers } from "@alzulejos/laranja-decorators";
262
+ import { AppModule } from "./app.module";
263
+
264
+ export default workers(AppModule); // or: export const jobs = workers(AppModule);
265
+ ```
266
+
267
+ Pass `AppModule` for the whole graph, or a leaner module for a smaller cold
268
+ start. There's exactly one per project. Required when a Nest project has
269
+ class-based workers; standalone [`cron()`](#cron-marker)/[`queue()`](#queue-marker)
270
+ functions don't need it (no DI). Returns its argument untouched — a static marker.
271
+
272
+ ---
273
+
274
+ ## `env()`
275
+
276
+ Declares an environment variable your code needs. At runtime it just returns
277
+ `process.env[name]`; laranja discovers each call and populates that variable on
278
+ every deployed function, with the value supplied from your shell or CI at deploy
279
+ time.
280
+
281
+ ```ts
282
+ function env(name: string): string | undefined
283
+ ```
284
+
285
+ ```ts
286
+ import { env } from "@alzulejos/laranja-decorators";
287
+
288
+ const dbUrl = env("DATABASE_URL");
289
+ ```
290
+
291
+ The name must be a **string literal** so it can be found statically. See
292
+ [environment variables](../guides/environment-variables.md#values-from-your-environment--env)
293
+ for supplying values, the `--strict` flag, and per-stage usage.
294
+
295
+ ---
296
+
297
+ ## Types
298
+
299
+ | Type | Description |
300
+ |---|---|
301
+ | `ScheduleInput` | `Schedule \| string` — anything accepted where a schedule is expected. |
302
+ | `Schedule` | Provider-neutral schedule: `{ kind: "rate", value, unit }` or `{ kind: "cron", expression, dialect }`. |
303
+ | `RateUnit` | `"minute" \| "minutes" \| "hour" \| "hours" \| "day" \| "days"`. |
304
+ | `CronExpression` | Enum of common cron strings, mirrored from `@nestjs/schedule`. |
305
+ | `JobHandler` | `(...args) => unknown \| Promise<unknown>` — a `cron()`/`queue()` handler. |
306
+
307
+ ## Related
308
+
309
+ - [Cron jobs](../guides/cron-jobs.md) · [Queues](../guides/queues.md) · [Schedules](../guides/schedules.md)
310
+ - [HTTP apps](../guides/http-apps.md)
@@ -0,0 +1,84 @@
1
+ ---
2
+ title: What gets deployed
3
+ description: The exact AWS resources laranja creates and how they're named.
4
+ order: 4
5
+ ---
6
+
7
+ # What gets deployed
8
+
9
+ laranja maps each thing it finds in your code to a small, predictable set of AWS
10
+ resources — all in your own account.
11
+
12
+ ## HTTP app → proxy Lambda + Function URL
13
+
14
+ Your entire Express app is deployed as **one Lambda function** fronted by a
15
+ **Lambda Function URL**. There is no API Gateway.
16
+
17
+ - All routes are served by this single proxy Lambda.
18
+ - The Function URL is **public** (`authType: NONE`) and CORS is open
19
+ (`*` origins, all methods, all headers) — your app handles auth/CORS as it
20
+ sees fit.
21
+ - Memory and timeout come from [`compute`](./config-file.md#compute)
22
+ in your config (the scaffold sets `{ memory: 256, timeout: 30 }`), overridable
23
+ per-resource under the `http` key in [`resources`](./config-file.md#resources).
24
+ - The public HTTPS URL is emitted as the `HttpUrl` stack output.
25
+
26
+ ```
27
+ GET https://‹id›.lambda-url.‹region›.on.aws/
28
+ ```
29
+
30
+ ## `@Cron` → Lambda + EventBridge rule
31
+
32
+ Each cron handler becomes **its own Lambda** plus an **EventBridge rule** that
33
+ invokes it on schedule.
34
+
35
+ - Memory and timeout come from [`compute`](./config-file.md#compute)
36
+ (default `{ memory: 256, timeout: 30 }`), overridable per cron id in
37
+ [`resources`](./config-file.md#resources).
38
+ - The schedule comes from your [`rate()`/`every()`](../guides/schedules.md)
39
+ builder or raw expression.
40
+
41
+ ## `@Queue` → SQS queue + consumer Lambda
42
+
43
+ Each queue handler becomes an **SQS queue** and a **consumer Lambda** wired to it.
44
+
45
+ - Encryption: **SQS-managed (SSE-SQS)**.
46
+ - **FIFO** queues are created when the name ends in `.fifo` or `fifo: true` is
47
+ set (content-based deduplication is enabled for FIFO).
48
+ - Default **batch size**: 10. Your handler is invoked per message with the
49
+ JSON-parsed body.
50
+ - **Partial-batch failures** are enabled: throwing for one message fails only
51
+ that message; the rest of the batch still succeeds.
52
+ - Consumer memory/timeout come from [`compute`](./config-file.md#compute)
53
+ (default `{ memory: 256, timeout: 30 }`). The queue's **visibility timeout** is
54
+ derived to satisfy AWS's rule that it be ≥ the consumer timeout, and can be set
55
+ explicitly per queue via [`resources`](./config-file.md#resources).
56
+ - The queue URL is emitted as a stack output.
57
+
58
+ ## Naming
59
+
60
+ Everything is named deterministically — no random suffixes:
61
+
62
+ | Resource | Pattern | Example |
63
+ |---|---|---|
64
+ | CloudFormation stack | `‹name›-‹stage›` | `my-api-prod` |
65
+ | Lambda functions | `‹name›-‹fn›-‹stage›` | `my-api-app-prod`, `my-api-sendEmail-prod` |
66
+
67
+ `‹fn›` is the handler's name (the method/function name), or the explicit `id` you
68
+ set on `@Cron`/`@Queue`. The HTTP proxy uses `app`. Names are truncated to AWS's
69
+ 64-character limit and sanitized to allowed characters.
70
+
71
+ Because the stage is part of the names, multiple stages can live in one account
72
+ without colliding — see [Stages & environments](../guides/stages-and-environments.md).
73
+
74
+ ## Supporting resources
75
+
76
+ Each Lambda gets an **IAM execution role** (and the queue consumers get the
77
+ permissions to read their queue / EventBridge to invoke crons). The first deploy
78
+ to an account/region also creates the one-time CDK **bootstrap** resources (an S3
79
+ asset bucket and roles).
80
+
81
+ ## Related
82
+
83
+ - [How it works](../getting-started/how-it-works.md)
84
+ - [HTTP apps](../guides/http-apps.md) · [Cron jobs](../guides/cron-jobs.md) · [Queues](../guides/queues.md)