@getstrata/core 0.5.89 → 0.5.91

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 (43) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/dist/core/database/factory.d.ts +3 -0
  4. package/dist/core/scheduler/osCron.d.ts +3 -1
  5. package/dist/entries/audit/exportAuditLogs.js +2 -2
  6. package/dist/entries/audit/siemFormatter.js +2 -2
  7. package/dist/entries/auth/intendedUrlCookie.js +2 -2
  8. package/dist/entries/auth/oauth/providers.js +2 -2
  9. package/dist/entries/auth/oauth/samlProvider.js +2 -2
  10. package/dist/entries/auth/passwordConfirmCookie.js +2 -2
  11. package/dist/entries/auth/sessionCookie.js +2 -2
  12. package/dist/entries/auth/sessionGuard.js +2 -2
  13. package/dist/entries/auth/tokenHash.js +2 -2
  14. package/dist/entries/cache/createCacheStore.js +2 -2
  15. package/dist/entries/database/factory.js +13 -0
  16. package/dist/entries/facades.js +2 -2
  17. package/dist/entries/http/csrfMiddleware.js +2 -2
  18. package/dist/entries/http/csrfToken.js +2 -2
  19. package/dist/entries/http/flashMiddleware.js +2 -2
  20. package/dist/entries/http/flashSession.js +2 -2
  21. package/dist/entries/http/loginThrottleMiddleware.js +2 -2
  22. package/dist/entries/http/memoryThrottleMiddleware.js +2 -2
  23. package/dist/entries/http/scimThrottleMiddleware.js +2 -2
  24. package/dist/entries/http/securityHeadersMiddleware.js +2 -2
  25. package/dist/entries/http/signedUrl.js +2 -2
  26. package/dist/entries/http/throttleMiddleware.js +2 -2
  27. package/dist/entries/jobs/exportAuditLogsJob.js +2 -2
  28. package/dist/entries/mail/mailer.js +2 -2
  29. package/dist/entries/openapi/generator.js +5 -5
  30. package/dist/entries/queue/createAppQueue.js +2 -2
  31. package/dist/entries/queue/publicQueue.js +2 -2
  32. package/dist/entries/queue/queueMetrics.js +2 -2
  33. package/dist/entries/queue/redisQueue.js +2 -2
  34. package/dist/entries/runtime/appKeyPrefix.js +2 -2
  35. package/dist/entries/scheduler/osCron.js +26 -0
  36. package/dist/entries/scheduler/schedule.js +45 -11
  37. package/dist/entries/security/oauthState.js +2 -2
  38. package/dist/entries/security/safeFetch.js +2 -2
  39. package/dist/entries/security/totp.js +2 -2
  40. package/dist/entries/tracing/tracingMiddleware.js +2 -2
  41. package/dist/entries/view.js +2 -2
  42. package/dist/index.js +32 -12
  43. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @getstrata/core changelog
2
2
 
3
+ ## 0.5.91
4
+
5
+ - `Schedule.command()` accepts any expression `Bun.cron.parse` understands. `dueTasks()` uses the next fire time in the current minute instead of a `*/N` whitelist.
6
+ - `Factory.create()` persists `make()` through subclass `persist()` and strips a placeholder `id` of `0`. No states, sequences, or relationships.
7
+
8
+ ## 0.5.90
9
+
10
+ - **Breaking identity defaults:** `appKeyPrefix()` is `strata` and `appDisplayName()` is `Strata` when `APP_KEY_PREFIX` / `APP_NAME` are unset (were `workhub` / `WorkHub`). WorkHub pins those env vars.
11
+ - `Schedule.command()` rejects cron strings other than `* * * * *` and `*/N * * * *` instead of silently never running them.
12
+ - OpenAPI marks `GET /users/me/*` as bearer-authenticated.
13
+ - OpenAPI `/users/me/current-organization` summaries no longer say Jetstream.
14
+
3
15
  ## 0.5.89
4
16
 
5
17
  - **Breaking:** removed `@getstrata/core/jobs/dispatchWebhookJob`. Import `DispatchWebhookJob` from the app webhook module (`src/modules/webhook/dispatchWebhookJob.ts`).
