@alzulejos/laranja 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.
- package/README.md +28 -0
- package/dist/aws.d.ts +79 -0
- package/dist/aws.js +170 -0
- package/dist/aws.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +134 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/deploy.d.ts +5 -0
- package/dist/commands/deploy.js +146 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/destroy.d.ts +3 -0
- package/dist/commands/destroy.js +60 -0
- package/dist/commands/destroy.js.map +1 -0
- package/dist/commands/eject.d.ts +9 -0
- package/dist/commands/eject.js +45 -0
- package/dist/commands/eject.js.map +1 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +103 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/logout.d.ts +5 -0
- package/dist/commands/logout.js +15 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/logs.d.ts +25 -0
- package/dist/commands/logs.js +135 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/plan.d.ts +10 -0
- package/dist/commands/plan.js +47 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/diagnostics.d.ts +31 -0
- package/dist/diagnostics.js +85 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/io.d.ts +9 -0
- package/dist/io.js +28 -0
- package/dist/io.js.map +1 -0
- package/dist/iohost.d.ts +36 -0
- package/dist/iohost.js +71 -0
- package/dist/iohost.js.map +1 -0
- package/dist/lifecycle.d.ts +12 -0
- package/dist/lifecycle.js +21 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/nest-build.d.ts +10 -0
- package/dist/nest-build.js +73 -0
- package/dist/nest-build.js.map +1 -0
- package/dist/pipeline.d.ts +34 -0
- package/dist/pipeline.js +115 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/plan-summary.d.ts +23 -0
- package/dist/plan-summary.js +131 -0
- package/dist/plan-summary.js.map +1 -0
- package/dist/project-link.d.ts +26 -0
- package/dist/project-link.js +77 -0
- package/dist/project-link.js.map +1 -0
- package/dist/report.d.ts +51 -0
- package/dist/report.js +183 -0
- package/dist/report.js.map +1 -0
- package/dist/resource-types.d.ts +9 -0
- package/dist/resource-types.js +19 -0
- package/dist/resource-types.js.map +1 -0
- package/dist/ui.d.ts +50 -0
- package/dist/ui.js +216 -0
- package/dist/ui.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-summary.js","sourceRoot":"","sources":["../src/plan-summary.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ProjectGroups } from "@alzulejos/laranja-core";
|
|
2
|
+
/** A dashboard project chosen (or created) via the interactive picker. */
|
|
3
|
+
export interface ResolvedProject {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
/** True when it was freshly created (vs. picked from the existing list). */
|
|
7
|
+
created?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Fill the empty `projectId: ""` in the config with a real value. Leaves a
|
|
11
|
+
* non-empty projectId untouched so we never clobber a user's edit. Returns true
|
|
12
|
+
* if the file was updated.
|
|
13
|
+
*/
|
|
14
|
+
export declare function writeProjectId(file: string, projectId: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Fill the empty `name: ""` with the chosen dashboard project's name, mirroring
|
|
17
|
+
* `writeProjectId`. Leaves a non-empty name untouched so we never clobber an edit.
|
|
18
|
+
*/
|
|
19
|
+
export declare function writeName(file: string, name: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Resolve which dashboard project this directory maps to. If the user has
|
|
22
|
+
* projects, let them pick one or choose to create a new one; with no projects,
|
|
23
|
+
* go straight to creating one. Returns the chosen/created project id (and the
|
|
24
|
+
* name when freshly created), or undefined if the user cancels.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveProjectId(apiKey: string, projects: ProjectGroups): Promise<ResolvedProject | undefined>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { createProject } from "@alzulejos/laranja-core";
|
|
3
|
+
import * as ui from "./ui.js";
|
|
4
|
+
/** Sentinel value for the "create a new project" choice in the picker. */
|
|
5
|
+
const CREATE_NEW = "\0create-new";
|
|
6
|
+
/**
|
|
7
|
+
* Fill the empty `projectId: ""` in the config with a real value. Leaves a
|
|
8
|
+
* non-empty projectId untouched so we never clobber a user's edit. Returns true
|
|
9
|
+
* if the file was updated.
|
|
10
|
+
*/
|
|
11
|
+
export function writeProjectId(file, projectId) {
|
|
12
|
+
if (!projectId)
|
|
13
|
+
return false;
|
|
14
|
+
const content = readFileSync(file, "utf8");
|
|
15
|
+
const updated = content.replace(/projectId:\s*""/, `projectId: ${JSON.stringify(projectId)}`);
|
|
16
|
+
if (updated === content)
|
|
17
|
+
return false;
|
|
18
|
+
writeFileSync(file, updated);
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Fill the empty `name: ""` with the chosen dashboard project's name, mirroring
|
|
23
|
+
* `writeProjectId`. Leaves a non-empty name untouched so we never clobber an edit.
|
|
24
|
+
*/
|
|
25
|
+
export function writeName(file, name) {
|
|
26
|
+
if (!name)
|
|
27
|
+
return false;
|
|
28
|
+
const content = readFileSync(file, "utf8");
|
|
29
|
+
const updated = content.replace(/name:\s*""/, `name: ${JSON.stringify(name)}`);
|
|
30
|
+
if (updated === content)
|
|
31
|
+
return false;
|
|
32
|
+
writeFileSync(file, updated);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolve which dashboard project this directory maps to. If the user has
|
|
37
|
+
* projects, let them pick one or choose to create a new one; with no projects,
|
|
38
|
+
* go straight to creating one. Returns the chosen/created project id (and the
|
|
39
|
+
* name when freshly created), or undefined if the user cancels.
|
|
40
|
+
*/
|
|
41
|
+
export async function resolveProjectId(apiKey, projects) {
|
|
42
|
+
const all = [...projects.personal, ...projects.collaborating];
|
|
43
|
+
let choice;
|
|
44
|
+
if (all.length > 0) {
|
|
45
|
+
// Group the picker into "Your projects" / "Shared with you" sections, only
|
|
46
|
+
// showing a heading for a group that actually has projects.
|
|
47
|
+
const section = (title, list) => list.length > 0
|
|
48
|
+
? [
|
|
49
|
+
{ label: title, value: "", header: true },
|
|
50
|
+
...list.map((p) => ({
|
|
51
|
+
label: p.framework
|
|
52
|
+
? `${p.name} ${ui.dim(`(${p.framework})`)}`
|
|
53
|
+
: p.name,
|
|
54
|
+
value: p.id,
|
|
55
|
+
})),
|
|
56
|
+
]
|
|
57
|
+
: [];
|
|
58
|
+
choice = await ui.select("Which project is this? (↑/↓, Enter)", [
|
|
59
|
+
...section("Your projects", projects.personal),
|
|
60
|
+
...section("Shared with you", projects.collaborating),
|
|
61
|
+
{ label: ui.orange("+ Create a new project"), value: CREATE_NEW },
|
|
62
|
+
]);
|
|
63
|
+
if (!choice)
|
|
64
|
+
return undefined; // cancelled
|
|
65
|
+
if (choice !== CREATE_NEW) {
|
|
66
|
+
const picked = all.find((p) => p.id === choice);
|
|
67
|
+
return { id: choice, name: picked?.name ?? "" };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// No projects yet, or the user chose to create one.
|
|
71
|
+
const name = await ui.promptText("New project name:");
|
|
72
|
+
if (!name)
|
|
73
|
+
return undefined;
|
|
74
|
+
const created = await createProject(name, apiKey);
|
|
75
|
+
return { id: created.id, name, created: true };
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=project-link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-link.js","sourceRoot":"","sources":["../src/project-link.ts"],"names":[],"mappings":"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"}
|
package/dist/report.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turn a deployed IR into the resource inventory the dashboard expects
|
|
3
|
+
* (`POST /deployment/:id/resources`). One row per LOGICAL laranja resource —
|
|
4
|
+
* the http proxy, each cron, each queue — not per physical AWS resource.
|
|
5
|
+
*
|
|
6
|
+
* Every resource is reported on every deploy, so the dashboard always shows the
|
|
7
|
+
* full outcome. ARNs are reconstructed deterministically from the IR: the stack
|
|
8
|
+
* pins each Lambda's `functionName` to `<app>-<label>-<stage>`, so the ARN is
|
|
9
|
+
* `arn:aws:lambda:<region>:<account>:function:<that name>`. The Function URL
|
|
10
|
+
* (http only) isn't reconstructable, so it comes from the stack outputs.
|
|
11
|
+
*
|
|
12
|
+
* Grouping: a Nest `workers()` module compiles to ONE shared worker Lambda that
|
|
13
|
+
* hosts every method-style `@Cron`/`@Queue` it owns (see laranja-cdk `stack.ts`).
|
|
14
|
+
* Such handlers carry a `workersId` (the module id) — the physical function label
|
|
15
|
+
* is that id, NOT the handler's own name, so every grouped cron/queue resolves to
|
|
16
|
+
* the same worker ARN. Each stays its own logical resource (its own node), so the
|
|
17
|
+
* dashboard renders e.g. two queues both pointing at one `<module>` Lambda; the
|
|
18
|
+
* `metadata.worker` field names that owning function for grouping/labels.
|
|
19
|
+
*/
|
|
20
|
+
import { type InfraIR, type DeployedResource } from "@alzulejos/laranja-core";
|
|
21
|
+
import type { PriorNodeLambda } from "./aws.js";
|
|
22
|
+
export interface BuildResourcesArgs {
|
|
23
|
+
ir: InfraIR;
|
|
24
|
+
region: string;
|
|
25
|
+
account: string;
|
|
26
|
+
/** Parsed CloudFormation outputs for the stack (e.g. `HttpUrl`). */
|
|
27
|
+
outputs: Record<string, string>;
|
|
28
|
+
/** env keys with no value at deploy — surfaced as per-resource `metadata.warnings`. */
|
|
29
|
+
missingEnv: string[];
|
|
30
|
+
/**
|
|
31
|
+
* Physical resource ids present in the stack BEFORE this deploy (from
|
|
32
|
+
* `getStackSnapshot`). A resource whose physical id is in this set is being
|
|
33
|
+
* UPDATED; anything else is CREATED. Empty on a first deploy → all CREATED.
|
|
34
|
+
*/
|
|
35
|
+
priorPhysicalIds: Set<string>;
|
|
36
|
+
/**
|
|
37
|
+
* laranja node Lambdas present in the stack BEFORE this deploy. Used to detect a
|
|
38
|
+
* REMOVED http proxy (it has no per-resource sibling). Empty on a first deploy.
|
|
39
|
+
*/
|
|
40
|
+
priorNodeLambdas: PriorNodeLambda[];
|
|
41
|
+
/**
|
|
42
|
+
* EventBridge schedule names present before this deploy (`<app>-<id>-<stage>`),
|
|
43
|
+
* one per logical cron. Any not produced by this deploy → REMOVED cron — this is
|
|
44
|
+
* how a grouped cron's removal is seen even though its worker Lambda survives.
|
|
45
|
+
* Omitted → treated as empty (no prior state, e.g. a first deploy).
|
|
46
|
+
*/
|
|
47
|
+
priorScheduleNames?: Set<string>;
|
|
48
|
+
/** SQS queue names present before this deploy, one per logical queue → REMOVED. */
|
|
49
|
+
priorQueueNames?: Set<string>;
|
|
50
|
+
}
|
|
51
|
+
export declare function buildDeployedResources(args: BuildResourcesArgs): DeployedResource[];
|
package/dist/report.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turn a deployed IR into the resource inventory the dashboard expects
|
|
3
|
+
* (`POST /deployment/:id/resources`). One row per LOGICAL laranja resource —
|
|
4
|
+
* the http proxy, each cron, each queue — not per physical AWS resource.
|
|
5
|
+
*
|
|
6
|
+
* Every resource is reported on every deploy, so the dashboard always shows the
|
|
7
|
+
* full outcome. ARNs are reconstructed deterministically from the IR: the stack
|
|
8
|
+
* pins each Lambda's `functionName` to `<app>-<label>-<stage>`, so the ARN is
|
|
9
|
+
* `arn:aws:lambda:<region>:<account>:function:<that name>`. The Function URL
|
|
10
|
+
* (http only) isn't reconstructable, so it comes from the stack outputs.
|
|
11
|
+
*
|
|
12
|
+
* Grouping: a Nest `workers()` module compiles to ONE shared worker Lambda that
|
|
13
|
+
* hosts every method-style `@Cron`/`@Queue` it owns (see laranja-cdk `stack.ts`).
|
|
14
|
+
* Such handlers carry a `workersId` (the module id) — the physical function label
|
|
15
|
+
* is that id, NOT the handler's own name, so every grouped cron/queue resolves to
|
|
16
|
+
* the same worker ARN. Each stays its own logical resource (its own node), so the
|
|
17
|
+
* dashboard renders e.g. two queues both pointing at one `<module>` Lambda; the
|
|
18
|
+
* `metadata.worker` field names that owning function for grouping/labels.
|
|
19
|
+
*/
|
|
20
|
+
import { dashboardName, describeSchedule, handlerLabel, handlerName, } from "@alzulejos/laranja-core";
|
|
21
|
+
/**
|
|
22
|
+
* Physical Lambda name — must match laranja-cdk `stack.ts` `fnName()`:
|
|
23
|
+
* `<app>-<label>-<stage>`, non-alphanumerics collapsed to "-", capped at 64.
|
|
24
|
+
*/
|
|
25
|
+
function functionName(ir, label) {
|
|
26
|
+
return `${ir.app.name}-${label}-${ir.app.stage}`.replace(/[^A-Za-z0-9-_]/g, "-").slice(0, 64);
|
|
27
|
+
}
|
|
28
|
+
export function buildDeployedResources(args) {
|
|
29
|
+
const { ir, region, account, outputs, missingEnv, priorPhysicalIds, priorNodeLambdas, priorScheduleNames = new Set(), priorQueueNames = new Set(), } = args;
|
|
30
|
+
// env warnings are app-wide (one process.env, shared by every Lambda), so they
|
|
31
|
+
// attach to each resource. `metadata` must be an object, never null.
|
|
32
|
+
const meta = (extra = {}) => missingEnv.length ? { ...extra, warnings: missingEnv } : { ...extra };
|
|
33
|
+
const arn = (label) => `arn:aws:lambda:${region}:${account}:function:${functionName(ir, label)}`;
|
|
34
|
+
// A resource whose pinned physical name was already in the stack is being
|
|
35
|
+
// modified; otherwise it's new. Lambdas key off their `<app>-<label>-<stage>`
|
|
36
|
+
// function name, the monitoring dashboard off its `<app>-<stage>` name.
|
|
37
|
+
const actionFor = (physicalId) => priorPhysicalIds.has(physicalId) ? "UPDATED" : "CREATED";
|
|
38
|
+
const resources = [];
|
|
39
|
+
// The monitoring dashboard is one physical AWS::CloudWatch::Dashboard named
|
|
40
|
+
// `<app>-<stage>` (see laranja-cdk). It has no ARN worth showing; the value is
|
|
41
|
+
// the console deep link, stored BE-side as `externalUrl` so the FE renders a
|
|
42
|
+
// clickable node without knowing the provider. Other providers fill the same
|
|
43
|
+
// field with their own console URL.
|
|
44
|
+
if (ir.app.monitoring) {
|
|
45
|
+
const name = dashboardName(ir.app.name, ir.app.stage);
|
|
46
|
+
resources.push({
|
|
47
|
+
name: "monitoring",
|
|
48
|
+
type: "dashboard",
|
|
49
|
+
action: actionFor(name),
|
|
50
|
+
metadata: meta(),
|
|
51
|
+
externalId: null,
|
|
52
|
+
externalUrl: `https://${region}.console.aws.amazon.com/cloudwatch/home?region=${region}#dashboards/dashboard/${name}`,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (ir.http) {
|
|
56
|
+
resources.push({
|
|
57
|
+
name: "http",
|
|
58
|
+
type: "http",
|
|
59
|
+
action: actionFor(functionName(ir, "app")),
|
|
60
|
+
metadata: meta(),
|
|
61
|
+
externalId: arn("app"),
|
|
62
|
+
externalUrl: outputs.HttpUrl ?? null,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
for (const cron of ir.crons) {
|
|
66
|
+
const label = cron.workersId ?? handlerLabel(cron);
|
|
67
|
+
resources.push({
|
|
68
|
+
name: cron.id,
|
|
69
|
+
type: "cron",
|
|
70
|
+
action: actionFor(functionName(ir, label)),
|
|
71
|
+
// Store a ready-to-display label alongside the structured schedule so the
|
|
72
|
+
// dashboard shows "Every minute" without re-deriving it from the cron string.
|
|
73
|
+
metadata: meta({
|
|
74
|
+
schedule: { ...cron.schedule, description: describeSchedule(cron.schedule) },
|
|
75
|
+
...(cron.workersId && { worker: cron.workersId }),
|
|
76
|
+
}),
|
|
77
|
+
// Grouped Nest crons run in their module's shared worker Lambda (label =
|
|
78
|
+
// workersId); a standalone cron owns its own function (label = handler name).
|
|
79
|
+
externalId: arn(label),
|
|
80
|
+
externalUrl: null,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
// A queue's DLQ target is another declared queue, referenced by its SQS `name`.
|
|
84
|
+
// Resource nodes are keyed by `q.id`, so translate name→id here — the dashboard
|
|
85
|
+
// draws the redrive edge (source queue → DLQ queue) directly between nodes.
|
|
86
|
+
const idByQueueName = new Map(ir.queues.map((q) => [q.name, q.id]));
|
|
87
|
+
for (const q of ir.queues) {
|
|
88
|
+
const label = q.workersId ?? handlerName(q);
|
|
89
|
+
resources.push({
|
|
90
|
+
name: q.id,
|
|
91
|
+
type: "queue",
|
|
92
|
+
action: actionFor(functionName(ir, label)),
|
|
93
|
+
metadata: meta({
|
|
94
|
+
queueName: q.name,
|
|
95
|
+
fifo: Boolean(q.fifo),
|
|
96
|
+
batchSize: q.batchSize ?? 10,
|
|
97
|
+
queueArn: `arn:aws:sqs:${region}:${account}:${q.name}`,
|
|
98
|
+
...(q.dlq && {
|
|
99
|
+
dlq: {
|
|
100
|
+
queue: idByQueueName.get(q.dlq.queue) ?? q.dlq.queue,
|
|
101
|
+
maxReceiveCount: q.dlq.maxReceiveCount,
|
|
102
|
+
},
|
|
103
|
+
}),
|
|
104
|
+
...(q.workersId && { worker: q.workersId }),
|
|
105
|
+
}),
|
|
106
|
+
// Grouped Nest queues share their module's worker Lambda (label = workersId);
|
|
107
|
+
// a standalone queue owns its own consumer function (label = handler name).
|
|
108
|
+
externalId: arn(label),
|
|
109
|
+
externalUrl: null,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
// REMOVED: a logical resource that was in the stack before but this deploy no
|
|
113
|
+
// longer produces. Detection keys off each resource's OWN physical CFN object, not
|
|
114
|
+
// the Lambda — so grouped Nest crons/queues (many sharing one worker Lambda) are
|
|
115
|
+
// covered: the shared Lambda survives, but the removed handler's schedule / queue
|
|
116
|
+
// disappears. Each deployment stores its own inventory as history, so this is just
|
|
117
|
+
// a row in THIS deploy's snapshot — no reconciliation against a persistent node.
|
|
118
|
+
const appPrefix = `${ir.app.name}-`;
|
|
119
|
+
const stageSuffix = `-${ir.app.stage}`;
|
|
120
|
+
// Best-effort friendly name: undo `fnName`'s `<app>-<label>-<stage>` wrapping.
|
|
121
|
+
const labelOf = (name) => {
|
|
122
|
+
let s = name;
|
|
123
|
+
if (s.startsWith(appPrefix))
|
|
124
|
+
s = s.slice(appPrefix.length);
|
|
125
|
+
if (s.endsWith(stageSuffix))
|
|
126
|
+
s = s.slice(0, -stageSuffix.length);
|
|
127
|
+
return s;
|
|
128
|
+
};
|
|
129
|
+
// cron: one EventBridge schedule per cron, named `<app>-<id>-<stage>`.
|
|
130
|
+
const liveScheduleNames = new Set(ir.crons.map((c) => functionName(ir, c.id)));
|
|
131
|
+
for (const name of priorScheduleNames) {
|
|
132
|
+
if (liveScheduleNames.has(name))
|
|
133
|
+
continue;
|
|
134
|
+
resources.push({
|
|
135
|
+
name: labelOf(name),
|
|
136
|
+
type: "cron",
|
|
137
|
+
action: "REMOVED",
|
|
138
|
+
metadata: {},
|
|
139
|
+
externalId: `arn:aws:scheduler:${region}:${account}:schedule/default/${name}`,
|
|
140
|
+
externalUrl: null,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
// queue: one SQS queue per declared queue, named `q.name` (DLQ targets are declared
|
|
144
|
+
// queues too, so a surviving queue always maps back to an ir.queue).
|
|
145
|
+
const liveQueueNames = new Set(ir.queues.map((q) => q.name));
|
|
146
|
+
for (const name of priorQueueNames) {
|
|
147
|
+
if (liveQueueNames.has(name))
|
|
148
|
+
continue;
|
|
149
|
+
resources.push({
|
|
150
|
+
name,
|
|
151
|
+
type: "queue",
|
|
152
|
+
action: "REMOVED",
|
|
153
|
+
metadata: {},
|
|
154
|
+
externalId: `arn:aws:sqs:${region}:${account}:${name}`,
|
|
155
|
+
externalUrl: null,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
// http: the proxy Lambda owns no per-resource sibling, so diff it off the Lambda
|
|
159
|
+
// snapshot — present before, gone now (the app dropped its `http()` marker).
|
|
160
|
+
if (!ir.http && priorNodeLambdas.some((l) => l.logicalId.startsWith("HttpFn"))) {
|
|
161
|
+
resources.push({
|
|
162
|
+
name: "http",
|
|
163
|
+
type: "http",
|
|
164
|
+
action: "REMOVED",
|
|
165
|
+
metadata: {},
|
|
166
|
+
externalId: arn("app"),
|
|
167
|
+
externalUrl: null,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
// A monitoring dashboard that existed before but is now switched off is REMOVED.
|
|
171
|
+
if (!ir.app.monitoring && priorPhysicalIds.has(dashboardName(ir.app.name, ir.app.stage))) {
|
|
172
|
+
resources.push({
|
|
173
|
+
name: "monitoring",
|
|
174
|
+
type: "dashboard",
|
|
175
|
+
action: "REMOVED",
|
|
176
|
+
metadata: {},
|
|
177
|
+
externalId: null,
|
|
178
|
+
externalUrl: null,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return resources;
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { InfraIR } from "@alzulejos/laranja-core";
|
|
2
|
+
/** Filename of the generated, committed resource-id types at the project root. */
|
|
3
|
+
export declare const RESOURCE_TYPES_FILE = "laranja.types.ts";
|
|
4
|
+
/**
|
|
5
|
+
* (Re)write `<project>/laranja.types.ts` from the scanned IR so the config's
|
|
6
|
+
* `resources` keys are type-checked against the project's real resource ids.
|
|
7
|
+
* Best-effort: a write failure must never block a deploy/plan/eject.
|
|
8
|
+
*/
|
|
9
|
+
export declare function writeResourceTypes(projectDir: string, ir: InfraIR): void;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { writeFileSync } from "node:fs";
|
|
3
|
+
import { generateResourceTypes } from "@alzulejos/laranja-scanner";
|
|
4
|
+
/** Filename of the generated, committed resource-id types at the project root. */
|
|
5
|
+
export const RESOURCE_TYPES_FILE = "laranja.types.ts";
|
|
6
|
+
/**
|
|
7
|
+
* (Re)write `<project>/laranja.types.ts` from the scanned IR so the config's
|
|
8
|
+
* `resources` keys are type-checked against the project's real resource ids.
|
|
9
|
+
* Best-effort: a write failure must never block a deploy/plan/eject.
|
|
10
|
+
*/
|
|
11
|
+
export function writeResourceTypes(projectDir, ir) {
|
|
12
|
+
try {
|
|
13
|
+
writeFileSync(path.join(projectDir, RESOURCE_TYPES_FILE), generateResourceTypes(ir));
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// Non-fatal: typing is a convenience; the scan-time hard error is the backstop.
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=resource-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-types.js","sourceRoot":"","sources":["../src/resource-types.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,kFAAkF;AAClF,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAAkB,CAAC;AAEtD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAkB,EAAE,EAAW;IAChE,IAAI,CAAC;QACH,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,EAAE,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAC;IACvF,CAAC;IAAC,MAAM,CAAC;QACP,gFAAgF;IAClF,CAAC;AACH,CAAC"}
|
package/dist/ui.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** Tiny zero-dependency terminal UI helpers (colors + spinner). */
|
|
2
|
+
export declare const dim: (s: string) => string;
|
|
3
|
+
export declare const bold: (s: string) => string;
|
|
4
|
+
export declare const orange: (s: string) => string;
|
|
5
|
+
export declare const green: (s: string) => string;
|
|
6
|
+
export declare const red: (s: string) => string;
|
|
7
|
+
export declare const cyan: (s: string) => string;
|
|
8
|
+
/** Branded header line. */
|
|
9
|
+
export declare function header(text: string): void;
|
|
10
|
+
/** A labelled step line: " <emoji> <label> <detail>". */
|
|
11
|
+
export declare function step(emoji: string, label: string, detail?: string): void;
|
|
12
|
+
export declare function note(text: string): void;
|
|
13
|
+
/** A non-fatal warning line — surfaced but doesn't stop the command. */
|
|
14
|
+
export declare function warn(text: string): void;
|
|
15
|
+
export interface Spinner {
|
|
16
|
+
/** Change the live spinner text. */
|
|
17
|
+
update(text: string): void;
|
|
18
|
+
/** Print a permanent line above the running spinner. */
|
|
19
|
+
log(line: string): void;
|
|
20
|
+
succeed(text?: string): void;
|
|
21
|
+
fail(text?: string): void;
|
|
22
|
+
stop(): void;
|
|
23
|
+
}
|
|
24
|
+
export interface Choice<T> {
|
|
25
|
+
label: string;
|
|
26
|
+
value: T;
|
|
27
|
+
/** Render as a dim, non-selectable section heading (cursor skips over it). */
|
|
28
|
+
header?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Read a single line of secret input (e.g. an API key) without echoing it.
|
|
32
|
+
* Shows `•` per character so the user sees progress. Returns the trimmed value,
|
|
33
|
+
* or `undefined` if cancelled (Esc / Ctrl-C) or there's no TTY to read from.
|
|
34
|
+
* Cross-platform: uses raw stdin, which Node supports on Windows/macOS/Linux.
|
|
35
|
+
*/
|
|
36
|
+
export declare function promptSecret(question: string): Promise<string | undefined>;
|
|
37
|
+
/**
|
|
38
|
+
* Read a single line of visible input (e.g. a project name), echoed as typed.
|
|
39
|
+
* Returns the trimmed value, or `undefined` if cancelled (Esc / Ctrl-C) or
|
|
40
|
+
* there's no TTY. Mirrors `promptSecret` but shows the characters.
|
|
41
|
+
*/
|
|
42
|
+
export declare function promptText(question: string): Promise<string | undefined>;
|
|
43
|
+
/**
|
|
44
|
+
* A zero-dependency arrow-key picker. Returns the chosen value, or undefined if
|
|
45
|
+
* the user cancels (q / Esc / Ctrl-C). Requires a TTY — callers must handle the
|
|
46
|
+
* non-TTY case themselves (there's no interactive input to read).
|
|
47
|
+
*/
|
|
48
|
+
export declare function select<T>(title: string, choices: Choice<T>[]): Promise<T | undefined>;
|
|
49
|
+
/** A braille spinner that degrades to plain lines on non-TTY output. */
|
|
50
|
+
export declare function spinner(initial: string): Spinner;
|