@egulatee/pulumi-stack-alias 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,104 @@
1
+ import { AliasConfig, AliasExports, ConditionalAliasConfig } from "./types";
2
+ /**
3
+ * Creates a stack alias that re-exports outputs from a target stack
4
+ *
5
+ * This is the core function of the Producer-Controlled Proxy pattern.
6
+ * It creates a StackReference to the target stack and re-exports specified outputs.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * // In alias stack infrastructure/dev
11
+ * import { createStackAlias } from "@egulatee/pulumi-stack-alias";
12
+ *
13
+ * const alias = createStackAlias({
14
+ * targetProject: "infrastructure",
15
+ * targetStack: "shared",
16
+ * outputs: ["vpcId", "clusterName", "endpoint"]
17
+ * });
18
+ *
19
+ * export const vpcId = alias.vpcId;
20
+ * export const clusterName = alias.clusterName;
21
+ * export const endpoint = alias.endpoint;
22
+ * ```
23
+ *
24
+ * @param config - Alias configuration
25
+ * @returns Record of Pulumi Outputs for each specified output name
26
+ */
27
+ export declare function createStackAlias(config: AliasConfig): AliasExports;
28
+ /**
29
+ * Creates a conditional alias based on pattern matching
30
+ *
31
+ * Evaluates pattern rules in order and uses the first matching target.
32
+ * Falls back to defaultTarget if no pattern matches.
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * // In infrastructure/index.ts
37
+ * import { createConditionalAlias } from "@egulatee/pulumi-stack-alias";
38
+ *
39
+ * const alias = createConditionalAlias({
40
+ * targetProject: "infrastructure",
41
+ * patterns: [
42
+ * { pattern: "*\/prod", target: "prod" },
43
+ * { pattern: "*\/staging", target: "shared" },
44
+ * { pattern: "*\/*-ephemeral", target: "shared" }
45
+ * ],
46
+ * defaultTarget: "shared",
47
+ * outputs: ["vpcId", "endpoint"]
48
+ * });
49
+ *
50
+ * export const vpcId = alias.vpcId;
51
+ * export const endpoint = alias.endpoint;
52
+ * ```
53
+ *
54
+ * @param config - Conditional alias configuration
55
+ * @returns Record of Pulumi Outputs for each specified output name
56
+ */
57
+ export declare function createConditionalAlias(config: ConditionalAliasConfig): AliasExports;
58
+ /**
59
+ * Creates a simple alias using a simplified API
60
+ *
61
+ * Convenience wrapper around createStackAlias for common use cases.
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * import { createSimpleAlias } from "@egulatee/pulumi-stack-alias";
66
+ *
67
+ * const alias = createSimpleAlias("infrastructure", "shared", ["vpcId"]);
68
+ * export const vpcId = alias.vpcId;
69
+ * ```
70
+ *
71
+ * @param targetProject - Target project name
72
+ * @param targetStack - Target stack name
73
+ * @param outputs - List of output names to re-export
74
+ * @returns Record of Pulumi Outputs for each specified output name
75
+ */
76
+ export declare function createSimpleAlias(targetProject: string, targetStack: string, outputs: string[]): AliasExports;
77
+ /**
78
+ * Pattern matching with wildcard support
79
+ *
80
+ * Supports wildcards (*) in project and stack positions, as well as
81
+ * prefix and suffix wildcards.
82
+ *
83
+ * Pattern format: "projectPattern/stackPattern"
84
+ *
85
+ * Wildcard rules:
86
+ * - "*" matches any value
87
+ * - "*-suffix" matches any string ending with "-suffix"
88
+ * - "prefix-*" matches any string starting with "prefix-"
89
+ * - "exact" matches exactly "exact"
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * matchesPattern("myproject/*", "myproject", "dev") // true
94
+ * matchesPattern("*\/dev", "anyproject", "dev") // true
95
+ * matchesPattern("*\/*-dev", "app", "service-dev") // true
96
+ * ```
97
+ *
98
+ * @param pattern - Pattern string (e.g., "myproject/*", "*\/dev")
99
+ * @param project - Current project name to match against
100
+ * @param stack - Current stack name to match against
101
+ * @returns True if pattern matches the project/stack combination
102
+ */
103
+ export declare function matchesPattern(pattern: string, project: string, stack: string): boolean;
104
+ //# sourceMappingURL=alias.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alias.d.ts","sourceRoot":"","sources":["../src/alias.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,YAAY,EACZ,sBAAsB,EACvB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,YAAY,CAWlE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB,GAAG,YAAY,CA0BnF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,GAChB,YAAY,CAEd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAavF"}
package/dist/alias.js ADDED
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createStackAlias = createStackAlias;
37
+ exports.createConditionalAlias = createConditionalAlias;
38
+ exports.createSimpleAlias = createSimpleAlias;
39
+ exports.matchesPattern = matchesPattern;
40
+ const pulumi = __importStar(require("@pulumi/pulumi"));
41
+ /**
42
+ * Creates a stack alias that re-exports outputs from a target stack
43
+ *
44
+ * This is the core function of the Producer-Controlled Proxy pattern.
45
+ * It creates a StackReference to the target stack and re-exports specified outputs.
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * // In alias stack infrastructure/dev
50
+ * import { createStackAlias } from "@egulatee/pulumi-stack-alias";
51
+ *
52
+ * const alias = createStackAlias({
53
+ * targetProject: "infrastructure",
54
+ * targetStack: "shared",
55
+ * outputs: ["vpcId", "clusterName", "endpoint"]
56
+ * });
57
+ *
58
+ * export const vpcId = alias.vpcId;
59
+ * export const clusterName = alias.clusterName;
60
+ * export const endpoint = alias.endpoint;
61
+ * ```
62
+ *
63
+ * @param config - Alias configuration
64
+ * @returns Record of Pulumi Outputs for each specified output name
65
+ */
66
+ function createStackAlias(config) {
67
+ const org = config.targetOrg || pulumi.getOrganization();
68
+ const targetStackName = `${org}/${config.targetProject}/${config.targetStack}`;
69
+ const targetStack = new pulumi.StackReference(targetStackName);
70
+ const exports = {};
71
+ for (const outputName of config.outputs) {
72
+ exports[outputName] = targetStack.requireOutput(outputName);
73
+ }
74
+ return exports;
75
+ }
76
+ /**
77
+ * Creates a conditional alias based on pattern matching
78
+ *
79
+ * Evaluates pattern rules in order and uses the first matching target.
80
+ * Falls back to defaultTarget if no pattern matches.
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * // In infrastructure/index.ts
85
+ * import { createConditionalAlias } from "@egulatee/pulumi-stack-alias";
86
+ *
87
+ * const alias = createConditionalAlias({
88
+ * targetProject: "infrastructure",
89
+ * patterns: [
90
+ * { pattern: "*\/prod", target: "prod" },
91
+ * { pattern: "*\/staging", target: "shared" },
92
+ * { pattern: "*\/*-ephemeral", target: "shared" }
93
+ * ],
94
+ * defaultTarget: "shared",
95
+ * outputs: ["vpcId", "endpoint"]
96
+ * });
97
+ *
98
+ * export const vpcId = alias.vpcId;
99
+ * export const endpoint = alias.endpoint;
100
+ * ```
101
+ *
102
+ * @param config - Conditional alias configuration
103
+ * @returns Record of Pulumi Outputs for each specified output name
104
+ */
105
+ function createConditionalAlias(config) {
106
+ const currentProject = pulumi.getProject();
107
+ const currentStack = pulumi.getStack();
108
+ // Find first matching pattern
109
+ let targetStack = config.defaultTarget;
110
+ for (const rule of config.patterns) {
111
+ if (matchesPattern(rule.pattern, currentProject, currentStack)) {
112
+ targetStack = rule.target;
113
+ break;
114
+ }
115
+ }
116
+ if (!targetStack) {
117
+ throw new Error(`No matching pattern found for ${currentProject}/${currentStack} ` +
118
+ `and no defaultTarget specified.`);
119
+ }
120
+ return createStackAlias({
121
+ targetProject: config.targetProject,
122
+ targetStack: targetStack,
123
+ targetOrg: config.targetOrg,
124
+ outputs: config.outputs,
125
+ });
126
+ }
127
+ /**
128
+ * Creates a simple alias using a simplified API
129
+ *
130
+ * Convenience wrapper around createStackAlias for common use cases.
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * import { createSimpleAlias } from "@egulatee/pulumi-stack-alias";
135
+ *
136
+ * const alias = createSimpleAlias("infrastructure", "shared", ["vpcId"]);
137
+ * export const vpcId = alias.vpcId;
138
+ * ```
139
+ *
140
+ * @param targetProject - Target project name
141
+ * @param targetStack - Target stack name
142
+ * @param outputs - List of output names to re-export
143
+ * @returns Record of Pulumi Outputs for each specified output name
144
+ */
145
+ function createSimpleAlias(targetProject, targetStack, outputs) {
146
+ return createStackAlias({ targetProject, targetStack, outputs });
147
+ }
148
+ /**
149
+ * Pattern matching with wildcard support
150
+ *
151
+ * Supports wildcards (*) in project and stack positions, as well as
152
+ * prefix and suffix wildcards.
153
+ *
154
+ * Pattern format: "projectPattern/stackPattern"
155
+ *
156
+ * Wildcard rules:
157
+ * - "*" matches any value
158
+ * - "*-suffix" matches any string ending with "-suffix"
159
+ * - "prefix-*" matches any string starting with "prefix-"
160
+ * - "exact" matches exactly "exact"
161
+ *
162
+ * @example
163
+ * ```typescript
164
+ * matchesPattern("myproject/*", "myproject", "dev") // true
165
+ * matchesPattern("*\/dev", "anyproject", "dev") // true
166
+ * matchesPattern("*\/*-dev", "app", "service-dev") // true
167
+ * ```
168
+ *
169
+ * @param pattern - Pattern string (e.g., "myproject/*", "*\/dev")
170
+ * @param project - Current project name to match against
171
+ * @param stack - Current stack name to match against
172
+ * @returns True if pattern matches the project/stack combination
173
+ */
174
+ function matchesPattern(pattern, project, stack) {
175
+ const [projectPattern, stackPattern] = pattern.split("/");
176
+ if (!projectPattern || !stackPattern) {
177
+ throw new Error(`Invalid pattern format: "${pattern}". Expected "projectPattern/stackPattern".`);
178
+ }
179
+ const projectMatches = matchesWildcard(projectPattern, project);
180
+ const stackMatches = matchesWildcard(stackPattern, stack);
181
+ return projectMatches && stackMatches;
182
+ }
183
+ /**
184
+ * Wildcard matching for a single component
185
+ *
186
+ * Supports:
187
+ * - "*" matches anything
188
+ * - "*-suffix" matches strings ending with suffix
189
+ * - "prefix-*" matches strings starting with prefix
190
+ * - "exact" matches exactly
191
+ *
192
+ * @internal
193
+ * @param pattern - Pattern string (may contain wildcards)
194
+ * @param value - Value to match against pattern
195
+ * @returns True if value matches pattern
196
+ */
197
+ function matchesWildcard(pattern, value) {
198
+ // Exact wildcard - matches anything
199
+ if (pattern === "*") {
200
+ return true;
201
+ }
202
+ // Suffix wildcard: *-dev matches foo-dev, bar-dev
203
+ if (pattern.startsWith("*")) {
204
+ const suffix = pattern.substring(1);
205
+ return value.endsWith(suffix);
206
+ }
207
+ // Prefix wildcard: prod-* matches prod-us, prod-eu
208
+ if (pattern.endsWith("*")) {
209
+ const prefix = pattern.substring(0, pattern.length - 1);
210
+ return value.startsWith(prefix);
211
+ }
212
+ // Exact match
213
+ return pattern === value;
214
+ }
215
+ //# sourceMappingURL=alias.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alias.js","sourceRoot":"","sources":["../src/alias.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @egulatee/pulumi-stack-alias
3
+ *
4
+ * Producer-side stack aliasing for Pulumi using lightweight proxy stacks.
5
+ *
6
+ * Consumers use standard StackReference (no library dependency).
7
+ * Producers use this library to create alias stacks that re-export outputs.
8
+ *
9
+ * ## Producer-Controlled Proxy Pattern
10
+ *
11
+ * Alias stacks re-export outputs from canonical stacks. Consumers use standard
12
+ * Pulumi StackReference without any library dependency. Producers use this
13
+ * library to create proxy stacks that keep outputs in sync.
14
+ *
15
+ * @packageDocumentation
16
+ */
17
+ export { createStackAlias, createConditionalAlias, createSimpleAlias, matchesPattern, } from "./alias";
18
+ export type { AliasConfig, AliasExports, PatternRule, ConditionalAliasConfig, } from "./types";
19
+ export { Output, StackReference } from "@pulumi/pulumi";
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,GACf,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,sBAAsB,GACvB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ /**
3
+ * @egulatee/pulumi-stack-alias
4
+ *
5
+ * Producer-side stack aliasing for Pulumi using lightweight proxy stacks.
6
+ *
7
+ * Consumers use standard StackReference (no library dependency).
8
+ * Producers use this library to create alias stacks that re-export outputs.
9
+ *
10
+ * ## Producer-Controlled Proxy Pattern
11
+ *
12
+ * Alias stacks re-export outputs from canonical stacks. Consumers use standard
13
+ * Pulumi StackReference without any library dependency. Producers use this
14
+ * library to create proxy stacks that keep outputs in sync.
15
+ *
16
+ * @packageDocumentation
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.StackReference = exports.Output = exports.matchesPattern = exports.createSimpleAlias = exports.createConditionalAlias = exports.createStackAlias = void 0;
20
+ var alias_1 = require("./alias");
21
+ Object.defineProperty(exports, "createStackAlias", { enumerable: true, get: function () { return alias_1.createStackAlias; } });
22
+ Object.defineProperty(exports, "createConditionalAlias", { enumerable: true, get: function () { return alias_1.createConditionalAlias; } });
23
+ Object.defineProperty(exports, "createSimpleAlias", { enumerable: true, get: function () { return alias_1.createSimpleAlias; } });
24
+ Object.defineProperty(exports, "matchesPattern", { enumerable: true, get: function () { return alias_1.matchesPattern; } });
25
+ // Re-export Pulumi types for convenience
26
+ var pulumi_1 = require("@pulumi/pulumi");
27
+ Object.defineProperty(exports, "Output", { enumerable: true, get: function () { return pulumi_1.Output; } });
28
+ Object.defineProperty(exports, "StackReference", { enumerable: true, get: function () { return pulumi_1.StackReference; } });
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,iCAKiB;AAJf,yGAAA,gBAAgB,OAAA;AAChB,+GAAA,sBAAsB,OAAA;AACtB,0GAAA,iBAAiB,OAAA;AACjB,uGAAA,cAAc,OAAA;AAUhB,yCAAyC;AACzC,yCAAwD;AAA/C,gGAAA,MAAM,OAAA;AAAE,wGAAA,cAAc,OAAA"}
@@ -0,0 +1,66 @@
1
+ import * as pulumi from "@pulumi/pulumi";
2
+ /**
3
+ * Configuration for creating a stack alias
4
+ */
5
+ export interface AliasConfig {
6
+ /**
7
+ * Target organization name (defaults to current organization)
8
+ */
9
+ targetOrg?: string;
10
+ /**
11
+ * Target project name
12
+ */
13
+ targetProject: string;
14
+ /**
15
+ * Target stack name
16
+ */
17
+ targetStack: string;
18
+ /**
19
+ * List of output names to re-export from the target stack
20
+ */
21
+ outputs: string[];
22
+ }
23
+ /**
24
+ * Record of aliased outputs (all are Pulumi Outputs)
25
+ */
26
+ export type AliasExports = Record<string, pulumi.Output<any>>;
27
+ /**
28
+ * A pattern rule for conditional aliasing
29
+ */
30
+ export interface PatternRule {
31
+ /**
32
+ * Pattern in format "project/stack" with wildcard support
33
+ * Examples: "* /prod", "myproject/ *", "* / *-ephemeral" (without spaces)
34
+ */
35
+ pattern: string;
36
+ /**
37
+ * Target stack name to use when this pattern matches
38
+ */
39
+ target: string;
40
+ }
41
+ /**
42
+ * Configuration for creating a conditional alias based on pattern matching
43
+ */
44
+ export interface ConditionalAliasConfig {
45
+ /**
46
+ * Target project name
47
+ */
48
+ targetProject: string;
49
+ /**
50
+ * Target organization name (defaults to current organization)
51
+ */
52
+ targetOrg?: string;
53
+ /**
54
+ * List of pattern rules (evaluated in order, first match wins)
55
+ */
56
+ patterns: PatternRule[];
57
+ /**
58
+ * Default target stack if no pattern matches (optional)
59
+ */
60
+ defaultTarget?: string;
61
+ /**
62
+ * List of output names to re-export from the target stack
63
+ */
64
+ outputs: string[];
65
+ }
66
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,EAAE,WAAW,EAAE,CAAC;IAExB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ # Examples
2
+
3
+ This directory contains example implementations of stack aliasing patterns.
4
+
5
+ ## Simple Alias
6
+
7
+ The `simple-alias` example shows the most basic usage:
8
+ - Create an alias stack that redirects to a canonical stack
9
+ - Re-export specific outputs
10
+
11
+ **Usage:**
12
+ ```typescript
13
+ import { createStackAlias } from "@egulatee/pulumi-stack-alias";
14
+
15
+ const alias = createStackAlias({
16
+ targetProject: "infrastructure",
17
+ targetStack: "shared",
18
+ outputs: ["vpcId", "endpoint"],
19
+ });
20
+
21
+ export const vpcId = alias.vpcId;
22
+ ```
23
+
24
+ ## Conditional Alias
25
+
26
+ The `conditional-alias` example demonstrates:
27
+ - Using stack configuration to determine behavior
28
+ - Same code handles both alias and canonical stacks
29
+ - Config-driven stack behavior
30
+
31
+ **Usage:**
32
+ ```typescript
33
+ const config = new pulumi.Config();
34
+ const aliasTarget = config.get("aliasTarget");
35
+
36
+ if (aliasTarget) {
37
+ // Alias stack - redirect
38
+ const alias = createStackAlias({ ... });
39
+ } else {
40
+ // Canonical stack - create resources
41
+ export const vpcId = /* actual resources */;
42
+ }
43
+ ```
44
+
45
+ ## Running Examples
46
+
47
+ 1. Install dependencies:
48
+ ```bash
49
+ npm install
50
+ ```
51
+
52
+ 2. Navigate to an example:
53
+ ```bash
54
+ cd examples/simple-alias
55
+ ```
56
+
57
+ 3. Initialize stacks:
58
+ ```bash
59
+ pulumi stack init shared
60
+ pulumi stack init dev
61
+ ```
62
+
63
+ 4. Deploy:
64
+ ```bash
65
+ pulumi up --stack shared # Deploy canonical stack first
66
+ pulumi up --stack dev # Deploy alias stack
67
+ ```
@@ -0,0 +1,2 @@
1
+ config:
2
+ infrastructure:aliasTarget: shared # dev aliases to shared
@@ -0,0 +1,2 @@
1
+ config:
2
+ # No aliasTarget = this is the canonical stack with actual resources
@@ -0,0 +1,2 @@
1
+ config:
2
+ infrastructure:aliasTarget: shared # staging aliases to shared
@@ -0,0 +1,4 @@
1
+ name: infrastructure
2
+ description: Conditional alias example with environment detection
3
+ runtime:
4
+ name: nodejs
@@ -0,0 +1,30 @@
1
+ import { createConditionalAlias } from "@egulatee/pulumi-stack-alias";
2
+
3
+ /**
4
+ * Conditional alias example using pattern matching
5
+ *
6
+ * This example demonstrates how to use createConditionalAlias to automatically
7
+ * route different stacks to appropriate canonical stacks based on patterns.
8
+ *
9
+ * Pattern matching rules:
10
+ * - prod stacks -> infrastructure/prod
11
+ * - staging stacks -> infrastructure/shared
12
+ * - dev stacks -> infrastructure/shared
13
+ * - *-ephemeral stacks -> infrastructure/shared
14
+ */
15
+
16
+ const alias = createConditionalAlias({
17
+ targetProject: "infrastructure",
18
+ patterns: [
19
+ { pattern: "*/prod", target: "prod" },
20
+ { pattern: "*/staging", target: "shared" },
21
+ { pattern: "*/dev", target: "shared" },
22
+ { pattern: "*/*-ephemeral", target: "shared" },
23
+ ],
24
+ defaultTarget: "shared",
25
+ outputs: ["vpcId", "endpoint", "clusterName"],
26
+ });
27
+
28
+ export const vpcId = alias.vpcId;
29
+ export const endpoint = alias.endpoint;
30
+ export const clusterName = alias.clusterName;
@@ -0,0 +1,4 @@
1
+ config:
2
+ # This configures the dev stack to be an alias
3
+ infrastructure:aliasTarget: shared
4
+ infrastructure:aliasProject: infrastructure
@@ -0,0 +1,4 @@
1
+ name: infrastructure
2
+ description: Example infrastructure project with stack aliasing
3
+ runtime:
4
+ name: nodejs
@@ -0,0 +1,23 @@
1
+ import { createStackAlias } from "@egulatee/pulumi-stack-alias";
2
+
3
+ /**
4
+ * Simple alias example: infrastructure/dev → infrastructure/shared
5
+ *
6
+ * This stack acts as an alias that redirects to the canonical 'shared' stack.
7
+ * All outputs from the shared stack are re-exported here.
8
+ */
9
+
10
+ const alias = createStackAlias({
11
+ targetProject: "infrastructure",
12
+ targetStack: "shared",
13
+ outputs: [
14
+ "vpcId",
15
+ "endpoint",
16
+ "clusterName",
17
+ ],
18
+ });
19
+
20
+ // Re-export all outputs
21
+ export const vpcId = alias.vpcId;
22
+ export const endpoint = alias.endpoint;
23
+ export const clusterName = alias.clusterName;
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@egulatee/pulumi-stack-alias",
3
+ "version": "0.2.0",
4
+ "description": "Producer-side stack aliasing for Pulumi using lightweight proxy stacks",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "test": "vitest",
10
+ "test:coverage": "vitest --coverage",
11
+ "lint": "eslint src --ext .ts",
12
+ "prepublishOnly": "npm run build"
13
+ },
14
+ "keywords": [
15
+ "pulumi",
16
+ "infrastructure-as-code",
17
+ "stack-alias",
18
+ "stack-reference",
19
+ "devops",
20
+ "multi-environment"
21
+ ],
22
+ "author": "Eric Gulatee",
23
+ "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/egulatee/pulumi-stack-alias.git"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/egulatee/pulumi-stack-alias/issues"
30
+ },
31
+ "homepage": "https://github.com/egulatee/pulumi-stack-alias#readme",
32
+ "peerDependencies": {
33
+ "@pulumi/pulumi": "^3.0.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^20.0.0",
37
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
38
+ "@typescript-eslint/parser": "^6.0.0",
39
+ "@vitest/coverage-v8": "^1.0.0",
40
+ "eslint": "^8.0.0",
41
+ "typescript": "^5.0.0",
42
+ "vitest": "^1.0.0"
43
+ },
44
+ "engines": {
45
+ "node": ">=18"
46
+ }
47
+ }