package/README.md CHANGED
@@ -82,7 +82,7 @@ import type { Migration } from "@getstrata/core/database/migrations/types";
82
82
  Package name: **`@getstrata/core`** (npm org [`@getstrata`](https://www.npmjs.com/org/getstrata)).
83
83
 
84
84
  1. Add `NPM_TOKEN` to GitHub repository secrets.
85
- 2. Tag a release: `git tag v0.5.94 && git push origin v0.5.94`
85
+ 2. Tag a release: `git tag v0.5.96 && git push origin v0.5.96`
86
86
  3. [Release workflow](../../.github/workflows/release.yml) builds and runs `npm publish --access public`.
87
87
 
88
88
  Previously published as `@eyk-workhub/framework@0.1.0`, deprecated in favor of this package.
@@ -2,5 +2,8 @@ declare class Factory<TRecord extends object> {
2
2
  constructor();
3
3
  protected definition(): TRecord;
4
4
  make(overrides?: Partial<TRecord>): TRecord;
5
+ create(overrides?: Partial<TRecord>): Promise<TRecord>;
6
+ protected insertable(record: TRecord): Partial<TRecord>;
7
+ protected persist(_values: Partial<TRecord>): Promise<TRecord>;
5
8
  }
6
9
  export { Factory };
@@ -7,8 +7,10 @@ interface InProcessCronJob {
7
7
  unref(): InProcessCronJob;
8
8
  }
9
9
  declare function parseScheduleExpression(expression: string, from?: Date): Date | null;
10
+ declare function isScheduleExpressionDue(expression: string, now?: Date): boolean;
11
+ declare function assertScheduleExpression(expression: string): void;
10
12
  declare function registerInProcessScheduleRunner(run: () => void | Promise<void>, expression?: string): InProcessCronJob;
11
13
  declare function installOsScheduleRunner(workerScriptPath: string, expression?: string, title?: string): Promise<void>;
12
14
  declare function uninstallOsScheduleRunner(title?: string): Promise<void>;
13
15
  export type { InProcessCronJob };
14
- export { DEFAULT_SCHEDULE_RUN_EXPRESSION, installOsScheduleRunner, OS_CRON_JOB_TITLE, parseScheduleExpression, registerInProcessScheduleRunner, uninstallOsScheduleRunner, };
16
+ export { assertScheduleExpression, DEFAULT_SCHEDULE_RUN_EXPRESSION, installOsScheduleRunner, isScheduleExpressionDue, OS_CRON_JOB_TITLE, parseScheduleExpression, registerInProcessScheduleRunner, uninstallOsScheduleRunner, };
@@ -4,7 +4,7 @@ import { repositoryConnection as db2 } from "@getstrata/core/database/repository
4
4
 
5
5
  // ../../src/core/runtime/appKeyPrefix.ts
6
6
  function appKeyPrefix() {
7
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
7
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
8
8
  }
9
9
  function appCookieName(kind) {
10
10
  return `${appKeyPrefix()}_${kind}`;
@@ -33,7 +33,7 @@ function webhookSignatureHeader() {
33
33
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
34
34
  }
35
35
  function appDisplayName() {
36
- return process.env.APP_NAME?.trim() || "WorkHub";
36
+ return process.env.APP_NAME?.trim() || "Strata";
37
37
  }
38
38
  function appEnv() {
39
39
  return process.env.APP_ENV?.trim() || "local";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // ../../src/core/runtime/appKeyPrefix.ts
3
3
  function appKeyPrefix() {
4
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
4
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
5
5
  }
6
6
  function appCookieName(kind) {
7
7
  return `${appKeyPrefix()}_${kind}`;
@@ -30,7 +30,7 @@ function webhookSignatureHeader() {
30
30
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
31
31
  }
32
32
  function appDisplayName() {
33
- return process.env.APP_NAME?.trim() || "WorkHub";
33
+ return process.env.APP_NAME?.trim() || "Strata";
34
34
  }
35
35
  function appEnv() {
36
36
  return process.env.APP_ENV?.trim() || "local";
@@ -34,7 +34,7 @@ function loginRedirectLocation(request) {
34
34
 
35
35
  // ../../src/core/runtime/appKeyPrefix.ts
36
36
  function appKeyPrefix() {
37
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
37
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
38
38
  }
39
39
  function appCookieName(kind) {
40
40
  return `${appKeyPrefix()}_${kind}`;
@@ -63,7 +63,7 @@ function webhookSignatureHeader() {
63
63
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
64
64
  }
65
65
  function appDisplayName() {
66
- return process.env.APP_NAME?.trim() || "WorkHub";
66
+ return process.env.APP_NAME?.trim() || "Strata";
67
67
  }
68
68
  function appEnv() {
69
69
  return process.env.APP_ENV?.trim() || "local";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // ../../src/core/runtime/appKeyPrefix.ts
3
3
  function appKeyPrefix() {
4
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
4
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
5
5
  }
6
6
  function appCookieName(kind) {
7
7
  return `${appKeyPrefix()}_${kind}`;
@@ -30,7 +30,7 @@ function webhookSignatureHeader() {
30
30
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
31
31
  }
32
32
  function appDisplayName() {
33
- return process.env.APP_NAME?.trim() || "WorkHub";
33
+ return process.env.APP_NAME?.trim() || "Strata";
34
34
  }
35
35
  function appEnv() {
36
36
  return process.env.APP_ENV?.trim() || "local";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // ../../src/core/runtime/appKeyPrefix.ts
3
3
  function appKeyPrefix() {
4
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
4
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
5
5
  }
6
6
  function appCookieName(kind) {
7
7
  return `${appKeyPrefix()}_${kind}`;
@@ -30,7 +30,7 @@ function webhookSignatureHeader() {
30
30
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
31
31
  }
32
32
  function appDisplayName() {
33
- return process.env.APP_NAME?.trim() || "WorkHub";
33
+ return process.env.APP_NAME?.trim() || "Strata";
34
34
  }
35
35
  function appEnv() {
36
36
  return process.env.APP_ENV?.trim() || "local";
@@ -4,7 +4,7 @@ import { createHmac, timingSafeEqual } from "crypto";
4
4
 
5
5
  // ../../src/core/runtime/appKeyPrefix.ts
6
6
  function appKeyPrefix() {
7
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
7
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
8
8
  }
9
9
  function appCookieName(kind) {
10
10
  return `${appKeyPrefix()}_${kind}`;
@@ -33,7 +33,7 @@ function webhookSignatureHeader() {
33
33
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
34
34
  }
35
35
  function appDisplayName() {
36
- return process.env.APP_NAME?.trim() || "WorkHub";
36
+ return process.env.APP_NAME?.trim() || "Strata";
37
37
  }
38
38
  function appEnv() {
39
39
  return process.env.APP_ENV?.trim() || "local";
@@ -4,7 +4,7 @@ import { createHmac, timingSafeEqual } from "crypto";
4
4
 
5
5
  // ../../src/core/runtime/appKeyPrefix.ts
6
6
  function appKeyPrefix() {
7
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
7
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
8
8
  }
9
9
  function appCookieName(kind) {
10
10
  return `${appKeyPrefix()}_${kind}`;
@@ -33,7 +33,7 @@ function webhookSignatureHeader() {
33
33
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
34
34
  }
35
35
  function appDisplayName() {
36
- return process.env.APP_NAME?.trim() || "WorkHub";
36
+ return process.env.APP_NAME?.trim() || "Strata";
37
37
  }
38
38
  function appEnv() {
39
39
  return process.env.APP_ENV?.trim() || "local";
@@ -89,7 +89,7 @@ import { createHmac, timingSafeEqual } from "crypto";
89
89
 
90
90
  // ../../src/core/runtime/appKeyPrefix.ts
91
91
  function appKeyPrefix() {
92
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
92
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
93
93
  }
94
94
  function appCookieName(kind) {
95
95
  return `${appKeyPrefix()}_${kind}`;
@@ -118,7 +118,7 @@ function webhookSignatureHeader() {
118
118
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
119
119
  }
120
120
  function appDisplayName() {
121
- return process.env.APP_NAME?.trim() || "WorkHub";
121
+ return process.env.APP_NAME?.trim() || "Strata";
122
122
  }
123
123
  function appEnv() {
124
124
  return process.env.APP_ENV?.trim() || "local";
@@ -4,7 +4,7 @@ import { createHash, createHmac } from "crypto";
4
4
 
5
5
  // ../../src/core/runtime/appKeyPrefix.ts
6
6
  function appKeyPrefix() {
7
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
7
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
8
8
  }
9
9
  function appCookieName(kind) {
10
10
  return `${appKeyPrefix()}_${kind}`;
@@ -33,7 +33,7 @@ function webhookSignatureHeader() {
33
33
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
34
34
  }
35
35
  function appDisplayName() {
36
- return process.env.APP_NAME?.trim() || "WorkHub";
36
+ return process.env.APP_NAME?.trim() || "Strata";
37
37
  }
38
38
  function appEnv() {
39
39
  return process.env.APP_ENV?.trim() || "local";
@@ -4,7 +4,7 @@ var {RedisClient } = globalThis.Bun;
4
4
 
5
5
  // ../../src/core/runtime/appKeyPrefix.ts
6
6
  function appKeyPrefix() {
7
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
7
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
8
8
  }
9
9
  function appCookieName(kind) {
10
10
  return `${appKeyPrefix()}_${kind}`;
@@ -33,7 +33,7 @@ function webhookSignatureHeader() {
33
33
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
34
34
  }
35
35
  function appDisplayName() {
36
- return process.env.APP_NAME?.trim() || "WorkHub";
36
+ return process.env.APP_NAME?.trim() || "Strata";
37
37
  }
38
38
  function appEnv() {
39
39
  return process.env.APP_ENV?.trim() || "local";
@@ -11,6 +11,19 @@ class Factory {
11
11
  ...overrides
12
12
  };
13
13
  }
14
+ async create(overrides = {}) {
15
+ return this.persist(this.insertable(this.make(overrides)));
16
+ }
17
+ insertable(record) {
18
+ const values = { ...record };
19
+ if (values.id === 0 || values.id === undefined || values.id === null) {
20
+ delete values.id;
21
+ }
22
+ return values;
23
+ }
24
+ persist(_values) {
25
+ throw new Error("Factory.persist() must be implemented to use create().");
26
+ }
14
27
  }
15
28
  export {
16
29
  Factory
@@ -13,7 +13,7 @@ import {
13
13
 
14
14
  // ../../src/core/runtime/appKeyPrefix.ts
15
15
  function appKeyPrefix() {
16
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
16
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
17
17
  }
18
18
  function appCookieName(kind) {
19
19
  return `${appKeyPrefix()}_${kind}`;
@@ -42,7 +42,7 @@ function webhookSignatureHeader() {
42
42
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
43
43
  }
44
44
  function appDisplayName() {
45
- return process.env.APP_NAME?.trim() || "WorkHub";
45
+ return process.env.APP_NAME?.trim() || "Strata";
46
46
  }
47
47
  function appEnv() {
48
48
  return process.env.APP_ENV?.trim() || "local";
@@ -7,7 +7,7 @@ import { timingSafeEqual } from "crypto";
7
7
 
8
8
  // ../../src/core/runtime/appKeyPrefix.ts
9
9
  function appKeyPrefix() {
10
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
10
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
11
11
  }
12
12
  function appCookieName(kind) {
13
13
  return `${appKeyPrefix()}_${kind}`;
@@ -36,7 +36,7 @@ function webhookSignatureHeader() {
36
36
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
37
37
  }
38
38
  function appDisplayName() {
39
- return process.env.APP_NAME?.trim() || "WorkHub";
39
+ return process.env.APP_NAME?.trim() || "Strata";
40
40
  }
41
41
  function appEnv() {
42
42
  return process.env.APP_ENV?.trim() || "local";
@@ -4,7 +4,7 @@ import { timingSafeEqual } from "crypto";
4
4
 
5
5
  // ../../src/core/runtime/appKeyPrefix.ts
6
6
  function appKeyPrefix() {
7
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
7
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
8
8
  }
9
9
  function appCookieName(kind) {
10
10
  return `${appKeyPrefix()}_${kind}`;
@@ -33,7 +33,7 @@ function webhookSignatureHeader() {
33
33
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
34
34
  }
35
35
  function appDisplayName() {
36
- return process.env.APP_NAME?.trim() || "WorkHub";
36
+ return process.env.APP_NAME?.trim() || "Strata";
37
37
  }
38
38
  function appEnv() {
39
39
  return process.env.APP_ENV?.trim() || "local";
@@ -4,7 +4,7 @@ import { createHmac, timingSafeEqual } from "crypto";
4
4
 
5
5
  // ../../src/core/runtime/appKeyPrefix.ts
6
6
  function appKeyPrefix() {
7
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
7
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
8
8
  }
9
9
  function appCookieName(kind) {
10
10
  return `${appKeyPrefix()}_${kind}`;
@@ -33,7 +33,7 @@ function webhookSignatureHeader() {
33
33
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
34
34
  }
35
35
  function appDisplayName() {
36
- return process.env.APP_NAME?.trim() || "WorkHub";
36
+ return process.env.APP_NAME?.trim() || "Strata";
37
37
  }
38
38
  function appEnv() {
39
39
  return process.env.APP_ENV?.trim() || "local";
@@ -4,7 +4,7 @@ import { createHmac, timingSafeEqual } from "crypto";
4
4
 
5
5
  // ../../src/core/runtime/appKeyPrefix.ts
6
6
  function appKeyPrefix() {
7
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
7
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
8
8
  }
9
9
  function appCookieName(kind) {
10
10
  return `${appKeyPrefix()}_${kind}`;
@@ -33,7 +33,7 @@ function webhookSignatureHeader() {
33
33
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
34
34
  }
35
35
  function appDisplayName() {
36
- return process.env.APP_NAME?.trim() || "WorkHub";
36
+ return process.env.APP_NAME?.trim() || "Strata";
37
37
  }
38
38
  function appEnv() {
39
39
  return process.env.APP_ENV?.trim() || "local";
@@ -4,7 +4,7 @@ var {RedisClient } = globalThis.Bun;
4
4
 
5
5
  // ../../src/core/runtime/appKeyPrefix.ts
6
6
  function appKeyPrefix() {
7
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
7
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
8
8
  }
9
9
  function appCookieName(kind) {
10
10
  return `${appKeyPrefix()}_${kind}`;
@@ -33,7 +33,7 @@ function webhookSignatureHeader() {
33
33
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
34
34
  }
35
35
  function appDisplayName() {
36
- return process.env.APP_NAME?.trim() || "WorkHub";
36
+ return process.env.APP_NAME?.trim() || "Strata";
37
37
  }
38
38
  function appEnv() {
39
39
  return process.env.APP_ENV?.trim() || "local";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // ../../src/core/runtime/appKeyPrefix.ts
3
3
  function appKeyPrefix() {
4
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
4
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
5
5
  }
6
6
  function appCookieName(kind) {
7
7
  return `${appKeyPrefix()}_${kind}`;
@@ -30,7 +30,7 @@ function webhookSignatureHeader() {
30
30
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
31
31
  }
32
32
  function appDisplayName() {
33
- return process.env.APP_NAME?.trim() || "WorkHub";
33
+ return process.env.APP_NAME?.trim() || "Strata";
34
34
  }
35
35
  function appEnv() {
36
36
  return process.env.APP_ENV?.trim() || "local";
@@ -4,7 +4,7 @@ var {RedisClient } = globalThis.Bun;
4
4
 
5
5
  // ../../src/core/runtime/appKeyPrefix.ts
6
6
  function appKeyPrefix() {
7
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
7
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
8
8
  }
9
9
  function appCookieName(kind) {
10
10
  return `${appKeyPrefix()}_${kind}`;
@@ -33,7 +33,7 @@ function webhookSignatureHeader() {
33
33
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
34
34
  }
35
35
  function appDisplayName() {
36
- return process.env.APP_NAME?.trim() || "WorkHub";
36
+ return process.env.APP_NAME?.trim() || "Strata";
37
37
  }
38
38
  function appEnv() {
39
39
  return process.env.APP_ENV?.trim() || "local";
@@ -9,7 +9,7 @@ import { currentRequestMeta, runWithRequestMeta } from "@getstrata/core/http/req
9
9
 
10
10
  // ../../src/core/runtime/appKeyPrefix.ts
11
11
  function appKeyPrefix() {
12
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
12
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
13
13
  }
14
14
  function appCookieName(kind) {
15
15
  return `${appKeyPrefix()}_${kind}`;
@@ -38,7 +38,7 @@ function webhookSignatureHeader() {
38
38
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
39
39
  }
40
40
  function appDisplayName() {
41
- return process.env.APP_NAME?.trim() || "WorkHub";
41
+ return process.env.APP_NAME?.trim() || "Strata";
42
42
  }
43
43
  function appEnv() {
44
44
  return process.env.APP_ENV?.trim() || "local";
@@ -6,7 +6,7 @@ import { timingSafeCompareString } from "@getstrata/core/security/timingSafeComp
6
6
 
7
7
  // ../../src/core/runtime/appKeyPrefix.ts
8
8
  function appKeyPrefix() {
9
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
9
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
10
10
  }
11
11
  function appCookieName(kind) {
12
12
  return `${appKeyPrefix()}_${kind}`;
@@ -35,7 +35,7 @@ function webhookSignatureHeader() {
35
35
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
36
36
  }
37
37
  function appDisplayName() {
38
- return process.env.APP_NAME?.trim() || "WorkHub";
38
+ return process.env.APP_NAME?.trim() || "Strata";
39
39
  }
40
40
  function appEnv() {
41
41
  return process.env.APP_ENV?.trim() || "local";
@@ -6,7 +6,7 @@ var {RedisClient } = globalThis.Bun;
6
6
 
7
7
  // ../../src/core/runtime/appKeyPrefix.ts
8
8
  function appKeyPrefix() {
9
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
9
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
10
10
  }
11
11
  function appCookieName(kind) {
12
12
  return `${appKeyPrefix()}_${kind}`;
@@ -35,7 +35,7 @@ function webhookSignatureHeader() {
35
35
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
36
36
  }
37
37
  function appDisplayName() {
38
- return process.env.APP_NAME?.trim() || "WorkHub";
38
+ return process.env.APP_NAME?.trim() || "Strata";
39
39
  }
40
40
  function appEnv() {
41
41
  return process.env.APP_ENV?.trim() || "local";
@@ -4,7 +4,7 @@ import { repositoryConnection as db2 } from "@getstrata/core/database/repository
4
4
 
5
5
  // ../../src/core/runtime/appKeyPrefix.ts
6
6
  function appKeyPrefix() {
7
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
7
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
8
8
  }
9
9
  function appCookieName(kind) {
10
10
  return `${appKeyPrefix()}_${kind}`;
@@ -33,7 +33,7 @@ function webhookSignatureHeader() {
33
33
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
34
34
  }
35
35
  function appDisplayName() {
36
- return process.env.APP_NAME?.trim() || "WorkHub";
36
+ return process.env.APP_NAME?.trim() || "Strata";
37
37
  }
38
38
  function appEnv() {
39
39
  return process.env.APP_ENV?.trim() || "local";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // ../../src/core/runtime/appKeyPrefix.ts
3
3
  function appKeyPrefix() {
4
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
4
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
5
5
  }
6
6
  function appCookieName(kind) {
7
7
  return `${appKeyPrefix()}_${kind}`;
@@ -30,7 +30,7 @@ function webhookSignatureHeader() {
30
30
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
31
31
  }
32
32
  function appDisplayName() {
33
- return process.env.APP_NAME?.trim() || "WorkHub";
33
+ return process.env.APP_NAME?.trim() || "Strata";
34
34
  }
35
35
  function appEnv() {
36
36
  return process.env.APP_ENV?.trim() || "local";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // ../../src/core/runtime/appKeyPrefix.ts
3
3
  function appKeyPrefix() {
4
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
4
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
5
5
  }
6
6
  function appCookieName(kind) {
7
7
  return `${appKeyPrefix()}_${kind}`;
@@ -30,7 +30,7 @@ function webhookSignatureHeader() {
30
30
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
31
31
  }
32
32
  function appDisplayName() {
33
- return process.env.APP_NAME?.trim() || "WorkHub";
33
+ return process.env.APP_NAME?.trim() || "Strata";
34
34
  }
35
35
  function appEnv() {
36
36
  return process.env.APP_ENV?.trim() || "local";
@@ -66,8 +66,8 @@ var PUBLIC_ROUTE_DESCRIPTIONS = {
66
66
  "POST /auth/tokens": "Create API token",
67
67
  "DELETE /auth/tokens/:id": "Revoke API token",
68
68
  "GET /users/me/export": "GDPR export of user data",
69
- "GET /users/me/current-organization": "Current Jetstream organization",
70
- "PUT /users/me/current-organization": "Switch current Jetstream organization",
69
+ "GET /users/me/current-organization": "Current organization",
70
+ "PUT /users/me/current-organization": "Switch current organization",
71
71
  "GET /users/me/invitations": "List pending team invitations for the signed-in email",
72
72
  "POST /users/me/invitations/:id/accept": "Accept a pending team invitation",
73
73
  "DELETE /users/me/invitations/:id": "Decline a pending team invitation",
@@ -126,7 +126,7 @@ function requiresBearerAuth(path, method) {
126
126
  if (method === "GET" && ["/organizations", "/projects", "/tasks", "/search"].some((prefix) => relative.startsWith(prefix) || path.startsWith(prefix))) {
127
127
  return false;
128
128
  }
129
- return relative.startsWith("/auth/") || ["POST", "PATCH", "PUT", "DELETE"].includes(method);
129
+ return relative.startsWith("/auth/") || relative.startsWith("/users/me") || path.startsWith("/users/me") || ["POST", "PATCH", "PUT", "DELETE"].includes(method);
130
130
  }
131
131
  function generateOpenApiSpec(routes) {
132
132
  const paths = {};
@@ -158,7 +158,7 @@ var {RedisClient } = globalThis.Bun;
158
158
 
159
159
  // ../../src/core/runtime/appKeyPrefix.ts
160
160
  function appKeyPrefix() {
161
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
161
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
162
162
  }
163
163
  function appCookieName(kind) {
164
164
  return `${appKeyPrefix()}_${kind}`;
@@ -187,7 +187,7 @@ function webhookSignatureHeader() {
187
187
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
188
188
  }
189
189
  function appDisplayName() {
190
- return process.env.APP_NAME?.trim() || "WorkHub";
190
+ return process.env.APP_NAME?.trim() || "Strata";
191
191
  }
192
192
  function appEnv() {
193
193
  return process.env.APP_ENV?.trim() || "local";
@@ -158,7 +158,7 @@ var {RedisClient } = globalThis.Bun;
158
158
 
159
159
  // ../../src/core/runtime/appKeyPrefix.ts
160
160
  function appKeyPrefix() {
161
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
161
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
162
162
  }
163
163
  function appCookieName(kind) {
164
164
  return `${appKeyPrefix()}_${kind}`;
@@ -187,7 +187,7 @@ function webhookSignatureHeader() {
187
187
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
188
188
  }
189
189
  function appDisplayName() {
190
- return process.env.APP_NAME?.trim() || "WorkHub";
190
+ return process.env.APP_NAME?.trim() || "Strata";
191
191
  }
192
192
  function appEnv() {
193
193
  return process.env.APP_ENV?.trim() || "local";
@@ -161,7 +161,7 @@ var {RedisClient } = globalThis.Bun;
161
161
 
162
162
  // ../../src/core/runtime/appKeyPrefix.ts
163
163
  function appKeyPrefix() {
164
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
164
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
165
165
  }
166
166
  function appCookieName(kind) {
167
167
  return `${appKeyPrefix()}_${kind}`;
@@ -190,7 +190,7 @@ function webhookSignatureHeader() {
190
190
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
191
191
  }
192
192
  function appDisplayName() {
193
- return process.env.APP_NAME?.trim() || "WorkHub";
193
+ return process.env.APP_NAME?.trim() || "Strata";
194
194
  }
195
195
  function appEnv() {
196
196
  return process.env.APP_ENV?.trim() || "local";
@@ -4,7 +4,7 @@ var {RedisClient } = globalThis.Bun;
4
4
 
5
5
  // ../../src/core/runtime/appKeyPrefix.ts
6
6
  function appKeyPrefix() {
7
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
7
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
8
8
  }
9
9
  function appCookieName(kind) {
10
10
  return `${appKeyPrefix()}_${kind}`;
@@ -33,7 +33,7 @@ function webhookSignatureHeader() {
33
33
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
34
34
  }
35
35
  function appDisplayName() {
36
- return process.env.APP_NAME?.trim() || "WorkHub";
36
+ return process.env.APP_NAME?.trim() || "Strata";
37
37
  }
38
38
  function appEnv() {
39
39
  return process.env.APP_ENV?.trim() || "local";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // ../../src/core/runtime/appKeyPrefix.ts
3
3
  function appKeyPrefix() {
4
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
4
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
5
5
  }
6
6
  function appCookieName(kind) {
7
7
  return `${appKeyPrefix()}_${kind}`;
@@ -30,7 +30,7 @@ function webhookSignatureHeader() {
30
30
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
31
31
  }
32
32
  function appDisplayName() {
33
- return process.env.APP_NAME?.trim() || "WorkHub";
33
+ return process.env.APP_NAME?.trim() || "Strata";
34
34
  }
35
35
  function appEnv() {
36
36
  return process.env.APP_ENV?.trim() || "local";
@@ -5,6 +5,30 @@ var OS_CRON_JOB_TITLE = "getstrata-schedule-run";
5
5
  function parseScheduleExpression(expression, from = new Date) {
6
6
  return Bun.cron.parse(expression, from);
7
7
  }
8
+ function minuteWindow(now) {
9
+ const start = new Date(now);
10
+ start.setSeconds(0, 0);
11
+ return { start, end: new Date(start.getTime() + 60000) };
12
+ }
13
+ function isScheduleExpressionDue(expression, now = new Date) {
14
+ const { start, end } = minuteWindow(now);
15
+ const next = parseScheduleExpression(expression, new Date(start.getTime() - 1));
16
+ if (!next) {
17
+ return false;
18
+ }
19
+ const timestamp = next.getTime();
20
+ return timestamp >= start.getTime() && timestamp < end.getTime();
21
+ }
22
+ function assertScheduleExpression(expression) {
23
+ try {
24
+ const next = parseScheduleExpression(expression);
25
+ if (!(next instanceof Date) || Number.isNaN(next.getTime())) {
26
+ throw new Error("unparsable");
27
+ }
28
+ } catch {
29
+ throw new Error(`Unsupported schedule expression "${expression}".`);
30
+ }
31
+ }
8
32
  function registerInProcessScheduleRunner(run, expression = DEFAULT_SCHEDULE_RUN_EXPRESSION) {
9
33
  const register = Bun.cron;
10
34
  return register(expression, async () => {
@@ -20,7 +44,9 @@ async function uninstallOsScheduleRunner(title = OS_CRON_JOB_TITLE) {
20
44
  export {
21
45
  DEFAULT_SCHEDULE_RUN_EXPRESSION,
22
46
  OS_CRON_JOB_TITLE,
47
+ assertScheduleExpression,
23
48
  installOsScheduleRunner,
49
+ isScheduleExpressionDue,
24
50
  parseScheduleExpression,
25
51
  registerInProcessScheduleRunner,
26
52
  uninstallOsScheduleRunner
@@ -1,23 +1,57 @@
1
1
  // @bun
2
+ // ../../src/core/scheduler/osCron.ts
3
+ var DEFAULT_SCHEDULE_RUN_EXPRESSION = "* * * * *";
4
+ var OS_CRON_JOB_TITLE = "getstrata-schedule-run";
5
+ function parseScheduleExpression(expression, from = new Date) {
6
+ return Bun.cron.parse(expression, from);
7
+ }
8
+ function minuteWindow(now) {
9
+ const start = new Date(now);
10
+ start.setSeconds(0, 0);
11
+ return { start, end: new Date(start.getTime() + 60000) };
12
+ }
13
+ function isScheduleExpressionDue(expression, now = new Date) {
14
+ const { start, end } = minuteWindow(now);
15
+ const next = parseScheduleExpression(expression, new Date(start.getTime() - 1));
16
+ if (!next) {
17
+ return false;
18
+ }
19
+ const timestamp = next.getTime();
20
+ return timestamp >= start.getTime() && timestamp < end.getTime();
21
+ }
22
+ function assertScheduleExpression(expression) {
23
+ try {
24
+ const next = parseScheduleExpression(expression);
25
+ if (!(next instanceof Date) || Number.isNaN(next.getTime())) {
26
+ throw new Error("unparsable");
27
+ }
28
+ } catch {
29
+ throw new Error(`Unsupported schedule expression "${expression}".`);
30
+ }
31
+ }
32
+ function registerInProcessScheduleRunner(run, expression = DEFAULT_SCHEDULE_RUN_EXPRESSION) {
33
+ const register = Bun.cron;
34
+ return register(expression, async () => {
35
+ await run();
36
+ }).unref();
37
+ }
38
+ async function installOsScheduleRunner(workerScriptPath, expression = DEFAULT_SCHEDULE_RUN_EXPRESSION, title = OS_CRON_JOB_TITLE) {
39
+ await Bun.cron(workerScriptPath, expression, title);
40
+ }
41
+ async function uninstallOsScheduleRunner(title = OS_CRON_JOB_TITLE) {
42
+ await Bun.cron.remove(title);
43
+ }
44
+
2
45
  // ../../src/core/scheduler/schedule.ts
3
46
  class Schedule {
4
47
  tasks = [];
5
48
  command(expression, name, run) {
49
+ assertScheduleExpression(expression);
6
50
  this.tasks.push({ expression, name, run });
7
51
  return this;
8
52
  }
9
53
  dueTasks(now = new Date) {
10
- const minute = now.getMinutes();
11
- return this.tasks.filter((task) => {
12
- if (task.expression === "* * * * *") {
13
- return true;
14
- }
15
- if (task.expression.startsWith("*/")) {
16
- const interval = Number.parseInt(task.expression.slice(2), 10);
17
- return Number.isInteger(interval) && interval > 0 && minute % interval === 0;
18
- }
19
- return false;
20
- });
54
+ return this.tasks.filter((task) => isScheduleExpressionDue(task.expression, now));
21
55
  }
22
56
  tasksList() {
23
57
  return [...this.tasks];
@@ -4,7 +4,7 @@ import { createHmac, randomBytes, timingSafeEqual } from "crypto";
4
4
 
5
5
  // ../../src/core/runtime/appKeyPrefix.ts
6
6
  function appKeyPrefix() {
7
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
7
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
8
8
  }
9
9
  function appCookieName(kind) {
10
10
  return `${appKeyPrefix()}_${kind}`;
@@ -33,7 +33,7 @@ function webhookSignatureHeader() {
33
33
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
34
34
  }
35
35
  function appDisplayName() {
36
- return process.env.APP_NAME?.trim() || "WorkHub";
36
+ return process.env.APP_NAME?.trim() || "Strata";
37
37
  }
38
38
  function appEnv() {
39
39
  return process.env.APP_ENV?.trim() || "local";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // ../../src/core/runtime/appKeyPrefix.ts
3
3
  function appKeyPrefix() {
4
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
4
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
5
5
  }
6
6
  function appCookieName(kind) {
7
7
  return `${appKeyPrefix()}_${kind}`;
@@ -30,7 +30,7 @@ function webhookSignatureHeader() {
30
30
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
31
31
  }
32
32
  function appDisplayName() {
33
- return process.env.APP_NAME?.trim() || "WorkHub";
33
+ return process.env.APP_NAME?.trim() || "Strata";
34
34
  }
35
35
  function appEnv() {
36
36
  return process.env.APP_ENV?.trim() || "local";
@@ -4,7 +4,7 @@ import { createHmac, randomBytes } from "crypto";
4
4
 
5
5
  // ../../src/core/runtime/appKeyPrefix.ts
6
6
  function appKeyPrefix() {
7
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
7
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
8
8
  }
9
9
  function appCookieName(kind) {
10
10
  return `${appKeyPrefix()}_${kind}`;
@@ -33,7 +33,7 @@ function webhookSignatureHeader() {
33
33
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
34
34
  }
35
35
  function appDisplayName() {
36
- return process.env.APP_NAME?.trim() || "WorkHub";
36
+ return process.env.APP_NAME?.trim() || "Strata";
37
37
  }
38
38
  function appEnv() {
39
39
  return process.env.APP_ENV?.trim() || "local";
@@ -4,7 +4,7 @@ import { randomBytes } from "crypto";
4
4
 
5
5
  // ../../src/core/runtime/appKeyPrefix.ts
6
6
  function appKeyPrefix() {
7
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
7
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
8
8
  }
9
9
  function appCookieName(kind) {
10
10
  return `${appKeyPrefix()}_${kind}`;
@@ -33,7 +33,7 @@ function webhookSignatureHeader() {
33
33
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
34
34
  }
35
35
  function appDisplayName() {
36
- return process.env.APP_NAME?.trim() || "WorkHub";
36
+ return process.env.APP_NAME?.trim() || "Strata";
37
37
  }
38
38
  function appEnv() {
39
39
  return process.env.APP_ENV?.trim() || "local";
@@ -386,7 +386,7 @@ import { timingSafeEqual } from "crypto";
386
386
 
387
387
  // ../../src/core/runtime/appKeyPrefix.ts
388
388
  function appKeyPrefix() {
389
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
389
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
390
390
  }
391
391
  function appCookieName(kind) {
392
392
  return `${appKeyPrefix()}_${kind}`;
@@ -415,7 +415,7 @@ function webhookSignatureHeader() {
415
415
  return process.env.WEBHOOK_SIGNATURE_HEADER?.trim() || `x-${appKeyPrefix()}-signature`;
416
416
  }
417
417
  function appDisplayName() {
418
- return process.env.APP_NAME?.trim() || "WorkHub";
418
+ return process.env.APP_NAME?.trim() || "Strata";
419
419
  }
420
420
  function appEnv() {
421
421
  return process.env.APP_ENV?.trim() || "local";
package/dist/index.js CHANGED
@@ -977,7 +977,7 @@ var {RedisClient } = globalThis.Bun;
977
977
 
978
978
  // ../../src/core/runtime/appKeyPrefix.ts
979
979
  function appKeyPrefix() {
980
- return process.env.APP_KEY_PREFIX?.trim() || "workhub";
980
+ return process.env.APP_KEY_PREFIX?.trim() || "strata";
981
981
  }
982
982
  function appCookieName(kind) {
983
983
  return `${appKeyPrefix()}_${kind}`;
@@ -6556,25 +6556,45 @@ async function collectQueueMetrics() {
6556
6556
  failedCount
6557
6557
  };
6558
6558
  }
6559
+ // ../../src/core/scheduler/osCron.ts
6560
+ function parseScheduleExpression(expression, from = new Date) {
6561
+ return Bun.cron.parse(expression, from);
6562
+ }
6563
+ function minuteWindow(now) {
6564
+ const start = new Date(now);
6565
+ start.setSeconds(0, 0);
6566
+ return { start, end: new Date(start.getTime() + 60000) };
6567
+ }
6568
+ function isScheduleExpressionDue(expression, now = new Date) {
6569
+ const { start, end } = minuteWindow(now);
6570
+ const next = parseScheduleExpression(expression, new Date(start.getTime() - 1));
6571
+ if (!next) {
6572
+ return false;
6573
+ }
6574
+ const timestamp = next.getTime();
6575
+ return timestamp >= start.getTime() && timestamp < end.getTime();
6576
+ }
6577
+ function assertScheduleExpression(expression) {
6578
+ try {
6579
+ const next = parseScheduleExpression(expression);
6580
+ if (!(next instanceof Date) || Number.isNaN(next.getTime())) {
6581
+ throw new Error("unparsable");
6582
+ }
6583
+ } catch {
6584
+ throw new Error(`Unsupported schedule expression "${expression}".`);
6585
+ }
6586
+ }
6587
+
6559
6588
  // ../../src/core/scheduler/schedule.ts
6560
6589
  class Schedule {
6561
6590
  tasks = [];
6562
6591
  command(expression, name, run) {
6592
+ assertScheduleExpression(expression);
6563
6593
  this.tasks.push({ expression, name, run });
6564
6594
  return this;
6565
6595
  }
6566
6596
  dueTasks(now = new Date) {
6567
- const minute = now.getMinutes();
6568
- return this.tasks.filter((task) => {
6569
- if (task.expression === "* * * * *") {
6570
- return true;
6571
- }
6572
- if (task.expression.startsWith("*/")) {
6573
- const interval = Number.parseInt(task.expression.slice(2), 10);
6574
- return Number.isInteger(interval) && interval > 0 && minute % interval === 0;
6575
- }
6576
- return false;
6577
- });
6597
+ return this.tasks.filter((task) => isScheduleExpressionDue(task.expression, now));
6578
6598
  }
6579
6599
  tasksList() {
6580
6600
  return [...this.tasks];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getstrata/core",
3
- "version": "0.5.89",
3
+ "version": "0.5.91",
4
4
  "description": "Strata — Laravel-inspired Bun framework public API",
5
5
  "type": "module",
6
6
  "license": "MIT",