@znemz/cfn-include 2.1.23 → 2.1.24
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/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +196 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +697 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/cache.d.ts +12 -0
- package/dist/lib/cache.d.ts.map +1 -0
- package/{lib → dist/lib}/cache.js +8 -13
- package/dist/lib/cache.js.map +1 -0
- package/dist/lib/cfnclient.d.ts +17 -0
- package/dist/lib/cfnclient.d.ts.map +1 -0
- package/dist/lib/cfnclient.js +69 -0
- package/dist/lib/cfnclient.js.map +1 -0
- package/dist/lib/include/query.d.ts +4 -0
- package/dist/lib/include/query.d.ts.map +1 -0
- package/dist/lib/include/query.js +14 -0
- package/dist/lib/include/query.js.map +1 -0
- package/dist/lib/internals.d.ts +10 -0
- package/dist/lib/internals.d.ts.map +1 -0
- package/dist/lib/internals.js +145 -0
- package/dist/lib/internals.js.map +1 -0
- package/dist/lib/parselocation.d.ts +3 -0
- package/dist/lib/parselocation.d.ts.map +1 -0
- package/dist/lib/parselocation.js +19 -0
- package/dist/lib/parselocation.js.map +1 -0
- package/dist/lib/promise-utils.d.ts +19 -0
- package/dist/lib/promise-utils.d.ts.map +1 -0
- package/dist/lib/promise-utils.js +36 -0
- package/dist/lib/promise-utils.js.map +1 -0
- package/dist/lib/promise.d.ts +6 -0
- package/dist/lib/promise.d.ts.map +1 -0
- package/dist/lib/promise.js +16 -0
- package/dist/lib/promise.js.map +1 -0
- package/dist/lib/replaceEnv.d.ts +8 -0
- package/dist/lib/replaceEnv.d.ts.map +1 -0
- package/dist/lib/replaceEnv.js +48 -0
- package/dist/lib/replaceEnv.js.map +1 -0
- package/dist/lib/request.d.ts +2 -0
- package/dist/lib/request.d.ts.map +1 -0
- package/dist/lib/request.js +19 -0
- package/dist/lib/request.js.map +1 -0
- package/dist/lib/schema.d.ts +9 -0
- package/dist/lib/schema.d.ts.map +1 -0
- package/dist/lib/schema.js +115 -0
- package/dist/lib/schema.js.map +1 -0
- package/dist/lib/scope.d.ts +23 -0
- package/dist/lib/scope.d.ts.map +1 -0
- package/dist/lib/scope.js +36 -0
- package/dist/lib/scope.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +13 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/yaml.d.ts +8 -0
- package/dist/lib/yaml.d.ts.map +1 -0
- package/dist/lib/yaml.js +74 -0
- package/dist/lib/yaml.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/options.d.ts +88 -0
- package/dist/types/options.d.ts.map +1 -0
- package/dist/types/options.js +5 -0
- package/dist/types/options.js.map +1 -0
- package/dist/types/template.d.ts +290 -0
- package/dist/types/template.d.ts.map +1 -0
- package/dist/types/template.js +5 -0
- package/dist/types/template.js.map +1 -0
- package/package.json +23 -10
- package/bin/cli.js +0 -204
- package/index.js +0 -899
- package/lib/cfnclient.js +0 -84
- package/lib/include/api.js +0 -13
- package/lib/include/query.js +0 -16
- package/lib/internals.js +0 -171
- package/lib/parselocation.js +0 -15
- package/lib/promise-utils.js +0 -46
- package/lib/promise.js +0 -18
- package/lib/replaceEnv.js +0 -66
- package/lib/request.js +0 -22
- package/lib/schema.js +0 -117
- package/lib/scope.js +0 -52
- package/lib/utils.js +0 -16
- package/lib/yaml.js +0 -76
package/lib/cfnclient.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { CloudFormationClient, ValidateTemplateCommand } from '@aws-sdk/client-cloudformation';
|
|
2
|
-
import { S3Client, PutObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3';
|
|
3
|
-
import { addProxyToClient } from 'aws-sdk-v3-proxy';
|
|
4
|
-
|
|
5
|
-
import path from 'node:path';
|
|
6
|
-
import crypto from 'node:crypto';
|
|
7
|
-
|
|
8
|
-
const S3 = (opts = {}) => addProxyToClient(new S3Client(opts));
|
|
9
|
-
const CloudFormation = (opts = {}) => addProxyToClient(new CloudFormationClient(opts));
|
|
10
|
-
|
|
11
|
-
class Client {
|
|
12
|
-
constructor({ region = 'us-east-1', bucket, prefix }) {
|
|
13
|
-
this.client = CloudFormation({
|
|
14
|
-
region,
|
|
15
|
-
});
|
|
16
|
-
this.s3 = S3();
|
|
17
|
-
this.bucket = bucket;
|
|
18
|
-
this.prefix = prefix;
|
|
19
|
-
this.region = region;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
digest(input) {
|
|
23
|
-
const hash = crypto.createHash('md5');
|
|
24
|
-
hash.update(input);
|
|
25
|
-
return hash.digest('hex');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async uploadTemplate(tpl, callback) {
|
|
29
|
-
const key = path.posix.join(this.prefix, `${this.digest(tpl)}.json`);
|
|
30
|
-
await this.s3.Send(
|
|
31
|
-
new PutObjectCommand({
|
|
32
|
-
Body: tpl,
|
|
33
|
-
Bucket: this.bucket,
|
|
34
|
-
Key: key,
|
|
35
|
-
}),
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
let res, err;
|
|
39
|
-
try {
|
|
40
|
-
res = await callback(key);
|
|
41
|
-
} catch (e) {
|
|
42
|
-
err = e;
|
|
43
|
-
}
|
|
44
|
-
await this.s3
|
|
45
|
-
.send(
|
|
46
|
-
new DeleteObjectCommand({
|
|
47
|
-
Bucket: this.bucket,
|
|
48
|
-
Key: key,
|
|
49
|
-
}),
|
|
50
|
-
)
|
|
51
|
-
.catch(() => {});
|
|
52
|
-
if (err) throw err;
|
|
53
|
-
return res;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async validateTemplate(tpl = '') {
|
|
57
|
-
const needsUpload = tpl.length > 51200;
|
|
58
|
-
if (needsUpload && !this.bucket) {
|
|
59
|
-
throw 'Cannot validate template larger than 50k without a bucket. Please provide a bucket name.';
|
|
60
|
-
}
|
|
61
|
-
if (needsUpload && tpl.length > 460800) {
|
|
62
|
-
throw 'Template exceeds maximum size of 450k';
|
|
63
|
-
}
|
|
64
|
-
if (needsUpload) {
|
|
65
|
-
return this.uploadTemplate(tpl, (key) =>
|
|
66
|
-
this.client
|
|
67
|
-
.send(
|
|
68
|
-
new ValidateTemplateCommand({
|
|
69
|
-
TemplateURL: `https://s3.${this.region}.amazonaws.com/${this.bucket}/${key}`,
|
|
70
|
-
}),
|
|
71
|
-
)
|
|
72
|
-
.promise(),
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return this.client.send(
|
|
77
|
-
new ValidateTemplateCommand({
|
|
78
|
-
TemplateBody: tpl,
|
|
79
|
-
}),
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export default Client;
|
package/lib/include/api.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// NOTE: This module uses the legacy AWS SDK v2 via aws-sdk-proxy
|
|
2
|
-
// It may be unused and could be removed or rewritten for SDK v3
|
|
3
|
-
import AWS from 'aws-sdk-proxy';
|
|
4
|
-
import jmespath from 'jmespath';
|
|
5
|
-
|
|
6
|
-
export default function (args) {
|
|
7
|
-
const service = new AWS[args.service](args.region ? { region: args.region } : null);
|
|
8
|
-
return service[args.action](args.parameters ? args.parameters : {})
|
|
9
|
-
.promise()
|
|
10
|
-
.then(function (res) {
|
|
11
|
-
return args.query ? jmespath.search(res, args.query) : res;
|
|
12
|
-
});
|
|
13
|
-
}
|
package/lib/include/query.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
|
-
import jmespath from 'jmespath';
|
|
3
|
-
|
|
4
|
-
// this exists cause in most cases lodash get is plenty sufficient
|
|
5
|
-
// also this bug / error in jmespath is ridiculous https://github.com/jmespath/jmespath.js/issues/35
|
|
6
|
-
const queryParsers = {
|
|
7
|
-
lodash: (obj, path) => _.get(obj, path) || '',
|
|
8
|
-
jmespath: jmespath.search,
|
|
9
|
-
default: jmespath.search,
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
queryParsers['default'] = queryParsers[process.env.CFN_INCLUDE_QUERY_PARSER] || queryParsers.default;
|
|
13
|
-
|
|
14
|
-
export function getParser(type) {
|
|
15
|
-
return queryParsers[type] || queryParsers.default;
|
|
16
|
-
}
|
package/lib/internals.js
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
function getAwsPseudoParameters() {
|
|
2
|
-
return {
|
|
3
|
-
'AWS::AccountId': process.env.AWS_ACCOUNT_ID || process.env.AWS_ACCOUNT_NUM || '${AWS::AccountId}',
|
|
4
|
-
'AWS::Partition': process.env.AWS_PARTITION || 'aws',
|
|
5
|
-
'AWS::Region': process.env.AWS_REGION || '${AWS::Region}',
|
|
6
|
-
'AWS::StackId': process.env.AWS_STACK_ID || '${AWS::StackId}',
|
|
7
|
-
'AWS::StackName': process.env.AWS_STACK_NAME || '${AWS::StackName}',
|
|
8
|
-
'AWS::URLSuffix': process.env.AWS_URL_SUFFIX || 'amazonaws.com',
|
|
9
|
-
'AWS::NotificationARNs': process.env.AWS_NOTIFICATION_ARNS || '${AWS::NotificationARNs}',
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Build an ARN for a CloudFormation resource based on its Type and Properties
|
|
15
|
-
* Supports both ARN construction and property name resolution
|
|
16
|
-
* @param {string} resourceType - The CloudFormation resource type (e.g., 'AWS::IAM::ManagedPolicy')
|
|
17
|
-
* @param {object} properties - The resource properties
|
|
18
|
-
* @param {object} pseudoParams - AWS pseudo-parameters including AccountId, Region
|
|
19
|
-
* @param {object} options - Optional configuration
|
|
20
|
-
* @param {string} options.returnType - 'arn' (default) or 'name' to return the resource name/identifier
|
|
21
|
-
* @returns {string|null} - The ARN, name, or null if not applicable
|
|
22
|
-
*/
|
|
23
|
-
function buildResourceArn(resourceType, properties = {}, pseudoParams = {}, options = {}) {
|
|
24
|
-
const accountId = pseudoParams['AWS::AccountId'] || '${AWS::AccountId}';
|
|
25
|
-
const region = pseudoParams['AWS::Region'] || '${AWS::Region}';
|
|
26
|
-
const partition = pseudoParams['AWS::Partition'] || 'aws';
|
|
27
|
-
const returnType = options.returnType || 'arn';
|
|
28
|
-
|
|
29
|
-
// Handle AWS::IAM::ManagedPolicy
|
|
30
|
-
if (resourceType === 'AWS::IAM::ManagedPolicy') {
|
|
31
|
-
const { ManagedPolicyName, Path } = properties;
|
|
32
|
-
if (ManagedPolicyName) {
|
|
33
|
-
if (returnType === 'name') {
|
|
34
|
-
return ManagedPolicyName;
|
|
35
|
-
}
|
|
36
|
-
const path = Path || '/';
|
|
37
|
-
return `arn:${partition}:iam::${accountId}:policy${path}${ManagedPolicyName}`;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Handle AWS::IAM::Role
|
|
42
|
-
if (resourceType === 'AWS::IAM::Role') {
|
|
43
|
-
const { RoleName, Path } = properties;
|
|
44
|
-
if (RoleName) {
|
|
45
|
-
if (returnType === 'name') {
|
|
46
|
-
return RoleName;
|
|
47
|
-
}
|
|
48
|
-
const path = Path || '/';
|
|
49
|
-
return `arn:${partition}:iam::${accountId}:role${path}${RoleName}`;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Handle AWS::S3::Bucket
|
|
54
|
-
if (resourceType === 'AWS::S3::Bucket') {
|
|
55
|
-
const { BucketName } = properties;
|
|
56
|
-
if (BucketName) {
|
|
57
|
-
if (returnType === 'name') {
|
|
58
|
-
return BucketName;
|
|
59
|
-
}
|
|
60
|
-
return `arn:${partition}:s3:::${BucketName}`;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Handle AWS::Lambda::Function
|
|
65
|
-
if (resourceType === 'AWS::Lambda::Function') {
|
|
66
|
-
const { FunctionName } = properties;
|
|
67
|
-
if (FunctionName) {
|
|
68
|
-
if (returnType === 'name') {
|
|
69
|
-
return FunctionName;
|
|
70
|
-
}
|
|
71
|
-
return `arn:${partition}:lambda:${region}:${accountId}:function:${FunctionName}`;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Handle AWS::SQS::Queue
|
|
76
|
-
if (resourceType === 'AWS::SQS::Queue') {
|
|
77
|
-
const { QueueName } = properties;
|
|
78
|
-
if (QueueName) {
|
|
79
|
-
if (returnType === 'name') {
|
|
80
|
-
return QueueName;
|
|
81
|
-
}
|
|
82
|
-
return `arn:${partition}:sqs:${region}:${accountId}:${QueueName}`;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Handle AWS::SNS::Topic
|
|
87
|
-
if (resourceType === 'AWS::SNS::Topic') {
|
|
88
|
-
const { TopicName } = properties;
|
|
89
|
-
if (TopicName) {
|
|
90
|
-
if (returnType === 'name') {
|
|
91
|
-
return TopicName;
|
|
92
|
-
}
|
|
93
|
-
return `arn:${partition}:sns:${region}:${accountId}:${TopicName}`;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Handle AWS::DynamoDB::Table
|
|
98
|
-
if (resourceType === 'AWS::DynamoDB::Table') {
|
|
99
|
-
const { TableName } = properties;
|
|
100
|
-
if (TableName) {
|
|
101
|
-
if (returnType === 'name') {
|
|
102
|
-
return TableName;
|
|
103
|
-
}
|
|
104
|
-
return `arn:${partition}:dynamodb:${region}:${accountId}:table/${TableName}`;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Handle AWS::RDS::DBInstance
|
|
109
|
-
if (resourceType === 'AWS::RDS::DBInstance') {
|
|
110
|
-
const { DBInstanceIdentifier } = properties;
|
|
111
|
-
if (DBInstanceIdentifier) {
|
|
112
|
-
if (returnType === 'name') {
|
|
113
|
-
return DBInstanceIdentifier;
|
|
114
|
-
}
|
|
115
|
-
return `arn:${partition}:rds:${region}:${accountId}:db:${DBInstanceIdentifier}`;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Handle AWS::EC2::SecurityGroup
|
|
120
|
-
if (resourceType === 'AWS::EC2::SecurityGroup') {
|
|
121
|
-
const { GroupName } = properties;
|
|
122
|
-
if (GroupName) {
|
|
123
|
-
if (returnType === 'name') {
|
|
124
|
-
return GroupName;
|
|
125
|
-
}
|
|
126
|
-
// Security groups need to be referenced by ID in most cases, not ARN
|
|
127
|
-
// This returns the name for reference purposes
|
|
128
|
-
return GroupName;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Handle AWS::IAM::InstanceProfile
|
|
133
|
-
if (resourceType === 'AWS::IAM::InstanceProfile') {
|
|
134
|
-
const { InstanceProfileName, Path } = properties;
|
|
135
|
-
if (InstanceProfileName) {
|
|
136
|
-
if (returnType === 'name') {
|
|
137
|
-
return InstanceProfileName;
|
|
138
|
-
}
|
|
139
|
-
const path = Path || '/';
|
|
140
|
-
return `arn:${partition}:iam::${accountId}:instance-profile${path}${InstanceProfileName}`;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Handle AWS::KMS::Key
|
|
145
|
-
if (resourceType === 'AWS::KMS::Key') {
|
|
146
|
-
// KMS keys are referenced by KeyId or KeyArn in properties
|
|
147
|
-
const { KeyId } = properties;
|
|
148
|
-
if (KeyId) {
|
|
149
|
-
if (returnType === 'name') {
|
|
150
|
-
return KeyId;
|
|
151
|
-
}
|
|
152
|
-
return `arn:${partition}:kms:${region}:${accountId}:key/${KeyId}`;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Handle AWS::SecretsManager::Secret
|
|
157
|
-
if (resourceType === 'AWS::SecretsManager::Secret') {
|
|
158
|
-
const { Name } = properties;
|
|
159
|
-
if (Name) {
|
|
160
|
-
if (returnType === 'name') {
|
|
161
|
-
return Name;
|
|
162
|
-
}
|
|
163
|
-
return `arn:${partition}:secretsmanager:${region}:${accountId}:secret:${Name}`;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Add more resource types as needed
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
export { getAwsPseudoParameters, buildResourceArn };
|
package/lib/parselocation.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export default function parseLocation(location) {
|
|
2
|
-
if (!location) return {};
|
|
3
|
-
if (!location.match) {
|
|
4
|
-
console.error('location.match is not a function', location);
|
|
5
|
-
}
|
|
6
|
-
const parsed = location.match(/^(((\w+):)?\/\/)?(.*?)([\\\/](.*))?$/);
|
|
7
|
-
|
|
8
|
-
return {
|
|
9
|
-
protocol: parsed[3],
|
|
10
|
-
host: parsed[4],
|
|
11
|
-
path: parsed[5],
|
|
12
|
-
relative: parsed[1] === undefined,
|
|
13
|
-
raw: location,
|
|
14
|
-
};
|
|
15
|
-
}
|
package/lib/promise-utils.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Native Promise utilities to replace bluebird.
|
|
3
|
-
* These are drop-in replacements for the bluebird methods we use.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Promise.props replacement - resolves an object of promises.
|
|
8
|
-
* @param {Object} obj - Object with promise values
|
|
9
|
-
* @returns {Promise<Object>} Object with resolved values
|
|
10
|
-
*/
|
|
11
|
-
async function promiseProps(obj) {
|
|
12
|
-
const keys = Object.keys(obj);
|
|
13
|
-
const values = await Promise.all(keys.map((key) => obj[key]));
|
|
14
|
-
const result = {};
|
|
15
|
-
for (let i = 0; i < keys.length; i++) {
|
|
16
|
-
result[keys[i]] = values[i];
|
|
17
|
-
}
|
|
18
|
-
return result;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Promise.try replacement - wraps a function to catch sync errors.
|
|
23
|
-
* @param {Function} fn - Function to execute
|
|
24
|
-
* @returns {Promise} Promise that resolves to fn result or rejects on error
|
|
25
|
-
*/
|
|
26
|
-
function promiseTry(fn) {
|
|
27
|
-
return new Promise((resolve, reject) => {
|
|
28
|
-
try {
|
|
29
|
-
resolve(fn());
|
|
30
|
-
} catch (err) {
|
|
31
|
-
reject(err);
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Promise.map replacement - maps over array with concurrency.
|
|
38
|
-
* @param {Array} arr - Array to map over
|
|
39
|
-
* @param {Function} fn - Async function to apply
|
|
40
|
-
* @returns {Promise<Array>} Array of resolved values
|
|
41
|
-
*/
|
|
42
|
-
function promiseMap(arr, fn) {
|
|
43
|
-
return Promise.all(arr.map(fn));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export { promiseProps, promiseTry, promiseMap };
|
package/lib/promise.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { promiseTry, promiseMap } from './promise-utils.js';
|
|
2
|
-
|
|
3
|
-
/*
|
|
4
|
-
Maps over objects or iterables just like lodash.
|
|
5
|
-
*/
|
|
6
|
-
const mapWhatever = (promises, cb) =>
|
|
7
|
-
promiseTry(() =>
|
|
8
|
-
Promise.resolve(promises).then((arrayOrObject) => {
|
|
9
|
-
if (Array.isArray(arrayOrObject)) {
|
|
10
|
-
return promiseMap(arrayOrObject, cb);
|
|
11
|
-
}
|
|
12
|
-
const size = Object.values(arrayOrObject).length;
|
|
13
|
-
const entries = Object.entries(arrayOrObject);
|
|
14
|
-
return Promise.all(entries.map(([key, value]) => cb(value, key, size)));
|
|
15
|
-
}),
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
export { mapWhatever, mapWhatever as mapX };
|
package/lib/replaceEnv.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
const passThrough = (template) => template;
|
|
2
|
-
const replaceProcessEnv = (template) => replaceEnv(template, process.env, false);
|
|
3
|
-
|
|
4
|
-
// Cache for compiled regex patterns to avoid re-creating them
|
|
5
|
-
const regexCache = new Map();
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Escape special regex characters in a string
|
|
9
|
-
* @param {string} str - String to escape
|
|
10
|
-
* @returns {string} Escaped string safe for regex
|
|
11
|
-
*/
|
|
12
|
-
function escapeRegExp(str) {
|
|
13
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Get a cached regex for variable substitution
|
|
18
|
-
* @param {string} key - Variable name
|
|
19
|
-
* @param {boolean} withBraces - Whether to match ${key} format (true) or $key format (false)
|
|
20
|
-
* @returns {RegExp} Cached regex pattern
|
|
21
|
-
*/
|
|
22
|
-
function getVarRegex(key, withBraces) {
|
|
23
|
-
const cacheKey = `${key}:${withBraces}`;
|
|
24
|
-
if (!regexCache.has(cacheKey)) {
|
|
25
|
-
const escaped = escapeRegExp(key);
|
|
26
|
-
const pattern = withBraces ? `\\$\\{${escaped}\\}` : `\\$${escaped}`;
|
|
27
|
-
regexCache.set(cacheKey, new RegExp(pattern, 'g'));
|
|
28
|
-
}
|
|
29
|
-
return regexCache.get(cacheKey);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
let processTemplate;
|
|
33
|
-
|
|
34
|
-
function replaceEnv(template, inject = {}, doEnv) {
|
|
35
|
-
processTemplate = doEnv ? replaceProcessEnv : passThrough;
|
|
36
|
-
|
|
37
|
-
if (!template || typeof template !== 'string') {
|
|
38
|
-
return processTemplate(template);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const keys = Object.keys(inject);
|
|
42
|
-
|
|
43
|
-
for (let i = 0; i < keys.length; i++) {
|
|
44
|
-
const key = keys[i];
|
|
45
|
-
const val = inject[key];
|
|
46
|
-
|
|
47
|
-
// Use cached regex patterns instead of creating new ones each time
|
|
48
|
-
const bareRegex = getVarRegex(key, false);
|
|
49
|
-
const bracedRegex = getVarRegex(key, true);
|
|
50
|
-
|
|
51
|
-
// Reset lastIndex for global regex reuse
|
|
52
|
-
bareRegex.lastIndex = 0;
|
|
53
|
-
bracedRegex.lastIndex = 0;
|
|
54
|
-
|
|
55
|
-
template = template.replace(bareRegex, val).replace(bracedRegex, val);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return processTemplate(template);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const IsRegExVar = (str) => /\$\w+/.test(str) || /\$\{\w+\}/.test(str);
|
|
62
|
-
|
|
63
|
-
replaceEnv.IsRegExVar = IsRegExVar; // hack to be backward compat
|
|
64
|
-
|
|
65
|
-
export default replaceEnv;
|
|
66
|
-
export { IsRegExVar };
|
package/lib/request.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { parse as urlParse } from 'node:url';
|
|
2
|
-
import https from 'node:https';
|
|
3
|
-
import http from 'node:http';
|
|
4
|
-
|
|
5
|
-
export default function request(location) {
|
|
6
|
-
const parsed = urlParse(location);
|
|
7
|
-
const proto = parsed.protocol === 'https:' ? https : http;
|
|
8
|
-
|
|
9
|
-
return new Promise((resolve, reject) =>
|
|
10
|
-
proto
|
|
11
|
-
.get(location, (res) => {
|
|
12
|
-
if (res.statusCode > 299) {
|
|
13
|
-
return reject(new Error('HTTP request failed with status code ' + res.statusCode));
|
|
14
|
-
}
|
|
15
|
-
const rawData = [];
|
|
16
|
-
res.setEncoding('utf8');
|
|
17
|
-
res.on('data', (chunk) => rawData.push(chunk));
|
|
18
|
-
res.on('end', () => resolve(rawData.join('')));
|
|
19
|
-
})
|
|
20
|
-
.on('error', reject),
|
|
21
|
-
);
|
|
22
|
-
}
|
package/lib/schema.js
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import yaml from 'js-yaml';
|
|
2
|
-
import _ from 'lodash';
|
|
3
|
-
|
|
4
|
-
const tags = [
|
|
5
|
-
{ short: 'Include', full: 'Fn::Include', type: 'scalar' },
|
|
6
|
-
{ short: 'Include', full: 'Fn::Include', type: 'mapping' },
|
|
7
|
-
{ short: 'Stringify', full: 'Fn::Stringify', type: 'sequence' },
|
|
8
|
-
{ short: 'Stringify', full: 'Fn::Stringify', type: 'mapping' },
|
|
9
|
-
{ short: 'Map', full: 'Fn::Map', type: 'sequence' },
|
|
10
|
-
{ short: 'Length', full: 'Fn::Length', type: 'sequence' },
|
|
11
|
-
{ short: 'Flatten', full: 'Fn::Flatten', type: 'sequence' },
|
|
12
|
-
{ short: 'FlattenDeep', full: 'Fn::FlattenDeep', type: 'sequence' },
|
|
13
|
-
{ short: 'Uniq', full: 'Fn::Uniq', type: 'sequence' },
|
|
14
|
-
{ short: 'GetEnv', full: 'Fn::GetEnv', type: 'sequence' },
|
|
15
|
-
{ short: 'GetEnv', full: 'Fn::GetEnv', type: 'scalar' },
|
|
16
|
-
{ short: 'Merge', full: 'Fn::Merge', type: 'sequence' },
|
|
17
|
-
{ short: 'Outputs', full: 'Fn::Outputs', type: 'mapping' },
|
|
18
|
-
{ short: 'LowerCamelCase', full: 'Fn::LowerCamelCase', type: 'scalar' },
|
|
19
|
-
{ short: 'UpperCamelCase', full: 'Fn::UpperCamelCase', type: 'scalar' },
|
|
20
|
-
{ short: 'Sequence', full: 'Fn::Sequence', type: 'sequence' },
|
|
21
|
-
{ short: 'DeepMerge', full: 'Fn::DeepMerge', type: 'sequence' },
|
|
22
|
-
{ short: 'Compact', full: 'Fn::Compact', type: 'sequence' },
|
|
23
|
-
{ short: 'Concat', full: 'Fn::Concat', type: 'sequence' },
|
|
24
|
-
{ short: 'Sort', full: 'Fn::Sort', type: 'sequence' },
|
|
25
|
-
{ short: 'SortedUniq', full: 'Fn::SortedUniq', type: 'sequence' },
|
|
26
|
-
{ short: 'SortBy', full: 'Fn::SortBy', type: 'mapping' },
|
|
27
|
-
{ short: 'SortObject', full: 'Fn::SortObject', type: 'mapping' },
|
|
28
|
-
{ short: 'ObjectKeys', full: 'Fn::ObjectKeys', type: 'sequence' },
|
|
29
|
-
{ short: 'ObjectValues', full: 'Fn::ObjectValues', type: 'sequence' },
|
|
30
|
-
{ short: 'Filenames', full: 'Fn::Filenames', type: 'sequence' },
|
|
31
|
-
{ short: 'Without', full: 'Fn::Without', type: 'sequence' },
|
|
32
|
-
{ short: 'Omit', full: 'Fn::Omit', type: 'sequence' },
|
|
33
|
-
{ short: 'Omit', full: 'Fn::Omit', type: 'mapping' },
|
|
34
|
-
{ short: 'OmitEmpty', full: 'Fn::OmitEmpty', type: 'mapping' },
|
|
35
|
-
{ short: 'Eval', full: 'Fn::Eval', type: 'sequence' },
|
|
36
|
-
{ short: 'IfEval', full: 'Fn::IfEval', type: 'mapping' },
|
|
37
|
-
{ short: 'JoinNow', full: 'Fn::JoinNow', type: 'scalar' },
|
|
38
|
-
{ short: 'SubNow', full: 'Fn::SubNow', type: 'scalar' },
|
|
39
|
-
{ short: 'SubNow', full: 'Fn::SubNow', type: 'sequence' },
|
|
40
|
-
{ short: 'RefNow', full: 'Fn::RefNow', type: 'scalar' },
|
|
41
|
-
{ short: 'ApplyTags', full: 'Fn::ApplyTags', type: 'mapping' },
|
|
42
|
-
|
|
43
|
-
// http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html
|
|
44
|
-
{ short: 'Base64', full: 'Fn::Base64', type: 'scalar' },
|
|
45
|
-
{ short: 'Base64', full: 'Fn::Base64', type: 'mapping' },
|
|
46
|
-
{ short: 'FindInMap', full: 'Fn::FindInMap', type: 'sequence' },
|
|
47
|
-
{ short: 'GetAtt', full: 'Fn::GetAtt', type: 'sequence' },
|
|
48
|
-
{ short: 'GetAtt', full: 'Fn::GetAtt', type: 'scalar', dotSyntax: true },
|
|
49
|
-
{ short: 'GetAZs', full: 'Fn::GetAZs', type: 'sequence' },
|
|
50
|
-
{ short: 'GetAZs', full: 'Fn::GetAZs', type: 'scalar' },
|
|
51
|
-
{ short: 'ImportValue', full: 'Fn::ImportValue', type: 'scalar' },
|
|
52
|
-
{ short: 'ImportValue', full: 'Fn::ImportValue', type: 'mapping' },
|
|
53
|
-
{ short: 'Join', full: 'Fn::Join', type: 'sequence' },
|
|
54
|
-
{ short: 'Select', full: 'Fn::Select', type: 'sequence' },
|
|
55
|
-
{ short: 'Sub', full: 'Fn::Sub', type: 'sequence' },
|
|
56
|
-
{ short: 'Sub', full: 'Fn::Sub', type: 'mapping' },
|
|
57
|
-
{ short: 'Sub', full: 'Fn::Sub', type: 'scalar' },
|
|
58
|
-
{ short: 'Split', full: 'Fn::Split', type: 'sequence' },
|
|
59
|
-
{ short: 'Ref', full: 'Ref', type: 'scalar' },
|
|
60
|
-
{ short: 'Cidr', full: 'Fn::Cidr', type: 'sequence' },
|
|
61
|
-
{ short: 'Cidr', full: 'Fn::Cidr', type: 'mapping' },
|
|
62
|
-
// http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-action-reference.html
|
|
63
|
-
{ short: 'GetParam', full: 'Fn::GetParam', type: 'sequence' },
|
|
64
|
-
// http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html
|
|
65
|
-
{ short: 'And', full: 'Fn::And', type: 'sequence' },
|
|
66
|
-
{ short: 'Equals', full: 'Fn::Equals', type: 'sequence' },
|
|
67
|
-
{ short: 'If', full: 'Fn::If', type: 'sequence' },
|
|
68
|
-
{ short: 'Not', full: 'Fn::Not', type: 'sequence' },
|
|
69
|
-
{ short: 'Or', full: 'Fn::Or', type: 'sequence' },
|
|
70
|
-
{ short: 'Condition', full: 'Condition', type: 'scalar' },
|
|
71
|
-
].map(function (fn) {
|
|
72
|
-
return new yaml.Type('!' + fn.short, {
|
|
73
|
-
kind: fn.type,
|
|
74
|
-
construct: function (obj) {
|
|
75
|
-
if (fn.dotSyntax && _.isString(obj)) {
|
|
76
|
-
const indexOfDot = obj.indexOf('.');
|
|
77
|
-
if (indexOfDot !== -1) obj = [obj.substr(0, indexOfDot), obj.substr(indexOfDot + 1)];
|
|
78
|
-
else obj = [obj];
|
|
79
|
-
}
|
|
80
|
-
return _.fromPairs([[fn.full, obj]]);
|
|
81
|
-
},
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
// build array of strings of all Amazon Intrinsic functions
|
|
86
|
-
const BANG_AMAZON_FUNCS = [
|
|
87
|
-
'Base64',
|
|
88
|
-
'FindInMap',
|
|
89
|
-
'GetAtt',
|
|
90
|
-
'GetAZs',
|
|
91
|
-
'ImportValue',
|
|
92
|
-
'Join',
|
|
93
|
-
'Select',
|
|
94
|
-
'Split',
|
|
95
|
-
'Sub',
|
|
96
|
-
'Ref',
|
|
97
|
-
'Cidr',
|
|
98
|
-
'GetParam',
|
|
99
|
-
'And',
|
|
100
|
-
'Equals',
|
|
101
|
-
'If',
|
|
102
|
-
'Not',
|
|
103
|
-
'Or',
|
|
104
|
-
'Condition',
|
|
105
|
-
];
|
|
106
|
-
|
|
107
|
-
const EXPLICIT_AMAZON_FUNCS = BANG_AMAZON_FUNCS.map((f) => `Fn::${f}`);
|
|
108
|
-
|
|
109
|
-
const yamlSchema = yaml.DEFAULT_SCHEMA.extend(tags);
|
|
110
|
-
|
|
111
|
-
// Test the function key to make sure it's something
|
|
112
|
-
// we should process.
|
|
113
|
-
const isOurExplicitFunction = (testKeyForFunc) =>
|
|
114
|
-
/Fn::.*/.test(testKeyForFunc) && !EXPLICIT_AMAZON_FUNCS.includes(testKeyForFunc);
|
|
115
|
-
|
|
116
|
-
export default yamlSchema;
|
|
117
|
-
export { EXPLICIT_AMAZON_FUNCS, BANG_AMAZON_FUNCS, isOurExplicitFunction };
|
package/lib/scope.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Scope helper functions for lazy prototype-chain based scope management.
|
|
3
|
-
*
|
|
4
|
-
* Instead of _.clone(scope) which copies O(n) properties each time,
|
|
5
|
-
* we use Object.create(scope) which creates a child scope in O(1) time
|
|
6
|
-
* that inherits from the parent via the prototype chain.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Create a child scope that inherits from the parent.
|
|
11
|
-
* Uses Object.create() for O(1) creation instead of cloning.
|
|
12
|
-
*
|
|
13
|
-
* @param {Object} parent - The parent scope to inherit from
|
|
14
|
-
* @param {Object} [additions={}] - Properties to add to the child scope
|
|
15
|
-
* @returns {Object} A new child scope with prototype chain to parent
|
|
16
|
-
*/
|
|
17
|
-
export function createChildScope(parent, additions = {}) {
|
|
18
|
-
const child = Object.create(parent);
|
|
19
|
-
Object.assign(child, additions);
|
|
20
|
-
return child;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Convert a prototype-chain scope to a plain object.
|
|
25
|
-
* Uses for...in to walk the entire prototype chain.
|
|
26
|
-
*
|
|
27
|
-
* Useful when we need to pass scope to functions that don't
|
|
28
|
-
* walk the prototype chain (e.g., Object.keys, _.forEach).
|
|
29
|
-
*
|
|
30
|
-
* @param {Object} scope - The scope to flatten
|
|
31
|
-
* @returns {Object} A plain object with all inherited properties
|
|
32
|
-
*/
|
|
33
|
-
export function scopeToObject(scope) {
|
|
34
|
-
const result = {};
|
|
35
|
-
for (const key in scope) {
|
|
36
|
-
result[key] = scope[key];
|
|
37
|
-
}
|
|
38
|
-
return result;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Iterate over all properties in a scope, including inherited ones.
|
|
43
|
-
* This is a replacement for _.forEach that walks the prototype chain.
|
|
44
|
-
*
|
|
45
|
-
* @param {Object} scope - The scope to iterate over
|
|
46
|
-
* @param {Function} callback - Function to call with (value, key)
|
|
47
|
-
*/
|
|
48
|
-
export function forEachInScope(scope, callback) {
|
|
49
|
-
for (const key in scope) {
|
|
50
|
-
callback(scope[key], key);
|
|
51
|
-
}
|
|
52
|
-
}
|
package/lib/utils.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
|
|
3
|
-
function upperCamelCase(str) {
|
|
4
|
-
assert(typeof str === 'string', 'argument to upper/lowerCamelCase must be a string');
|
|
5
|
-
return str
|
|
6
|
-
.split(/[\._-\s]+/)
|
|
7
|
-
.map((s) => s.charAt(0).toUpperCase() + s.slice(1).toLowerCase())
|
|
8
|
-
.join('');
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function lowerCamelCase(str) {
|
|
12
|
-
const upper = upperCamelCase(str);
|
|
13
|
-
return upper.charAt(0).toLowerCase() + upper.slice(1);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export { lowerCamelCase, upperCamelCase };
|