@adonis-agora/durable 0.27.0 → 0.29.0

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 (44) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/dist/assets/spa/assets/index-Db5aPtlJ.js +16 -0
  3. package/dist/assets/spa/assets/index-Db5aPtlJ.js.map +1 -0
  4. package/dist/assets/spa/index.html +1 -1
  5. package/dist/providers/dashboard_provider.d.ts +17 -15
  6. package/dist/providers/dashboard_provider.d.ts.map +1 -1
  7. package/dist/providers/dashboard_provider.js +100 -33
  8. package/dist/providers/dashboard_provider.js.map +1 -1
  9. package/dist/src/dashboard/access_denied_page.d.ts +102 -0
  10. package/dist/src/dashboard/access_denied_page.d.ts.map +1 -0
  11. package/dist/src/dashboard/access_denied_page.js +266 -0
  12. package/dist/src/dashboard/access_denied_page.js.map +1 -0
  13. package/dist/src/dashboard/compat-view.d.ts +1 -1
  14. package/dist/src/dashboard/compat-view.d.ts.map +1 -1
  15. package/dist/src/dashboard/compat-view.js +1 -1
  16. package/dist/src/dashboard/compat-view.js.map +1 -1
  17. package/dist/src/dashboard/define_config.d.ts +27 -0
  18. package/dist/src/dashboard/define_config.d.ts.map +1 -1
  19. package/dist/src/dashboard/define_config.js +1 -0
  20. package/dist/src/dashboard/define_config.js.map +1 -1
  21. package/dist/src/dashboard/handlers.d.ts +3 -3
  22. package/dist/src/dashboard/handlers.js +2 -2
  23. package/dist/src/dashboard/index.d.ts +4 -3
  24. package/dist/src/dashboard/index.d.ts.map +1 -1
  25. package/dist/src/dashboard/index.js +3 -2
  26. package/dist/src/dashboard/index.js.map +1 -1
  27. package/dist/src/dashboard/login_page.d.ts +23 -10
  28. package/dist/src/dashboard/login_page.d.ts.map +1 -1
  29. package/dist/src/dashboard/login_page.js +29 -41
  30. package/dist/src/dashboard/login_page.js.map +1 -1
  31. package/dist/src/dashboard/spa.d.ts +21 -4
  32. package/dist/src/dashboard/spa.d.ts.map +1 -1
  33. package/dist/src/dashboard/spa.js +19 -5
  34. package/dist/src/dashboard/spa.js.map +1 -1
  35. package/dist/src/index.d.ts +1 -1
  36. package/dist/src/index.js +1 -1
  37. package/package.json +3 -3
  38. package/dist/assets/dashboard.html +0 -559
  39. package/dist/assets/spa/assets/index-CS0tc60i.js +0 -16
  40. package/dist/assets/spa/assets/index-CS0tc60i.js.map +0 -1
  41. package/dist/src/dashboard/html.d.ts +0 -7
  42. package/dist/src/dashboard/html.d.ts.map +0 -1
  43. package/dist/src/dashboard/html.js +0 -24
  44. package/dist/src/dashboard/html.js.map +0 -1
@@ -1,27 +1,26 @@
1
+ import { escapeHtml } from './access_denied_page.js';
2
+ import { sanitizeReturnTo } from './auth.js';
1
3
  /**
2
- * The built-in `dashboardAuth` login page (`GET <basePath>/login`). Deliberately a small,
3
- * dependency-free, hand-authored HTML page — NOT part of the bundled dashboard SPA — so gating the
4
- * dashboard shell doesn't require rebuilding or extending the bundled `assets/dashboard.html`.
5
- *
6
- * `returnTo` and any error state are read CLIENT-SIDE from `location.search` (never server-echoed
7
- * into the HTML), so this function's only per-request-ish input is `basePath` — a developer-
8
- * controlled config value, not user input — and the page body is otherwise a static template.
9
- * This sidesteps HTML-escaping entirely: there is no reflected query-param interpolation surface
10
- * to get wrong.
11
- *
12
- * The visual language (dark zinc card, mono type, emerald accent) mirrors the Agora consoles so
13
- * they feel like one family. The submit flow POSTs JSON via `fetch` and follows the JSON
14
- * `redirectTo` it gets back (rather than a classic form POST + server redirect), which is why the
15
- * markup keeps its own `<script>`.
16
- *
17
- * The password input has NO `required` attribute and the value is forwarded AS-IS (empty string
18
- * when blank): the host's `login` hook — not this page — decides whether a password matters, so an
19
- * email-only host (gate on username, ignore password) works with the same page as a host with real
20
- * passwords.
4
+ * JSON for embedding INSIDE an inline `<script>`: `JSON.stringify` alone leaves `</script>` (and
5
+ * `<!--`) untouched, and the HTML parser ends the script element on the first `</script>` it sees
6
+ * regardless of JavaScript string boundaries — so a `returnTo` of `/x</script><script>…` would run.
7
+ * Escaping the angle brackets (and `&`, plus the two line terminators JSON allows but JS doesn't)
8
+ * as `\uXXXX` keeps the value byte-identical once parsed and inert to the HTML parser.
21
9
  */
