Skip to content

Commit eed6c12

Browse files
committed
Initial commit: shared business logic package with StripeHelpers
0 parents  commit eed6c12

10 files changed

Lines changed: 330 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, master, develop]
6+
pull_request:
7+
branches: [main, master, develop]
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
13+
strategy:
14+
matrix:
15+
node-version: [18.x, 20.x]
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Setup Node.js ${{ matrix.node-version }}
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: ${{ matrix.node-version }}
25+
cache: 'npm'
26+
27+
- name: Install dependencies
28+
run: npm ci
29+
30+
- name: Run build
31+
run: npm run build
32+
33+
- name: Check build output
34+
run: |
35+
if [ ! -d "dist" ]; then
36+
echo "Build failed: dist directory not found"
37+
exit 1
38+
fi
39+
if [ ! -f "dist/index.js" ]; then
40+
echo "Build failed: dist/index.js not found"
41+
exit 1
42+
fi

.github/workflows/publish.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Publish
2+
3+
on:
4+
push:
5+
branches: [main, master]
6+
7+
jobs:
8+
publish:
9+
runs-on: ubuntu-latest
10+
if: "!contains(github.event.head_commit.message, '[skip publish]')"
11+
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v4
15+
16+
- name: Setup Node.js
17+
uses: actions/setup-node@v4
18+
with:
19+
node-version: '20.x'
20+
registry-url: 'https://registry.npmjs.org'
21+
cache: 'npm'
22+
23+
- name: Install dependencies
24+
run: npm ci
25+
26+
- name: Build package
27+
run: npm run build
28+
29+
- name: Publish to npm
30+
run: npm publish
31+
env:
32+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules
2+
dist
3+
*.log
4+
.DS_Store
5+
.idea
6+
.vscode
7+
*.tsbuildinfo

.npmignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
src
2+
*.test.ts
3+
*.test.tsx
4+
*.spec.ts
5+
*.spec.tsx
6+
tsconfig.json
7+
.gitignore
8+
.git
9+
node_modules
10+
*.log
11+
.DS_Store
12+
.idea
13+
.vscode

README.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# @swipecast/shared
2+
3+
Shared business logic package for Swipecast React Native and Web applications.
4+
5+
## Installation
6+
7+
```bash
8+
npm install @swipecast/shared
9+
# or
10+
yarn add @swipecast/shared
11+
```
12+
13+
## Usage
14+
15+
### StripeHelpers
16+
17+
```typescript
18+
import { StripeHelpers } from '@swipecast/shared';
19+
20+
const card = {
21+
brand: 'American Express',
22+
last4: '1234',
23+
exp_month: 12,
24+
exp_year: 2025,
25+
};
26+
27+
const label = StripeHelpers.getCardBrandLabel(card); // "Amex"
28+
```
29+
30+
## Development
31+
32+
### Setup
33+
34+
```bash
35+
npm install
36+
```
37+
38+
### Build
39+
40+
```bash
41+
npm run build
42+
```
43+
44+
This will compile TypeScript to JavaScript in the `dist` directory.
45+
46+
## Publishing
47+
48+
### Automatic Publishing (CI/CD)
49+
50+
The package is automatically published to npm when code is pushed to the `main` branch. The workflow will:
51+
1. Build the package
52+
2. Publish to npm using the `NPM_TOKEN` secret
53+
54+
**Setup:**
55+
1. Add your npm token as a GitHub secret named `NPM_TOKEN`:
56+
- Go to your repository settings → Secrets and variables → Actions
57+
- Add a new secret with your npm token (get it from npmjs.com → Access Tokens)
58+
59+
2. Update the version in `package.json` before pushing:
60+
```bash
61+
npm version patch # for bug fixes
62+
npm version minor # for new features
63+
npm version major # for breaking changes
64+
```
65+
66+
3. Push to main:
67+
```bash
68+
git push origin main
69+
```
70+
71+
**Skip publishing:** Add `[skip publish]` to your commit message to skip automatic publishing.
72+
73+
### Manual Publishing
74+
75+
If you need to publish manually:
76+
77+
1. Make sure you're logged into npm:
78+
```bash
79+
npm login
80+
```
81+
82+
2. Update the version in `package.json`:
83+
```bash
84+
npm version patch # for bug fixes
85+
npm version minor # for new features
86+
npm version major # for breaking changes
87+
```
88+
89+
3. Publish:
90+
```bash
91+
npm publish
92+
```
93+
94+
The `prepublishOnly` script will automatically build the package before publishing.
95+
96+
### Publishing to a Private Registry
97+
98+
If you're using a private npm registry, update the `publishConfig` in `package.json`:
99+
100+
```json
101+
{
102+
"publishConfig": {
103+
"registry": "https://your-private-registry.com"
104+
}
105+
}
106+
```
107+
108+
## Project Structure
109+
110+
```
111+
shared/
112+
├── src/
113+
│ ├── stripe_helpers.ts # Stripe-related business logic
114+
│ └── index.ts # Main entry point
115+
├── dist/ # Compiled output (generated)
116+
├── package.json
117+
├── tsconfig.json
118+
└── README.md
119+
```
120+
121+
## License
122+
123+
UNLICENSED

