@tracearr/shared 2.2.0-beta.2 → 2.2.0-beta.3

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 (84) hide show
  1. package/dist/automations/__tests__/actions.test.d.ts +2 -0
  2. package/dist/automations/__tests__/actions.test.d.ts.map +1 -0
  3. package/dist/automations/__tests__/actions.test.js +68 -0
  4. package/dist/automations/__tests__/actions.test.js.map +1 -0
  5. package/dist/automations/__tests__/conditions.test.d.ts +2 -0
  6. package/dist/automations/__tests__/conditions.test.d.ts.map +1 -0
  7. package/dist/automations/__tests__/conditions.test.js +55 -0
  8. package/dist/automations/__tests__/conditions.test.js.map +1 -0
  9. package/dist/automations/__tests__/definition.test.d.ts +2 -0
  10. package/dist/automations/__tests__/definition.test.d.ts.map +1 -0
  11. package/dist/automations/__tests__/definition.test.js +376 -0
  12. package/dist/automations/__tests__/definition.test.js.map +1 -0
  13. package/dist/automations/__tests__/share.test.d.ts +2 -0
  14. package/dist/automations/__tests__/share.test.d.ts.map +1 -0
  15. package/dist/automations/__tests__/share.test.js +98 -0
  16. package/dist/automations/__tests__/share.test.js.map +1 -0
  17. package/dist/automations/__tests__/templates.test.d.ts +2 -0
  18. package/dist/automations/__tests__/templates.test.d.ts.map +1 -0
  19. package/dist/automations/__tests__/templates.test.js +278 -0
  20. package/dist/automations/__tests__/templates.test.js.map +1 -0
  21. package/dist/automations/__tests__/triggers.test.d.ts +2 -0
  22. package/dist/automations/__tests__/triggers.test.d.ts.map +1 -0
  23. package/dist/automations/__tests__/triggers.test.js +42 -0
  24. package/dist/automations/__tests__/triggers.test.js.map +1 -0
  25. package/dist/automations/actions.d.ts +783 -0
  26. package/dist/automations/actions.d.ts.map +1 -0
  27. package/dist/automations/actions.js +97 -0
  28. package/dist/automations/actions.js.map +1 -0
  29. package/dist/automations/conditions.d.ts +459 -0
  30. package/dist/automations/conditions.d.ts.map +1 -0
  31. package/dist/automations/conditions.js +460 -0
  32. package/dist/automations/conditions.js.map +1 -0
  33. package/dist/automations/definition.d.ts +1389 -0
  34. package/dist/automations/definition.d.ts.map +1 -0
  35. package/dist/automations/definition.js +215 -0
  36. package/dist/automations/definition.js.map +1 -0
  37. package/dist/automations/dryRun.d.ts +413 -0
  38. package/dist/automations/dryRun.d.ts.map +1 -0
  39. package/dist/automations/dryRun.js +9 -0
  40. package/dist/automations/dryRun.js.map +1 -0
  41. package/dist/automations/index.d.ts +8 -0
  42. package/dist/automations/index.d.ts.map +1 -0
  43. package/dist/automations/index.js +8 -0
  44. package/dist/automations/index.js.map +1 -0
  45. package/dist/automations/share.d.ts +27 -0
  46. package/dist/automations/share.d.ts.map +1 -0
  47. package/dist/automations/share.js +119 -0
  48. package/dist/automations/share.js.map +1 -0
  49. package/dist/automations/templates.d.ts +1304 -0
  50. package/dist/automations/templates.d.ts.map +1 -0
  51. package/dist/automations/templates.js +525 -0
  52. package/dist/automations/templates.js.map +1 -0
  53. package/dist/automations/triggers.d.ts +141 -0
  54. package/dist/automations/triggers.d.ts.map +1 -0
  55. package/dist/automations/triggers.js +172 -0
  56. package/dist/automations/triggers.js.map +1 -0
  57. package/dist/constants.d.ts +22 -40
  58. package/dist/constants.d.ts.map +1 -1
  59. package/dist/constants.js +25 -56
  60. package/dist/constants.js.map +1 -1
  61. package/dist/destinations.d.ts +21 -22
  62. package/dist/destinations.d.ts.map +1 -1
  63. package/dist/destinations.js +13 -2
  64. package/dist/destinations.js.map +1 -1
  65. package/dist/index.d.ts +10 -5
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +15 -9
  68. package/dist/index.js.map +1 -1
  69. package/dist/listQuery.d.ts +41 -0
  70. package/dist/listQuery.d.ts.map +1 -0
  71. package/dist/listQuery.js +33 -0
  72. package/dist/listQuery.js.map +1 -0
  73. package/dist/schemas.d.ts +152 -832
  74. package/dist/schemas.d.ts.map +1 -1
  75. package/dist/schemas.js +90 -287
  76. package/dist/schemas.js.map +1 -1
  77. package/dist/types.d.ts +51 -137
  78. package/dist/types.d.ts.map +1 -1
  79. package/dist/types.js.map +1 -1
  80. package/dist/violations.d.ts +2 -1
  81. package/dist/violations.d.ts.map +1 -1
  82. package/dist/violations.js +7 -0
  83. package/dist/violations.js.map +1 -1
  84. package/package.json +2 -1