22
- export function renderLoginPage(basePath) {
10
+ function jsonForScript(value) {
11
+ return JSON.stringify(value)
12
+ .replaceAll('<', '\\u003c')
13
+ .replaceAll('>', '\\u003e')
14
+ .replaceAll('&', '\\u0026')
15
+ .replaceAll('\u2028', '\\u2028')
16
+ .replaceAll('\u2029', '\\u2029');
17
+ }
18
+ export function renderLoginPage(basePath, options = {}) {
23
19
  const loginAction = `${basePath}/login`;
24
20
  const defaultReturnTo = basePath === '' ? '/' : basePath;
21
+ const returnTo = sanitizeReturnTo(options.returnTo, defaultReturnTo);
22
+ const nonceAttr = options.nonce !== undefined ? ` nonce="${escapeHtml(options.nonce)}"` : '';
23
+ const errorStyle = options.error ? ' style="display:block"' : '';
25
24
  return `<!doctype html>
26
25
  <html lang="en">
27
26
  <head>
@@ -29,7 +28,7 @@ export function renderLoginPage(basePath) {
29
28
  <meta name="viewport" content="width=device-width, initial-scale=1" />
30
29
  <meta name="robots" content="noindex, nofollow" />
31
30
  <title>Sign in — Durable</title>
32
- <style>
31
+ <style${nonceAttr}>
33
32
  :root { color-scheme: dark; }
34
33
  * { box-sizing: border-box; }
35
34
  body {
@@ -104,7 +103,8 @@ export function renderLoginPage(basePath) {
104
103
  <body>
105
104
  <div class="card">
106
105
  <p class="brand">Durable</p>
107
- <form id="login-form" autocomplete="on">
106
+ <form id="login-form" method="post" action="${escapeHtml(loginAction)}" autocomplete="on">
107
+ <input type="hidden" name="returnTo" value="${escapeHtml(returnTo)}" />
108
108
  <label>
109
109
  <span class="field-label">Username</span>
110
110
  <input id="username" name="username" type="text" autocomplete="username" required autofocus />
@@ -113,41 +113,29 @@ export function renderLoginPage(basePath) {
113
113
  <span class="field-label">Password</span>
114
114
  <input id="password" name="password" type="password" autocomplete="current-password" />
115
115
  </label>
116
- <p id="error" role="alert">Invalid username or password.</p>
116
+ <p id="error" role="alert"${errorStyle}>Invalid username or password.</p>
117
117
  <button id="submit" type="submit">Sign in</button>
118
118
  </form>
119
119
  </div>
120
- <script>
120
+ <script${nonceAttr}>
121
121
  (function () {
122
- var LOGIN_ACTION = ${JSON.stringify(loginAction)};
123
- var DEFAULT_RETURN_TO = ${JSON.stringify(defaultReturnTo)};
124
- var params = new URLSearchParams(window.location.search);
122
+ var LOGIN_ACTION = ${jsonForScript(loginAction)};
123
+ var RETURN_TO = ${jsonForScript(returnTo)};
125
124
  var errorBox = document.getElementById('error');
126
- if (params.get('error')) errorBox.style.display = 'block';
127
-
128
- function sameOriginReturnTo(value) {
129
- if (typeof value !== 'string' || value === '') return DEFAULT_RETURN_TO;
130
- if (value.charAt(0) !== '/' || value.charAt(1) === '/' || value.indexOf('://') !== -1) {
131
- return DEFAULT_RETURN_TO;
132
- }
133
- return value;
134
- }
135
-
136
125
  var form = document.getElementById('login-form');
137
126
  var submitButton = document.getElementById('submit');
138
127
  form.addEventListener('submit', function (event) {
139
128
  event.preventDefault();
140
129
  submitButton.disabled = true;
141
130
  errorBox.style.display = 'none';
142
- var returnTo = sameOriginReturnTo(params.get('returnTo'));
143
131
  fetch(LOGIN_ACTION, {
144
132
  method: 'POST',
145
- headers: { 'content-type': 'application/json' },
133
+ headers: { 'content-type': 'application/json', accept: 'application/json' },
146
134
  credentials: 'same-origin',
147
135
  body: JSON.stringify({
148
136
  username: document.getElementById('username').value,
149
137
  password: document.getElementById('password').value,
150
- returnTo: returnTo,
138
+ returnTo: RETURN_TO,
151
139
  }),
152
140
  })
153
141
  .then(function (response) {
@@ -155,7 +143,7 @@ export function renderLoginPage(basePath) {
155
143
  return response.json();
156
144
  })
157
145
  .then(function (data) {
158
- window.location.href = data.redirectTo || DEFAULT_RETURN_TO;
146
+ window.location.href = data.redirectTo || RETURN_TO;
159
147
  })
160
148
  .catch(function () {
161
149
  errorBox.style.display = 'block';
@@ -1 +1 @@
1
- {"version":3,"file":"login_page.js","sourceRoot":"","sources":["../../../src/dashboard/login_page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,MAAM,WAAW,GAAG,GAAG,QAAQ,QAAQ,CAAC;IACxC,MAAM,eAAe,GAAG,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;IACzD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAiGc,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;4BACtB,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA6CnD,CAAC;AACT,CAAC"}
1
+ {"version":3,"file":"login_page.js","sourceRoot":"","sources":["../../../src/dashboard/login_page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAqC7C;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;SACzB,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC;SAC1B,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC;SAC1B,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC;SAC1B,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC;SAC/B,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,OAAO,GAAqB,EAAE;IAC9E,MAAM,WAAW,GAAG,GAAG,QAAQ,QAAQ,CAAC;IACxC,MAAM,eAAe,GAAG,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;IACzD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACrE,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7F,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,OAAO;;;;;;;QAOD,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kDA2EiC,UAAU,CAAC,WAAW,CAAC;oDACrB,UAAU,CAAC,QAAQ,CAAC;;;;;;;;;kCAStC,UAAU;;;;SAInC,SAAS;;uBAEK,aAAa,CAAC,WAAW,CAAC;oBAC7B,aAAa,CAAC,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAiCnC,CAAC;AACT,CAAC"}
@@ -11,12 +11,29 @@ export declare const BASE_PLACEHOLDER = "/__DURABLE_DASHBOARD__/";
11
11
  export declare const CONTENT_TYPES: Record<string, string>;
12
12
  /** Content type for a served asset filename, defaulting to octet-stream. */
13
13
  export declare function contentTypeFor(file: string): string;
14
+ /** `id` of the JSON data block `renderIndexHtml` injects; `src/client/durable-client.ts` reads it. */
15
+ export declare const CONFIG_ELEMENT_ID = "durable-dashboard-config";
16
+ /** What the page tells the SPA about the deployment it is mounted in. */
17
+ export interface InjectedConfig {
18
+ /** UI mount base (`/durable`; `''` for a root mount). */
19
+ base: string;
20
+ /** JSON API base (`/durable/api`). */
21
+ api: string;
22
+ }
14
23
  /**
15
24
  * Rewrite the built `index.html` for serving: point Vite's placeholder base at the configured mount
16
- * path, and inject the two globals `src/client/durable-client.ts` reads
17
- * (`window.__DURABLE_BASE__`/`window.__DURABLE_API__`) — the SAME globals
18
- * `@dudousxd/nestjs-durable-dashboard`'s own UI controller injects, so the SPA's client code (ported
19
- * verbatim) needs no adaptation for which server it's running against.
25
+ * path, and hand the SPA the two values `src/client/durable-client.ts` builds URLs from — the UI
26
+ * mount base and the JSON API base.
27
+ *
28
+ * They go in as a JSON DATA BLOCK (`<script type="application/json">`), not as an inline script
29
+ * assigning `window.__DURABLE_BASE__`/`__DURABLE_API__`. A data block is never executed, so no
30
+ * Content-Security-Policy can refuse it; an inline script IS, and a host with
31
+ * `script-src 'self' 'nonce-…'` (`@adonisjs/shield`'s `@nonce`, the recommended setup) silently
32
+ * dropped ours. The globals were then undefined, the SPA fell back to `/durable/api`, and on any
33
+ * other mount path EVERY request from a console that had rendered perfectly well answered 404 —
34
+ * the module script Vite emits is a same-origin file, so the page itself kept loading and the
35
+ * failure looked like a routing bug rather than a policy one. The globals are still read by the
36
+ * client as a fallback (tests, hand-embedding), but this is no longer how the provider speaks.
20
37
  */
21
38
  export declare function renderIndexHtml(html: string, basePath: string, apiBasePath: string): string;
22
39
  //# sourceMappingURL=spa.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"spa.d.ts","sourceRoot":"","sources":["../../../src/dashboard/spa.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;4GAC4G;AAC5G,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AAE1D,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAchD,CAAC;AAEF,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAI3F"}
1
+ {"version":3,"file":"spa.d.ts","sourceRoot":"","sources":["../../../src/dashboard/spa.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;4GAC4G;AAC5G,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AAE1D,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAchD,CAAC;AAEF,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED,sGAAsG;AACtG,eAAO,MAAM,iBAAiB,6BAA6B,CAAC;AAE5D,yEAAyE;AACzE,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAQ3F"}
@@ -28,16 +28,30 @@ export function contentTypeFor(file) {
28
28
  const ext = file.slice(file.lastIndexOf('.'));
29
29
  return CONTENT_TYPES[ext] ?? 'application/octet-stream';
30
30
  }
31
+ /** `id` of the JSON data block `renderIndexHtml` injects; `src/client/durable-client.ts` reads it. */
32
+ export const CONFIG_ELEMENT_ID = 'durable-dashboard-config';
31
33
  /**
32
34
  * Rewrite the built `index.html` for serving: point Vite's placeholder base at the configured mount
33
- * path, and inject the two globals `src/client/durable-client.ts` reads
34
- * (`window.__DURABLE_BASE__`/`window.__DURABLE_API__`) — the SAME globals
35
- * `@dudousxd/nestjs-durable-dashboard`'s own UI controller injects, so the SPA's client code (ported
36
- * verbatim) needs no adaptation for which server it's running against.
35
+ * path, and hand the SPA the two values `src/client/durable-client.ts` builds URLs from — the UI
36
+ * mount base and the JSON API base.
37
+ *
38
+ * They go in as a JSON DATA BLOCK (`<script type="application/json">`), not as an inline script
39
+ * assigning `window.__DURABLE_BASE__`/`__DURABLE_API__`. A data block is never executed, so no
40
+ * Content-Security-Policy can refuse it; an inline script IS, and a host with
41
+ * `script-src 'self' 'nonce-…'` (`@adonisjs/shield`'s `@nonce`, the recommended setup) silently
42
+ * dropped ours. The globals were then undefined, the SPA fell back to `/durable/api`, and on any
43
+ * other mount path EVERY request from a console that had rendered perfectly well answered 404 —
44
+ * the module script Vite emits is a same-origin file, so the page itself kept loading and the
45
+ * failure looked like a routing bug rather than a policy one. The globals are still read by the
46
+ * client as a fallback (tests, hand-embedding), but this is no longer how the provider speaks.
37
47
  */
38
48
  export function renderIndexHtml(html, basePath, apiBasePath) {
39
49
  const based = html.split(BASE_PLACEHOLDER).join(`${basePath}/`);
40
- const inject = `<script>window.__DURABLE_BASE__=${JSON.stringify(basePath)};window.__DURABLE_API__=${JSON.stringify(apiBasePath)};</script>`;
50
+ const config = { base: basePath, api: apiBasePath };
51
+ // `<` escaped as `\u003c` inside the JSON: a data block ends at the first `</script`, and a
52
+ // config value must not be able to close it early. Valid JSON either way.
53
+ const json = JSON.stringify(config).replace(/</g, '\\u003c');
54
+ const inject = `<script type="application/json" id="${CONFIG_ELEMENT_ID}">${json}</script>`;
41
55
  return based.includes('</head>') ? based.replace('</head>', `${inject}</head>`) : inject + based;
42
56
  }
43
57
  //# sourceMappingURL=spa.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"spa.js","sourceRoot":"","sources":["../../../src/dashboard/spa.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;4GAC4G;AAC5G,MAAM,CAAC,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;AAE1D,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,KAAK,EAAE,gCAAgC;IACvC,MAAM,EAAE,gCAAgC;IACxC,MAAM,EAAE,yBAAyB;IACjC,MAAM,EAAE,iCAAiC;IACzC,OAAO,EAAE,iCAAiC;IAC1C,MAAM,EAAE,eAAe;IACvB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,cAAc;IACtB,QAAQ,EAAE,YAAY;IACtB,OAAO,EAAE,WAAW;CACrB,CAAC;AAEF,4EAA4E;AAC5E,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9C,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAC;AAC1D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,QAAgB,EAAE,WAAmB;IACjF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,mCAAmC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,2BAA2B,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,YAAY,CAAC;IAC7I,OAAO,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC;AACnG,CAAC"}
1
+ {"version":3,"file":"spa.js","sourceRoot":"","sources":["../../../src/dashboard/spa.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;4GAC4G;AAC5G,MAAM,CAAC,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;AAE1D,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,KAAK,EAAE,gCAAgC;IACvC,MAAM,EAAE,gCAAgC;IACxC,MAAM,EAAE,yBAAyB;IACjC,MAAM,EAAE,iCAAiC;IACzC,OAAO,EAAE,iCAAiC;IAC1C,MAAM,EAAE,eAAe;IACvB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,cAAc;IACtB,QAAQ,EAAE,YAAY;IACtB,OAAO,EAAE,WAAW;CACrB,CAAC;AAEF,4EAA4E;AAC5E,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9C,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAC;AAC1D,CAAC;AAED,sGAAsG;AACtG,MAAM,CAAC,MAAM,iBAAiB,GAAG,0BAA0B,CAAC;AAU5D;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,QAAgB,EAAE,WAAmB;IACjF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC;IAChE,MAAM,MAAM,GAAmB,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;IACpE,4FAA4F;IAC5F,0EAA0E;IAC1E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,uCAAuC,iBAAiB,KAAK,IAAI,WAAW,CAAC;IAC5F,OAAO,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC;AACnG,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export declare const VERSION = "0.27.0";
2
+ export declare const VERSION = "0.29.0";
3
3
  export { configure } from '../configure.js';
4
4
  export * from './admission.js';
5
5
  export type { AdmissionContext, AdmissionFactory, RedisAdmissionConfig, } from './admissions/factory.js';
package/dist/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export const VERSION = '0.27.0';
2
+ export const VERSION = '0.29.0';
3
3
  // Re-export the configure hook from the package root so `node ace configure` finds it.
4
4
  // AdonisJS imports the package MAIN and reads `configure` off the module namespace —
5
5
  // the `./configure` subpath alone is never consulted.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adonis-agora/durable",
3
- "version": "0.27.0",
3
+ "version": "0.29.0",
4
4
  "description": "Durable cross-app workflows for AdonisJS — deterministic replay engine, AdonisJS binding, ace commands, dashboard, OpenTelemetry, Telescope, testing harness and Redis admission, all in one package. Part of the Agora ecosystem.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -151,7 +151,7 @@
151
151
  }
152
152
  },
153
153
  "devDependencies": {
154
- "@adonis-agora/durable-dashboard": "0.2.3",
154
+ "@adonis-agora/durable-dashboard": "0.2.4",
155
155
  "@adonisjs/assembler": "8.5.0",
156
156
  "@adonisjs/core": "7.5.0",
157
157
  "@adonisjs/lucid": "22.4.2",
@@ -193,7 +193,7 @@
193
193
  "build": "pnpm run clean && tsc -p tsconfig.build.json && pnpm run copy:stubs && pnpm run check:dist",
194
194
  "check:dist": "node ../../scripts/assert-build-output.mjs dist src/index.js",
195
195
  "clean": "rm -rf dist",
196
- "copy:stubs": "mkdir -p dist/stubs/config dist/stubs/database/migrations dist/stubs/make/workflow dist/assets && cp stubs/config/durable.stub dist/stubs/config/durable.stub && cp stubs/config/durable_dashboard.stub dist/stubs/config/durable_dashboard.stub && cp -r stubs/database/migrations/. dist/stubs/database/migrations/ && cp stubs/make/workflow/main.stub dist/stubs/make/workflow/main.stub && cp assets/dashboard.html dist/assets/dashboard.html && rm -rf dist/assets/spa && cp -r ../dashboard/dist/spa dist/assets/spa",
196
+ "copy:stubs": "mkdir -p dist/stubs/config dist/stubs/database/migrations dist/stubs/make/workflow dist/assets && cp stubs/config/durable.stub dist/stubs/config/durable.stub && cp stubs/config/durable_dashboard.stub dist/stubs/config/durable_dashboard.stub && cp -r stubs/database/migrations/. dist/stubs/database/migrations/ && cp stubs/make/workflow/main.stub dist/stubs/make/workflow/main.stub && rm -rf dist/assets/spa && cp -r ../dashboard/dist/spa dist/assets/spa",
197
197
  "test": "vitest run --passWithNoTests",
198
198
  "test:watch": "vitest",
199
199
  "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.tests.json"