aws-lambda-layer-cli 1.4.1
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/LICENSE +21 -0
- package/README.md +393 -0
- package/bin/aws-lambda-layer.js +89 -0
- package/completion/aws-lambda-layer-completion.bash +101 -0
- package/completion/aws-lambda-layer-completion.zsh +110 -0
- package/package.json +31 -0
- package/scripts/aws-lambda-layer +821 -0
- package/scripts/build_pypi.sh +37 -0
- package/scripts/create_nodejs_layer.sh +459 -0
- package/scripts/create_python_layer.sh +465 -0
- package/scripts/install.js +34 -0
- package/scripts/install.ps1 +663 -0
- package/scripts/install.sh +107 -0
- package/scripts/pypi_resources/__init__.py +9 -0
- package/scripts/pypi_resources/cli.py +83 -0
- package/scripts/sync_version.js +24 -0
- package/scripts/uninstall.ps1 +180 -0
- package/scripts/uninstall.sh +58 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
# Directory setup
|
|
5
|
+
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
6
|
+
BUILD_DIR="$BASE_DIR/aws_lambda_layer_cli"
|
|
7
|
+
ASSETS_DIR="$BUILD_DIR/assets"
|
|
8
|
+
|
|
9
|
+
echo "Preparing PyPI package structure..."
|
|
10
|
+
|
|
11
|
+
# Clean up any previous build artifacts
|
|
12
|
+
rm -rf "$BUILD_DIR" "$BASE_DIR/dist" "$BASE_DIR/build" "$BASE_DIR/aws_lambda_layer_cli.egg-info"
|
|
13
|
+
|
|
14
|
+
# Create package directories
|
|
15
|
+
mkdir -p "$ASSETS_DIR"
|
|
16
|
+
|
|
17
|
+
# Copy Python package files
|
|
18
|
+
cp "$BASE_DIR/scripts/pypi_resources/__init__.py" "$BUILD_DIR/"
|
|
19
|
+
cp "$BASE_DIR/scripts/pypi_resources/cli.py" "$BUILD_DIR/"
|
|
20
|
+
cp "$BASE_DIR/VERSION.txt" "$BUILD_DIR/"
|
|
21
|
+
|
|
22
|
+
# Copy assets (bash scripts)
|
|
23
|
+
cp "$BASE_DIR/scripts/aws-lambda-layer" "$ASSETS_DIR/"
|
|
24
|
+
cp "$BASE_DIR/scripts/create_nodejs_layer.sh" "$ASSETS_DIR/"
|
|
25
|
+
cp "$BASE_DIR/scripts/create_python_layer.sh" "$ASSETS_DIR/"
|
|
26
|
+
|
|
27
|
+
# Create __init__.py for assets package
|
|
28
|
+
touch "$ASSETS_DIR/__init__.py"
|
|
29
|
+
|
|
30
|
+
echo "Building PyPI package..."
|
|
31
|
+
cd "$BASE_DIR"
|
|
32
|
+
python3 -m build
|
|
33
|
+
|
|
34
|
+
echo "Cleaning up temporary package files..."
|
|
35
|
+
rm -rf "$BUILD_DIR" "$BASE_DIR/aws_lambda_layer_cli.egg-info" "$BASE_DIR/build"
|
|
36
|
+
|
|
37
|
+
echo "Build complete! Artifacts are in dist/"
|
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Node.js Lambda Layer Creator with NVM support and version specification
|
|
4
|
+
# Usage:
|
|
5
|
+
# ./create_nodejs_layer.sh -i express@4.18.2,axios@1.6.2
|
|
6
|
+
# ./create_nodejs_layer.sh -i express@4.18.2,axios,lodash@4.17.21 -n my-layer.zip
|
|
7
|
+
# ./create_nodejs_layer.sh --packages=express@4.18.2,axios --name=my-layer.zip --node-version=24
|
|
8
|
+
|
|
9
|
+
set -e # Exit on error
|
|
10
|
+
set -u # Treat unset variables as errors
|
|
11
|
+
|
|
12
|
+
# Generate unique temporary directory
|
|
13
|
+
TEMP_DIR=$(mktemp -d)
|
|
14
|
+
WORK_DIR="$TEMP_DIR/layer-build"
|
|
15
|
+
NODE_DIR="$WORK_DIR/nodejs"
|
|
16
|
+
|
|
17
|
+
# Default values
|
|
18
|
+
PACKAGES=""
|
|
19
|
+
LAYER_NAME=""
|
|
20
|
+
NODE_VERSION="24" # Default to Node.js 24
|
|
21
|
+
ORIGINAL_DIR=$(pwd)
|
|
22
|
+
|
|
23
|
+
# Colors for output
|
|
24
|
+
RED='\033[0;31m'
|
|
25
|
+
GREEN='\033[0;32m'
|
|
26
|
+
YELLOW='\033[1;33m'
|
|
27
|
+
BLUE='\033[0;34m'
|
|
28
|
+
NC='\033[0m'
|
|
29
|
+
|
|
30
|
+
# Security functions
|
|
31
|
+
sanitize_filename() {
|
|
32
|
+
local filename="$1"
|
|
33
|
+
# Remove dangerous characters: /, \, :, |, <, >, ?, *, ", ', `, $, (, ), {, }, ;, &, !
|
|
34
|
+
filename=$(echo "$filename" | sed 's/[\/\\:|<>?*"\`$(){};&!]//g')
|
|
35
|
+
# Remove leading/trailing dots and hyphens
|
|
36
|
+
filename=$(echo "$filename" | sed 's/^[.-]*//' | sed 's/[.-]*$//')
|
|
37
|
+
# Limit length
|
|
38
|
+
echo "${filename:0:100}"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
validate_version() {
|
|
42
|
+
local version="$1"
|
|
43
|
+
# Allow only numbers and dots
|
|
44
|
+
if [[ ! "$version" =~ ^[0-9]+(\.[0-9]+)*$ ]]; then
|
|
45
|
+
printf "${RED}Error: Invalid version format: $version${NC}\n"
|
|
46
|
+
printf "Version must contain only numbers and dots (e.g., 24, 20.0.0)\n"
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
escape_package_name() {
|
|
52
|
+
local pkg="$1"
|
|
53
|
+
# Whitelist for Node.js: A-Za-z0-9._-@/ (with version operators: ^~<>)
|
|
54
|
+
# FIXED: Place hyphen at the end of character class to avoid regex range interpretation
|
|
55
|
+
echo "$pkg" | sed 's/[^A-Za-z0-9._@\/~^><=+-]//g'
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# Extract base package name from version specification
|
|
59
|
+
# Example: express@4.18.2 -> express
|
|
60
|
+
# Example: @aws-sdk/client-lambda@3.515.0 -> @aws-sdk/client-lambda
|
|
61
|
+
extract_package_name() {
|
|
62
|
+
local pkg="$1"
|
|
63
|
+
# Remove version specification after @
|
|
64
|
+
if [[ "$pkg" == *@* && ! "$pkg" =~ ^@ ]]; then
|
|
65
|
+
# Regular package with version: express@4.18.2
|
|
66
|
+
echo "${pkg%%@*}"
|
|
67
|
+
elif [[ "$pkg" == @*@* ]]; then
|
|
68
|
+
# Scoped package with version: @aws-sdk/client-lambda@3.515.0
|
|
69
|
+
# Keep @scope/name part
|
|
70
|
+
echo "${pkg%@*}"
|
|
71
|
+
else
|
|
72
|
+
# No version specified
|
|
73
|
+
echo "$pkg"
|
|
74
|
+
fi
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# Extract version from package string if specified
|
|
78
|
+
# Example: express@4.18.2 -> 4.18.2
|
|
79
|
+
extract_package_version() {
|
|
80
|
+
local pkg="$1"
|
|
81
|
+
if [[ "$pkg" == *@* ]]; then
|
|
82
|
+
if [[ "$pkg" == @*@* ]]; then
|
|
83
|
+
# Scoped package: @aws-sdk/client-lambda@3.515.0
|
|
84
|
+
echo "${pkg##*@}"
|
|
85
|
+
else
|
|
86
|
+
# Regular package: express@4.18.2
|
|
87
|
+
echo "${pkg##*@}"
|
|
88
|
+
fi
|
|
89
|
+
else
|
|
90
|
+
echo ""
|
|
91
|
+
fi
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# Cleanup function
|
|
95
|
+
cleanup() {
|
|
96
|
+
if [ -d "$TEMP_DIR" ]; then
|
|
97
|
+
rm -rf "$TEMP_DIR"
|
|
98
|
+
fi
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
# Trap to ensure cleanup on exit
|
|
102
|
+
trap cleanup EXIT
|
|
103
|
+
|
|
104
|
+
# Parse command line arguments
|
|
105
|
+
while [[ $# -gt 0 ]]; do
|
|
106
|
+
case "$1" in
|
|
107
|
+
-i|--packages)
|
|
108
|
+
if [[ -n "${2:-}" && "${2:-}" != -* ]]; then
|
|
109
|
+
PACKAGES="$2"
|
|
110
|
+
shift 2
|
|
111
|
+
else
|
|
112
|
+
printf "${RED}Error: $1 requires an argument${NC}\n"
|
|
113
|
+
printf "Example: $1 express@4.18.2,axios\n"
|
|
114
|
+
exit 1
|
|
115
|
+
fi
|
|
116
|
+
;;
|
|
117
|
+
--packages=*)
|
|
118
|
+
PACKAGES="${1#*=}"
|
|
119
|
+
shift
|
|
120
|
+
;;
|
|
121
|
+
-n|--name)
|
|
122
|
+
if [[ -n "${2:-}" && "${2:-}" != -* ]]; then
|
|
123
|
+
LAYER_NAME="$2"
|
|
124
|
+
shift 2
|
|
125
|
+
else
|
|
126
|
+
printf "${RED}Error: $1 requires an argument${NC}\n"
|
|
127
|
+
printf "Example: $1 my-layer.zip\n"
|
|
128
|
+
exit 1
|
|
129
|
+
fi
|
|
130
|
+
;;
|
|
131
|
+
--name=*)
|
|
132
|
+
LAYER_NAME="${1#*=}"
|
|
133
|
+
shift
|
|
134
|
+
;;
|
|
135
|
+
--node-version)
|
|
136
|
+
if [[ -n "${2:-}" && "${2:-}" != -* ]]; then
|
|
137
|
+
NODE_VERSION="$2"
|
|
138
|
+
validate_version "$NODE_VERSION"
|
|
139
|
+
shift 2
|
|
140
|
+
else
|
|
141
|
+
printf "${RED}Error: $1 requires an argument${NC}\n"
|
|
142
|
+
printf "Example: $1 24\n"
|
|
143
|
+
exit 1
|
|
144
|
+
fi
|
|
145
|
+
;;
|
|
146
|
+
--node-version=*)
|
|
147
|
+
NODE_VERSION="${1#*=}"
|
|
148
|
+
validate_version "$NODE_VERSION"
|
|
149
|
+
shift
|
|
150
|
+
;;
|
|
151
|
+
-h|--help)
|
|
152
|
+
cat << 'EOF'
|
|
153
|
+
Node.js Lambda Layer Creator with NVM support
|
|
154
|
+
|
|
155
|
+
Usage:
|
|
156
|
+
./create_nodejs_layer.sh -i express@4.18.2,axios@1.6.2
|
|
157
|
+
./create_nodejs_layer.sh --packages=express@4.18.2,axios,lodash -n my-layer.zip
|
|
158
|
+
./create_nodejs_layer.sh -i @aws-sdk/client-lambda@3.515.0 --name=aws-layer.zip --node-version=24
|
|
159
|
+
|
|
160
|
+
Options:
|
|
161
|
+
-i, --packages Comma-separated list of npm packages (with optional versions)
|
|
162
|
+
-n, --name Name of the output zip file
|
|
163
|
+
--node-version Node.js version (default: 24). Uses nvm if available, falls back to system node
|
|
164
|
+
-h, --help Show this help message
|
|
165
|
+
|
|
166
|
+
Version Specification:
|
|
167
|
+
Package versions can be specified using @ symbol:
|
|
168
|
+
express@4.18.2 # Exact version
|
|
169
|
+
express@^4.18.0 # Caret range
|
|
170
|
+
express@~4.18.0 # Tilde range
|
|
171
|
+
@aws-sdk/client-lambda@3.515.0 # Scoped package with version
|
|
172
|
+
|
|
173
|
+
Examples:
|
|
174
|
+
./create_nodejs_layer.sh -i express@4.18.2
|
|
175
|
+
./create_nodejs_layer.sh -i axios@1.6.2,lodash@4.17.21,moment@2.29.4 -n utilities.zip
|
|
176
|
+
./create_nodejs_layer.sh --packages=express@4.18.2,axios --name=web-framework.zip --node-version=24
|
|
177
|
+
EOF
|
|
178
|
+
exit 0
|
|
179
|
+
;;
|
|
180
|
+
*)
|
|
181
|
+
printf "${RED}Unknown option: $1${NC}\n"
|
|
182
|
+
printf "Use -h or --help for usage information\n"
|
|
183
|
+
exit 1
|
|
184
|
+
;;
|
|
185
|
+
esac
|
|
186
|
+
done
|
|
187
|
+
|
|
188
|
+
# Check if packages are provided
|
|
189
|
+
if [ -z "$PACKAGES" ]; then
|
|
190
|
+
printf "${RED}Error: Packages argument is required${NC}\n"
|
|
191
|
+
printf "Use -i or --packages to specify packages (comma-separated)\n"
|
|
192
|
+
printf "Example: ./create_nodejs_layer.sh -i express@4.18.2,axios\n"
|
|
193
|
+
exit 1
|
|
194
|
+
fi
|
|
195
|
+
# Check dependencies
|
|
196
|
+
if ! command -v zip &> /dev/null; then
|
|
197
|
+
printf "${RED}Error: 'zip' command is not installed${NC}\n"
|
|
198
|
+
exit 1
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
if ! command -v npm &> /dev/null; then
|
|
202
|
+
printf "${RED}Error: 'npm' command is not installed${NC}\n"
|
|
203
|
+
exit 1
|
|
204
|
+
fi
|
|
205
|
+
# Function to get Node.js version securely
|
|
206
|
+
get_node_version() {
|
|
207
|
+
local version=""
|
|
208
|
+
|
|
209
|
+
# Try to get version from node command
|
|
210
|
+
if command -v node >/dev/null 2>&1; then
|
|
211
|
+
version=$(node --version 2>/dev/null | head -1 || echo "")
|
|
212
|
+
if [[ -n "$version" ]]; then
|
|
213
|
+
# Remove 'v' prefix and get major version
|
|
214
|
+
version=${version#v}
|
|
215
|
+
version=${version%%.*}
|
|
216
|
+
echo "$version"
|
|
217
|
+
return 0
|
|
218
|
+
fi
|
|
219
|
+
fi
|
|
220
|
+
|
|
221
|
+
echo ""
|
|
222
|
+
return 1
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
# Sanitize packages input using whitelist
|
|
226
|
+
SANITIZED_PACKAGES=""
|
|
227
|
+
IFS=',' read -ra PACKAGE_ARRAY <<< "$PACKAGES"
|
|
228
|
+
for pkg in "${PACKAGE_ARRAY[@]}"; do
|
|
229
|
+
# Trim whitespace
|
|
230
|
+
pkg=$(echo "$pkg" | xargs)
|
|
231
|
+
# Escape package name using whitelist
|
|
232
|
+
escaped_pkg=$(escape_package_name "$pkg")
|
|
233
|
+
if [ -n "$escaped_pkg" ]; then
|
|
234
|
+
SANITIZED_PACKAGES="${SANITIZED_PACKAGES}${SANITIZED_PACKAGES:+,}$escaped_pkg"
|
|
235
|
+
else
|
|
236
|
+
printf "${YELLOW}Warning: Package name '$pkg' contains no valid characters after sanitization${NC}\n"
|
|
237
|
+
fi
|
|
238
|
+
done
|
|
239
|
+
|
|
240
|
+
if [ -z "$SANITIZED_PACKAGES" ]; then
|
|
241
|
+
printf "${RED}Error: No valid packages provided after sanitization${NC}\n"
|
|
242
|
+
exit 1
|
|
243
|
+
fi
|
|
244
|
+
|
|
245
|
+
# Check if any package names were changed
|
|
246
|
+
if [ "$PACKAGES" != "$SANITIZED_PACKAGES" ]; then
|
|
247
|
+
printf "${YELLOW}Warning: Some package names were sanitized:${NC}\n"
|
|
248
|
+
printf " Original: $PACKAGES\n"
|
|
249
|
+
printf " Sanitized: $SANITIZED_PACKAGES\n"
|
|
250
|
+
PACKAGES="$SANITIZED_PACKAGES"
|
|
251
|
+
fi
|
|
252
|
+
|
|
253
|
+
# Set Node.js version if specified (already has default 24)
|
|
254
|
+
printf "Node.js version: $NODE_VERSION\n"
|
|
255
|
+
CURRENT_NODE_VERSION=$(get_node_version || echo "")
|
|
256
|
+
if [[ -n "$NODE_VERSION" ]]; then
|
|
257
|
+
printf "Using Node.js version: $NODE_VERSION\n"
|
|
258
|
+
|
|
259
|
+
# Check if nvm is available
|
|
260
|
+
if [[ -f "$HOME/.nvm/nvm.sh" ]]; then
|
|
261
|
+
printf "Using nvm to set Node.js version...\n"
|
|
262
|
+
# Source nvm securely with fixed path
|
|
263
|
+
if [ -f "$HOME/.nvm/nvm.sh" ]; then
|
|
264
|
+
# shellcheck source=/dev/null
|
|
265
|
+
source "$HOME/.nvm/nvm.sh"
|
|
266
|
+
else
|
|
267
|
+
printf "${RED}Error: nvm not found at expected location${NC}\n"
|
|
268
|
+
exit 1
|
|
269
|
+
fi
|
|
270
|
+
|
|
271
|
+
# Check if requested version is installed using safe method
|
|
272
|
+
NVM_VERSIONS=$(nvm list --no-colors 2>/dev/null | grep -e "->|v$NODE_VERSION\." | head -1 || true)
|
|
273
|
+
if [[ -n "$NVM_VERSIONS" ]]; then
|
|
274
|
+
nvm use "$NODE_VERSION" > /dev/null 2>&1 || true
|
|
275
|
+
printf "Switched to Node.js version: $(node --version 2>/dev/null || echo 'unknown')\n"
|
|
276
|
+
else
|
|
277
|
+
printf "${YELLOW}Warning: Requested Node.js version $NODE_VERSION not found via nvm${NC}\n"
|
|
278
|
+
printf "Using current Node.js version: $(node --version 2>/dev/null || echo 'unknown')\n"
|
|
279
|
+
fi
|
|
280
|
+
elif command -v nvm >/dev/null 2>&1; then
|
|
281
|
+
printf "Using nvm to set Node.js version...\n"
|
|
282
|
+
# Check if requested version is installed
|
|
283
|
+
NVM_VERSIONS=$(nvm list --no-colors 2>/dev/null | grep -E "->|v$NODE_VERSION\." | head -1 || true)
|
|
284
|
+
if [[ -n "$NVM_VERSIONS" ]]; then
|
|
285
|
+
nvm use "$NODE_VERSION" > /dev/null 2>&1 || true
|
|
286
|
+
printf "Switched to Node.js version: $(node --version 2>/dev/null || echo 'unknown')\n"
|
|
287
|
+
else
|
|
288
|
+
printf "${YELLOW}Warning: Requested Node.js version $NODE_VERSION not found via nvm${NC}\n"
|
|
289
|
+
printf "Using current Node.js version: $(node --version 2>/dev/null || echo 'unknown')\n"
|
|
290
|
+
fi
|
|
291
|
+
else
|
|
292
|
+
printf "${YELLOW}Warning: nvm not found. Using system Node.js${NC}\n"
|
|
293
|
+
if [[ -n "$CURRENT_NODE_VERSION" ]]; then
|
|
294
|
+
printf "Current Node.js version: $CURRENT_NODE_VERSION\n"
|
|
295
|
+
else
|
|
296
|
+
printf "${YELLOW}Warning: Could not determine Node.js version${NC}\n"
|
|
297
|
+
fi
|
|
298
|
+
fi
|
|
299
|
+
fi
|
|
300
|
+
|
|
301
|
+
# Get current Node.js version for naming
|
|
302
|
+
NODE_VERSION_USED=$(get_node_version || echo "$NODE_VERSION")
|
|
303
|
+
|
|
304
|
+
printf "${BLUE}=========================================${NC}\n"
|
|
305
|
+
printf "${GREEN}Node.js Lambda Layer Creator${NC}\n"
|
|
306
|
+
printf "${BLUE}=========================================${NC}\n"
|
|
307
|
+
printf "Packages: $PACKAGES\n"
|
|
308
|
+
printf "Node.js version: $NODE_VERSION_USED\n"
|
|
309
|
+
if [ -n "$LAYER_NAME" ]; then
|
|
310
|
+
printf "Output name: $LAYER_NAME\n"
|
|
311
|
+
fi
|
|
312
|
+
printf "\n"
|
|
313
|
+
|
|
314
|
+
# Step 1: Create directory structure
|
|
315
|
+
printf "[1/5] Creating directory structure...\n"
|
|
316
|
+
mkdir -p "$NODE_DIR"
|
|
317
|
+
cd "$WORK_DIR"
|
|
318
|
+
|
|
319
|
+
# Step 2: Initialize npm project
|
|
320
|
+
printf "[2/5] Initializing npm project...\n"
|
|
321
|
+
cd "$NODE_DIR"
|
|
322
|
+
npm init -y --silent
|
|
323
|
+
|
|
324
|
+
# Step 3: Install packages with versions
|
|
325
|
+
printf "[3/5] Installing packages...\n"
|
|
326
|
+
# Convert to array for safe expansion
|
|
327
|
+
IFS=',' read -ra PKG_ARRAY <<< "$PACKAGES"
|
|
328
|
+
|
|
329
|
+
# Disable nounset for npm execution as some environment wrappers might trigger unbound variable errors
|
|
330
|
+
set +u
|
|
331
|
+
npm install --save --silent "${PKG_ARRAY[@]}"
|
|
332
|
+
set -u
|
|
333
|
+
|
|
334
|
+
# Count packages from command argument
|
|
335
|
+
PACKAGE_COUNT=$(echo "$PACKAGES" | tr ',' '\n' | wc -l | tr -d ' ')
|
|
336
|
+
|
|
337
|
+
# Step 4: Determine layer name
|
|
338
|
+
printf "[4/5] Determining layer name...\n"
|
|
339
|
+
if [ -z "$LAYER_NAME" ]; then
|
|
340
|
+
if [ "$PACKAGE_COUNT" -eq 1 ]; then
|
|
341
|
+
# Single package: get base package name without version
|
|
342
|
+
PKG_FULL="$PACKAGES"
|
|
343
|
+
PKG_NAME=$(extract_package_name "$PKG_FULL")
|
|
344
|
+
SPECIFIED_VERSION=$(extract_package_version "$PKG_FULL")
|
|
345
|
+
|
|
346
|
+
# Handle scoped packages
|
|
347
|
+
if [[ "$PKG_NAME" == @* ]]; then
|
|
348
|
+
SCOPE=$(echo "$PKG_NAME" | cut -d'/' -f1)
|
|
349
|
+
PKG=$(echo "$PKG_NAME" | cut -d'/' -f2)
|
|
350
|
+
PKG_JSON="$NODE_DIR/node_modules/$SCOPE/$PKG/package.json"
|
|
351
|
+
else
|
|
352
|
+
PKG_JSON="$NODE_DIR/node_modules/$PKG_NAME/package.json"
|
|
353
|
+
fi
|
|
354
|
+
|
|
355
|
+
if [ -f "$PKG_JSON" ]; then
|
|
356
|
+
# Use grep instead of node -p with require
|
|
357
|
+
INSTALLED_VERSION=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$PKG_JSON" | head -1 | cut -d'"' -f4 || echo "1.0.0")
|
|
358
|
+
if [ -z "$INSTALLED_VERSION" ]; then
|
|
359
|
+
INSTALLED_VERSION="1.0.0"
|
|
360
|
+
fi
|
|
361
|
+
|
|
362
|
+
# If user specified a version, include it in the name
|
|
363
|
+
if [ -n "$SPECIFIED_VERSION" ]; then
|
|
364
|
+
# Extract just the version number from spec (remove operators)
|
|
365
|
+
SPEC_VERSION=$(echo "$SPECIFIED_VERSION" | sed 's/^[=<>!~^]*//')
|
|
366
|
+
LAYER_NAME="${PKG_NAME}-${SPEC_VERSION}-nodejs${NODE_VERSION_USED}"
|
|
367
|
+
printf " Specified version: $SPEC_VERSION\n"
|
|
368
|
+
else
|
|
369
|
+
LAYER_NAME="${PKG_NAME}-${INSTALLED_VERSION}-nodejs${NODE_VERSION_USED}"
|
|
370
|
+
printf " Installed version: $INSTALLED_VERSION\n"
|
|
371
|
+
fi
|
|
372
|
+
else
|
|
373
|
+
# Use project version as fallback
|
|
374
|
+
PROJECT_VERSION=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$NODE_DIR/package.json" | head -1 | cut -d'"' -f4 || echo "1.0.0")
|
|
375
|
+
if [ -z "$PROJECT_VERSION" ]; then
|
|
376
|
+
PROJECT_VERSION="1.0.0"
|
|
377
|
+
fi
|
|
378
|
+
|
|
379
|
+
if [ -n "$SPECIFIED_VERSION" ]; then
|
|
380
|
+
LAYER_NAME="${PKG_NAME}-${SPECIFIED_VERSION}-nodejs${NODE_VERSION_USED}"
|
|
381
|
+
printf " Specified version: $SPECIFIED_VERSION\n"
|
|
382
|
+
else
|
|
383
|
+
LAYER_NAME="${PKG_NAME}-${PROJECT_VERSION}-nodejs${NODE_VERSION_USED}"
|
|
384
|
+
printf " Project version: $PROJECT_VERSION\n"
|
|
385
|
+
fi
|
|
386
|
+
fi
|
|
387
|
+
else
|
|
388
|
+
# Multiple packages: use nodejs-[date]-nodejs[version].zip
|
|
389
|
+
LAYER_NAME="nodejs-$(date +%Y%m%d)-nodejs${NODE_VERSION_USED}"
|
|
390
|
+
printf " Multiple packages, using date-based name\n"
|
|
391
|
+
fi
|
|
392
|
+
|
|
393
|
+
# Sanitize the layer name
|
|
394
|
+
LAYER_NAME=$(sanitize_filename "$LAYER_NAME")
|
|
395
|
+
fi
|
|
396
|
+
|
|
397
|
+
# Additional sanitization for layer name
|
|
398
|
+
LAYER_NAME=$(sanitize_filename "$LAYER_NAME")
|
|
399
|
+
|
|
400
|
+
# Ensure .zip extension and check for path traversal
|
|
401
|
+
if [[ "$LAYER_NAME" =~ \.\. ]] || [[ "$LAYER_NAME" =~ ^/ ]]; then
|
|
402
|
+
printf "${RED}Error: Invalid layer name (path traversal detected)${NC}\n"
|
|
403
|
+
exit 1
|
|
404
|
+
fi
|
|
405
|
+
|
|
406
|
+
if [[ ! "$LAYER_NAME" =~ \.zip$ ]]; then
|
|
407
|
+
LAYER_NAME="${LAYER_NAME}.zip"
|
|
408
|
+
fi
|
|
409
|
+
|
|
410
|
+
# Step 5: Zip the nodejs directory
|
|
411
|
+
printf "[5/5] Creating zip file: $LAYER_NAME\n"
|
|
412
|
+
cd "$WORK_DIR"
|
|
413
|
+
zip -r "$LAYER_NAME" "nodejs" -q
|
|
414
|
+
|
|
415
|
+
# Move zip to original directory - Check path
|
|
416
|
+
if [[ -f "$LAYER_NAME" ]]; then
|
|
417
|
+
mv "$LAYER_NAME" "$ORIGINAL_DIR/"
|
|
418
|
+
else
|
|
419
|
+
printf "${RED}Error: Zip file not created${NC}\n"
|
|
420
|
+
exit 1
|
|
421
|
+
fi
|
|
422
|
+
|
|
423
|
+
printf "\n"
|
|
424
|
+
printf "${GREEN}✅ Node.js Lambda layer created successfully!${NC}\n"
|
|
425
|
+
printf "📁 File: $ORIGINAL_DIR/$LAYER_NAME\n"
|
|
426
|
+
printf "🚀 Node.js Version: $NODE_VERSION_USED\n"
|
|
427
|
+
printf "📦 Size: $(du -h "$ORIGINAL_DIR/$LAYER_NAME" | cut -f1)\n"
|
|
428
|
+
printf "📊 Package Count: $PACKAGE_COUNT\n"
|
|
429
|
+
|
|
430
|
+
# Output installed packages with versions for description
|
|
431
|
+
printf "Installed packages: "
|
|
432
|
+
IFS=',' read -ra PKG_ARRAY <<< "$PACKAGES"
|
|
433
|
+
INSTALLED_PKGS=""
|
|
434
|
+
for pkg_full in "${PKG_ARRAY[@]}"; do
|
|
435
|
+
pkg_name=$(extract_package_name "$pkg_full")
|
|
436
|
+
|
|
437
|
+
# Find package.json
|
|
438
|
+
if [[ "$pkg_name" == @* ]]; then
|
|
439
|
+
scope=$(echo "$pkg_name" | cut -d'/' -f1)
|
|
440
|
+
pkg=$(echo "$pkg_name" | cut -d'/' -f2)
|
|
441
|
+
pkg_json="$NODE_DIR/node_modules/$scope/$pkg/package.json"
|
|
442
|
+
else
|
|
443
|
+
pkg_json="$NODE_DIR/node_modules/$pkg_name/package.json"
|
|
444
|
+
fi
|
|
445
|
+
|
|
446
|
+
if [ -f "$pkg_json" ]; then
|
|
447
|
+
installed_ver=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$pkg_json" | head -1 | cut -d'"' -f4)
|
|
448
|
+
if [ -n "$installed_ver" ]; then
|
|
449
|
+
if [ -n "$INSTALLED_PKGS" ]; then
|
|
450
|
+
INSTALLED_PKGS="$INSTALLED_PKGS, ${pkg_name}@${installed_ver}"
|
|
451
|
+
else
|
|
452
|
+
INSTALLED_PKGS="${pkg_name}@${installed_ver}"
|
|
453
|
+
fi
|
|
454
|
+
fi
|
|
455
|
+
fi
|
|
456
|
+
done
|
|
457
|
+
printf "$INSTALLED_PKGS\n"
|
|
458
|
+
|
|
459
|
+
printf "\n"
|