@jskit-ai/google-rewarded-core 0.1.95 → 0.1.97

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.
Files changed (31) hide show
  1. package/package.json +39 -108
  2. package/src/server/GoogleRewardedCoreProvider.js +29 -41
  3. package/src/server/GoogleRewardedResources.js +69 -0
  4. package/src/server/actions.js +65 -15
  5. package/src/server/registerRoutes.js +3 -5
  6. package/test/featureRuntime.test.js +90 -0
  7. package/test/routes.test.js +1 -10
  8. package/src/server/providerConfigs/GoogleRewardedProviderConfigsProvider.js +0 -98
  9. package/src/server/providerConfigs/actions.js +0 -148
  10. package/src/server/providerConfigs/registerRoutes.js +0 -176
  11. package/src/server/providerConfigs/repository.js +0 -107
  12. package/src/server/providerConfigs/service.js +0 -60
  13. package/src/server/rules/GoogleRewardedRulesProvider.js +0 -98
  14. package/src/server/rules/actions.js +0 -148
  15. package/src/server/rules/registerRoutes.js +0 -176
  16. package/src/server/rules/repository.js +0 -107
  17. package/src/server/rules/service.js +0 -60
  18. package/src/server/unlockReceipts/GoogleRewardedUnlockReceiptsProvider.js +0 -98
  19. package/src/server/unlockReceipts/actions.js +0 -148
  20. package/src/server/unlockReceipts/registerRoutes.js +0 -176
  21. package/src/server/unlockReceipts/repository.js +0 -107
  22. package/src/server/unlockReceipts/service.js +0 -60
  23. package/src/server/watchSessions/GoogleRewardedWatchSessionsProvider.js +0 -98
  24. package/src/server/watchSessions/actions.js +0 -148
  25. package/src/server/watchSessions/registerRoutes.js +0 -176
  26. package/src/server/watchSessions/repository.js +0 -107
  27. package/src/server/watchSessions/service.js +0 -60
  28. /package/{templates/migrations → migrations}/google_rewarded_provider_configs_initial.cjs +0 -0
  29. /package/{templates/migrations → migrations}/google_rewarded_rules_initial.cjs +0 -0
  30. /package/{templates/migrations → migrations}/google_rewarded_unlock_receipts_initial.cjs +0 -0
  31. /package/{templates/migrations → migrations}/google_rewarded_watch_sessions_initial.cjs +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/google-rewarded-core",
3
- "version": "0.1.95",
3
+ "version": "0.1.97",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./shared": "./src/shared/index.js",
@@ -12,41 +12,41 @@
12
12
  "kind": "runtime",
13
13
  "capabilities": {
14
14
  "provides": [
15
- "crud.google-rewarded-rules",
16
- "crud.google-rewarded-provider-configs",
17
- "crud.google-rewarded-watch-sessions",
18
- "crud.google-rewarded-unlock-receipts",
15
+ "google-rewarded.rules",
16
+ "google-rewarded.provider-configs",
17
+ "google-rewarded.watch-sessions",
18
+ "google-rewarded.unlock-receipts",
19
19
  "google-rewarded.core"
20
20
  ],
21
21
  "requires": [
22
22
  "runtime.actions",
23
23
  "runtime.database",
24
- "auth.policy",
25
- "json-rest-api.core"
24
+ "runtime.http",
25
+ "runtime.json-rest-api"
26
26
  ]
27
27
  },