@@ -0,0 +1,141 @@
1
+ import { z } from 'zod';
2
+ export type TriggerContext = 'session' | 'account' | 'media' | 'server' | 'install';
3
+ /** Whether a trigger of this context carries everything `requires` names. */
4
+ export declare function contextSupplies(context: TriggerContext, requires: TriggerContext): boolean;
5
+ /** What a trigger is about, and what the list filters on. */
6
+ export declare const TRIGGER_GROUPS: readonly ["sessions", "accounts", "library", "servers", "updates"];
7
+ export type TriggerGroup = (typeof TRIGGER_GROUPS)[number];
8
+ export declare const TRIGGERS: {
9
+ readonly 'session.started': {
10
+ readonly context: "session";
11
+ readonly group: "sessions";
12
+ readonly variables: readonly ["user.username", "user.identityName", "session.mediaTitle", "session.mediaType", "server.name", "server.type"];
13
+ };
14
+ readonly 'session.stopped': {
15
+ readonly context: "session";
16
+ readonly group: "sessions";
17
+ readonly variables: readonly ["user.username", "user.identityName", "session.mediaTitle", "session.mediaType", "server.name", "server.type", "durationMinutes"];
18
+ };
19
+ readonly 'session.transcode_changed': {
20
+ readonly context: "session";
21
+ readonly group: "sessions";
22
+ readonly variables: readonly ["user.username", "user.identityName", "session.mediaTitle", "session.mediaType", "server.name", "server.type"];
23
+ };
24
+ readonly 'session.paused': {
25
+ readonly context: "session";
26
+ readonly group: "sessions";
27
+ readonly variables: readonly ["user.username", "user.identityName", "session.mediaTitle", "session.mediaType", "server.name", "server.type"];
28
+ };
29
+ readonly 'session.held_for': {
30
+ readonly context: "session";
31
+ readonly group: "sessions";
32
+ readonly variables: readonly ["user.username", "user.identityName", "session.mediaTitle", "session.mediaType", "server.name", "server.type", "minutes"];
33
+ };
34
+ readonly 'account.inactive_for': {
35
+ readonly context: "account";
36
+ readonly group: "accounts";
37
+ readonly variables: readonly ["user.username", "user.identityName", "server.name", "server.type", "days"];
38
+ };
39
+ readonly 'account.new_device': {
40
+ readonly context: "session";
41
+ readonly group: "accounts";
42
+ readonly variables: readonly ["user.username", "user.identityName", "session.mediaTitle", "session.mediaType", "server.name", "server.type", "device.name", "device.platform", "device.product", "device.location"];
43
+ };
44
+ readonly 'account.trust_changed': {
45
+ readonly context: "account";
46
+ readonly group: "accounts";
47
+ readonly variables: readonly ["user.username", "user.identityName", "server.name", "server.type", "trust.previous", "trust.new", "trust.reason"];
48
+ };
49
+ readonly 'media.added': {
50
+ readonly context: "media";
51
+ readonly group: "library";
52
+ readonly variables: readonly ["media.title", "media.type", "media.year", "media.library", "media.server", "server.name", "server.type"];
53
+ };
54
+ readonly 'media.upgraded': {
55
+ readonly context: "media";
56
+ readonly group: "library";
57
+ readonly variables: readonly ["media.title", "media.type", "media.year", "media.library", "media.server", "server.name", "server.type", "media.from.resolution", "media.to.resolution", "media.from.dynamicRange", "media.to.dynamicRange", "media.from.videoCodec", "media.to.videoCodec", "media.from.audioCodec", "media.to.audioCodec", "media.from.audioChannels", "media.to.audioChannels", "media.from.fileSize", "media.to.fileSize"];
58
+ };
59
+ readonly 'server.down': {
60
+ readonly context: "server";
61
+ readonly group: "servers";
62
+ readonly variables: readonly ["server.name", "server.type"];
63
+ };
64
+ readonly 'server.up': {
65
+ readonly context: "server";
66
+ readonly group: "servers";
67
+ readonly variables: readonly ["server.name", "server.type"];
68
+ };
69
+ readonly 'plugin.update_available': {
70
+ readonly context: "server";
71
+ readonly group: "updates";
72
+ readonly variables: readonly ["server.name", "server.type", "installedVersion", "latestVersion", "downloadUrl"];
73
+ };
74
+ readonly 'server.update_available': {
75
+ readonly context: "server";
76
+ readonly group: "updates";
77
+ readonly variables: readonly ["server.name", "server.type", "installedVersion", "latestVersion", "releaseUrl"];
78
+ };
79
+ readonly 'tracearr.update_available': {
80
+ readonly context: "install";
81
+ readonly group: "updates";
82
+ readonly variables: readonly ["current", "latest", "releaseUrl"];
83
+ };
84
+ };
85
+ export type TriggerType = keyof typeof TRIGGERS;
86
+ export declare const TRIGGER_TYPES: TriggerType[];
87
+ /** Triggers a violation is never about: nobody did anything wrong by picking up a new phone. */
88
+ export declare const NOTIFICATION_ONLY_TRIGGERS: readonly ["account.new_device", "account.trust_changed"];
89
+ export declare const heldForParamsSchema: z.ZodObject<{
90
+ minutes: z.ZodNumber;
91
+ measure: z.ZodEnum<{
92
+ current: "current";
93
+ total: "total";
94
+ }>;
95
+ }, z.core.$strict>;
96
+ export declare const inactiveForParamsSchema: z.ZodObject<{
97
+ days: z.ZodNumber;
98
+ }, z.core.$strict>;
99
+ export declare const triggerNodeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
100
+ type: z.ZodEnum<{
101
+ "session.started": "session.started";
102
+ "session.stopped": "session.stopped";
103
+ "session.transcode_changed": "session.transcode_changed";
104
+ "session.paused": "session.paused";
105
+ "account.new_device": "account.new_device";
106
+ "account.trust_changed": "account.trust_changed";
107
+ "media.added": "media.added";
108
+ "media.upgraded": "media.upgraded";
109
+ "server.down": "server.down";
110
+ "server.up": "server.up";
111
+ "plugin.update_available": "plugin.update_available";
112
+ "server.update_available": "server.update_available";
113
+ "tracearr.update_available": "tracearr.update_available";
114
+ }>;
115
+ id: z.ZodUUID;
116
+ enabled: z.ZodBoolean;
117
+ }, z.core.$strict>, z.ZodObject<{
118
+ type: z.ZodLiteral<"session.held_for">;
119
+ params: z.ZodObject<{
120
+ minutes: z.ZodNumber;
121
+ measure: z.ZodEnum<{
122
+ current: "current";
123
+ total: "total";
124
+ }>;
125
+ }, z.core.$strict>;
126
+ id: z.ZodUUID;
127
+ enabled: z.ZodBoolean;
128
+ }, z.core.$strict>, z.ZodObject<{
129
+ type: z.ZodLiteral<"account.inactive_for">;
130
+ params: z.ZodObject<{
131
+ days: z.ZodNumber;
132
+ }, z.core.$strict>;
133
+ id: z.ZodUUID;
134
+ enabled: z.ZodBoolean;
135
+ }, z.core.$strict>], "type">;
136
+ export type TriggerNode = z.infer<typeof triggerNodeSchema>;
137
+ /** The most demanding context every enabled trigger can satisfy; null when nothing is enabled. */
138
+ export declare function contextOf(triggers: readonly TriggerNode[]): TriggerContext | null;
139
+ /** The variables every enabled trigger offers, so a template renders whichever one fired. */
140
+ export declare function variablesFor(triggers: readonly TriggerNode[]): string[];
141
+ //# sourceMappingURL=triggers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../../src/automations/triggers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;AAcpF,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAK1F;AA8CD,6DAA6D;AAC7D,eAAO,MAAM,cAAc,oEAAqE,CAAC;AACjG,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6DpB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,QAAQ,CAAC;AAChD,eAAO,MAAM,aAAa,EAA4B,WAAW,EAAE,CAAC;AAEpE,gGAAgG;AAChG,eAAO,MAAM,0BAA0B,0DAGI,CAAC;AAa5C,eAAO,MAAM,mBAAmB;;;;;;kBAG9B,CAAC;AACH,eAAO,MAAM,uBAAuB;;kBAElC,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAQ5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,kGAAkG;AAClG,wBAAgB,SAAS,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,GAAG,cAAc,GAAG,IAAI,CAQjF;AAED,6FAA6F;AAC7F,wBAAgB,YAAY,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,EAAE,CAOvE"}
@@ -0,0 +1,172 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * What each context sits under. `media` names a server and no account, so the
4
+ * contexts are a tree rather than a line and `install` is its root.
5
+ */
6
+ const TRIGGER_CONTEXT_PARENT = {
7
+ session: 'account',
8
+ account: 'server',
9
+ media: 'server',
10
+ server: 'install',
11
+ install: null,
12
+ };
13
+ /** Whether a trigger of this context carries everything `requires` names. */
14
+ export function contextSupplies(context, requires) {
15
+ for (let at = context; at; at = TRIGGER_CONTEXT_PARENT[at]) {
16
+ if (at === requires)
17
+ return true;
18
+ }
19
+ return false;
20
+ }
21
+ /** The narrowest context both supply: their lowest common ancestor in the tree. */
22
+ function meet(a, b) {
23
+ for (let at = b; at; at = TRIGGER_CONTEXT_PARENT[at]) {
24
+ if (contextSupplies(a, at))
25
+ return at;
26
+ }
27
+ // Unreachable: every chain ends at the root, which supplies nothing and is shared.
28
+ return 'install';
29
+ }
30
+ const SESSION_VARS = [
31
+ 'user.username',
32
+ 'user.identityName',
33
+ 'session.mediaTitle',
34
+ 'session.mediaType',
35
+ 'server.name',
36
+ 'server.type',
37
+ ];
38
+ const ACCOUNT_VARS = ['user.username', 'user.identityName', 'server.name', 'server.type'];
39
+ const SERVER_VARS = ['server.name', 'server.type'];
40
+ /** `server.name` doubles `media.server` so an automation that also carries a server trigger keeps one. */
41
+ const MEDIA_VARS = [
42
+ 'media.title',
43
+ 'media.type',
44
+ 'media.year',
45
+ 'media.library',
46
+ 'media.server',
47
+ 'server.name',
48
+ 'server.type',
49
+ ];
50
+ const MEDIA_QUALITY_VARS = [
51
+ 'media.from.resolution',
52
+ 'media.to.resolution',
53
+ 'media.from.dynamicRange',
54
+ 'media.to.dynamicRange',
55
+ 'media.from.videoCodec',
56
+ 'media.to.videoCodec',
57
+ 'media.from.audioCodec',
58
+ 'media.to.audioCodec',
59
+ 'media.from.audioChannels',
60
+ 'media.to.audioChannels',
61
+ 'media.from.fileSize',
62
+ 'media.to.fileSize',
63
+ ];
64
+ /** What a trigger is about, and what the list filters on. */
65
+ export const TRIGGER_GROUPS = ['sessions', 'accounts', 'library', 'servers', 'updates'];
66
+ export const TRIGGERS = {
67
+ 'session.started': { context: 'session', group: 'sessions', variables: SESSION_VARS },
68
+ 'session.stopped': {
69
+ context: 'session',
70
+ group: 'sessions',
71
+ variables: [...SESSION_VARS, 'durationMinutes'],
72
+ },
73
+ 'session.transcode_changed': { context: 'session', group: 'sessions', variables: SESSION_VARS },
74
+ 'session.paused': { context: 'session', group: 'sessions', variables: SESSION_VARS },
75
+ 'session.held_for': {
76
+ context: 'session',
77
+ group: 'sessions',
78
+ variables: [...SESSION_VARS, 'minutes'],
79
+ },
80
+ 'account.inactive_for': {
81
+ context: 'account',
82
+ group: 'accounts',
83
+ variables: [...ACCOUNT_VARS, 'days'],
84
+ },
85
+ 'account.new_device': {
86
+ context: 'session',
87
+ group: 'accounts',
88
+ variables: [
89
+ ...SESSION_VARS,
90
+ 'device.name',
91
+ 'device.platform',
92
+ 'device.product',
93
+ 'device.location',
94
+ ],
95
+ },
96
+ 'account.trust_changed': {
97
+ context: 'account',
98
+ group: 'accounts',
99
+ variables: [...ACCOUNT_VARS, 'trust.previous', 'trust.new', 'trust.reason'],
100
+ },
101
+ 'media.added': { context: 'media', group: 'library', variables: MEDIA_VARS },
102
+ 'media.upgraded': {
103
+ context: 'media',
104
+ group: 'library',
105
+ variables: [...MEDIA_VARS, ...MEDIA_QUALITY_VARS],
106
+ },
107
+ 'server.down': { context: 'server', group: 'servers', variables: SERVER_VARS },
108
+ 'server.up': { context: 'server', group: 'servers', variables: SERVER_VARS },
109
+ 'plugin.update_available': {
110
+ context: 'server',
111
+ group: 'updates',
112
+ variables: [...SERVER_VARS, 'installedVersion', 'latestVersion', 'downloadUrl'],
113
+ },
114
+ 'server.update_available': {
115
+ context: 'server',
116
+ group: 'updates',
117
+ variables: [...SERVER_VARS, 'installedVersion', 'latestVersion', 'releaseUrl'],
118
+ },
119
+ 'tracearr.update_available': {
120
+ context: 'install',
121
+ group: 'updates',
122
+ variables: ['current', 'latest', 'releaseUrl'],
123
+ },
124
+ };
125
+ export const TRIGGER_TYPES = Object.keys(TRIGGERS);
126
+ /** Triggers a violation is never about: nobody did anything wrong by picking up a new phone. */
127
+ export const NOTIFICATION_ONLY_TRIGGERS = [
128
+ 'account.new_device',
129
+ 'account.trust_changed',
130
+ ];
131
+ const PARAMLESS_TRIGGER_TYPES = TRIGGER_TYPES.filter((type) => type !== 'session.held_for' && type !== 'account.inactive_for');
132
+ // z.uuid() rather than schemas.ts's uuidSchema: schemas.ts re-exports this directory's
133
+ // condition and action schemas, and importing back would read the binding before it exists.
134
+ const nodeBase = { id: z.uuid(), enabled: z.boolean() };
135
+ export const heldForParamsSchema = z.strictObject({
136
+ minutes: z.number().int().min(1).max(1440),
137
+ measure: z.enum(['current', 'total']),
138
+ });
139
+ export const inactiveForParamsSchema = z.strictObject({
140
+ days: z.number().int().min(1).max(3650),
141
+ });
142
+ export const triggerNodeSchema = z.discriminatedUnion('type', [
143
+ z.strictObject({ ...nodeBase, type: z.enum(PARAMLESS_TRIGGER_TYPES) }),
144
+ z.strictObject({ ...nodeBase, type: z.literal('session.held_for'), params: heldForParamsSchema }),
145
+ z.strictObject({
146
+ ...nodeBase,
147
+ type: z.literal('account.inactive_for'),
148
+ params: inactiveForParamsSchema,
149
+ }),
150
+ ]);
151
+ /** The most demanding context every enabled trigger can satisfy; null when nothing is enabled. */
152
+ export function contextOf(triggers) {
153
+ let shared = null;
154
+ for (const trigger of triggers) {
155
+ if (!trigger.enabled)
156
+ continue;
157
+ const context = TRIGGERS[trigger.type].context;
158
+ shared = shared === null ? context : meet(shared, context);
159
+ }
160
+ return shared;
161
+ }
162
+ /** The variables every enabled trigger offers, so a template renders whichever one fired. */
163
+ export function variablesFor(triggers) {
164
+ const sets = triggers
165
+ .filter((trigger) => trigger.enabled)
166
+ .map((trigger) => new Set(TRIGGERS[trigger.type].variables));
167
+ const first = sets[0];
168
+ if (!first)
169
+ return [];
170
+ return [...first].filter((variable) => sets.every((set) => set.has(variable)));
171
+ }
172
+ //# sourceMappingURL=triggers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triggers.js","sourceRoot":"","sources":["../../src/automations/triggers.ts"],"names":[],"mappings":"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"}
@@ -2,45 +2,7 @@
2
2
  * Shared constants for Tracearr
