@owlmeans/server-job 0.1.18-rc.2 → 0.1.18-rc.21

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 (62) hide show
  1. package/README.md +36 -86
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/server-job/SKILL.md +60 -107
  4. package/build/actions/cancel.d.ts +3 -4
  5. package/build/actions/cancel.d.ts.map +1 -1
  6. package/build/actions/cancel.js +11 -6
  7. package/build/actions/cancel.js.map +1 -1
  8. package/build/actions/get.d.ts +3 -4
  9. package/build/actions/get.d.ts.map +1 -1
  10. package/build/actions/get.js +6 -4
  11. package/build/actions/get.js.map +1 -1
  12. package/build/actions/list.d.ts +3 -4
  13. package/build/actions/list.d.ts.map +1 -1
  14. package/build/actions/list.js +10 -12
  15. package/build/actions/list.js.map +1 -1
  16. package/build/actions/watch.d.ts +5 -6
  17. package/build/actions/watch.d.ts.map +1 -1
  18. package/build/actions/watch.js +21 -20
  19. package/build/actions/watch.js.map +1 -1
  20. package/build/entrypoints.d.ts +3 -4
  21. package/build/entrypoints.d.ts.map +1 -1
  22. package/build/entrypoints.js +10 -10
  23. package/build/entrypoints.js.map +1 -1
  24. package/build/helper.d.ts +3 -5
  25. package/build/helper.d.ts.map +1 -1
  26. package/build/helper.js +9 -11
  27. package/build/helper.js.map +1 -1
  28. package/build/index.d.ts +0 -3
  29. package/build/index.d.ts.map +1 -1
  30. package/build/index.js +0 -3
  31. package/build/index.js.map +1 -1
  32. package/build/types.d.ts +18 -46
  33. package/build/types.d.ts.map +1 -1
  34. package/build/utils/index.d.ts +2 -2
  35. package/build/utils/index.d.ts.map +1 -1
  36. package/build/utils/index.js +2 -2
  37. package/build/utils/index.js.map +1 -1
  38. package/build/utils/policy.d.ts +7 -0
  39. package/build/utils/policy.d.ts.map +1 -0
  40. package/build/utils/policy.js +10 -0
  41. package/build/utils/policy.js.map +1 -0
  42. package/build/utils/view.d.ts +18 -0
  43. package/build/utils/view.d.ts.map +1 -0
  44. package/build/utils/view.js +94 -0
  45. package/build/utils/view.js.map +1 -0
  46. package/package.json +17 -14
  47. package/src/actions/cancel.ts +15 -12
  48. package/src/actions/get.ts +10 -10
  49. package/src/actions/list.ts +15 -21
  50. package/src/actions/watch.ts +24 -25
  51. package/src/helper.ts +10 -18
  52. package/src/index.ts +0 -3
  53. package/src/types.ts +21 -48
  54. package/src/utils/index.ts +2 -2
  55. package/src/utils/policy.ts +20 -0
  56. package/src/utils/view.ts +102 -0
  57. package/tests/view.spec.ts +55 -0
  58. package/src/consts.ts +0 -28
  59. package/src/entrypoints.ts +0 -56
  60. package/src/schemas.ts +0 -19
  61. package/src/utils/owner.ts +0 -60
  62. package/src/utils/resource.ts +0 -40