28
28
  "runtime": {
29
29
  "server": {
30
30
  "providers": [
31
31
  {
32
- "entrypoint": "src/server/rules/GoogleRewardedRulesProvider.js",
33
- "export": "GoogleRewardedRulesProvider"
32
+ "entrypoint": "src/server/GoogleRewardedResources.js",
33
+ "export": "GoogleRewardedRulesFeature"
34
34
  },
35
35
  {
36
- "entrypoint": "src/server/providerConfigs/GoogleRewardedProviderConfigsProvider.js",
37
- "export": "GoogleRewardedProviderConfigsProvider"
36
+ "entrypoint": "src/server/GoogleRewardedResources.js",
37
+ "export": "GoogleRewardedProviderConfigsFeature"
38
38
  },
39
39
  {
40
- "entrypoint": "src/server/watchSessions/GoogleRewardedWatchSessionsProvider.js",
41
- "export": "GoogleRewardedWatchSessionsProvider"
40
+ "entrypoint": "src/server/GoogleRewardedResources.js",
41
+ "export": "GoogleRewardedWatchSessionsFeature"
42
42
  },
43
43
  {
44
- "entrypoint": "src/server/unlockReceipts/GoogleRewardedUnlockReceiptsProvider.js",
45
- "export": "GoogleRewardedUnlockReceiptsProvider"
44
+ "entrypoint": "src/server/GoogleRewardedResources.js",
45
+ "export": "GoogleRewardedUnlockReceiptsFeature"
46
46
  },
47
47
  {
48
48
  "entrypoint": "src/server/GoogleRewardedCoreProvider.js",
49
- "export": "GoogleRewardedCoreProvider"
49
+ "export": "GoogleRewardedCoreFeature"
50
50
  }
51
51
  ]
52
52
  },
@@ -56,35 +56,26 @@
56
56
  },
57
57
  "metadata": {
58
58
  "jskit": {
59
- "scaffoldShape": "crud-server-v1",
60
59
  "tableOwnership": {
61
60
  "tables": [
62
61
  {
63
62
  "tableName": "google_rewarded_rules",
64
- "provenance": "crud-server-generator",
65
- "ownerKind": "crud-package",
66
- "providerEntrypoint": "src/server/rules/GoogleRewardedRulesProvider.js",
63
+ "providerEntrypoint": "src/server/GoogleRewardedResources.js",
67
64
  "ownershipFilter": "workspace"
68
65
  },
69
66
  {
70
67
  "tableName": "google_rewarded_provider_configs",
71
- "provenance": "crud-server-generator",
72
- "ownerKind": "crud-package",
73
- "providerEntrypoint": "src/server/providerConfigs/GoogleRewardedProviderConfigsProvider.js",
68
+ "providerEntrypoint": "src/server/GoogleRewardedResources.js",
74
69
  "ownershipFilter": "workspace"
75
70
  },
76
71
  {
77
72
  "tableName": "google_rewarded_watch_sessions",
78
- "provenance": "crud-server-generator",
79
- "ownerKind": "crud-package",
80
- "providerEntrypoint": "src/server/watchSessions/GoogleRewardedWatchSessionsProvider.js",
73
+ "providerEntrypoint": "src/server/GoogleRewardedResources.js",
81
74
  "ownershipFilter": "workspace_user"
82
75
  },
83
76
  {
84
77
  "tableName": "google_rewarded_unlock_receipts",
85
- "provenance": "crud-server-generator",
86
- "ownerKind": "crud-package",
87
- "providerEntrypoint": "src/server/unlockReceipts/GoogleRewardedUnlockReceiptsProvider.js",
78
+ "providerEntrypoint": "src/server/GoogleRewardedResources.js",
88
79
  "ownershipFilter": "workspace_user"
89
80
  }
90
81
  ]
@@ -105,89 +96,29 @@
105
96
  "summary": "Exports the server helper that enforces a rewarded unlock before a protected feature action continues."
106
97
  }
107
98
  ],
108
- "containerTokens": {
109
- "server": [
110
- "repository.google_rewarded_rules",
111
- "crud.google_rewarded_rules",
112
- "repository.google_rewarded_provider_configs",
113
- "crud.google_rewarded_provider_configs",
114
- "repository.google_rewarded_watch_sessions",
115
- "crud.google_rewarded_watch_sessions",
116
- "repository.google_rewarded_unlock_receipts",
117
- "crud.google_rewarded_unlock_receipts",
118
- "google-rewarded.core.service"
119
- ],
120
- "client": []
121
- }
99
+ "capabilities": [
100
+ "google-rewarded.rules",
101
+ "google-rewarded.provider-configs",
102
+ "google-rewarded.watch-sessions",
103
+ "google-rewarded.unlock-receipts",
104
+ "google-rewarded.core"
105
+ ]
122
106
  }
123
107
  },