3
3
  */
4
4
  import { classifyByDimensions, type ResolutionLabel } from './resolution.js';
5
- export declare const RULE_DEFAULTS: {
6
- readonly impossible_travel: {
7
- readonly maxSpeedKmh: 500;
8
- readonly ignoreVpnRanges: false;
9
- readonly excludePrivateIps: false;
10
- };
11
- readonly simultaneous_locations: {
12
- readonly minDistanceKm: 100;
13
- readonly excludePrivateIps: false;
14
- };
15
- readonly device_velocity: {
16
- readonly maxIps: 5;
17
- readonly windowHours: 24;
18
- readonly excludePrivateIps: false;
19
- readonly groupByDevice: false;
20
- };
21
- readonly concurrent_streams: {
22
- readonly maxStreams: 3;
23
- readonly excludePrivateIps: false;
24
- };
25
- readonly geo_restriction: {
26
- readonly mode: "blocklist";
27
- readonly countries: readonly [];
28
- readonly excludePrivateIps: false;
29
- };
30
- readonly account_inactivity: {
31
- readonly inactivityValue: 30;
32
- readonly inactivityUnit: "days";
33
- };
34
- };
35
- export declare const RULE_DISPLAY_NAMES: {
36
- readonly impossible_travel: "Impossible Travel";
37
- readonly simultaneous_locations: "Simultaneous Locations";
38
- readonly device_velocity: "Device Velocity";
39
- readonly concurrent_streams: "Concurrent Streams";
40
- readonly geo_restriction: "Geo Restriction";
41
- readonly account_inactivity: "Account Inactivity";
42
- };
43
- export declare const IDENTITY_AWARE_CONDITION_FIELDS: readonly ["concurrent_streams", "active_session_distance_km", "travel_speed_kmh", "unique_ips_in_window", "unique_devices_in_window"];
5
+ export { IDENTITY_AWARE_CONDITION_FIELDS } from './automations/conditions.js';
44
6
  export declare const SEVERITY_LEVELS: {
45
7
  readonly low: {
46
8
  readonly label: "Low";
@@ -62,6 +24,7 @@ export declare const WS_EVENTS: {
62
24
  readonly SESSION_STOPPED: "session:stopped";
63
25
  readonly SESSION_UPDATED: "session:updated";
64
26
  readonly VIOLATION_NEW: "violation:new";
27
+ readonly RUN_FINISHED: "run:finished";
65
28
  readonly STATS_UPDATED: "stats:updated";
66
29
  readonly IMPORT_PROGRESS: "import:progress";
67
30
  readonly IMPORT_JELLYSTAT_PROGRESS: "import:jellystat:progress";
@@ -79,6 +42,7 @@ export declare const WS_EVENTS: {
79
42
  readonly SERVER_CONNECTION: "server:connection";
80
43
  readonly NOTIFICATION_TOAST: "notification:toast";
81
44
  readonly DESTINATIONS_CHANGED: "destinations:changed";
45
+ readonly SERVERS_CHANGED: "servers:changed";
82
46
  };
83
47
  /**
84
48
  * Set the global prefix prepended to all Redis keys.
@@ -144,6 +108,9 @@ export declare const REDIS_KEYS: {
144
108
  LIBRARY_SYNC_SHORTFALL: (serverId: string, libraryId: string) => string;
145
109
  LIBRARY_PRECACHE_WATERMARK: (serverId: string) => string;
146
110
  LIBRARY_PRECACHE_LAST_FULL: (serverId: string) => string;
111
+ IMAGE_CACHE_SCHEMA: string;
112
+ IMAGE_CACHE_TALLY: string;
113
+ IMAGE_CACHE_DISK_LIMITED: string;
147
114
  REFRESH_TOKEN: (hash: string) => string;
148
115
  PLEX_TEMP_TOKEN: (token: string) => string;
149
116
  MOBILE_REFRESH_TOKEN: (hash: string) => string;
@@ -154,7 +121,9 @@ export declare const REDIS_KEYS: {
154
121
  SESSION_LOCK: (serverId: string, sessionKey: string) => string;
155
122
  TERMINATION_COOLDOWN: (serverId: string, sessionKey: string, ratingKey: string) => string;
156
123
  TERMINATION_COOLDOWN_COMPOSITE: (serverId: string, serverUserId: string, deviceId: string, ratingKey: string) => string;
157
- RULE_COOLDOWN: (ruleId: string, targetId: string) => string;
124
+ ACTION_COOLDOWN: (automationId: string, targetId: string) => string;
125
+ AUTOMATION_COOLDOWN: (automationId: string, subjectKey: string) => string;
126
+ AUTOMATION_EVALS: (automationId: string) => string;
158
127
  SESSION_WRITE_RETRY: (sessionId: string) => string;
159
128
  readonly SESSION_WRITE_RETRY_SET: string;
160
129
  FILTER_OPTIONS: (userId: string, scopeHash: string) => string;
@@ -204,6 +173,17 @@ export declare const NOTIFICATION_EVENTS: {
204
173
  readonly SERVER_DOWN: "server_down";
205
174
  readonly SERVER_UP: "server_up";
206
175
  readonly PLUGIN_UPDATE_AVAILABLE: "plugin_update_available";
176
+ readonly SERVER_UPDATE_AVAILABLE: "server_update_available";
177
+ readonly TRACEARR_UPDATE_AVAILABLE: "tracearr_update_available";
178
+ readonly MEDIA_ADDED: "media_added";
179
+ readonly MEDIA_UPGRADED: "media_upgraded";
180
+ readonly NEW_DEVICE: "new_device";
181
+ readonly TRUST_SCORE_CHANGED: "trust_score_changed";
182
+ };
183
+ /** The one size a poster is cached at. Every poster URL the server hands out uses it. */
184
+ export declare const POSTER_IMAGE_SIZE: {
185
+ readonly width: 360;
186
+ readonly height: 540;
207
187
  };
208
188
  /**
209
189
  * server_version_key of the placeholder version rows the multi-version
@@ -274,6 +254,8 @@ export declare const UNIT_CONVERSION: {
274
254
  readonly KM_TO_MILES: 0.621371;
275
255
  readonly MILES_TO_KM: 1.60934;
276
256
  };
257
+ /** Base 1024, matching the byte formatter the dashboard renders file sizes with. */
258
+ export declare const BYTES_PER_GB: number;
277
259
  export type UnitSystem = 'metric' | 'imperial';
278
260
  /**
279
261
  * Convert kilometers to miles
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
package/dist/constants.js CHANGED
@@ -2,60 +2,7 @@
2
2
  * Shared constants for Tracearr
3
3
  */
4
4
  import { classifyByDimensions } from './resolution.js';
5
- // Rule type definitions with default parameters
6
- export const RULE_DEFAULTS = {
7
- impossible_travel: {
8
- maxSpeedKmh: 500,
9
- ignoreVpnRanges: false,
10
- excludePrivateIps: false,
11
- },
12
- simultaneous_locations: {
13
- minDistanceKm: 100,
14
- excludePrivateIps: false,
15
- },
16
- device_velocity: {
17
- maxIps: 5,
18
- windowHours: 24,
19
- excludePrivateIps: false,
20
- groupByDevice: false,
21
- },
22
- concurrent_streams: {
23
- maxStreams: 3,
24
- excludePrivateIps: false,
25
- },
26
- geo_restriction: {
27
- mode: 'blocklist',
28
- countries: [],
29
- excludePrivateIps: false,
30
- },
31
- account_inactivity: {
32
- inactivityValue: 30,
33
- inactivityUnit: 'days',
34
- },
35
- };
36
- // Rule type display names
37
- export const RULE_DISPLAY_NAMES = {
38
- impossible_travel: 'Impossible Travel',
39
- simultaneous_locations: 'Simultaneous Locations',
40
- device_velocity: 'Device Velocity',
41
- concurrent_streams: 'Concurrent Streams',
42
- geo_restriction: 'Geo Restriction',
43
- account_inactivity: 'Account Inactivity',
44
- };
45
- // Condition fields whose evaluators are identity-aware (see belongsToIdentity in
46
- // services/rules/evaluators/index.ts): they aggregate across every server_user id
47
- // belonging to the same identity when the evaluation context carries
48
- // identityServerUserIds. The UI (RuleBuilder) offers enforceAcrossServers as soon
49
- // as ANY condition on the rule uses a field from this set, not only when every
50
- // field does - one identity-aware condition is enough for cross-server action
51
- // reach to make sense for the rule as a whole.
52
- export const IDENTITY_AWARE_CONDITION_FIELDS = [
53
- 'concurrent_streams',
54
- 'active_session_distance_km',
55
- 'travel_speed_kmh',
56
- 'unique_ips_in_window',
57
- 'unique_devices_in_window',
58
- ];
5
+ export { IDENTITY_AWARE_CONDITION_FIELDS } from './automations/conditions.js';
59
6
  // Severity levels
60
7
  export const SEVERITY_LEVELS = {
61
8
  low: { label: 'Low', priority: 1 },
@@ -72,6 +19,7 @@ export const WS_EVENTS = {
72
19
  SESSION_STOPPED: 'session:stopped',
73
20
  SESSION_UPDATED: 'session:updated',
74
21
  VIOLATION_NEW: 'violation:new',
22
+ RUN_FINISHED: 'run:finished',
75
23
  STATS_UPDATED: 'stats:updated',
76
24
  IMPORT_PROGRESS: 'import:progress',
77
25
  IMPORT_JELLYSTAT_PROGRESS: 'import:jellystat:progress',
@@ -89,6 +37,7 @@ export const WS_EVENTS = {
89
37
  SERVER_CONNECTION: 'server:connection',
90
38
  NOTIFICATION_TOAST: 'notification:toast',
91
39
  DESTINATIONS_CHANGED: 'destinations:changed',
40
+ SERVERS_CHANGED: 'servers:changed',
92
41
  };
93
42
  // Redis key prefix (set at startup via setRedisPrefix)
94
43
  let _redisPrefix = '';
@@ -245,6 +194,11 @@ export const REDIS_KEYS = {
245
194
  // job walks library_items scoped only by server)
246
195
  LIBRARY_PRECACHE_WATERMARK: (serverId) => `${_redisPrefix}tracearr:library:precache:watermark:${serverId}`,
247
196
  LIBRARY_PRECACHE_LAST_FULL: (serverId) => `${_redisPrefix}tracearr:library:precache:last-full:${serverId}`,
197
+ // Poster cache: one-time boot reconciliation marker, the last sweep's tally,
198
+ // and the disk-limited flag the precache sets when the guard refused writes.
199
+ IMAGE_CACHE_SCHEMA: `${_redisPrefix}tracearr:image-cache:schema`,
200
+ IMAGE_CACHE_TALLY: `${_redisPrefix}tracearr:image-cache:tally`,
201
+ IMAGE_CACHE_DISK_LIMITED: `${_redisPrefix}tracearr:image-cache:disk-limited`,
248
202
  // Auth tokens
249
203
  REFRESH_TOKEN: (hash) => `${_redisPrefix}tracearr:refresh:${hash}`,
250
204
  PLEX_TEMP_TOKEN: (token) => `${_redisPrefix}tracearr:plex_temp:${token}`,
@@ -260,8 +214,13 @@ export const REDIS_KEYS = {
260
214
  SESSION_LOCK: (serverId, sessionKey) => `${_redisPrefix}session:lock:${serverId}:${sessionKey}`,
261
215
  TERMINATION_COOLDOWN: (serverId, sessionKey, ratingKey) => `${_redisPrefix}termination:cooldown:${serverId}:${sessionKey}:${ratingKey}`,
262
216
  TERMINATION_COOLDOWN_COMPOSITE: (serverId, serverUserId, deviceId, ratingKey) => `${_redisPrefix}termination:cooldown:composite:${serverId}:${serverUserId}:${deviceId}:${ratingKey}`,
263
- // Rule cooldowns
264
- RULE_COOLDOWN: (ruleId, targetId) => `${_redisPrefix}tracearr:rule:cooldown:${ruleId}:${targetId}`,
217
+ // Per-action cooldown on one target. The key string keeps its v1 shape so
218
+ // cooldowns already armed in Redis stay honoured.
219
+ ACTION_COOLDOWN: (automationId, targetId) => `${_redisPrefix}tracearr:rule:cooldown:${automationId}:${targetId}`,
220
+ // Automation-level cooldown, keyed on the run's subject
221
+ AUTOMATION_COOLDOWN: (automationId, subjectKey) => `${_redisPrefix}tracearr:automation:cooldown:${automationId}:${subjectKey}`,
222
+ // Capped ring of evaluations that matched a trigger but recorded no run
223
+ AUTOMATION_EVALS: (automationId) => `${_redisPrefix}tracearr:automation:evals:${automationId}`,
265
224
  // Session write retry queue (for failed DB writes)
266
225
  SESSION_WRITE_RETRY: (sessionId) => `${_redisPrefix}tracearr:session:write-retry:${sessionId}`,
267
226
  get SESSION_WRITE_RETRY_SET() {
@@ -327,7 +286,15 @@ export const NOTIFICATION_EVENTS = {
327
286
  SERVER_DOWN: 'server_down',
328
287
  SERVER_UP: 'server_up',
329
288
  PLUGIN_UPDATE_AVAILABLE: 'plugin_update_available',
289
+ SERVER_UPDATE_AVAILABLE: 'server_update_available',
290
+ TRACEARR_UPDATE_AVAILABLE: 'tracearr_update_available',
291
+ MEDIA_ADDED: 'media_added',
292
+ MEDIA_UPGRADED: 'media_upgraded',
293
+ NEW_DEVICE: 'new_device',
294
+ TRUST_SCORE_CHANGED: 'trust_score_changed',
330
295
  };
296
+ /** The one size a poster is cached at. Every poster URL the server hands out uses it. */
297
+ export const POSTER_IMAGE_SIZE = { width: 360, height: 540 };
331
298
  // API version
332
299
  /**
333
300
  * server_version_key of the placeholder version rows the multi-version
@@ -417,6 +384,8 @@ export const UNIT_CONVERSION = {
417
384
  KM_TO_MILES: 0.621371,
418
385
  MILES_TO_KM: 1.60934,
419
386
  };
387
+ /** Base 1024, matching the byte formatter the dashboard renders file sizes with. */
388
+ export const BYTES_PER_GB = 1024 ** 3;
420
389
  /**
421
390
  * Convert kilometers to miles
422
391
  */