@strifeapp/astro 1.4.1 → 1.5.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.
- package/README.md +64 -0
- package/dist/Insights.astro +18 -14
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -11
- package/dist/insights-mode.d.ts +14 -0
- package/dist/insights-mode.d.ts.map +1 -0
- package/dist/insights-mode.js +6 -0
- package/dist/share-middleware.d.ts +36 -0
- package/dist/share-middleware.d.ts.map +1 -0
- package/dist/share-middleware.js +49 -0
- package/dist/share.d.ts +126 -0
- package/dist/share.d.ts.map +1 -0
- package/dist/share.js +104 -0
- package/dist/{vite-plugin-strife-store-B-B_HXbA.js → vite-plugin-strife-store-Ch0cgrwA.js} +4 -0
- package/dist/vite-plugin-strife-store-entry.js +1 -1
- package/dist/vite-plugin-strife-store.d.ts.map +1 -1
- package/package.json +13 -5
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ Official [Strife](https://strife.app) integration for [Astro](https://astro.buil
|
|
|
11
11
|
- [Usage](#usage)
|
|
12
12
|
- [Reading content](#reading-content)
|
|
13
13
|
- [Telemetry: `<Insights />`](#telemetry-insights)
|
|
14
|
+
- [Share links](#share-links)
|
|
14
15
|
- [TypeScript: typing `strife:store`](#typescript-typing-strifestore)
|
|
15
16
|
- [Direct Vite plugin](#direct-vite-plugin)
|
|
16
17
|
- [Configuration](#configuration)
|
|
@@ -100,6 +101,69 @@ On every page load it reports Core Web Vitals (LCP, INP, CLS, FCP, TTFB) and, wh
|
|
|
100
101
|
|
|
101
102
|
> The API only stores a beacon when its `Origin` is one of the team's registered domains. For local development, run the API in `Development` and add `localhost` to your team's `Domains`.
|
|
102
103
|
|
|
104
|
+
> **Content Security Policy:** if your site sends a CSP header, allow the insights endpoint in `connect-src` (e.g. `connect-src 'self' https://api.strife.app`) — otherwise the browser blocks the beacon (a CSP violation is logged to the console; no request is sent and nothing is stored). Use your custom `endpoint`'s origin if you overrode it.
|
|
105
|
+
|
|
106
|
+
Inside the Strife live preview (`Astro.locals.editMode`) only the accessibility audit runs; on a [share link](#share-links) (`Astro.locals.share`) the component renders nothing and sends no beacon at all.
|
|
107
|
+
|
|
108
|
+
### Share links
|
|
109
|
+
|
|
110
|
+
An editor can hand a reviewer a link to a frozen, unpublished version of a document: `{origin}{locale root prefix}/share/{guid}` — for example `https://example.com/share/0123…cdef` or `https://example.com/sv/share/0123…cdef`. The integration registers a `pre` middleware (`@strifeapp/astro/share-middleware`) that resolves such a request to its share snapshot in the `Content/ByUrl` index — for the locale Astro resolved (`context.currentLocale`) — and either sets `Astro.locals.share` or answers with **your 404 page** (unknown, expired or revoked links look like content that does not exist). Both responses carry `X-Robots-Tag: noindex, nofollow`, `Cache-Control: private, no-store` and `Referrer-Policy: no-referrer`; edit mode is forced off on share routes, so `<LivePreview />` never activates there.
|
|
111
|
+
|
|
112
|
+
You author the page — it renders in your own layout. Copy [`templates/share-page.astro`](https://github.com/wieldyapp/wieldy/blob/master/src/sdk/js/src/packages/astro/templates/share-page.astro) to `src/pages/share/[guid].astro`:
|
|
113
|
+
|
|
114
|
+
```astro
|
|
115
|
+
---
|
|
116
|
+
export const prerender = false; // rendered on demand — never prebuilt
|
|
117
|
+
import Layout from '../../layouts/Layout.astro';
|
|
118
|
+
|
|
119
|
+
const { name, expiresAt, locale, content } = Astro.locals.share!;
|
|
120
|
+
---
|
|
121
|
+
<Layout title={content.displayName ?? 'Preview'}>
|
|
122
|
+
<aside role="status">{name ? `Preview “${name}”` : 'Preview'} — expires {expiresAt.toISOString()}</aside>
|
|
123
|
+
<h1>{content.heading}</h1>
|
|
124
|
+
</Layout>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`Astro.locals.share` is `{ docId, name, expiresAt: Date, locale, content }`. `content` is the index row for that locale: `docId`, `locale`, `collection`, `displayName`, `url`, `shareName`, `expiresAt`, plus every field you list in `share.fields`, so one lookup both decides the 404 and feeds the render:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
strife({
|
|
131
|
+
share: {
|
|
132
|
+
fields: ['heading', 'body'], // your template fields, projected onto Astro.locals.share.content
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Without `share.fields`, `content` carries the row fields only and the page queries its own fields by `docId` + `locale` (`whereEquals('docId', content.docId)`, `whereEquals('status', 'share')`).
|
|
138
|
+
|
|
139
|
+
| Option | Where | Description |
|
|
140
|
+
| --- | --- | --- |
|
|
141
|
+
| `share.fields` | integration | Extra `Content/ByUrl` fields to project onto `content`. |
|
|
142
|
+
| `share.middleware: false` | integration | Skip the automatic registration; compose the middleware yourself (below). |
|
|
143
|
+
| `resolveLocale(context)` | `createShareMiddleware` | Resolve the request's locale when your site does not use Astro i18n routing. Defaults to `context.currentLocale`. |
|
|
144
|
+
|
|
145
|
+
When the resolved locale has no row in the snapshot (a cookie- or Accept-Language-driven locale the draft never had, a link pasted under another prefix), the middleware serves the snapshot's own `shareLocale` row instead of the 404 — the same fallback as the .NET SDK. If your site resolves its locale in its own middleware (a cookie, a header, its own path scheme), Astro's `currentLocale` is not enough — opt out of the automatic registration and compose the middleware where your locale is known:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
// src/middleware.ts
|
|
149
|
+
import { sequence } from 'astro:middleware';
|
|
150
|
+
import { createShareMiddleware } from '@strifeapp/astro/share-middleware';
|
|
151
|
+
|
|
152
|
+
export const onRequest = sequence(
|
|
153
|
+
myLocaleMiddleware,
|
|
154
|
+
createShareMiddleware({ resolveLocale: (context) => context.locals.locale }),
|
|
155
|
+
);
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Keep these in mind:
|
|
159
|
+
|
|
160
|
+
- The share guid is the link's secret. Render `name` as text only (never `set:html`), emit no Open Graph tags on the page, keep `/share/*` out of CDN caching rules and analytics, and keep access-log retention short — a bearer URL is inherently logged by proxies. The middleware logs nothing on a hit and never logs the guid.
|
|
161
|
+
- `/share/{guid}` and `/{one segment}/share/{guid}` are reserved by the convention; the prefix segment is opaque (the locale comes from your resolution, not the path). Only a tail of exactly 32 lowercase hex characters is a share request — a share-shaped path with any other tail (`/help/share/link`) is not claimed by the middleware and reaches your own routes, as in the .NET SDK.
|
|
162
|
+
- A miss is rendered through Astro's rewrite to `/404`. Astro forbids rewriting from an on-demand route to a **prerendered** page, so if your `src/pages/404.astro` is static the middleware answers a bare `404` (headers included) and your adapter or host serves the static 404 page; add `export const prerender = false` to `404.astro` to render it through the rewrite instead.
|
|
163
|
+
- Share links need a `Content/ByUrl` index built from a `@strifeapp/strife` release that includes share links, deployed with `strife push` (the developer docs state the exact versions); until then Strife refuses to create shares for the team, and the route answers your 404 page.
|
|
164
|
+
|
|
165
|
+
`resolveShare(guid, locale)` from `@strifeapp/astro/share` is the same lookup as a function, returning the share context or `null`.
|
|
166
|
+
|
|
103
167
|
### TypeScript: typing `strife:store`
|
|
104
168
|
|
|
105
169
|
Typed ambient declarations for the `strife:store` virtual module are not bundled in this release. Until a typed surface is published, add your own declaration (e.g. in `src/env.d.ts`):
|
package/dist/Insights.astro
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
// consumer's runtime/build (see the integration's env schema).
|
|
25
25
|
import { getSecret } from 'astro:env/server';
|
|
26
26
|
import { decodeSecrets } from '@strifeapp/strife/secrets';
|
|
27
|
+
import { insightsMode } from './insights-mode.js';
|
|
27
28
|
|
|
28
29
|
export interface Props {
|
|
29
30
|
/** Override the collection endpoint. Defaults to the hosted Strife API. */
|
|
@@ -62,29 +63,31 @@ function resolveSiteId(): string | null {
|
|
|
62
63
|
|
|
63
64
|
const site = resolveSiteId();
|
|
64
65
|
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
|
|
66
|
+
// The middleware-set locals decide the audience. We split the work: Web Vitals run
|
|
67
|
+
// only for REAL visitors (they need real-user device/network/interaction variance),
|
|
68
|
+
// while the heavy axe-core accessibility audit runs only in the editor's live
|
|
69
|
+
// preview (`editMode`) — a11y is deterministic per content version, so the editor is
|
|
70
|
+
// the right place for it, and it keeps axe-core off every real visitor entirely. A
|
|
71
|
+
// share link (`share`, STR-2165) is neither: it sends nothing at all — it is not
|
|
72
|
+
// audience traffic, and a beacon would carry the share path, i.e. the guid. Without
|
|
73
|
+
// the middleware, plain sites get Web Vitals exactly as before.
|
|
74
|
+
const mode = insightsMode(Astro.locals);
|
|
73
75
|
---
|
|
74
76
|
|
|
75
|
-
{site && (
|
|
77
|
+
{site && mode !== 'off' && (
|
|
76
78
|
<Fragment>
|
|
77
|
-
<script is:inline define:vars={{ site, endpoint, accessibility,
|
|
78
|
-
window.__strifeInsights = { site, endpoint, accessibility,
|
|
79
|
+
<script is:inline define:vars={{ site, endpoint, accessibility, mode }}>
|
|
80
|
+
window.__strifeInsights = { site, endpoint, accessibility, mode };
|
|
79
81
|
</script>
|
|
80
82
|
<script>
|
|
81
83
|
import { onLCP, onINP, onCLS, onFCP, onTTFB } from 'web-vitals';
|
|
84
|
+
import type { InsightsMode } from './insights-mode.js';
|
|
82
85
|
|
|
83
86
|
const cfg = (window as any).__strifeInsights || {};
|
|
84
87
|
const ENDPOINT: string = cfg.endpoint;
|
|
85
88
|
const SITE: string = cfg.site;
|
|
86
89
|
const RUN_A11Y: boolean = cfg.accessibility !== false;
|
|
87
|
-
const
|
|
90
|
+
const MODE: InsightsMode = cfg.mode;
|
|
88
91
|
|
|
89
92
|
/** Beacon a payload to the collection endpoint (fire-and-forget). */
|
|
90
93
|
function send(payload: Record<string, unknown>) {
|
|
@@ -231,17 +234,18 @@ const editMode = Astro.locals.editMode ?? false;
|
|
|
231
234
|
scheduleAccessibilityAudit();
|
|
232
235
|
}
|
|
233
236
|
|
|
234
|
-
if (
|
|
237
|
+
if (MODE === 'audit') {
|
|
235
238
|
// In the Strife live preview: only the accessibility audit runs. The editor is
|
|
236
239
|
// the right place for the heavy axe-core scan (a11y is deterministic per content
|
|
237
240
|
// version), and it keeps axe-core off every real visitor.
|
|
238
241
|
auditOnce();
|
|
239
242
|
// Astro View Transitions: re-audit the newly loaded page.
|
|
240
243
|
document.addEventListener('astro:page-load', auditOnce);
|
|
241
|
-
} else {
|
|
244
|
+
} else if (MODE === 'vitals') {
|
|
242
245
|
// A real visitor: Web Vitals only, batched on pagehide. No axe-core download/run.
|
|
243
246
|
initWebVitals();
|
|
244
247
|
}
|
|
248
|
+
// 'off' (a share link) never reaches this script: the component renders nothing.
|
|
245
249
|
</script>
|
|
246
250
|
</Fragment>
|
|
247
251
|
)}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
import { AstroIntegration } from 'astro';
|
|
2
2
|
import { IAuthOptions } from 'ravendb';
|
|
3
|
+
import { ShareContext } from './share';
|
|
4
|
+
export type { ShareContent, ShareContext } from './share';
|
|
3
5
|
export interface IntegrationOptions extends IAuthOptions {
|
|
4
6
|
certificate?: string;
|
|
5
7
|
password?: string;
|
|
6
8
|
urls?: string[];
|
|
7
9
|
database?: string;
|
|
8
10
|
collections?: Collection[];
|
|
11
|
+
/** Share links (`/share/{guid}`); see `@strifeapp/astro/share-middleware`. */
|
|
12
|
+
share?: ShareOptions;
|
|
13
|
+
}
|
|
14
|
+
export interface ShareOptions {
|
|
15
|
+
/**
|
|
16
|
+
* Index fields to project onto `Astro.locals.share.content` beside the row fields
|
|
17
|
+
* (your template fields, e.g. `['heading', 'body']`), so the middleware's one
|
|
18
|
+
* lookup also feeds the render. Without it, `content` carries the row fields only
|
|
19
|
+
* and the share page queries its own fields by `docId` + `locale`.
|
|
20
|
+
*/
|
|
21
|
+
fields?: string[];
|
|
22
|
+
/**
|
|
23
|
+
* `false` skips the automatic `pre` registration of the share middleware. Do this
|
|
24
|
+
* when your site resolves its locale in its own middleware: compose
|
|
25
|
+
* `createShareMiddleware({ resolveLocale })` from `@strifeapp/astro/share-middleware`
|
|
26
|
+
* in `src/middleware.ts` instead.
|
|
27
|
+
*/
|
|
28
|
+
middleware?: boolean;
|
|
9
29
|
}
|
|
10
30
|
export interface Collection {
|
|
11
31
|
name: string;
|
|
@@ -21,6 +41,14 @@ declare global {
|
|
|
21
41
|
* e.g. render draft vs published content.
|
|
22
42
|
*/
|
|
23
43
|
editMode?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Set by the share middleware on a `/share/{guid}` request that resolved to a
|
|
46
|
+
* live share snapshot: the snapshot's id, its editor-given name (text only —
|
|
47
|
+
* never `set:html`), when the link expires, the resolved locale, and the
|
|
48
|
+
* `Content/ByUrl` projection to render. Absent on every other request, and
|
|
49
|
+
* on every share miss (the middleware answers those with the site's 404 page).
|
|
50
|
+
*/
|
|
51
|
+
share?: ShareContext;
|
|
24
52
|
}
|
|
25
53
|
}
|
|
26
54
|
}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE1D,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,8EAA8E;IAC9E,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,GAAG,CAAC;QACZ,UAAU,MAAM;YACd;;;;;eAKG;YACH,QAAQ,CAAC,EAAE,OAAO,CAAC;YACnB;;;;;;eAMG;YACH,KAAK,CAAC,EAAE,YAAY,CAAC;SACtB;KACF;CACF;AAMD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,gBAAgB,CAoExF"}
|
package/dist/index.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { envField as e } from "astro/config";
|
|
2
|
-
import { v as
|
|
3
|
-
const
|
|
2
|
+
import { v as i } from "./vite-plugin-strife-store-Ch0cgrwA.js";
|
|
3
|
+
const c = {
|
|
4
4
|
type: "pfx"
|
|
5
5
|
};
|
|
6
|
-
function
|
|
6
|
+
function l(t) {
|
|
7
7
|
return {
|
|
8
8
|
name: "@strife/astro",
|
|
9
9
|
hooks: {
|
|
10
|
-
"astro:config:setup": ({ updateConfig:
|
|
11
|
-
const
|
|
12
|
-
...
|
|
10
|
+
"astro:config:setup": ({ updateConfig: o, addMiddleware: r }) => {
|
|
11
|
+
const s = {
|
|
12
|
+
...c,
|
|
13
13
|
...t ? Object.fromEntries(
|
|
14
|
-
Object.entries(t).filter(([,
|
|
14
|
+
Object.entries(t).filter(([, n]) => n != null)
|
|
15
15
|
) : {}
|
|
16
16
|
};
|
|
17
|
-
|
|
17
|
+
o({
|
|
18
18
|
env: {
|
|
19
19
|
schema: {
|
|
20
20
|
// Consolidated single-var secret (packs urls/database/certificate/password,
|
|
@@ -32,16 +32,19 @@ function p(t) {
|
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
vite: {
|
|
35
|
-
plugins: [
|
|
35
|
+
plugins: [i(s)]
|
|
36
36
|
}
|
|
37
|
-
}),
|
|
37
|
+
}), r({
|
|
38
38
|
entrypoint: "@strifeapp/astro/edit-mode-middleware",
|
|
39
39
|
order: "pre"
|
|
40
|
+
}), s.share?.middleware !== !1 && r({
|
|
41
|
+
entrypoint: "@strifeapp/astro/share-middleware",
|
|
42
|
+
order: "pre"
|
|
40
43
|
});
|
|
41
44
|
}
|
|
42
45
|
}
|
|
43
46
|
};
|
|
44
47
|
}
|
|
45
48
|
export {
|
|
46
|
-
|
|
49
|
+
l as default
|
|
47
50
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which telemetry `<Insights />` runs for a request, from the middleware-set locals:
|
|
3
|
+
* - `vitals`: a real visitor — Core Web Vitals only;
|
|
4
|
+
* - `audit`: the Strife live preview (edit mode) — the axe-core accessibility audit only;
|
|
5
|
+
* - `off`: a share link (R14) — nothing at all. A share is not audience traffic, and a
|
|
6
|
+
* beacon would carry the share path, i.e. the guid.
|
|
7
|
+
* Pure, so the gate is unit-tested; Insights.astro only forwards the result.
|
|
8
|
+
*/
|
|
9
|
+
export type InsightsMode = 'vitals' | 'audit' | 'off';
|
|
10
|
+
export declare function insightsMode(locals: {
|
|
11
|
+
editMode?: boolean;
|
|
12
|
+
share?: unknown;
|
|
13
|
+
}): InsightsMode;
|
|
14
|
+
//# sourceMappingURL=insights-mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insights-mode.d.ts","sourceRoot":"","sources":["../src/insights-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;AAEtD,wBAAgB,YAAY,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,YAAY,CAI1F"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { APIContext, MiddlewareHandler } from 'astro';
|
|
2
|
+
import { ResolveShareOptions } from './share';
|
|
3
|
+
/**
|
|
4
|
+
* Share-link middleware (STR-2165). Registered `pre` by the integration (see
|
|
5
|
+
* src/index.ts) unless `share.middleware` is `false`; also exported as
|
|
6
|
+
* `createShareMiddleware` so a site that resolves its locale in its own middleware
|
|
7
|
+
* can compose it there with `resolveLocale`.
|
|
8
|
+
*
|
|
9
|
+
* For a share path (`/share/{guid}` after an optional locale root prefix, where the
|
|
10
|
+
* tail is a valid guid — 32 lowercase hex characters) it looks the snapshot up for
|
|
11
|
+
* the site's resolved locale and:
|
|
12
|
+
* - on a hit sets `Astro.locals.share = { docId, name, expiresAt, locale, content }`
|
|
13
|
+
* and lets the site's `src/pages/share/[guid].astro` render it;
|
|
14
|
+
* - on any miss renders the site's 404 page through Astro's rewrite, re-wrapped so
|
|
15
|
+
* the status is 404 (Astro answers a rewrite with 200).
|
|
16
|
+
* Both carry `X-Robots-Tag: noindex, nofollow`, `Cache-Control: private, no-store`
|
|
17
|
+
* and `Referrer-Policy: no-referrer`. Edit mode is forced off on share routes, so
|
|
18
|
+
* `<LivePreview />` never activates there. Nothing is logged on a hit, and the guid
|
|
19
|
+
* is never logged. Every other path passes through untouched — including a
|
|
20
|
+
* share-shaped path whose tail is not a guid (`/help/share/link`): as in the .NET
|
|
21
|
+
* resolver, that is not a share request but an ordinary site route.
|
|
22
|
+
*/
|
|
23
|
+
export interface ShareMiddlewareOptions extends ResolveShareOptions {
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the locale of the current request. Defaults to Astro's
|
|
26
|
+
* `context.currentLocale` (i18n routing). A site that resolves its locale itself
|
|
27
|
+
* — from a cookie, a header, its own path scheme — must pass this, or a
|
|
28
|
+
* multi-locale share resolves the wrong (or no) row.
|
|
29
|
+
*/
|
|
30
|
+
resolveLocale?: (context: APIContext) => string | undefined | Promise<string | undefined>;
|
|
31
|
+
}
|
|
32
|
+
export declare const SHARE_RESPONSE_HEADERS: Readonly<Record<string, string>>;
|
|
33
|
+
export declare function createShareMiddleware(options?: ShareMiddlewareOptions): MiddlewareHandler;
|
|
34
|
+
/** The default instance the integration registers via `addMiddleware`. */
|
|
35
|
+
export declare const onRequest: MiddlewareHandler;
|
|
36
|
+
//# sourceMappingURL=share-middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"share-middleware.d.ts","sourceRoot":"","sources":["../src/share-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,EAA4C,KAAK,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE7F;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,sBAAuB,SAAQ,mBAAmB;IACjE;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CAC3F;AAED,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIlE,CAAC;AAEH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,iBAAiB,CA0B7F;AAED,0EAA0E;AAC1E,eAAO,MAAM,SAAS,EAAE,iBAA2C,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { matchSharePath as u, isShareGuid as i, lookupShare as h } from "./share.js";
|
|
2
|
+
const d = Object.freeze({
|
|
3
|
+
"X-Robots-Tag": "noindex, nofollow",
|
|
4
|
+
"Cache-Control": "private, no-store",
|
|
5
|
+
"Referrer-Policy": "no-referrer"
|
|
6
|
+
});
|
|
7
|
+
function f(r = {}) {
|
|
8
|
+
return async (e, a) => {
|
|
9
|
+
const t = u(e.url.pathname);
|
|
10
|
+
if (t === null || !i(t)) return a();
|
|
11
|
+
e.locals.editMode = !1;
|
|
12
|
+
const o = r.resolveLocale ? await r.resolveLocale(e) : e.currentLocale, n = await h(t, o, r);
|
|
13
|
+
return n.share === null ? (n.reason === "query_error" && console.warn("[strife] share lookup failed (reason=query_error); answering 404"), w(a)) : (e.locals.share = n.share, l(await a()));
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const S = f();
|
|
17
|
+
async function w(r) {
|
|
18
|
+
let e;
|
|
19
|
+
try {
|
|
20
|
+
e = await r("/404");
|
|
21
|
+
} catch {
|
|
22
|
+
e = new Response(null, { status: 404 });
|
|
23
|
+
}
|
|
24
|
+
return l(e, 404);
|
|
25
|
+
}
|
|
26
|
+
function l(r, e) {
|
|
27
|
+
const a = e !== void 0 && r.status !== e ? s(r, e) : r, t = (o) => {
|
|
28
|
+
for (const [n, c] of Object.entries(d))
|
|
29
|
+
o.set(n, c);
|
|
30
|
+
};
|
|
31
|
+
try {
|
|
32
|
+
return t(a.headers), a;
|
|
33
|
+
} catch {
|
|
34
|
+
const o = s(a, a.status);
|
|
35
|
+
return t(o.headers), o;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function s(r, e) {
|
|
39
|
+
return new Response(r.body, {
|
|
40
|
+
status: e,
|
|
41
|
+
statusText: r.statusText,
|
|
42
|
+
headers: new Headers(r.headers)
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
d as SHARE_RESPONSE_HEADERS,
|
|
47
|
+
f as createShareMiddleware,
|
|
48
|
+
S as onRequest
|
|
49
|
+
};
|
package/dist/share.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { IDocumentStore } from 'ravendb';
|
|
2
|
+
/**
|
|
3
|
+
* Share links (STR-2165): resolve a `/share/{guid}` request to the one live share
|
|
4
|
+
* snapshot its guid names, reading the `Content/ByUrl` projection for the resolved
|
|
5
|
+
* locale. Locale handling mirrors the .NET SDK's `DefaultRouteResolver` exactly:
|
|
6
|
+
* - with a resolved locale the query carries a locale clause; when it yields no row
|
|
7
|
+
* (a cookie- or Accept-Language-driven locale the draft never had, a link pasted
|
|
8
|
+
* under another prefix) the guid is re-queried without the clause (bounded to
|
|
9
|
+
* `MAX_SHARE_LOCALE_ROWS`) and only the snapshot's own row — `locale` equal to
|
|
10
|
+
* its `shareLocale` — is kept, so the preview is served rather than hidden;
|
|
11
|
+
* - without a resolved locale the guid-only query pages every row of the snapshot
|
|
12
|
+
* (again bounded to `MAX_SHARE_LOCALE_ROWS`, never just the first two), and more
|
|
13
|
+
* than one candidate row is decided by the same rule: the `shareLocale` row wins,
|
|
14
|
+
* and anything other than exactly one such row is an `ambiguous_locale` miss.
|
|
15
|
+
* Pure with respect to Astro — the store is injectable, so the lookup is
|
|
16
|
+
* unit-testable without RavenDB; `resolveShare` without a store reads the
|
|
17
|
+
* integration's `strife:store` virtual module.
|
|
18
|
+
*
|
|
19
|
+
* The guid is the bearer secret of the link: nothing in this module logs it, and
|
|
20
|
+
* a thrown query (an index build that predates share links, an unreachable store)
|
|
21
|
+
* is a miss, never an exception that could surface it on an error page.
|
|
22
|
+
*/
|
|
23
|
+
/** The content index the integration queries; deployed by `strife push`. */
|
|
24
|
+
export declare const SHARE_INDEX_NAME = "Content/ByUrl";
|
|
25
|
+
/** A share guid is exactly 32 lowercase hex characters — nothing looser. */
|
|
26
|
+
export declare const SHARE_GUID_PATTERN: RegExp;
|
|
27
|
+
/**
|
|
28
|
+
* Upper bound on locales one snapshot can carry rows for; a guid-only query (no
|
|
29
|
+
* resolved locale, or the locale fallback) never scans further. Same constant as the
|
|
30
|
+
* .NET resolver's `MaxShareLocaleRows`.
|
|
31
|
+
*/
|
|
32
|
+
export declare const MAX_SHARE_LOCALE_ROWS = 64;
|
|
33
|
+
/**
|
|
34
|
+
* Row fields every share lookup projects from the index: the share metadata plus
|
|
35
|
+
* what a page needs to pick a layout (`collection`, `displayName`, `url`). `deleted`
|
|
36
|
+
* is not stored in the index; RavenDB's default projection behaviour reads it from
|
|
37
|
+
* the document, which is exactly the soft-delete check we want. Site-specific
|
|
38
|
+
* template fields come from the `fields` option.
|
|
39
|
+
*/
|
|
40
|
+
export declare const SHARE_ROW_FIELDS: readonly ["docId", "locale", "collection", "displayName", "url", "status", "shareGuid", "shareName", "expiresAt", "shareLocale", "createdAt", "changedAt", "publishedAt", "origin", "labels", "deleted"];
|
|
41
|
+
/**
|
|
42
|
+
* The `Content/ByUrl` row for the snapshot in the resolved locale — the same
|
|
43
|
+
* projected, locale-translated object a page gets when it queries the index, plus
|
|
44
|
+
* any site fields passed through `fields`.
|
|
45
|
+
*/
|
|
46
|
+
export interface ShareContent {
|
|
47
|
+
docId: string;
|
|
48
|
+
locale: string;
|
|
49
|
+
status: 'share';
|
|
50
|
+
shareGuid: string;
|
|
51
|
+
shareName?: string | null;
|
|
52
|
+
expiresAt: string;
|
|
53
|
+
/** The locale the editor was viewing when sharing — the one the link targets. */
|
|
54
|
+
shareLocale?: string | null;
|
|
55
|
+
collection?: string | null;
|
|
56
|
+
displayName?: string | null;
|
|
57
|
+
url?: string | null;
|
|
58
|
+
[field: string]: unknown;
|
|
59
|
+
}
|
|
60
|
+
/** What a share page sees on `Astro.locals.share`. */
|
|
61
|
+
export interface ShareContext {
|
|
62
|
+
/** The snapshot's document id (`{canonicalId}/share/{guid}`). Never log it. */
|
|
63
|
+
docId: string;
|
|
64
|
+
/** The editor-given name, or `null`. Render as text only — never `set:html`. */
|
|
65
|
+
name: string | null;
|
|
66
|
+
/** UTC instant after which the link stops resolving. */
|
|
67
|
+
expiresAt: Date;
|
|
68
|
+
/** The locale the row was resolved for. */
|
|
69
|
+
locale: string;
|
|
70
|
+
/** The index projection for that locale; render this. */
|
|
71
|
+
content: ShareContent;
|
|
72
|
+
}
|
|
73
|
+
export type ShareMissReason = 'malformed_guid' | 'not_found' | 'ambiguous_locale' | 'deleted' | 'no_expiry' | 'expired' | 'query_error';
|
|
74
|
+
export type ShareLookup = {
|
|
75
|
+
share: ShareContext;
|
|
76
|
+
reason: null;
|
|
77
|
+
} | {
|
|
78
|
+
share: null;
|
|
79
|
+
reason: ShareMissReason;
|
|
80
|
+
};
|
|
81
|
+
export interface ResolveShareOptions {
|
|
82
|
+
/** The document store to query. Defaults to the integration's `strife:store`. */
|
|
83
|
+
store?: IDocumentStore;
|
|
84
|
+
/**
|
|
85
|
+
* Extra index fields to project onto `content` (your template fields, e.g.
|
|
86
|
+
* `['heading', 'body']`), so one lookup both decides the 404 and feeds the render.
|
|
87
|
+
* Defaults to the integration's `share.fields` option.
|
|
88
|
+
*/
|
|
89
|
+
fields?: readonly string[];
|
|
90
|
+
/** Clock, for tests. */
|
|
91
|
+
now?: () => Date;
|
|
92
|
+
}
|
|
93
|
+
export declare function isShareGuid(value: unknown): value is string;
|
|
94
|
+
/**
|
|
95
|
+
* Matches the share convention `/share/{guid}` after an optional single locale root
|
|
96
|
+
* prefix segment (`/sv/share/{guid}`, `/svenska/share/{guid}`), with or without a
|
|
97
|
+
* trailing slash. Returns the raw guid segment — validate it with `isShareGuid` — or
|
|
98
|
+
* `null` when the path is not share-shaped. The prefix is opaque: the locale comes
|
|
99
|
+
* from the site's own resolution, never from the path.
|
|
100
|
+
*/
|
|
101
|
+
export declare function matchSharePath(pathname: string): string | null;
|
|
102
|
+
/**
|
|
103
|
+
* Picks the single live snapshot row or names the miss. Mirrors the .NET SDK's
|
|
104
|
+
* `DefaultRouteResolver.ClassifyShareRows` so both site SDKs agree on "live": with
|
|
105
|
+
* more than one row (several locales of one snapshot and no locale resolver to pick
|
|
106
|
+
* between them) the share's own locale wins — the row whose `locale` equals its
|
|
107
|
+
* `shareLocale` — and anything other than exactly one such row is `ambiguous_locale`.
|
|
108
|
+
*/
|
|
109
|
+
export declare function classifyShareRows(rows: readonly Record<string, unknown>[], now: Date): ShareLookup;
|
|
110
|
+
/**
|
|
111
|
+
* Looks a share up and reports the outcome with its miss reason. A malformed guid
|
|
112
|
+
* never reaches the store. `locale` is the site's resolved locale: the query carries
|
|
113
|
+
* it as a clause, and when that yields no row the guid is re-queried without the
|
|
114
|
+
* clause and only the snapshot's own `shareLocale` row is kept (the .NET resolver's
|
|
115
|
+
* locale fallback). When `locale` is `undefined` (a single-locale site without Astro
|
|
116
|
+
* i18n) the clause is omitted from the start and the query pages every row of the
|
|
117
|
+
* snapshot; more than one row then resolves to the `shareLocale` row, or is an
|
|
118
|
+
* `ambiguous_locale` miss (see `classifyShareRows`).
|
|
119
|
+
*/
|
|
120
|
+
export declare function lookupShare(guid: string, locale: string | undefined, options?: ResolveShareOptions): Promise<ShareLookup>;
|
|
121
|
+
/**
|
|
122
|
+
* Resolves `guid` in `locale` to the share context, or `null` on any miss
|
|
123
|
+
* (unknown, malformed, deleted, expired, missing expiry, query failure).
|
|
124
|
+
*/
|
|
125
|
+
export declare function resolveShare(guid: string, locale: string | undefined, options?: ResolveShareOptions): Promise<ShareContext | null>;
|
|
126
|
+
//# sourceMappingURL=share.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"share.d.ts","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,kBAAkB,CAAC;AAEhD,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,QAAmB,CAAC;AAEnD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,0MAiBnB,CAAC;AAEX;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,wDAAwD;IACxD,SAAS,EAAE,IAAI,CAAC;IAChB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,OAAO,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,MAAM,eAAe,GACvB,gBAAgB,GAChB,WAAW,GACX,kBAAkB,GAClB,SAAS,GACT,WAAW,GACX,SAAS,GACT,aAAa,CAAC;AAElB,MAAM,MAAM,WAAW,GACnB;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,IAAI,CAAA;CAAE,GACrC;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,CAAC;AAE7C,MAAM,WAAW,mBAAmB;IAClC,iFAAiF;IACjF,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE3D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG9D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,GAAG,WAAW,CA2BlG;AAcD;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,WAAW,CAAC,CAetB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAE9B"}
|
package/dist/share.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
const i = "Content/ByUrl", c = /^[0-9a-f]{32}$/, E = 64, h = [
|
|
2
|
+
"docId",
|
|
3
|
+
"locale",
|
|
4
|
+
"collection",
|
|
5
|
+
"displayName",
|
|
6
|
+
"url",
|
|
7
|
+
"status",
|
|
8
|
+
"shareGuid",
|
|
9
|
+
"shareName",
|
|
10
|
+
"expiresAt",
|
|
11
|
+
"shareLocale",
|
|
12
|
+
"createdAt",
|
|
13
|
+
"changedAt",
|
|
14
|
+
"publishedAt",
|
|
15
|
+
"origin",
|
|
16
|
+
"labels",
|
|
17
|
+
"deleted"
|
|
18
|
+
];
|
|
19
|
+
function f(e) {
|
|
20
|
+
return typeof e == "string" && c.test(e);
|
|
21
|
+
}
|
|
22
|
+
function p(e) {
|
|
23
|
+
const r = /^\/(?:[^/]+\/)?share\/([^/]+)\/?$/.exec(e);
|
|
24
|
+
return r ? r[1] : null;
|
|
25
|
+
}
|
|
26
|
+
function d(e, r) {
|
|
27
|
+
if (e.length === 0) return { share: null, reason: "not_found" };
|
|
28
|
+
let t = e[0];
|
|
29
|
+
if (e.length > 1) {
|
|
30
|
+
const a = e.filter(u);
|
|
31
|
+
if (a.length !== 1) return { share: null, reason: "ambiguous_locale" };
|
|
32
|
+
t = a[0];
|
|
33
|
+
}
|
|
34
|
+
if (t.deleted === !0) return { share: null, reason: "deleted" };
|
|
35
|
+
const s = m(t.expiresAt);
|
|
36
|
+
if (s === null) return { share: null, reason: "no_expiry" };
|
|
37
|
+
if (s.getTime() <= r.getTime()) return { share: null, reason: "expired" };
|
|
38
|
+
const n = t;
|
|
39
|
+
return {
|
|
40
|
+
share: {
|
|
41
|
+
docId: String(n.docId),
|
|
42
|
+
name: typeof n.shareName == "string" ? n.shareName : null,
|
|
43
|
+
expiresAt: s,
|
|
44
|
+
locale: String(n.locale),
|
|
45
|
+
content: n
|
|
46
|
+
},
|
|
47
|
+
reason: null
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function u(e) {
|
|
51
|
+
return e.shareLocale != null && e.locale === e.shareLocale;
|
|
52
|
+
}
|
|
53
|
+
function m(e) {
|
|
54
|
+
if (e instanceof Date) return Number.isNaN(e.getTime()) ? null : e;
|
|
55
|
+
if (typeof e != "string" || e === "") return null;
|
|
56
|
+
const r = new Date(e);
|
|
57
|
+
return Number.isNaN(r.getTime()) ? null : r;
|
|
58
|
+
}
|
|
59
|
+
async function y(e, r, t = {}) {
|
|
60
|
+
if (!f(e)) return { share: null, reason: "malformed_guid" };
|
|
61
|
+
const s = t.now ?? (() => /* @__PURE__ */ new Date());
|
|
62
|
+
let n;
|
|
63
|
+
try {
|
|
64
|
+
const { store: a, fields: l } = await _(t);
|
|
65
|
+
n = await A(a, e, r, l);
|
|
66
|
+
} catch {
|
|
67
|
+
return { share: null, reason: "query_error" };
|
|
68
|
+
}
|
|
69
|
+
return d(n, s());
|
|
70
|
+
}
|
|
71
|
+
async function g(e, r, t = {}) {
|
|
72
|
+
return (await y(e, r, t)).share;
|
|
73
|
+
}
|
|
74
|
+
async function A(e, r, t, s) {
|
|
75
|
+
const n = e.openSession();
|
|
76
|
+
try {
|
|
77
|
+
const a = S(s);
|
|
78
|
+
let l = n.query({ indexName: i }).whereEquals("shareGuid", r).whereEquals("status", "share");
|
|
79
|
+
t && (l = l.whereEquals("locale", t));
|
|
80
|
+
const o = await l.selectFields(a).take(t ? 2 : 64).all();
|
|
81
|
+
return o.length > 0 || !t ? o : (await n.query({ indexName: i }).whereEquals("shareGuid", r).whereEquals("status", "share").selectFields(a).take(64).all()).filter(u);
|
|
82
|
+
} finally {
|
|
83
|
+
n.dispose();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function S(e) {
|
|
87
|
+
return [.../* @__PURE__ */ new Set([...h, ...e ?? []])];
|
|
88
|
+
}
|
|
89
|
+
async function _(e) {
|
|
90
|
+
if (e.store) return { store: e.store, fields: e.fields };
|
|
91
|
+
const r = await import("strife:store");
|
|
92
|
+
return { store: r.store, fields: e.fields ?? r.shareOptions?.fields };
|
|
93
|
+
}
|
|
94
|
+
export {
|
|
95
|
+
E as MAX_SHARE_LOCALE_ROWS,
|
|
96
|
+
c as SHARE_GUID_PATTERN,
|
|
97
|
+
i as SHARE_INDEX_NAME,
|
|
98
|
+
h as SHARE_ROW_FIELDS,
|
|
99
|
+
d as classifyShareRows,
|
|
100
|
+
f as isShareGuid,
|
|
101
|
+
y as lookupShare,
|
|
102
|
+
p as matchSharePath,
|
|
103
|
+
g as resolveShare
|
|
104
|
+
};
|
|
@@ -96,6 +96,10 @@ function n(o) {
|
|
|
96
96
|
// operator-controlled path). The store only connects and reads — Astro no
|
|
97
97
|
// longer deploys the index or seeds templates.
|
|
98
98
|
export { store };
|
|
99
|
+
|
|
100
|
+
// Non-secret share-link options (@strifeapp/astro/share reads the projection
|
|
101
|
+
// fields from here when the auto-registered middleware resolves a share).
|
|
102
|
+
export const shareOptions = defaultConfig.share || {};
|
|
99
103
|
`;
|
|
100
104
|
}
|
|
101
105
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-plugin-strife-store.d.ts","sourceRoot":"","sources":["../src/vite-plugin-strife-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAKlD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"vite-plugin-strife-store.d.ts","sourceRoot":"","sources":["../src/vite-plugin-strife-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAKlD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAiH9E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strifeapp/astro",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Official Strife integration for Astro — connect your Astro site to a RavenDB-backed Strife content store via a strife:store virtual module.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astro-integration",
|
|
@@ -39,6 +39,14 @@
|
|
|
39
39
|
"types": "./dist/edit-mode-middleware.d.ts",
|
|
40
40
|
"import": "./dist/edit-mode-middleware.js"
|
|
41
41
|
},
|
|
42
|
+
"./share": {
|
|
43
|
+
"types": "./dist/share.d.ts",
|
|
44
|
+
"import": "./dist/share.js"
|
|
45
|
+
},
|
|
46
|
+
"./share-middleware": {
|
|
47
|
+
"types": "./dist/share-middleware.d.ts",
|
|
48
|
+
"import": "./dist/share-middleware.js"
|
|
49
|
+
},
|
|
42
50
|
"./LivePreview.astro": "./dist/LivePreview.astro",
|
|
43
51
|
"./Insights.astro": "./dist/Insights.astro",
|
|
44
52
|
"./vite-plugin-strife-store": "./dist/vite-plugin-strife-store-entry.js"
|
|
@@ -63,17 +71,17 @@
|
|
|
63
71
|
"@strifeapp/strife": "^1.1.0",
|
|
64
72
|
"axe-core": "^4.11.0",
|
|
65
73
|
"dotenv": "^17.2.3",
|
|
66
|
-
"jose": "^
|
|
74
|
+
"jose": "^6.2.9",
|
|
67
75
|
"ravendb": "^7.1.4",
|
|
68
76
|
"serialize-javascript": "^7.0.5",
|
|
69
|
-
"web-vitals": "^
|
|
77
|
+
"web-vitals": "^6.1.1"
|
|
70
78
|
},
|
|
71
79
|
"devDependencies": {
|
|
72
80
|
"@types/serialize-javascript": "^5.0.4",
|
|
73
|
-
"astro": "^6.
|
|
81
|
+
"astro": "^6.4.8",
|
|
74
82
|
"rimraf": "^6.0.1",
|
|
75
83
|
"typescript": "^5.7.3",
|
|
76
|
-
"vite": "^7.
|
|
84
|
+
"vite": "^7.3.6",
|
|
77
85
|
"vite-plugin-dts": "^4.5.3",
|
|
78
86
|
"vitest": "^4.1.7"
|
|
79
87
|
},
|