124
- "mutations": {
125
- "dependencies": {
126
- "runtime": {
127
- "@jskit-ai/auth-core": "0.1.157",
128
- "@jskit-ai/crud-core": "0.1.170",
129
- "@jskit-ai/database-runtime": "0.1.159",
130
- "@jskit-ai/http-runtime": "0.1.157",
131
- "@jskit-ai/json-rest-api-core": "0.1.103",
132
- "@jskit-ai/kernel": "0.1.159",
133
- "@jskit-ai/resource-crud-core": "0.1.101",
134
- "@jskit-ai/workspaces-core": "0.1.137"
135
- },
136
- "dev": {}
137
- },
138
- "packageJson": {
139
- "scripts": {}
140
- },
141
- "procfile": {},
142
- "files": [
143
- {
144
- "op": "install-migration",
145
- "from": "templates/migrations/google_rewarded_rules_initial.cjs",
146
- "toDir": "migrations",
147
- "extension": ".cjs",
148
- "reason": "Install Google rewarded rules schema migration.",
149
- "category": "google-rewarded",
150
- "id": "google-rewarded-rules-initial-schema"
151
- },
152
- {
153
- "op": "install-migration",
154
- "from": "templates/migrations/google_rewarded_provider_configs_initial.cjs",
155
- "toDir": "migrations",
156
- "extension": ".cjs",
157
- "reason": "Install Google rewarded provider config schema migration.",
158
- "category": "google-rewarded",
159
- "id": "google-rewarded-provider-configs-initial-schema"
160
- },
161
- {
162
- "op": "install-migration",
163
- "from": "templates/migrations/google_rewarded_watch_sessions_initial.cjs",
164
- "toDir": "migrations",
165
- "extension": ".cjs",
166
- "reason": "Install Google rewarded watch sessions schema migration.",
167
- "category": "google-rewarded",
168
- "id": "google-rewarded-watch-sessions-initial-schema"
169
- },
170
- {
171
- "op": "install-migration",
172
- "from": "templates/migrations/google_rewarded_unlock_receipts_initial.cjs",
173
- "toDir": "migrations",
174
- "extension": ".cjs",
175
- "reason": "Install Google rewarded unlock receipts schema migration.",
176
- "category": "google-rewarded",
177
- "id": "google-rewarded-unlock-receipts-initial-schema"
178
- }
179
- ],
180
- "text": []
108
+ "migrations": {
109
+ "directories": [
110
+ "migrations"
111
+ ]
181
112
  }
182
113
  },
183
114
  "dependencies": {
184
- "@jskit-ai/auth-core": "0.1.157",
185
- "@jskit-ai/crud-core": "0.1.170",
186
- "@jskit-ai/database-runtime": "0.1.159",
187
- "@jskit-ai/http-runtime": "0.1.157",
188
- "@jskit-ai/json-rest-api-core": "0.1.103",
189
- "@jskit-ai/kernel": "0.1.159",
190
- "@jskit-ai/resource-crud-core": "0.1.101",
191
- "@jskit-ai/workspaces-core": "0.1.137"
115
+ "@jskit-ai/auth-core": "0.1.159",
116
+ "@jskit-ai/crud-core": "0.1.172",
117
+ "@jskit-ai/database-runtime": "0.1.161",
118
+ "@jskit-ai/http-runtime": "0.1.159",
119
+ "@jskit-ai/json-rest-api-core": "0.1.105",
120
+ "@jskit-ai/kernel": "0.1.161",
121
+ "@jskit-ai/resource-crud-core": "0.1.103",
122
+ "@jskit-ai/workspaces-core": "0.1.139"
192
123
  }
193
124
  }
@@ -1,51 +1,39 @@
1
- import { withActionDefaults } from "@jskit-ai/kernel/shared/actions";
1
+ import { defineFeature } from "@jskit-ai/kernel/server/features";
2
2
 
3
3
  import { createService } from "./service.js";
4
- import { googleRewardedActions } from "./actions.js";
4
+ import { createGoogleRewardedActions } from "./actions.js";
5
5
  import { registerRoutes } from "./registerRoutes.js";
6
6
 