@@ -1,60 +0,0 @@
1
- import type { BasicConfig, BasicContext } from '@owlmeans/context'
2
- import type { AbstractRequest } from '@owlmeans/entrypoint'
3
- import { AuthorizationError } from '@owlmeans/auth'
4
- import type { Criteria } from '@owlmeans/resource'
5
- import type { JobRecord } from '@owlmeans/queue'
6
- import { DEFAULT_OWNER_FIELD } from '../consts.js'
7
- import type { JobHandlerOptions } from '../types.js'
8
-
9
- /**
10
- * The subject a job is attributed to.
11
- *
12
- * Profile first, user second — the same pair `@owlmeans/server-socket` addresses a connection by,
13
- * so a job enqueued for one profile of a multi-profile account is not visible to the others.
14
- */
15
- export const jobOwnerOf = (req: AbstractRequest): string | undefined =>
16
- req.auth?.profileId ?? req.auth?.userId
17
-
18
- /**
19
- * @throws {AuthorizationError} when the request carries no authenticated subject.
20
- */
21
- export const requireJobOwner = (req: AbstractRequest): string => {
22
- const owner = jobOwnerOf(req)
23
- if (owner == null || owner === '') {
24
- throw new AuthorizationError()
25
- }
26
-
27
- return owner
28
- }
29
-
30
- export const ownerFieldOf = (opts?: JobHandlerOptions): string =>
31
- opts?.ownerField ?? DEFAULT_OWNER_FIELD
32
-
33
- /** What one record says its owner is — the payload's own field, never a broker one. */
34
- export const ownerOf = (record: JobRecord, opts?: JobHandlerOptions): unknown =>
35
- (record.data as Record<string, unknown> | undefined)?.[ownerFieldOf(opts)]
36
-
37
- /**
38
- * Who this request reads the queue as: the owner every record must name, or `undefined` for a
39
- * request that reads it unscoped.
40
- *
41
- * `undefined` is reachable only through {@link JobHandlerOptions.admin}. Absent an admin check
42
- * every read is narrowed to the caller's own jobs and an anonymous request is refused, so a group
43
- * wired with no options at all is scoped rather than open.
44
- *
45
- * @throws {AuthorizationError}
46
- */
47
- export const jobViewer = async <C extends BasicConfig, T extends BasicContext<C>>(
48
- req: AbstractRequest, ctx: T, opts?: JobHandlerOptions
49
- ): Promise<string | undefined> => {
50
- if (opts?.admin != null && await opts.admin(req, ctx as BasicContext<BasicConfig>)) {
51
- return undefined
52
- }
53
-
54
- return requireJobOwner(req)
55
- }
56
-
57
- /** The criteria one viewer reads the queue through; nothing to add when they read it unscoped. */
58
- export const jobScope = (
59
- viewer: string | undefined, opts?: JobHandlerOptions
60
- ): Criteria<JobRecord> => viewer == null ? {} : { [`data.${ownerFieldOf(opts)}`]: viewer }
@@ -1,40 +0,0 @@
1
- import type { BasicConfig, BasicContext } from '@owlmeans/context'
2
- import type { JobRecord, QueueResource } from '@owlmeans/queue'
3
- import { UnknownJob } from '@owlmeans/queue'
4
- import type { Context, JobHandlerOptions } from '../types.js'
5
- import { ownerOf } from './owner.js'
6
-
7
- /**
8
- * The queue these handlers read.
9
- *
10
- * Named by the declaration or, with nothing named, the context's sole declared queue — which
11
- * `ctx.jobs()` refuses to guess once a second queue exists, so an app that grows one is told to
12
- * name it rather than quietly served the wrong backlog.
13
- */
14
- export const jobsOf = <D = unknown, R = unknown>(
15
- ctx: BasicContext<BasicConfig>, opts?: JobHandlerOptions
16
- ): QueueResource<D, R> => (ctx as unknown as Context).jobs<D, R>(opts?.queue)
17
-
18
- /** Does this viewer own that record? An unscoped viewer (`undefined`) owns everything. */
19
- export const owns = (
20
- record: JobRecord, viewer: string | undefined, opts?: JobHandlerOptions
21
- ): boolean => viewer == null || ownerOf(record, opts) === viewer
22
-
23
- /**
24
- * One job, as this viewer is allowed to see it.
25
- *
26
- * A job that exists but belongs to someone else answers exactly as an absent one does: telling an
27
- * unauthorized caller apart from a wrong id is what turns an id space into an enumeration oracle.
28
- *
29
- * @throws {UnknownJob}
30
- */
31
- export const readOwnedJob = async <D = unknown, R = unknown>(
32
- resource: QueueResource<D, R>, id: string, viewer: string | undefined, opts?: JobHandlerOptions
33
- ): Promise<JobRecord<D, R>> => {
34
- const record = await resource.load(id)
35
- if (record == null || !owns(record, viewer, opts)) {
36
- throw new UnknownJob(`${resource.queue}:${id}`)
37
- }
38
-
39
- return record
40
- }