@owlmeans/payment 0.1.18-rc.21 → 0.1.18-rc.22
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/README.md +2 -2
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/payment/SKILL.md +2 -2
- package/package.json +11 -11
- package/tests/entitlement.spec.d.ts +2 -0
- package/tests/entitlement.spec.d.ts.map +1 -0
- package/tests/entitlement.spec.js +72 -0
- package/tests/entitlement.spec.js.map +1 -0
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ quantity-priced checkout.
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
bun add @owlmeans/payment@^0.1.18-rc.
|
|
18
|
+
bun add @owlmeans/payment@^0.1.18-rc.22
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
## Usage
|
|
@@ -83,7 +83,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
83
83
|
your project's skill store (`.agents/skills/`):
|
|
84
84
|
|
|
85
85
|
```sh
|
|
86
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
86
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.21
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/payment",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-09-
|
|
4
|
+
"version": "0.1.18-rc.22",
|
|
5
|
+
"generatedAt": "2026-09-15T12:21:31.943Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -8,7 +8,7 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/payment
|
|
9
9
|
|
|
10
10
|
**Layer:** Core
|
|
11
|
-
**Install:** `"@owlmeans/payment": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/payment": "^0.1.18-rc.22"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
The contracts half of payments: the catalogue (products, plans, localizations), the subscription
|
|
14
14
|
record, the entitlement grammar, and the entrypoint declarations both sides of a checkout share. It
|
|
@@ -108,7 +108,7 @@ for framework materialization, never a public compatibility export.
|
|
|
108
108
|
import { paymentApi } from '@owlmeans/payment'
|
|
109
109
|
import { bindAll } from '@owlmeans/client-entrypoint'
|
|
110
110
|
|
|
111
|
-
export const
|
|
111
|
+
export const clientBindings = [...bindAll(paymentApi.service)]
|
|
112
112
|
|
|
113
113
|
const result = await ctx.entrypoint(paymentApi.service.checkout.session.external.create).call({
|
|
114
114
|
body: { productSku, entitySlug, service, amountMinor, successUrl }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/payment",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.22",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -32,16 +32,16 @@
|
|
|
32
32
|
"ajv": "*"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@owlmeans/api-config": "^0.1.18-rc.
|
|
36
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
37
|
-
"@owlmeans/basic-envelope": "^0.1.18-rc.
|
|
38
|
-
"@owlmeans/config": "^0.1.18-rc.
|
|
39
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
40
|
-
"@owlmeans/error": "^0.1.18-rc.
|
|
41
|
-
"@owlmeans/i18n": "^0.1.18-rc.
|
|
42
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
43
|
-
"@owlmeans/resource": "^0.1.18-rc.
|
|
44
|
-
"@owlmeans/route": "^0.1.18-rc.
|
|
35
|
+
"@owlmeans/api-config": "^0.1.18-rc.21",
|
|
36
|
+
"@owlmeans/auth": "^0.1.18-rc.18",
|
|
37
|
+
"@owlmeans/basic-envelope": "^0.1.18-rc.21",
|
|
38
|
+
"@owlmeans/config": "^0.1.18-rc.21",
|
|
39
|
+
"@owlmeans/context": "^0.1.18-rc.17",
|
|
40
|
+
"@owlmeans/error": "^0.1.18-rc.17",
|
|
41
|
+
"@owlmeans/i18n": "^0.1.18-rc.17",
|
|
42
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.20",
|
|
43
|
+
"@owlmeans/resource": "^0.1.18-rc.18",
|
|
44
|
+
"@owlmeans/route": "^0.1.18-rc.18"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@owlmeans/dep-config": "workspace:*",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entitlement.spec.d.ts","sourceRoot":"","sources":["entitlement.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { describe, test, expect } from 'bun:test';
|
|
2
|
+
import { CAPABILITY_FEATURE_SCOPE, entitlementList, formatEntitlementParam, hasEntitlement, parseEntitlementParam, } from '../src/entitlement.js';
|
|
3
|
+
const pro = [
|
|
4
|
+
{ scope: 'renewable', permissions: { production: 1, credits: 5000 } },
|
|
5
|
+
{ scope: CAPABILITY_FEATURE_SCOPE, permissions: { 'branding--whitelabel': true, 'domain--custom': true } },
|
|
6
|
+
];
|
|
7
|
+
describe('the parameter grammar', () => {
|
|
8
|
+
test('a bare permission has no scope and no floor', () => {
|
|
9
|
+
expect(parseEntitlementParam('domain--custom')).toEqual({ permission: 'domain--custom' });
|
|
10
|
+
});
|
|
11
|
+
test('a scope is everything before the first colon', () => {
|
|
12
|
+
expect(parseEntitlementParam('feature:branding--whitelabel'))
|
|
13
|
+
.toEqual({ scope: 'feature', permission: 'branding--whitelabel' });
|
|
14
|
+
});
|
|
15
|
+
test('a floor is parsed as a number', () => {
|
|
16
|
+
expect(parseEntitlementParam('renewable:credits>=100'))
|
|
17
|
+
.toEqual({ scope: 'renewable', permission: 'credits', atLeast: 100 });
|
|
18
|
+
});
|
|
19
|
+
test('formatting round-trips', () => {
|
|
20
|
+
for (const param of ['domain--custom', 'feature:branding--whitelabel', 'renewable:credits>=100']) {
|
|
21
|
+
expect(formatEntitlementParam(parseEntitlementParam(param))).toBe(param);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
describe('the predicate', () => {
|
|
26
|
+
test('a held feature passes', () => {
|
|
27
|
+
expect(hasEntitlement(pro, 'feature:branding--whitelabel')).toBe(true);
|
|
28
|
+
});
|
|
29
|
+
test('a feature nobody granted does not', () => {
|
|
30
|
+
expect(hasEntitlement(pro, 'feature:branding--nonexistent')).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
test('a scope that does not match is not consulted', () => {
|
|
33
|
+
expect(hasEntitlement(pro, 'renewable:branding--whitelabel')).toBe(false);
|
|
34
|
+
// …and without a scope, any set may answer.
|
|
35
|
+
expect(hasEntitlement(pro, 'branding--whitelabel')).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
test('a numeric floor compares', () => {
|
|
38
|
+
expect(hasEntitlement(pro, 'renewable:credits>=5000')).toBe(true);
|
|
39
|
+
expect(hasEntitlement(pro, 'renewable:credits>=5001')).toBe(false);
|
|
40
|
+
});
|
|
41
|
+
test('a boolean cannot satisfy a numeric floor', () => {
|
|
42
|
+
expect(hasEntitlement(pro, 'feature:branding--whitelabel>=1')).toBe(false);
|
|
43
|
+
});
|
|
44
|
+
test('an explicit false is not a grant', () => {
|
|
45
|
+
expect(hasEntitlement([{ scope: 'feature', permissions: { x: false } }], 'feature:x')).toBe(false);
|
|
46
|
+
expect(hasEntitlement([{ scope: 'feature', permissions: { x: null } }], 'feature:x')).toBe(false);
|
|
47
|
+
});
|
|
48
|
+
test('no capabilities at all is a refusal, never a pass', () => {
|
|
49
|
+
expect(hasEntitlement(undefined, 'feature:branding--whitelabel')).toBe(false);
|
|
50
|
+
expect(hasEntitlement([], 'feature:branding--whitelabel')).toBe(false);
|
|
51
|
+
});
|
|
52
|
+
test('a malformed parameter refuses rather than throwing', () => {
|
|
53
|
+
// A gate that crashed on a typo would take down the endpoint it guards.
|
|
54
|
+
expect(() => hasEntitlement(pro, '')).not.toThrow();
|
|
55
|
+
expect(hasEntitlement(pro, '')).toBe(false);
|
|
56
|
+
expect(hasEntitlement(pro, 'feature:')).toBe(false);
|
|
57
|
+
expect(hasEntitlement(pro, 'renewable:credits>=abc')).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
describe('listing', () => {
|
|
61
|
+
test('unions every granted capability, scoped', () => {
|
|
62
|
+
expect(entitlementList(pro).sort()).toEqual([
|
|
63
|
+
'feature:branding--whitelabel', 'feature:domain--custom',
|
|
64
|
+
'renewable:credits', 'renewable:production',
|
|
65
|
+
]);
|
|
66
|
+
});
|
|
67
|
+
test('skips what is not granted', () => {
|
|
68
|
+
expect(entitlementList([{ scope: 'feature', permissions: { a: true, b: false, c: null } }]))
|
|
69
|
+
.toEqual(['feature:a']);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
//# sourceMappingURL=entitlement.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entitlement.spec.js","sourceRoot":"","sources":["entitlement.spec.ts"],"names":[],"mappings":"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"}
|