7
- class GoogleRewardedCoreProvider {
8
- static id = "google-rewarded.core";
9
-
10
- static startsAfter = ["runtime.actions"];
11
-
12
- register(app) {
13
- if (
14
- !app ||
15
- typeof app.singleton !== "function" ||
16
- typeof app.service !== "function" ||
17
- typeof app.actions !== "function"
18
- ) {
19
- throw new Error("GoogleRewardedCoreProvider requires application singleton()/service()/actions().");
20
- }
21
-
22
- app.service(
23
- "google-rewarded.core.service",
24
- (scope) => createService({
25
- googleRewardedRulesRepository: scope.make("repository.google_rewarded_rules"),
26
- googleRewardedProviderConfigsRepository: scope.make("repository.google_rewarded_provider_configs"),
27
- googleRewardedWatchSessionsRepository: scope.make("repository.google_rewarded_watch_sessions"),
28
- googleRewardedUnlockReceiptsRepository: scope.make("repository.google_rewarded_unlock_receipts")
29
- })
30
- );
31
-
32
- app.actions(
33
- withActionDefaults(googleRewardedActions, {
34
- domain: "google-rewarded",
35
- dependencies: {
36
- googleRewardedService: "google-rewarded.core.service"
37
- }
38
- })
39
- );
40
- }
41
-
42
- boot(app) {
43
- registerRoutes(app, {
7
+ const GoogleRewardedCoreFeature = defineFeature({
8
+ id: "google-rewarded.core",
9
+ domain: "google-rewarded",
10
+ requires: {
11
+ http: "runtime.http",
12
+ providerConfigs: "google-rewarded.provider-configs",
13
+ rules: "google-rewarded.rules",
14
+ unlockReceipts: "google-rewarded.unlock-receipts",
15
+ watchSessions: "google-rewarded.watch-sessions"
16
+ },
17
+ provides: {
18
+ googleRewarded: "google-rewarded.core"
19
+ },
20
+ setup({ http, providerConfigs, rules, unlockReceipts, watchSessions }) {
21
+ const googleRewarded = createService({
22
+ googleRewardedRulesRepository: rules.repository,
23
+ googleRewardedProviderConfigsRepository: providerConfigs.repository,
24
+ googleRewardedWatchSessionsRepository: watchSessions.repository,
25
+ googleRewardedUnlockReceiptsRepository: unlockReceipts.repository
26
+ });
27
+ registerRoutes(http.router, {
44
28
  routeOwnershipFilter: "workspace_user",
45
29
  routeSurface: "app",
46
30
  routeRelativePath: "google-rewarded"
47
31
  });
32
+ return { googleRewarded };
33
+ },
34
+ actions({ googleRewarded }) {
35
+ return createGoogleRewardedActions({ googleRewarded });
48
36
  }
49
- }
37
+ });
50
38
 
51
- export { GoogleRewardedCoreProvider };
39
+ export { GoogleRewardedCoreFeature };
@@ -0,0 +1,69 @@
1
+ import { defineCrudJsonApiFeature } from "@jskit-ai/crud-core/server/defineCrudJsonApiFeature";
2
+ import { routeParamsValidator } from "@jskit-ai/workspaces-core/server/validators/routeParamsValidator";
3
+ import { workspaceSlugParamsValidator } from "@jskit-ai/workspaces-core/server/validators/routeParamsValidator";
4
+ import { buildWorkspaceInputFromRouteParams } from "@jskit-ai/workspaces-core/server/support/workspaceRouteInput";
5
+ import { resource as providerConfigResource } from "../shared/googleRewardedProviderConfigResource.js";
6
+ import { resource as ruleResource } from "../shared/googleRewardedRuleResource.js";
7
+ import { resource as unlockReceiptResource } from "../shared/googleRewardedUnlockReceiptResource.js";
8
+ import { resource as watchSessionResource } from "../shared/googleRewardedWatchSessionResource.js";
9
+
10
+ function workspaceScope() {
11
+ return {
12
+ routeBase: "/w/:workspaceSlug",
13
+ actionInputValidator: workspaceSlugParamsValidator,
14
+ routeParamsValidator,
15
+ inputKeys: ["workspaceSlug"],
16
+ input: (request) => buildWorkspaceInputFromRouteParams(request.input.params)
17
+ };
18
+ }
19
+
20
+ const GoogleRewardedRulesFeature = defineCrudJsonApiFeature({
21
+ id: "google-rewarded.rules",
22
+ capability: "google-rewarded.rules",
23
+ resource: ruleResource,
24
+ surface: "admin",
25
+ ownershipFilter: "workspace",
26
+ relativePath: "/google-rewarded-rules",
27
+ internal: true,
28
+ scope: workspaceScope()
29
+ });
30
+
31
+ const GoogleRewardedProviderConfigsFeature = defineCrudJsonApiFeature({
32
+ id: "google-rewarded.provider-configs",
33
+ capability: "google-rewarded.provider-configs",
34
+ resource: providerConfigResource,
35
+ surface: "admin",
36
+ ownershipFilter: "workspace",
37
+ relativePath: "/google-rewarded-provider-configs",
38
+ internal: true,
39
+ scope: workspaceScope()
40
+ });
41
+
42
+ const GoogleRewardedWatchSessionsFeature = defineCrudJsonApiFeature({
43
+ id: "google-rewarded.watch-sessions",
44
+ capability: "google-rewarded.watch-sessions",
45
+ resource: watchSessionResource,
46
+ surface: "admin",
47
+ ownershipFilter: "workspace_user",
48
+ relativePath: "/google-rewarded-watch-sessions",
49
+ internal: true,
50
+ scope: workspaceScope()
51
+ });
52
+
53
+ const GoogleRewardedUnlockReceiptsFeature = defineCrudJsonApiFeature({
54
+ id: "google-rewarded.unlock-receipts",
55
+ capability: "google-rewarded.unlock-receipts",
56
+ resource: unlockReceiptResource,
57
+ surface: "admin",
58
+ ownershipFilter: "workspace_user",
59
+ relativePath: "/google-rewarded-unlock-receipts",
60
+ internal: true,
61
+ scope: workspaceScope()
62
+ });
63
+
64
+ export {
65
+ GoogleRewardedProviderConfigsFeature,
66
+ GoogleRewardedRulesFeature,
67
+ GoogleRewardedUnlockReceiptsFeature,
68
+ GoogleRewardedWatchSessionsFeature
69
+ };
@@ -8,19 +8,39 @@ import {
8
8
  grantRewardOutputValidator,
9
9
  closeSessionOutputValidator
10
10
  } from "./inputSchemas.js";
11
+ import { createEntityChangedActionEvent } from "@jskit-ai/kernel/server/actions";
12
+ import { resolveCrudRecordChangedEvent } from "@jskit-ai/resource-crud-core/shared/crudNamespaceSupport";
11
13
 
12
14
  const ACTION_CURRENT = "google-rewarded.current.read";
13
15
  const ACTION_START = "google-rewarded.start";
14
16
  const ACTION_GRANT = "google-rewarded.grant";
15
17
  const ACTION_CLOSE = "google-rewarded.close";
16
18
 
17
- const googleRewardedActions = Object.freeze([
19
+ const watchSessionChanged = resolveCrudRecordChangedEvent("google_rewarded_watch_sessions");
20
+ const unlockReceiptChanged = resolveCrudRecordChangedEvent("google_rewarded_unlock_receipts");
21
+
22
+ function changedEvent({ entity, operation, entityId, event }) {
23
+ return createEntityChangedActionEvent({
24
+ source: "google-rewarded",
25
+ entity,
26
+ operation,
27
+ entityId,
28
+ realtime: { event, audience: "event_scope" }
29
+ });
30
+ }
31
+
32
+ function createGoogleRewardedActions({ googleRewarded } = {}) {
33
+ if (!googleRewarded) {
34
+ throw new TypeError("createGoogleRewardedActions requires googleRewarded.");
35
+ }
36
+ return Object.freeze([
18
37
  {
19
38
  id: ACTION_CURRENT,
20
39
  version: 1,
21
40
  kind: "query",
22
41
  channels: ["api", "automation", "internal"],
23
- surfacesFrom: "enabled",
42
+ surfaces: ["app"],
43
+ permission: { require: "authenticated" },
24
44
  input: currentQueryInputValidator,
25
45
  output: currentStateOutputValidator,
26
46
  idempotency: "none",
@@ -28,8 +48,8 @@ const googleRewardedActions = Object.freeze([
28
48
  actionName: ACTION_CURRENT
29
49
  },
30
50
  observability: {},
31
- async execute(input, context, deps) {
32
- return deps.googleRewardedService.getCurrentState(input, {
51
+ async execute(input, context) {
52
+ return googleRewarded.getCurrentState(input, {
33
53
  context
34
54
  });
35
55
  }
@@ -39,7 +59,8 @@ const googleRewardedActions = Object.freeze([
39
59
  version: 1,
40
60
  kind: "command",
41
61
  channels: ["api", "automation", "internal"],
42
- surfacesFrom: "enabled",
62
+ surfaces: ["app"],
63
+ permission: { require: "authenticated" },
43
64
  input: startCommandInputValidator,
44
65
  output: startGateOutputValidator,
45
66
  idempotency: "optional",
@@ -47,8 +68,14 @@ const googleRewardedActions = Object.freeze([
47
68
  actionName: ACTION_START
48
69
  },
49
70
  observability: {},
50
- async execute(input, context, deps) {
51
- return deps.googleRewardedService.startGate(input, {
71
+ events: [changedEvent({
72
+ entity: "watch-session",
73
+ operation: "created",
74
+ entityId: ({ result }) => result?.session?.id,
75
+ event: watchSessionChanged
76
+ })],
77
+ async execute(input, context) {
78
+ return googleRewarded.startGate(input, {
52
79
  context
53
80
  });
54
81
  }
@@ -58,7 +85,8 @@ const googleRewardedActions = Object.freeze([
58
85
  version: 1,
59
86
  kind: "command",
60
87
  channels: ["api", "automation", "internal"],
61
- surfacesFrom: "enabled",
88
+ surfaces: ["app"],
89
+ permission: { require: "authenticated" },
62
90
  input: grantCommandInputValidator,
63
91
  output: grantRewardOutputValidator,
64
92
  idempotency: "optional",
@@ -66,8 +94,22 @@ const googleRewardedActions = Object.freeze([
66
94
  actionName: ACTION_GRANT
67
95
  },
68
96
  observability: {},
69
- async execute(input, context, deps) {
70
- return deps.googleRewardedService.grantReward(input, {
97
+ events: [
98
+ changedEvent({
99
+ entity: "watch-session",
100
+ operation: "updated",
101
+ entityId: ({ result }) => result?.session?.id,
102
+ event: watchSessionChanged
103
+ }),
104
+ changedEvent({
105
+ entity: "unlock-receipt",
106
+ operation: "created",
107
+ entityId: ({ result }) => result?.unlock?.id,
108
+ event: unlockReceiptChanged
109
+ })
110
+ ],
111
+ async execute(input, context) {
112
+ return googleRewarded.grantReward(input, {
71
113
  context
72
114
  });
73
115
  }
@@ -77,7 +119,8 @@ const googleRewardedActions = Object.freeze([
77
119
  version: 1,
78
120
  kind: "command",
79
121
  channels: ["api", "automation", "internal"],
80
- surfacesFrom: "enabled",
122
+ surfaces: ["app"],
123
+ permission: { require: "authenticated" },
81
124
  input: closeCommandInputValidator,
82
125
  output: closeSessionOutputValidator,
83
126
  idempotency: "optional",
@@ -85,18 +128,25 @@ const googleRewardedActions = Object.freeze([
85
128
  actionName: ACTION_CLOSE
86
129
  },
87
130
  observability: {},
88
- async execute(input, context, deps) {
89
- return deps.googleRewardedService.closeSession(input, {
131
+ events: [changedEvent({
132
+ entity: "watch-session",
133
+ operation: "updated",
134
+ entityId: ({ result }) => result?.session?.id,
135
+ event: watchSessionChanged
136
+ })],
137
+ async execute(input, context) {
138
+ return googleRewarded.closeSession(input, {
90
139
  context
91
140
  });
92
141
  }
93
142
  }
94
- ]);
143
+ ]);
144
+ }
95
145
 
96
146
  export {
97
147
  ACTION_CURRENT,
98
148
  ACTION_START,
99
149
  ACTION_GRANT,
100
150
  ACTION_CLOSE,
101
- googleRewardedActions
151
+ createGoogleRewardedActions
102
152
  };
@@ -37,18 +37,16 @@ function createWorkflowResponses(outputValidator) {
37
37
  }
38
38
 
39
39
  function registerRoutes(
40
- app,
40
+ router,
41
41
  {
42
42
  routeOwnershipFilter = "workspace_user",
43
43
  routeSurface = "app",
44
44
  routeRelativePath = "google-rewarded"
45
45
  } = {}
46
46
  ) {
47
- if (!app || typeof app.make !== "function") {
48
- throw new Error("registerRoutes requires application make().");
47
+ if (!router || typeof router.register !== "function") {
48
+ throw new Error("registerRoutes requires an HTTP router.");
49
49
  }
50
-
51
- const router = app.make("jskit.http.router");
52
50
  const normalizedRouteSurface = normalizeSurfaceId(routeSurface);
53
51
  const routeBase = resolveScopedApiBasePath({
54
52
  routeBase: "/w/:workspaceSlug",
@@ -0,0 +1,90 @@
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 { GoogleRewardedCoreFeature } from "../src/server/GoogleRewardedCoreProvider.js";
7
+ import {
8
+ GoogleRewardedProviderConfigsFeature,
9
+ GoogleRewardedRulesFeature,
10
+ GoogleRewardedUnlockReceiptsFeature,
11
+ GoogleRewardedWatchSessionsFeature
12
+ } from "../src/server/GoogleRewardedResources.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("Google rewarded composes standard resource capabilities around one explicit domain feature", async () => {
25
+ const routes = [];
26
+ const resources = {};
27
+ let actions;
28
+ let googleRewarded;
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.database", "runtime.database", { knex }),
38
+ valueProvider("test.http", "runtime.http", {
39
+ router: {
40
+ register(method, path, contract, handler) {
41
+ routes.push({ method, path, contract, handler });
42
+ }
43
+ }
44
+ }),
45
+ valueProvider("test.json-rest-api", "runtime.json-rest-api", {
46
+ resources,
47
+ async addResource(name, config) {
48
+ resources[name] = { config };
49
+ }
50
+ }),
51
+ GoogleRewardedRulesFeature,
52
+ GoogleRewardedProviderConfigsFeature,
53
+ GoogleRewardedWatchSessionsFeature,
54
+ GoogleRewardedUnlockReceiptsFeature,
55
+ GoogleRewardedCoreFeature,
56
+ defineProvider({
57
+ id: "test.observer",
58
+ requires: {
59
+ actionCatalogue: "runtime.actions",
60
+ rewarded: "google-rewarded.core"
61
+ },
62
+ setup(dependencies) {
63
+ actions = dependencies.actionCatalogue;
64
+ googleRewarded = dependencies.rewarded;
65
+ return {};
66
+ }
67
+ })
68
+ ]
69
+ });
70
+
71
+ await runtime.start();
72
+
73
+ const definitions = actions.listDefinitions();
74
+ assert.equal(definitions.length, 24);
75
+ assert.deepEqual(
76
+ definitions.slice(-4).map((entry) => entry.id),
77
+ [
78
+ "google-rewarded.current.read",
79
+ "google-rewarded.start",
80
+ "google-rewarded.grant",
81
+ "google-rewarded.close"
82
+ ]
83
+ );
84
+ assert.ok(definitions.every((entry) => !Object.hasOwn(entry, "dependencies")));
85
+ assert.equal(typeof googleRewarded.getCurrentState, "function");
86
+ assert.equal(routes.length, 24);
87
+ assert.equal(Object.keys(resources).length, 4);
88
+
89
+ await runtime.shutdown();
90
+ });
@@ -35,16 +35,7 @@ function mountRoutes() {
35
35
  }
36
36
  };
37
37
 
38
- const app = {
39
- make(token) {
40
- if (token !== "jskit.http.router") {
41
- throw new Error(`Unexpected token: ${String(token)}`);
42
- }
43
- return router;
44
- }
45
- };
46
-
47
- registerRoutes(app);
38
+ registerRoutes(router);
48
39
  return registeredRoutes;
49
40
  }
50
41