Skip to content

Commit b6b6f85

Browse files
committed
Add examples
1 parent 18d622b commit b6b6f85

6 files changed

Lines changed: 276 additions & 0 deletions

File tree

JavaScript/1-closure.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict';
2+
3+
const withContext = (context) => (accountId) => {
4+
const { console, rbac, user } = context;
5+
console.log(`User ${user.name} requesting balance for ${accountId}`);
6+
if (!rbac.check(user.role, 'read:balance')) {
7+
console.error('Access denied: insufficient permissions');
8+
return null;
9+
}
10+
const balance = 15420.5;
11+
console.log('Access granted');
12+
return balance;
13+
};
14+
15+
// Usage
16+
17+
const rbac = {
18+
permissions: {
19+
admin: ['read:balance', 'read:transactions', 'write:transactions'],
20+
user: ['read:balance'],
21+
guest: [],
22+
},
23+
check: (role, permission) => rbac.permissions[role]?.includes(permission),
24+
};
25+
26+
const context = { console, rbac, user: { name: 'Marcus', role: 'admin' } };
27+
const getBalance = withContext(context);
28+
const balance = getBalance('Account-123');
29+
console.log(`Access granted: balance = $${balance}`);

JavaScript/2-oop.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
'use strict';
2+
3+
class AccountService {
4+
constructor(context) {
5+
this.context = context;
6+
}
7+
8+
getBalance(accountId) {
9+
const { console, rbac, user } = this.context;
10+
console.log(`User ${user.name} requesting balance for ${accountId}`);
11+
if (!rbac.check(user.role, 'read:balance')) {
12+
console.error('Access denied: insufficient permissions');
13+
return null;
14+
}
15+
const balance = 15420.5;
16+
console.log('Access granted');
17+
return balance;
18+
}
19+
}
20+
21+
// Usage
22+
23+
class RBAC {
24+
constructor() {
25+
this.permissions = {
26+
admin: ['read:balance', 'read:transactions', 'write:transactions'],
27+
user: ['read:balance'],
28+
guest: [],
29+
};
30+
}
31+
32+
check(role, permission) {
33+
return this.permissions[role]?.includes(permission);
34+
}
35+
}
36+
37+
class User {
38+
constructor(name, role) {
39+
this.name = name;
40+
this.role = role;
41+
}
42+
}
43+
44+
const rbac = new RBAC();
45+
const user = new User('Marcus', 'admin');
46+
const context = { console, rbac, user };
47+
48+
const accountService = new AccountService(context);
49+
const balance = accountService.getBalance('Account-123');
50+
console.log(`Access granted: balance = $${balance}`);

JavaScript/3-factory.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict';
2+
3+
const createAccountService = (context) => {
4+
const { console, rbac, user } = context;
5+
6+
const getBalance = (accountId) => {
7+
console.log(`User ${user.name} requesting balance for ${accountId}`);
8+
if (!rbac.check(user.role, 'read:balance')) {
9+
console.error('Access denied: insufficient permissions');
10+
return null;
11+
}
12+
return 15420.5;
13+
};
14+
15+
const getTransactions = (accountId) => {
16+
if (!rbac.check(user.role, 'read:transactions')) {
17+
console.error('Access denied: insufficient permissions');
18+
return null;
19+
}
20+
console.log(`User ${user.name} reading transactions for ${accountId}`);
21+
return ['TR-123', 'TR-456', 'TR-789'];
22+
};
23+
24+
return { getBalance, getTransactions };
25+
};
26+
27+
// Usage
28+
29+
const rbac = {
30+
permissions: {
31+
admin: ['read:balance', 'read:transactions', 'write:transactions'],
32+
user: ['read:balance'],
33+
guest: [],
34+
},
35+
check: (role, permission) => rbac.permissions[role]?.includes(permission),
36+
};
37+
38+
const context = { console, rbac, user: { name: 'Marcus', role: 'admin' } };
39+
40+
const accountService = createAccountService(context);
41+
42+
console.log('Balance:', accountService.getBalance('ACC-001'));
43+
console.log('Transactions:', accountService.getTransactions('ACC-001'));