package-lock.json

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "@swipecast/shared",
3+
"version": "1.0.0",
4+
"description": "Shared business logic for Swipecast React Native and Web applications",
5+
"main": "dist/index.js",
6+
"types": "dist/index.d.ts",
7+
"files": [
8+
"dist",
9+
"README.md"
10+
],
11+
"scripts": {
12+
"build": "npm run clean && tsc",
13+
"clean": "rm -rf dist",
14+
"prepublishOnly": "npm run build"
15+
},
16+
"keywords": [
17+
"swipecast",
18+
"shared",
19+
"business-logic",
20+
"react-native",
21+
"web"
22+
],
23+
"author": "",
24+
"license": "UNLICENSED",
25+
"publishConfig": {
26+
"registry": "https://registry.npmjs.org/"
27+
},
28+
"devDependencies": {
29+
"typescript": "^5.1.0"
30+
}
31+
}

src/helpers/stripe_helpers.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Stripe-related business logic that works across React Native and Web
3+
*/
4+
5+
export interface StripeCard {
6+
brand: string;
7+
last4?: string;
8+
exp_month?: number;
9+
exp_year?: number;
10+
}
11+
12+
export class StripeHelpers {
13+
/**
14+
* Returns a formatted card brand label. Abbreviates "American Express" to "Amex".
15+
* @param card - The card object containing brand information.
16+
* @returns The formatted card brand label.
17+
*/
18+
static getCardBrandLabel(card: StripeCard): string {
19+
const brandMap: Record<string, string> = {
20+
'american express': 'Amex',
21+
visa: 'Visa',
22+
mastercard: 'Mastercard',
23+
discover: 'Discover',
24+
jcb: 'JCB',
25+
diners: 'Diners Club',
26+
unionpay: 'UnionPay',
27+
};
28+
29+
const brand = card.brand?.toLowerCase() || '';
30+
return brandMap[brand] || (brand ? brand.charAt(0).toUpperCase() + brand.slice(1) : '');
31+
}
32+
}

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './helpers/stripe_helpers';

tsconfig.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2020",
4+
"module": "commonjs",
5+
"lib": ["ES2020"],
6+
"declaration": true,
7+
"declarationMap": true,
8+
"sourceMap": true,
9+
"outDir": "./dist",
10+
"rootDir": "./src",
11+
"strict": true,
12+
"esModuleInterop": true,
13+
"skipLibCheck": true,
14+
"forceConsistentCasingInFileNames": true,
15+
"moduleResolution": "node",
16+
"resolveJsonModule": true
17+
},
18+
"include": ["src/**/*"],
19+
"exclude": ["node_modules", "dist"]
20+
}

0 commit comments

Comments
 (0)