@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.
- package/.eslintrc.json +21 -0
- package/.github/workflows/ci.yml +63 -0
- package/.github/workflows/publish.yml +35 -0
- package/LICENSE +21 -0
- package/README.md +496 -0
- package/dist/alias.d.ts +104 -0
- package/dist/alias.d.ts.map +1 -0
- package/dist/alias.js +215 -0
- package/dist/alias.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +66 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/examples/README.md +67 -0
- package/examples/conditional-alias/Pulumi.dev.yaml +2 -0
- package/examples/conditional-alias/Pulumi.shared.yaml +2 -0
- package/examples/conditional-alias/Pulumi.staging.yaml +2 -0
- package/examples/conditional-alias/Pulumi.yaml +4 -0
- package/examples/conditional-alias/index.ts +30 -0
- package/examples/simple-alias/Pulumi.dev.yaml +4 -0
- package/examples/simple-alias/Pulumi.yaml +4 -0
- package/examples/simple-alias/index.ts +23 -0
- package/package.json +47 -0
- package/src/alias.ts +204 -0
- package/src/index.ts +33 -0
- package/src/types.ts +77 -0
- package/tests/alias.test.ts +463 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +19 -0
package/dist/alias.d.ts
ADDED
|
@@ -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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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|
package/dist/types.d.ts
ADDED
|
@@ -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 @@
|
|
|
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,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,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
|
+
}
|