JavaScript/4-pipeline.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
'use strict';
2+
3+
const { randomUUID } = require('node:crypto');
4+
5+
const generateRequestId = () => `req-${Date.now()}-${randomUUID()}`;
6+
7+
const appendTrace = (context, step) => {
8+
const { trace = [] } = context;
9+
return [...trace, step];
10+
};
11+
12+
const pipeline =
13+
(...steps) =>
14+
(context) => {
15+
const initial = Promise.resolve(context);
16+
const next = (chain, mw) => chain.then((ctx) => mw(ctx));
17+
return steps.reduce(next, initial);
18+
};
19+
20+
const tracing = (context) => {
21+
const { console } = context;
22+
const next = {
23+
...context,
24+
requestId: context.requestId ?? generateRequestId(),
25+
trace: appendTrace(context, 'tracing'),
26+
};
27+
console.log(`[${next.requestId}] trace: ${next.trace.join(' -> ')}`);
28+
return Promise.resolve(next);
29+
};
30+
31+
const auth = (context) => {
32+
const { console, headers } = context;
33+
const user = headers?.user ?? { name: 'anonymous', role: 'guest' };
34+
console.log(`[${context.requestId}] auth: ${user.name}`);
35+
return Promise.resolve({ ...context, user });
36+
};
37+
38+
const rbac = (context) => {
39+
const permissions = {
40+
admin: ['read:balance', 'read:transactions'],
41+
user: ['read:balance'],
42+
guest: [],
43+
};
44+
const check = (role, permission) => permissions[role]?.includes(permission);
45+
return Promise.resolve({ ...context, rbac: { check, permissions } });
46+
};
47+
48+
const getBalance = (context) => {
49+
const { console, rbac, user, requestId } = context;
50+
if (!rbac.check(user.role, 'read:balance')) {
51+
console.error(`[${requestId}] Access denied for ${user.name}`);
52+
return Promise.resolve({ ...context, status: 403, body: null });
53+
}
54+
console.log(`[${requestId}] Balance for ${user.name}`);
55+
const result = { ...context, status: 200, body: { balance: 15420.5 } };
56+
return Promise.resolve(result);
57+
};
58+
59+
// Usage
60+
61+
const execute = pipeline(tracing, auth, rbac, getBalance);
62+
63+
const context = {
64+
console,
65+
headers: { user: { name: 'Marcus', role: 'admin' } },
66+
};
67+
68+
execute(context).then((ctx) => {
69+
console.log('Response:', ctx.status, ctx.body);
70+
});

JavaScript/5-async.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict';
2+
3+
const { AsyncLocalStorage } = require('node:async_hooks');
4+
const asyncLocalStorage = new AsyncLocalStorage();
5+
6+
const getBalance = async (accountId) => {
7+
const context = asyncLocalStorage.getStore();
8+
if (!context) throw new Error('No context');
9+
const { console, rbac, user, requestId } = context;
10+
console.log(`[${requestId}] User ${user.name} balance for ${accountId}`);
11+
if (!rbac.check(user.role, 'read:balance')) {
12+
console.error(`[${requestId}] Access denied for ${user.name}`);
13+
return null;
14+
}
15+
console.log(`[${requestId}] Balance for ${user.name}`);
16+
return Promise.resolve(15420.5);
17+
};
18+
19+
// Usage
20+
21+
const rbac = {
22+
permissions: {
23+
admin: ['read:balance'],
24+
user: ['read:balance'],
25+
guest: [],
26+
},
27+
check: (role, permission) => rbac.permissions[role]?.includes(permission),
28+
};
29+
30+
const context = {
31+
console,
32+
rbac,
33+
user: { name: 'Marcus', role: 'admin' },
34+
requestId: 'req-001',
35+
};
36+
37+
asyncLocalStorage.run(context, () => {
38+
console.log('Call: getBalance("ACC-001")');
39+
getBalance('ACC-002').then((result) => {
40+
console.log('Result:', result);
41+
});
42+
});

JavaScript/6-immutable.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict';
2+
3+
const createContext = (base, data = {}) => Object.freeze({ ...base, ...data });
4+
5+
const withUser = (base, user) => createContext(base, { user });
6+
7+
const withRequest = (base, requestId) => createContext(base, { requestId });
8+
9+
const getBalance = (context, accountId) => {
10+
const { console, rbac, user, requestId } = context;
11+
if (!user) {
12+
console.error('No user in context');
13+
return null;
14+
}
15+
console.log(`Request ID: ${requestId}`);
16+
console.log(`User ${user.name} requesting balance for account ${accountId}`);
17+
if (!rbac.check(user.role, 'read:balance')) {
18+
console.error(`Access denied for ${user.name}`);
19+
return null;
20+
}
21+
return 15420.5;
22+
};
23+
24+
// Usage
25+
26+
const rbac = {
27+
permissions: {
28+
admin: ['read:balance'],
29+
user: ['read:balance'],
30+
guest: [],
31+
},
32+
check: (role, permission) => rbac.permissions[role]?.includes(permission),
33+
};
34+
35+
const context1 = createContext({ console, rbac });
36+
console.log('Context 1:', getBalance(context1, 'ACC-002'), '\n');
37+
38+
const context2 = withUser(context1, { name: 'Marcus', role: 'admin' });
39+
console.log('Context 2:', getBalance(context2, 'ACC-002'), '\n');
40+
41+
const context3 = withRequest(context2, 'req-' + Date.now());
42+
console.log('Context 3:', getBalance(context3, 'ACC-002'), '\n');

0 commit comments

Comments
 (0)