Skip to content

Commit 733f267

Browse files
meabedDEV.ME Team
andauthored
feat: serverless architecture support with performance improvements (#382)
* chore: update deps * docs: add Support section and improve LICENSE documentation - Add Support section with links for issues, email support, commercial licensing, and dev.me website - Move LICENSE section to end of README for better document flow - Retain comprehensive license usage table for clarity - Format consistent with other devmehq repositories * chore: update readme * chore: update ci * feat: Add serverless architecture support (#381) * feat: Add serverless architecture support without Node.js dependencies - Added lightweight serverless version (244KB minified) with resource loader pattern - Created full serverless version (40MB) with all resources bundled inline - Implemented support for multiple platforms: - AWS Lambda - Cloudflare Workers - Vercel Edge Functions - Deno Deploy - Added resource loader implementations for various storage backends (KV, S3, CDN, Redis) - Created deployment scripts for resource distribution - Added comprehensive documentation and examples for each platform - Integrated Biome.js for linting and formatting - Added tests for serverless functionality - Maintained backward compatibility with existing Node.js version BREAKING CHANGE: None - existing functionality remains unchanged * refactor: Simplify serverless architecture and use @rollup/plugin-typescript - Replaced rollup-plugin-typescript2 with @rollup/plugin-typescript - Removed redundant serverless build configurations - Kept only the lightweight serverless version (244KB minified) - Simplified file naming: removed '.lite' suffix from serverless builds - Updated documentation to reflect simplified architecture - Fixed TypeScript plugin configuration for proper declaration file generation * fix: Update serverless tests to pass correctly - Fixed BSON serialization in mock resource loader to use actual BSON library - Updated test expectations to match mock data values - Handled parsePhoneNumber errors properly for invalid input - Added console.error suppression during tests - Fixed UK number type test to handle FIXED_LINE_OR_MOBILE response All tests now pass successfully (52 passed). * fix: update test imports and biome configuration - Fixed serverless test to use parsePhoneNumberWithError instead of parsePhoneNumber - Updated biome.json with proper linting rules and globals - Cleaned up rollup configuration formatting - Fixed Node.js import protocol in src/index.ts * docs: add serverless documentation to README - Added serverless feature to features list - Created comprehensive serverless section with examples - Included examples for AWS Lambda, Cloudflare Workers, and Vercel Edge - Added resource deployment instructions - Added performance optimization tips - Referenced detailed SERVERLESS.md for more information * feat: replace @rollup/plugin-typescript with rollup-plugin-esbuild - Replaced @rollup/plugin-typescript with rollup-plugin-esbuild for faster builds - Converted rollup configs to CommonJS format to avoid bundleConfigAsCjs issues - Added esbuild dependency with proper configuration - Updated build scripts to use .cjs config files - All tests passing and builds working correctly - Removed old ESM config files * feat: improve build system with structured scripts and exports - Added separate build:main and build:serverless commands - Main build command now runs build:all (both main and serverless) - Added build:types command for TypeScript declaration generation - Added watch:serverless command for development - Added proper package.json exports field for better ESM/CJS support - Added serverless entry point at ./serverless for easier imports - Added TypeScript as dev dependency for declaration generation - All scripts now use yarn consistently - All tests passing with 52 test cases * chore: update pkgs * feat: enhance CI workflows with comprehensive GitHub job summaries - Added detailed job summaries with release numbers, tags, and build info - CI workflow now displays current version, latest tag, commit count, and branch - Release workflow shows production release information with installation instructions - Added build step to ensure artifacts are generated during CI - Enhanced release detection to show version changes and release types - Added recent tags display for better version tracking - Improved formatting with emojis and markdown for better readability Features: - 📦 Build information (version, tags, commits, branch, SHA) - 🧪 Test results status - 📁 Generated files listing - 🚀 Release information (version changes, installation commands) - 🏷️ Recent tags display (last 10 versions) * feat: improve CI/CD workflows with enhanced release tracking - Added semantic release output capture and parsing - Extract version and tag information from release process - Improved job summaries with conditional release information - Added PR information display for pull request events - Enhanced release detection with grep patterns - Added NPM and GitHub release links in summaries - Better formatting and organization of job summaries - Added workflow metadata (run ID, number, actor, event) CI Workflow: - Conditionally shows pre-release info for develop branch - Displays CI test pass status for other branches - Shows PR details when triggered by pull requests Release Workflow: - Captures semantic-release output for analysis - Extracts version and tag from successful releases - Provides direct links to NPM package and GitHub release - Clear messaging for both successful and skipped releases * fix: correct npm package link in README badges to use scoped package name --------- Co-authored-by: DEV.ME Team <[email protected]>
1 parent 6a5d6c0 commit 733f267

27 files changed

+3129
-245
lines changed

.github/workflows/ci.yml

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646
- name: Setup Node.js
4747
uses: actions/setup-node@v4
4848
with:
49-
node-version: lts/*
49+
node-version: 24
5050

5151
- name: Yarn
5252
run: yarn install --frozen-lockfile
@@ -56,10 +56,79 @@ jobs:
5656
yarn preparemetadata
5757
yarn test
5858
59+
- name: Build
60+
run: yarn build
61+
5962
- name: Release
63+
id: semantic_release
6064
if: github.ref == 'refs/heads/develop'
6165
run: |
6266
git config --global user.email "[email protected]"
6367
git config --global user.name "DEV.ME Team"
6468
npm i -g semantic-release @semantic-release/git @semantic-release/github conventional-changelog-conventionalcommits
65-
npx semantic-release --no-ci --debug
69+
npx semantic-release --no-ci --debug 2>&1 | tee release-output.txt
70+
71+
# Extract version and tag info from release output
72+
if grep -q "Published release" release-output.txt; then
73+
echo "release_published=true" >> $GITHUB_OUTPUT
74+
VERSION=$(grep -oP 'Published release \K[0-9]+\.[0-9]+\.[0-9]+' release-output.txt | head -1)
75+
echo "version=$VERSION" >> $GITHUB_OUTPUT
76+
echo "tag=v$VERSION" >> $GITHUB_OUTPUT
77+
else
78+
echo "release_published=false" >> $GITHUB_OUTPUT
79+
fi
80+
81+
- name: Add CI Summary
82+
if: always()
83+
run: |
84+
echo "## 🔬 CI Summary" >> $GITHUB_STEP_SUMMARY
85+
echo "" >> $GITHUB_STEP_SUMMARY
86+
87+
# Check if release step was run (only on develop branch)
88+
if [[ "${{ github.ref }}" == "refs/heads/develop" ]]; then
89+
if [[ "${{ steps.semantic_release.outputs.release_published }}" == "true" ]]; then
90+
echo "### ✅ Pre-release Published Successfully!" >> $GITHUB_STEP_SUMMARY
91+
echo "" >> $GITHUB_STEP_SUMMARY
92+
echo "- **Version:** \`${{ steps.semantic_release.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
93+
echo "- **Tag:** \`${{ steps.semantic_release.outputs.tag }}\`" >> $GITHUB_STEP_SUMMARY
94+
echo "- **Branch:** \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
95+
echo "- **Commit:** \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
96+
echo "" >> $GITHUB_STEP_SUMMARY
97+
echo "### 🔗 Links" >> $GITHUB_STEP_SUMMARY
98+
echo "- [NPM Package](https://www.npmjs.com/package/@devmehq/email-validator-js/v/${{ steps.semantic_release.outputs.version }})" >> $GITHUB_STEP_SUMMARY
99+
echo "- [GitHub Release](https://github.com/${{ github.repository }}/releases/tag/${{ steps.semantic_release.outputs.tag }})" >> $GITHUB_STEP_SUMMARY
100+
else
101+
echo "### ℹ️ No Pre-release Published" >> $GITHUB_STEP_SUMMARY
102+
echo "" >> $GITHUB_STEP_SUMMARY
103+
echo "No pre-release was created. This could be because:" >> $GITHUB_STEP_SUMMARY
104+
echo "- No relevant commits found for release" >> $GITHUB_STEP_SUMMARY
105+
echo "- Commits don't follow conventional commit format" >> $GITHUB_STEP_SUMMARY
106+
echo "- Release conditions not met" >> $GITHUB_STEP_SUMMARY
107+
fi
108+
else
109+
echo "### ✅ CI Tests Passed" >> $GITHUB_STEP_SUMMARY
110+
echo "" >> $GITHUB_STEP_SUMMARY
111+
echo "All tests completed successfully on branch \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
112+
echo "" >> $GITHUB_STEP_SUMMARY
113+
echo "ℹ️ **Note:** Releases are only created from the \`develop\` branch" >> $GITHUB_STEP_SUMMARY
114+
fi
115+
116+
echo "" >> $GITHUB_STEP_SUMMARY
117+
echo "### 📊 Build Information" >> $GITHUB_STEP_SUMMARY
118+
echo "- **Workflow:** \`${{ github.workflow }}\`" >> $GITHUB_STEP_SUMMARY
119+
echo "- **Branch:** \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
120+
echo "- **Commit:** \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
121+
echo "- **Run ID:** \`${{ github.run_id }}\`" >> $GITHUB_STEP_SUMMARY
122+
echo "- **Run Number:** \`${{ github.run_number }}\`" >> $GITHUB_STEP_SUMMARY
123+
echo "- **Actor:** \`${{ github.actor }}\`" >> $GITHUB_STEP_SUMMARY
124+
echo "- **Event:** \`${{ github.event_name }}\`" >> $GITHUB_STEP_SUMMARY
125+
126+
# Add PR information if available
127+
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
128+
echo "" >> $GITHUB_STEP_SUMMARY
129+
echo "### 🔀 Pull Request Information" >> $GITHUB_STEP_SUMMARY
130+
echo "- **PR Number:** #${{ github.event.pull_request.number }}" >> $GITHUB_STEP_SUMMARY
131+
echo "- **PR Title:** ${{ github.event.pull_request.title }}" >> $GITHUB_STEP_SUMMARY
132+
echo "- **Base Branch:** \`${{ github.event.pull_request.base.ref }}\`" >> $GITHUB_STEP_SUMMARY
133+
echo "- **Head Branch:** \`${{ github.event.pull_request.head.ref }}\`" >> $GITHUB_STEP_SUMMARY
134+
fi

.github/workflows/release.yml

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
- name: Setup Node.js
4040
uses: actions/setup-node@v4
4141
with:
42-
node-version: lts/*
42+
node-version: 24
4343

4444
- name: Yarn
4545
run: yarn install --frozen-lockfile
@@ -49,9 +49,57 @@ jobs:
4949
yarn preparemetadata
5050
yarn test
5151
52+
- name: Build
53+
run: yarn build
54+
5255
- name: Release
56+
id: semantic_release
5357
run: |
5458
git config --global user.email "[email protected]"
5559
git config --global user.name "DEV.ME Team"
5660
npm i -g semantic-release @semantic-release/git @semantic-release/github conventional-changelog-conventionalcommits
57-
npx semantic-release --no-ci --debug
61+
npx semantic-release --no-ci --debug 2>&1 | tee release-output.txt
62+
63+
# Extract version and tag info from release output
64+
if grep -q "Published release" release-output.txt; then
65+
echo "release_published=true" >> $GITHUB_OUTPUT
66+
VERSION=$(grep -oP 'Published release \K[0-9]+\.[0-9]+\.[0-9]+' release-output.txt | head -1)
67+
echo "version=$VERSION" >> $GITHUB_OUTPUT
68+
echo "tag=v$VERSION" >> $GITHUB_OUTPUT
69+
else
70+
echo "release_published=false" >> $GITHUB_OUTPUT
71+
fi
72+
73+
- name: Add Release Summary
74+
if: always()
75+
run: |
76+
echo "## 📦 Release Summary" >> $GITHUB_STEP_SUMMARY
77+
echo "" >> $GITHUB_STEP_SUMMARY
78+
79+
if [[ "${{ steps.semantic_release.outputs.release_published }}" == "true" ]]; then
80+
echo "### ✅ Release Published Successfully!" >> $GITHUB_STEP_SUMMARY
81+
echo "" >> $GITHUB_STEP_SUMMARY
82+
echo "- **Version:** \`${{ steps.semantic_release.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
83+
echo "- **Tag:** \`${{ steps.semantic_release.outputs.tag }}\`" >> $GITHUB_STEP_SUMMARY
84+
echo "- **Branch:** \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
85+
echo "- **Commit:** \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
86+
echo "" >> $GITHUB_STEP_SUMMARY
87+
echo "### 🔗 Links" >> $GITHUB_STEP_SUMMARY
88+
echo "- [NPM Package](https://www.npmjs.com/package/@devmehq/email-validator-js/v/${{ steps.semantic_release.outputs.version }})" >> $GITHUB_STEP_SUMMARY
89+
echo "- [GitHub Release](https://github.com/${{ github.repository }}/releases/tag/${{ steps.semantic_release.outputs.tag }})" >> $GITHUB_STEP_SUMMARY
90+
else
91+
echo "### ℹ️ No Release Published" >> $GITHUB_STEP_SUMMARY
92+
echo "" >> $GITHUB_STEP_SUMMARY
93+
echo "No release was created. This could be because:" >> $GITHUB_STEP_SUMMARY
94+
echo "- No relevant commits found for release" >> $GITHUB_STEP_SUMMARY
95+
echo "- Commits don't follow conventional commit format" >> $GITHUB_STEP_SUMMARY
96+
echo "- Release conditions not met" >> $GITHUB_STEP_SUMMARY
97+
fi
98+
99+
echo "" >> $GITHUB_STEP_SUMMARY
100+
echo "### 📊 Build Information" >> $GITHUB_STEP_SUMMARY
101+
echo "- **Workflow:** \`${{ github.workflow }}\`" >> $GITHUB_STEP_SUMMARY
102+
echo "- **Run ID:** \`${{ github.run_id }}\`" >> $GITHUB_STEP_SUMMARY
103+
echo "- **Run Number:** \`${{ github.run_number }}\`" >> $GITHUB_STEP_SUMMARY
104+
echo "- **Actor:** \`${{ github.actor }}\`" >> $GITHUB_STEP_SUMMARY
105+
echo "- **Event:** \`${{ github.event_name }}\`" >> $GITHUB_STEP_SUMMARY

.prettierrc.yaml

Lines changed: 0 additions & 4 deletions
This file was deleted.

.scripts/prepare.js

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,7 @@
22
* This script loads the geocoder and carrier data from the libphonenumber repository,
33
* creates bson files from them and autogenerated the types in src/locales.ts
44
*/
5-
const {
6-
readdirSync,
7-
writeFileSync,
8-
lstatSync,
9-
createReadStream,
10-
mkdirSync,
11-
} = require('fs')
5+
const { readdirSync, writeFileSync, lstatSync, createReadStream, mkdirSync } = require('fs')
126
const { join, basename } = require('path')
137
const { createInterface } = require('readline')
148
const { execSync } = require('child_process')
@@ -21,7 +15,7 @@ async function prepareLocale(localePath, locale, type) {
2115
const files = readdirSync(localePath).filter((source) => fileRe.test(source))
2216
const lineRe = /^([0-9]+)\|(.*)$/
2317
for (let i = 0; i < files.length; ++i) {
24-
let data = {}
18+
const data = {}
2519
const file = files[i]
2620
const countryCode = basename(file, '.txt')
2721
const ccRe = new RegExp(`^${countryCode}`)
@@ -49,9 +43,7 @@ async function prepareLocale(localePath, locale, type) {
4943
}
5044

5145
async function preparePath(dataPath, type) {
52-
const locales = readdirSync(dataPath).filter((source) =>
53-
isDir(join(dataPath, source))
54-
)
46+
const locales = readdirSync(dataPath).filter((source) => isDir(join(dataPath, source)))
5547
const promises = []
5648
for (let i = 0; i < locales.length; ++i) {
5749
const locale = locales[i]
@@ -65,11 +57,8 @@ async function preparePath(dataPath, type) {
6557

6658
async function prepareTimezones() {
6759
const lineRe = /^([0-9]+)\|(.*)$/
68-
let data = {}
69-
const file = join(
70-
__dirname,
71-
'/../resources/libphonenumber/resources/timezones/map_data.txt'
72-
)
60+
const data = {}
61+
const file = join(__dirname, '/../resources/libphonenumber/resources/timezones/map_data.txt')
7362
const fileStream = createReadStream(file)
7463
const rl = createInterface({
7564
input: fileStream,
@@ -93,20 +82,15 @@ const prepare = async () => {
9382
mkdirSync(join(__dirname, '/../resources/geocodes'), { recursive: true })
9483
mkdirSync(join(__dirname, '/../resources/carrier'), { recursive: true })
9584
execSync(
96-
`cd ${join(
97-
__dirname,
98-
'/../resources'
99-
)} && git clone https://github.com/google/libphonenumber`
85+
`cd ${join(__dirname, '/../resources')} && git clone https://github.com/google/libphonenumber`
10086
)
10187
console.log('Preparing metadata...')
10288
const dataBasePath = join(__dirname, '/../resources/libphonenumber/resources')
10389
let generatedTypes = '/* THIS FILE IS AUTOGENERATED. */\n'
10490

10591
const geocodingPath = join(dataBasePath, 'geocoding')
10692
const { locales: geoLocales } = await preparePath(geocodingPath, 'geocodes')
107-
generatedTypes += `export type GeocoderLocale = ${geoLocales
108-
.map((l) => `'${l}'`)
109-
.join(' | ')};\n`
93+
generatedTypes += `export type GeocoderLocale = ${geoLocales.map((l) => `'${l}'`).join(' | ')};\n`
11094

11195
const carrierPath = join(dataBasePath, 'carrier')
11296
const { locales: carrierLocales } = await preparePath(carrierPath, 'carrier')

0 commit comments

Comments
 (0)