@jskit-ai/rewarded-core 0.1.120

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.
@@ -0,0 +1,95 @@
1
+ import { defineCrudResource } from "@jskit-ai/resource-crud-core/shared/crudResource";
2
+
3
+ const resource = defineCrudResource({
4
+ namespace: "rewarded_provider_configs",
5
+ tableName: "rewarded_provider_configs",
6
+ schema: {
7
+ workspaceId: {
8
+ type: "id",
9
+ required: true,
10
+ search: true,
11
+ hidden: true,
12
+ operations: {}
13
+ },
14
+ surface: {
15
+ type: "string",
16
+ maxLength: 64,
17
+ required: true,
18
+ search: true,
19
+ operations: {
20
+ output: { required: true },
21
+ create: { required: true },
22
+ patch: { required: false }
23
+ }
24
+ },
25
+ enabled: {
26
+ type: "boolean",
27
+ search: true,
28
+ operations: {
29
+ output: { required: true },
30
+ create: { required: false },
31
+ patch: { required: false }
32
+ }
33
+ },
34
+ placement: {
35
+ type: "string",
36
+ maxLength: 255,
37
+ required: true,
38
+ search: true,
39
+ operations: {
40
+ output: { required: true },
41
+ create: { required: true },
42
+ patch: { required: false }
43
+ }
44
+ },
45
+ provider: {
46
+ type: "string",
47
+ maxLength: 64,
48
+ required: true,
49
+ search: true,
50
+ operations: {
51
+ output: { required: true },
52
+ create: { required: true },
53
+ patch: { required: false }
54
+ }
55
+ },
56
+ createdAt: {
57
+ type: "dateTime",
58
+ default: "now()",
59
+ storage: { writeSerializer: "datetime-utc" },
60
+ operations: {
61
+ output: { required: true }
62
+ }
63
+ },
64
+ updatedAt: {
65
+ type: "dateTime",
66
+ default: "now()",
67
+ storage: { writeSerializer: "datetime-utc" },
68
+ operations: {
69
+ output: { required: true }
70
+ }
71
+ },
72
+ },
73
+ searchSchema: {
74
+ id: { type: "id", actualField: "id" },
75
+ q: { type: "string", oneOf: ["surface","placement","provider"], filterOperator: "like", splitBy: " ", matchAll: true },
76
+ },
77
+ defaultSort: ["-createdAt"],
78
+ autofilter: "workspace",
79
+ messages: {
80
+ validation: "Fix invalid values and try again.",
81
+ saveSuccess: "Record saved.",
82
+ saveError: "Unable to save record.",
83
+ deleteSuccess: "Record deleted.",
84
+ deleteError: "Unable to delete record."
85
+ },
86
+ contract: {
87
+ lookup: {
88
+ containerKey: "lookups",
89
+ defaultInclude: "*",
90
+ maxDepth: 3
91
+ }
92
+ }
93
+ });
94
+
95
+ export { resource };
@@ -0,0 +1,136 @@
1
+ import { defineCrudResource } from "@jskit-ai/resource-crud-core/shared/crudResource";
2
+
3
+ const resource = defineCrudResource({
4
+ namespace: "rewarded_rules",
5
+ tableName: "rewarded_rules",
6
+ schema: {
7
+ workspaceId: {
8
+ type: "id",
9
+ required: true,
10
+ search: true,
11
+ hidden: true,
12
+ operations: {}
13
+ },
14
+ gateKey: {
15
+ type: "string",
16
+ maxLength: 120,
17
+ required: true,
18
+ search: true,
19
+ operations: {
20
+ output: { required: true },
21
+ create: { required: true },
22
+ patch: { required: false }
23
+ }
24
+ },
25
+ surface: {
26
+ type: "string",
27
+ maxLength: 64,
28
+ required: true,
29
+ search: true,
30
+ operations: {
31
+ output: { required: true },
32
+ create: { required: true },
33
+ patch: { required: false }
34
+ }
35
+ },
36
+ enabled: {
37
+ type: "boolean",
38
+ search: true,
39
+ operations: {
40
+ output: { required: true },
41
+ create: { required: false },
42
+ patch: { required: false }
43
+ }
44
+ },
45
+ unlockMinutes: {
46
+ type: "integer",
47
+ min: 0,
48
+ search: true,
49
+ operations: {
50
+ output: { required: true },
51
+ create: { required: false },
52
+ patch: { required: false }
53
+ }
54
+ },
55
+ cooldownMinutes: {
56
+ type: "integer",
57
+ min: 0,
58
+ search: true,
59
+ operations: {
60
+ output: { required: true },
61
+ create: { required: false },
62
+ patch: { required: false }
63
+ }
64
+ },
65
+ dailyLimit: {
66
+ type: "integer",
67
+ min: 0,
68
+ nullable: true,
69
+ search: true,
70
+ operations: {
71
+ output: { required: true },
72
+ create: { required: false },
73
+ patch: { required: false }
74
+ }
75
+ },
76
+ title: {
77
+ type: "string",
78
+ maxLength: 160,
79
+ search: true,
80
+ operations: {
81
+ output: { required: true },
82
+ create: { required: false },
83
+ patch: { required: false }
84
+ }
85
+ },
86
+ description: {
87
+ type: "string",
88
+ maxLength: 65535,
89
+ nullable: true,
90
+ search: true,
91
+ operations: {
92
+ output: { required: true },
93
+ create: { required: false },
94
+ patch: { required: false }
95
+ }
96
+ },
97
+ createdAt: {
98
+ type: "dateTime",
99
+ default: "now()",
100
+ storage: { writeSerializer: "datetime-utc" },
101
+ operations: {
102
+ output: { required: true }
103
+ }
104
+ },
105
+ updatedAt: {
106
+ type: "dateTime",
107
+ default: "now()",
108
+ storage: { writeSerializer: "datetime-utc" },
109
+ operations: {
110
+ output: { required: true }
111
+ }
112
+ },
113
+ },
114
+ searchSchema: {
115
+ id: { type: "id", actualField: "id" },
116
+ q: { type: "string", oneOf: ["gateKey","surface","title","description"], filterOperator: "like", splitBy: " ", matchAll: true },
117
+ },
118
+ defaultSort: ["-createdAt"],
119
+ autofilter: "workspace",
120
+ messages: {
121
+ validation: "Fix invalid values and try again.",
122
+ saveSuccess: "Record saved.",
123
+ saveError: "Unable to save record.",
124
+ deleteSuccess: "Record deleted.",
125
+ deleteError: "Unable to delete record."
126
+ },
127
+ contract: {
128
+ lookup: {
129
+ containerKey: "lookups",
130
+ defaultInclude: "*",
131
+ maxDepth: 3
132
+ }
133
+ }
134
+ });
135
+
136
+ export { resource };
@@ -0,0 +1,113 @@
1
+ import { defineCrudResource } from "@jskit-ai/resource-crud-core/shared/crudResource";
2
+
3
+ const resource = defineCrudResource({
4
+ namespace: "rewarded_unlock_receipts",
5
+ tableName: "rewarded_unlock_receipts",
6
+ schema: {
7
+ workspaceId: {
8
+ type: "id",
9
+ required: true,
10
+ search: true,
11
+ hidden: true,
12
+ operations: {}
13
+ },
14
+ userId: {
15
+ type: "id",
16
+ required: true,
17
+ search: true,
18
+ hidden: true,
19
+ operations: {}
20
+ },
21
+ gateKey: {
22
+ type: "string",
23
+ maxLength: 120,
24
+ required: true,
25
+ search: true,
26
+ operations: {
27
+ output: { required: true },
28
+ create: { required: true },
29
+ patch: { required: false }
30
+ }
31
+ },
32
+ providerConfigId: {
33
+ type: "id",
34
+ nullable: true,
35
+ search: true,
36
+ relation: { kind: "lookup", namespace: "rewarded-provider-configs", valueKey: "id" },
37
+ belongsTo: "rewardedProviderConfigs",
38
+ as: "providerConfig",
39
+ ui: { formControl: "autocomplete" },
40
+ operations: {
41
+ output: { required: true },
42
+ create: { required: false },
43
+ patch: { required: false }
44
+ }
45
+ },
46
+ watchSessionId: {
47
+ type: "id",
48
+ nullable: true,
49
+ search: true,
50
+ relation: { kind: "lookup", namespace: "rewarded-watch-sessions", valueKey: "id" },
51
+ belongsTo: "rewardedWatchSessions",
52
+ as: "watchSession",
53
+ ui: { formControl: "autocomplete" },
54
+ operations: {
55
+ output: { required: true },
56
+ create: { required: false },
57
+ patch: { required: false }
58
+ }
59
+ },
60
+ grantedAt: {
61
+ type: "dateTime",
62
+ default: "now()",
63
+ search: true,
64
+ storage: { writeSerializer: "datetime-utc" },
65
+ operations: {
66
+ output: { required: true },
67
+ create: { required: false },
68
+ patch: { required: false }
69
+ }
70
+ },
71
+ unlockedUntil: {
72
+ type: "dateTime",
73
+ required: true,
74
+ search: true,
75
+ storage: { writeSerializer: "datetime-utc" },
76
+ operations: {
77
+ output: { required: true },
78
+ create: { required: true },
79
+ patch: { required: false }
80
+ }
81
+ },
82
+ createdAt: {
83
+ type: "dateTime",
84
+ default: "now()",
85
+ storage: { writeSerializer: "datetime-utc" },
86
+ operations: {
87
+ output: { required: true }
88
+ }
89
+ },
90
+ },
91
+ searchSchema: {
92
+ id: { type: "id", actualField: "id" },
93
+ q: { type: "string", oneOf: ["gateKey"], filterOperator: "like", splitBy: " ", matchAll: true },
94
+ },
95
+ defaultSort: ["-createdAt"],
96
+ autofilter: "workspace_user",
97
+ messages: {
98
+ validation: "Fix invalid values and try again.",
99
+ saveSuccess: "Record saved.",
100
+ saveError: "Unable to save record.",
101
+ deleteSuccess: "Record deleted.",
102
+ deleteError: "Unable to delete record."
103
+ },
104
+ contract: {
105
+ lookup: {
106
+ containerKey: "lookups",
107
+ defaultInclude: "*",
108
+ maxDepth: 3
109
+ }
110
+ }
111
+ });
112
+
113
+ export { resource };
@@ -0,0 +1,139 @@
1
+ import { defineCrudResource } from "@jskit-ai/resource-crud-core/shared/crudResource";
2
+
3
+ const resource = defineCrudResource({
4
+ namespace: "rewarded_watch_sessions",
5
+ tableName: "rewarded_watch_sessions",
6
+ schema: {
7
+ workspaceId: {
8
+ type: "id",
9
+ required: true,
10
+ search: true,
11
+ hidden: true,
12
+ operations: {}
13
+ },
14
+ userId: {
15
+ type: "id",
16
+ required: true,
17
+ search: true,
18
+ hidden: true,
19
+ operations: {}
20
+ },
21
+ gateKey: {
22
+ type: "string",
23
+ maxLength: 120,
24
+ required: true,
25
+ search: true,
26
+ operations: {
27
+ output: { required: true },
28
+ create: { required: true },
29
+ patch: { required: false }
30
+ }
31
+ },
32
+ providerConfigId: {
33
+ type: "id",
34
+ nullable: true,
35
+ search: true,
36
+ relation: { kind: "lookup", namespace: "rewarded-provider-configs", valueKey: "id" },
37
+ belongsTo: "rewardedProviderConfigs",
38
+ as: "providerConfig",
39
+ ui: { formControl: "autocomplete" },
40
+ operations: {
41
+ output: { required: true },
42
+ create: { required: false },
43
+ patch: { required: false }
44
+ }
45
+ },
46
+ status: {
47
+ type: "string",
48
+ maxLength: 32,
49
+ search: true,
50
+ operations: {
51
+ output: { required: true },
52
+ create: { required: false },
53
+ patch: { required: false }
54
+ }
55
+ },
56
+ startedAt: {
57
+ type: "dateTime",
58
+ default: "now()",
59
+ search: true,
60
+ storage: { writeSerializer: "datetime-utc" },
61
+ operations: {
62
+ output: { required: true },
63
+ create: { required: false },
64
+ patch: { required: false }
65
+ }
66
+ },
67
+ rewardedAt: {
68
+ type: "dateTime",
69
+ nullable: true,
70
+ search: true,
71
+ storage: { writeSerializer: "datetime-utc" },
72
+ operations: {
73
+ output: { required: true },
74
+ create: { required: false },
75
+ patch: { required: false }
76
+ }
77
+ },
78
+ completedAt: {
79
+ type: "dateTime",
80
+ nullable: true,
81
+ search: true,
82
+ storage: { writeSerializer: "datetime-utc" },
83
+ operations: {
84
+ output: { required: true },
85
+ create: { required: false },
86
+ patch: { required: false }
87
+ }
88
+ },
89
+ closedAt: {
90
+ type: "dateTime",
91
+ nullable: true,
92
+ search: true,
93
+ storage: { writeSerializer: "datetime-utc" },
94
+ operations: {
95
+ output: { required: true },
96
+ create: { required: false },
97
+ patch: { required: false }
98
+ }
99
+ },
100
+ createdAt: {
101
+ type: "dateTime",
102
+ default: "now()",
103
+ storage: { writeSerializer: "datetime-utc" },
104
+ operations: {
105
+ output: { required: true }
106
+ }
107
+ },
108
+ updatedAt: {
109
+ type: "dateTime",
110
+ default: "now()",
111
+ storage: { writeSerializer: "datetime-utc" },
112
+ operations: {
113
+ output: { required: true }
114
+ }
115
+ },
116
+ },
117
+ searchSchema: {
118
+ id: { type: "id", actualField: "id" },
119
+ q: { type: "string", oneOf: ["gateKey","status"], filterOperator: "like", splitBy: " ", matchAll: true },
120
+ },
121
+ defaultSort: ["-createdAt"],
122
+ autofilter: "workspace_user",
123
+ messages: {
124
+ validation: "Fix invalid values and try again.",
125
+ saveSuccess: "Record saved.",
126
+ saveError: "Unable to save record.",
127
+ deleteSuccess: "Record deleted.",
128
+ deleteError: "Unable to delete record."
129
+ },
130
+ contract: {
131
+ lookup: {
132
+ containerKey: "lookups",
133
+ defaultInclude: "*",
134
+ maxDepth: 3
135
+ }
136
+ }
137
+ });
138
+
139
+ export { resource };
@@ -0,0 +1,91 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { createActionProvider } from "@jskit-ai/kernel/server/actions";
5
+ import { createCapabilityRuntime, defineProvider } from "@jskit-ai/kernel/shared/capabilities";
6
+ import { RewardedCoreFeature } from "../src/server/RewardedCoreProvider.js";
7
+ import {
8
+ RewardedProviderConfigsFeature,
9
+ RewardedRulesFeature,
10
+ RewardedUnlockReceiptsFeature,
11
+ RewardedWatchSessionsFeature
12
+ } from "../src/server/RewardedResources.js";
13
+
14
+ function valueProvider(id, capability, value) {
15
+ return defineProvider({
16
+ id,
17
+ provides: { value: capability },
18
+ setup() {
19
+ return { value };
20
+ }
21
+ });
22
+ }
23
+
24
+ test("Rewarded composes standard resource capabilities around one explicit domain feature", async () => {
25
+ const routes = [];
26
+ const resources = {};
27
+ let actions;
28
+ let rewarded;
29
+ const knex = Object.assign(() => {}, {
30
+ async transaction(callback) {
31
+ return callback({});
32
+ }
33
+ });
34
+ const runtime = createCapabilityRuntime({
35
+ providers: [
36
+ createActionProvider(),
37
+ valueProvider("test.grant-policy", "rewarded.grant-policy", { authorizeGrant: async () => false }),
38
+ valueProvider("test.database", "runtime.database", { knex }),
39
+ valueProvider("test.http", "runtime.http", {
40
+ router: {
41
+ register(method, path, contract, handler) {
42
+ routes.push({ method, path, contract, handler });
43
+ }
44
+ }
45
+ }),
46
+ valueProvider("test.json-rest-api", "runtime.json-rest-api", {
47
+ resources,
48
+ async addResource(name, config) {
49
+ resources[name] = { config };
50
+ }
51
+ }),
52
+ RewardedRulesFeature,
53
+ RewardedProviderConfigsFeature,
54
+ RewardedWatchSessionsFeature,
55
+ RewardedUnlockReceiptsFeature,
56
+ RewardedCoreFeature,
57
+ defineProvider({
58
+ id: "test.observer",
59
+ requires: {
60
+ actionCatalogue: "runtime.actions",
61
+ rewarded: "rewarded.core"
62
+ },
63
+ setup(dependencies) {
64
+ actions = dependencies.actionCatalogue;
65
+ rewarded = dependencies.rewarded;
66
+ return {};
67
+ }
68
+ })
69
+ ]
70
+ });
71
+
72
+ await runtime.start();
73
+
74
+ const definitions = actions.listDefinitions();
75
+ assert.equal(definitions.length, 24);
76
+ assert.deepEqual(
77
+ definitions.slice(-4).map((entry) => entry.id),
78
+ [
79
+ "rewarded.current.read",
80
+ "rewarded.start",
81
+ "rewarded.grant",
82
+ "rewarded.close"
83
+ ]
84
+ );
85
+ assert.ok(definitions.every((entry) => !Object.hasOwn(entry, "dependencies")));
86
+ assert.equal(typeof rewarded.getCurrentState, "function");
87
+ assert.equal(routes.length, 24);
88
+ assert.equal(Object.keys(resources).length, 4);
89
+
90
+ await runtime.shutdown();
91
+ });