@formicoidea/labre-core 0.36.0 → 0.38.1
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/dist/_pkgs/affine-block-frame/frame-manager.d.ts +31 -0
- package/dist/_pkgs/affine-block-frame/frame-manager.js +62 -2
- package/dist/_pkgs/affine-block-frame/frame-tool.js +6 -2
- package/dist/_pkgs/affine-block-surface/extensions/audit.js +12 -34
- package/dist/_pkgs/affine-block-surface/extensions/reading-widget.d.ts +25 -13
- package/dist/_pkgs/affine-block-surface/extensions/reading-widget.js +58 -24
- package/dist/_pkgs/affine-block-surface/extensions/reading.d.ts +83 -7
- package/dist/_pkgs/affine-block-surface/extensions/reading.js +51 -42
- package/dist/_pkgs/affine-block-surface/extensions/validation.d.ts +321 -16
- package/dist/_pkgs/affine-block-surface/extensions/validation.js +945 -62
- package/dist/_pkgs/affine-block-surface/framework-background/facts.d.ts +24 -0
- package/dist/_pkgs/affine-block-surface/framework-background/facts.js +31 -0
- package/dist/_pkgs/affine-block-surface/framework-background/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-surface/framework-background/index.js +1 -0
- package/dist/_pkgs/affine-block-surface/framework-background/stacking.d.ts +131 -0
- package/dist/_pkgs/affine-block-surface/framework-background/stacking.js +184 -0
- package/dist/_pkgs/affine-block-surface/utils/sort.d.ts +15 -1
- package/dist/_pkgs/affine-block-surface/utils/sort.js +30 -31
- package/dist/_pkgs/affine-block-surface/view.js +5 -0
- package/dist/_pkgs/affine-gfx-group/element-renderer/utils.js +3 -1
- package/dist/_pkgs/affine-gfx-template/index.d.ts +1 -0
- package/dist/_pkgs/affine-gfx-template/index.js +1 -0
- package/dist/_pkgs/affine-gfx-template/make-snapshot.d.ts +16 -2
- package/dist/_pkgs/affine-gfx-template/make-snapshot.js +43 -4
- package/dist/_pkgs/affine-gfx-template/services/template-middlewares.js +1 -0
- package/dist/_pkgs/affine-gfx-template/services/template.d.ts +6 -0
- package/dist/_pkgs/affine-gfx-template/services/template.js +6 -0
- package/dist/_pkgs/affine-gfx-template/snapshot-from-action.d.ts +20 -0
- package/dist/_pkgs/affine-gfx-template/snapshot-from-action.js +205 -0
- package/dist/_pkgs/affine-gfx-template/toolbar/template-panel.js +4 -0
- package/dist/_pkgs/affine-gfx-template/toolbar/template-type.d.ts +13 -0
- package/dist/_pkgs/affine-inline-link/link-node/configs/toolbar.d.ts +11 -17
- package/dist/_pkgs/affine-inline-link/link-node/configs/toolbar.js +55 -14
- package/dist/_pkgs/affine-model/elements/cynefin/cynefin.d.ts +9 -20
- package/dist/_pkgs/affine-model/elements/cynefin/cynefin.js +7 -28
- package/dist/_pkgs/affine-model/elements/edgy/board.d.ts +9 -21
- package/dist/_pkgs/affine-model/elements/edgy/board.js +8 -29
- package/dist/_pkgs/affine-model/elements/edgy/facets.d.ts +14 -28
- package/dist/_pkgs/affine-model/elements/edgy/facets.js +12 -36
- package/dist/_pkgs/affine-model/elements/estuarine/estuarine.d.ts +9 -19
- package/dist/_pkgs/affine-model/elements/estuarine/estuarine.js +7 -27
- package/dist/_pkgs/affine-shared/services/link-preview-service/link-preview-service.d.ts +28 -0
- package/dist/_pkgs/affine-shared/services/link-preview-service/link-preview-service.js +20 -3
- package/dist/translations.js +8 -2
- package/package.json +1 -1
|
@@ -32,19 +32,21 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
32
32
|
}
|
|
33
33
|
return useValue ? value : void 0;
|
|
34
34
|
};
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import { backgroundIncludesPoint } from '../framework-background/index.js';
|
|
35
|
+
import { field } from '../../../std/gfx/index.js';
|
|
36
|
+
import { FrameworkBackgroundElementModel } from '../framework-background/index.js';
|
|
38
37
|
/**
|
|
39
38
|
* A blank white board for free-form EDGY modelling: the user places EDGY base
|
|
40
39
|
* shapes and connectors on top of it and the board grants them the dependency
|
|
41
40
|
* spotlight-on-hover behavior (see the surface `Spotlight` extension).
|
|
42
41
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
42
|
+
* An INSTANCE of the framework-background primitive
|
|
43
|
+
* ({@link FrameworkBackgroundElementModel}): the passive-canvas geometry —
|
|
44
|
+
* non-connectable, picked by its border band, lassoed and intersected as a
|
|
45
|
+
* rotated rectangle — comes from the primitive, and the fields below are the
|
|
46
|
+
* persisted document, unchanged.
|
|
45
47
|
*/
|
|
46
48
|
let EdgyBoardElementModel = (() => {
|
|
47
|
-
let _classSuper =
|
|
49
|
+
let _classSuper = FrameworkBackgroundElementModel;
|
|
48
50
|
let _resizeEnabled_decorators;
|
|
49
51
|
let _resizeEnabled_initializers = [];
|
|
50
52
|
let _resizeEnabled_extraInitializers = [];
|
|
@@ -73,29 +75,6 @@ let EdgyBoardElementModel = (() => {
|
|
|
73
75
|
get type() {
|
|
74
76
|
return 'edgyBoard';
|
|
75
77
|
}
|
|
76
|
-
/** Connectors must link elements, never the board itself. */
|
|
77
|
-
get connectable() {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
containsBound(bounds) {
|
|
81
|
-
const points = getPointsFromBoundWithRotation(this);
|
|
82
|
-
return points.some(point => bounds.containsPoint(point));
|
|
83
|
-
}
|
|
84
|
-
getLineIntersections(start, end) {
|
|
85
|
-
const points = getPointsFromBoundWithRotation(this);
|
|
86
|
-
return linePolygonIntersects(start, end, points);
|
|
87
|
-
}
|
|
88
|
-
getNearestPoint(point) {
|
|
89
|
-
return polygonNearestPoint(Bound.deserialize(this.xywh).points, point);
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Picked by its BORDER band: a board is a passive canvas and the clicks over
|
|
93
|
-
* its area belong to what the user laid on it. Same test every framework
|
|
94
|
-
* background runs — see {@link backgroundIncludesPoint}.
|
|
95
|
-
*/
|
|
96
|
-
includesPoint(x, y, options) {
|
|
97
|
-
return backgroundIncludesPoint(this, x, y, options);
|
|
98
|
-
}
|
|
99
78
|
#resizeEnabled_accessor_storage = __runInitializers(this, _resizeEnabled_initializers, true);
|
|
100
79
|
get resizeEnabled() { return this.#resizeEnabled_accessor_storage; }
|
|
101
80
|
set resizeEnabled(value) { this.#resizeEnabled_accessor_storage = value; }
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
export type EdgyFacetsProps = BaseElementProps & {
|
|
6
|
-
/** When false the resize handles are hidden — toggled from the toolbar. */
|
|
7
|
-
resizeEnabled?: boolean;
|
|
1
|
+
import type { SerializedXYWH } from '../../../global/gfx/index.js';
|
|
2
|
+
import { FrameworkBackgroundElementModel } from '../framework-background/index.js';
|
|
3
|
+
import type { FrameworkBackgroundProps } from '../framework-background/index.js';
|
|
4
|
+
export type EdgyFacetsProps = FrameworkBackgroundProps & {
|
|
8
5
|
/** When false the three facet name labels are hidden. */
|
|
9
6
|
showLabels?: boolean;
|
|
10
7
|
/** When false the six white zone pictograms are hidden. */
|
|
@@ -35,29 +32,18 @@ export type EdgyFacetsProps = BaseElementProps & {
|
|
|
35
32
|
* white pictograms, drawn on the surface canvas. The user places regular
|
|
36
33
|
* edgeless elements (the EDGY base shapes) on top of it.
|
|
37
34
|
*
|
|
38
|
-
*
|
|
39
|
-
* {@link
|
|
40
|
-
*
|
|
35
|
+
* An INSTANCE of the framework-background primitive
|
|
36
|
+
* ({@link FrameworkBackgroundElementModel}), like the Wardley background: the
|
|
37
|
+
* passive-canvas geometry comes from the primitive, the fields below are the
|
|
38
|
+
* persisted document.
|
|
39
|
+
*
|
|
40
|
+
* The facet LABELS stay double-clickable all the same: their zones are added
|
|
41
|
+
* by `EdgyView.includesPoint`, which is what the pointer router consults, so
|
|
42
|
+
* the rename target lives with the code that draws it and the model layer
|
|
43
|
+
* stays free of it.
|
|
41
44
|
*/
|
|
42
|
-
export declare class EdgyFacetsElementModel extends
|
|
45
|
+
export declare class EdgyFacetsElementModel extends FrameworkBackgroundElementModel<EdgyFacetsProps> {
|
|
43
46
|
get type(): string;
|
|
44
|
-
/**
|
|
45
|
-
* The diagram is a passive canvas: connectors must not snap their endpoints
|
|
46
|
-
* to it (an EDGY link should connect elements, never the facets diagram).
|
|
47
|
-
*/
|
|
48
|
-
get connectable(): boolean;
|
|
49
|
-
containsBound(bounds: Bound): boolean;
|
|
50
|
-
getLineIntersections(start: IVec, end: IVec): import("../../../global/gfx/index.js").PointLocation[] | null;
|
|
51
|
-
getNearestPoint(point: IVec): IVec;
|
|
52
|
-
/**
|
|
53
|
-
* Picked by its BORDER band — see {@link backgroundIncludesPoint}.
|
|
54
|
-
*
|
|
55
|
-
* The facet LABELS stay double-clickable all the same: their zones are added
|
|
56
|
-
* by `EdgyView.includesPoint`, which is what the pointer router consults, so
|
|
57
|
-
* the rename target lives with the code that draws it and the model layer
|
|
58
|
-
* stays free of it.
|
|
59
|
-
*/
|
|
60
|
-
includesPoint(x: number, y: number, options?: PointTestOptions): boolean;
|
|
61
47
|
accessor resizeEnabled: boolean;
|
|
62
48
|
accessor showLabels: boolean;
|
|
63
49
|
accessor showPictos: boolean;
|
|
@@ -32,9 +32,8 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
32
32
|
}
|
|
33
33
|
return useValue ? value : void 0;
|
|
34
34
|
};
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import { backgroundIncludesPoint } from '../framework-background/index.js';
|
|
35
|
+
import { field } from '../../../std/gfx/index.js';
|
|
36
|
+
import { FrameworkBackgroundElementModel } from '../framework-background/index.js';
|
|
38
37
|
/**
|
|
39
38
|
* A static "EDGY Enterprise Design Facets" diagram: three overlapping circles
|
|
40
39
|
* (Identity / Architecture / Experience) with their three pairwise
|
|
@@ -42,12 +41,18 @@ import { backgroundIncludesPoint } from '../framework-background/index.js';
|
|
|
42
41
|
* white pictograms, drawn on the surface canvas. The user places regular
|
|
43
42
|
* edgeless elements (the EDGY base shapes) on top of it.
|
|
44
43
|
*
|
|
45
|
-
*
|
|
46
|
-
* {@link
|
|
47
|
-
*
|
|
44
|
+
* An INSTANCE of the framework-background primitive
|
|
45
|
+
* ({@link FrameworkBackgroundElementModel}), like the Wardley background: the
|
|
46
|
+
* passive-canvas geometry comes from the primitive, the fields below are the
|
|
47
|
+
* persisted document.
|
|
48
|
+
*
|
|
49
|
+
* The facet LABELS stay double-clickable all the same: their zones are added
|
|
50
|
+
* by `EdgyView.includesPoint`, which is what the pointer router consults, so
|
|
51
|
+
* the rename target lives with the code that draws it and the model layer
|
|
52
|
+
* stays free of it.
|
|
48
53
|
*/
|
|
49
54
|
let EdgyFacetsElementModel = (() => {
|
|
50
|
-
let _classSuper =
|
|
55
|
+
let _classSuper = FrameworkBackgroundElementModel;
|
|
51
56
|
let _resizeEnabled_decorators;
|
|
52
57
|
let _resizeEnabled_initializers = [];
|
|
53
58
|
let _resizeEnabled_extraInitializers = [];
|
|
@@ -106,35 +111,6 @@ let EdgyFacetsElementModel = (() => {
|
|
|
106
111
|
get type() {
|
|
107
112
|
return 'edgy';
|
|
108
113
|
}
|
|
109
|
-
/**
|
|
110
|
-
* The diagram is a passive canvas: connectors must not snap their endpoints
|
|
111
|
-
* to it (an EDGY link should connect elements, never the facets diagram).
|
|
112
|
-
*/
|
|
113
|
-
get connectable() {
|
|
114
|
-
return false;
|
|
115
|
-
}
|
|
116
|
-
containsBound(bounds) {
|
|
117
|
-
const points = getPointsFromBoundWithRotation(this);
|
|
118
|
-
return points.some(point => bounds.containsPoint(point));
|
|
119
|
-
}
|
|
120
|
-
getLineIntersections(start, end) {
|
|
121
|
-
const points = getPointsFromBoundWithRotation(this);
|
|
122
|
-
return linePolygonIntersects(start, end, points);
|
|
123
|
-
}
|
|
124
|
-
getNearestPoint(point) {
|
|
125
|
-
return polygonNearestPoint(Bound.deserialize(this.xywh).points, point);
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Picked by its BORDER band — see {@link backgroundIncludesPoint}.
|
|
129
|
-
*
|
|
130
|
-
* The facet LABELS stay double-clickable all the same: their zones are added
|
|
131
|
-
* by `EdgyView.includesPoint`, which is what the pointer router consults, so
|
|
132
|
-
* the rename target lives with the code that draws it and the model layer
|
|
133
|
-
* stays free of it.
|
|
134
|
-
*/
|
|
135
|
-
includesPoint(x, y, options) {
|
|
136
|
-
return backgroundIncludesPoint(this, x, y, options);
|
|
137
|
-
}
|
|
138
114
|
#resizeEnabled_accessor_storage = __runInitializers(this, _resizeEnabled_initializers, true);
|
|
139
115
|
get resizeEnabled() { return this.#resizeEnabled_accessor_storage; }
|
|
140
116
|
set resizeEnabled(value) { this.#resizeEnabled_accessor_storage = value; }
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
export type EstuarineProps = BaseElementProps & {
|
|
6
|
-
/** When false the resize handles are hidden — toggled from the toolbar. */
|
|
7
|
-
resizeEnabled?: boolean;
|
|
1
|
+
import type { SerializedXYWH } from '../../../global/gfx/index.js';
|
|
2
|
+
import { FrameworkBackgroundElementModel } from '../framework-background/index.js';
|
|
3
|
+
import type { FrameworkBackgroundProps } from '../framework-background/index.js';
|
|
4
|
+
export type EstuarineProps = FrameworkBackgroundProps & {
|
|
8
5
|
/** Per-curve visibility (the curve + its legend) — toggled from the toolbar. */
|
|
9
6
|
showLiminal?: boolean;
|
|
10
7
|
showVolatile?: boolean;
|
|
@@ -18,20 +15,13 @@ export type EstuarineProps = BaseElementProps & {
|
|
|
18
15
|
* Volatile (red, dipping below zero) and Counter-factual (dark) — each with its
|
|
19
16
|
* legend. The user drops hexagon constraint nodes (native shapes) into the space.
|
|
20
17
|
*
|
|
21
|
-
*
|
|
18
|
+
* An INSTANCE of the framework-background primitive
|
|
19
|
+
* ({@link FrameworkBackgroundElementModel}), like the Wardley / EDGY
|
|
20
|
+
* backgrounds: the passive-canvas geometry comes from the primitive, the
|
|
21
|
+
* fields below are the persisted document.
|
|
22
22
|
*/
|
|
23
|
-
export declare class EstuarineElementModel extends
|
|
23
|
+
export declare class EstuarineElementModel extends FrameworkBackgroundElementModel<EstuarineProps> {
|
|
24
24
|
get type(): string;
|
|
25
|
-
get connectable(): boolean;
|
|
26
|
-
containsBound(bounds: Bound): boolean;
|
|
27
|
-
getLineIntersections(start: IVec, end: IVec): import("../../../global/gfx/index.js").PointLocation[] | null;
|
|
28
|
-
getNearestPoint(point: IVec): IVec;
|
|
29
|
-
/**
|
|
30
|
-
* Picked by its BORDER band — see {@link backgroundIncludesPoint}. The map is
|
|
31
|
-
* a space constraint nodes are dropped into, so the clicks inside it are
|
|
32
|
-
* theirs.
|
|
33
|
-
*/
|
|
34
|
-
includesPoint(x: number, y: number, options?: PointTestOptions): boolean;
|
|
35
25
|
accessor resizeEnabled: boolean;
|
|
36
26
|
accessor showLiminal: boolean;
|
|
37
27
|
accessor showVolatile: boolean;
|
|
@@ -32,19 +32,21 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
32
32
|
}
|
|
33
33
|
return useValue ? value : void 0;
|
|
34
34
|
};
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import { backgroundIncludesPoint } from '../framework-background/index.js';
|
|
35
|
+
import { field } from '../../../std/gfx/index.js';
|
|
36
|
+
import { FrameworkBackgroundElementModel } from '../framework-background/index.js';
|
|
38
37
|
/**
|
|
39
38
|
* A static "Estuarine framework" map: the 2D energy (e, vertical, double-headed)
|
|
40
39
|
* / time (t, horizontal) space with the three reference curves — Liminal (green),
|
|
41
40
|
* Volatile (red, dipping below zero) and Counter-factual (dark) — each with its
|
|
42
41
|
* legend. The user drops hexagon constraint nodes (native shapes) into the space.
|
|
43
42
|
*
|
|
44
|
-
*
|
|
43
|
+
* An INSTANCE of the framework-background primitive
|
|
44
|
+
* ({@link FrameworkBackgroundElementModel}), like the Wardley / EDGY
|
|
45
|
+
* backgrounds: the passive-canvas geometry comes from the primitive, the
|
|
46
|
+
* fields below are the persisted document.
|
|
45
47
|
*/
|
|
46
48
|
let EstuarineElementModel = (() => {
|
|
47
|
-
let _classSuper =
|
|
49
|
+
let _classSuper = FrameworkBackgroundElementModel;
|
|
48
50
|
let _resizeEnabled_decorators;
|
|
49
51
|
let _resizeEnabled_initializers = [];
|
|
50
52
|
let _resizeEnabled_extraInitializers = [];
|
|
@@ -88,28 +90,6 @@ let EstuarineElementModel = (() => {
|
|
|
88
90
|
get type() {
|
|
89
91
|
return 'estuarine';
|
|
90
92
|
}
|
|
91
|
-
get connectable() {
|
|
92
|
-
return false;
|
|
93
|
-
}
|
|
94
|
-
containsBound(bounds) {
|
|
95
|
-
const points = getPointsFromBoundWithRotation(this);
|
|
96
|
-
return points.some(point => bounds.containsPoint(point));
|
|
97
|
-
}
|
|
98
|
-
getLineIntersections(start, end) {
|
|
99
|
-
const points = getPointsFromBoundWithRotation(this);
|
|
100
|
-
return linePolygonIntersects(start, end, points);
|
|
101
|
-
}
|
|
102
|
-
getNearestPoint(point) {
|
|
103
|
-
return polygonNearestPoint(Bound.deserialize(this.xywh).points, point);
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Picked by its BORDER band — see {@link backgroundIncludesPoint}. The map is
|
|
107
|
-
* a space constraint nodes are dropped into, so the clicks inside it are
|
|
108
|
-
* theirs.
|
|
109
|
-
*/
|
|
110
|
-
includesPoint(x, y, options) {
|
|
111
|
-
return backgroundIncludesPoint(this, x, y, options);
|
|
112
|
-
}
|
|
113
93
|
#resizeEnabled_accessor_storage = __runInitializers(this, _resizeEnabled_initializers, true);
|
|
114
94
|
get resizeEnabled() { return this.#resizeEnabled_accessor_storage; }
|
|
115
95
|
set resizeEnabled(value) { this.#resizeEnabled_accessor_storage = value; }
|
|
@@ -14,6 +14,10 @@ export type LinkPreviewResponseData = {
|
|
|
14
14
|
videos?: string[];
|
|
15
15
|
favicons?: string[];
|
|
16
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Returns extra headers to send with a link preview request.
|
|
19
|
+
*/
|
|
20
|
+
export type LinkPreviewHeadersFn = () => Record<string, string> | Promise<Record<string, string>>;
|
|
17
21
|
export interface LinkPreviewProvider {
|
|
18
22
|
/**
|
|
19
23
|
* Query link preview data for a given URL
|
|
@@ -27,15 +31,39 @@ export interface LinkPreviewProvider {
|
|
|
27
31
|
* Get the endpoint for link preview
|
|
28
32
|
*/
|
|
29
33
|
endpoint: string;
|
|
34
|
+
/**
|
|
35
|
+
* Set a hook returning extra headers, merged over `Content-Type` on every
|
|
36
|
+
* request sent to the configured endpoint (e.g. an `Authorization` header).
|
|
37
|
+
* Pass `null` to remove it.
|
|
38
|
+
*
|
|
39
|
+
* Optional: hosts implementing this provider themselves may omit it.
|
|
40
|
+
*/
|
|
41
|
+
setHeaders?: (fn: LinkPreviewHeadersFn | null) => void;
|
|
42
|
+
/**
|
|
43
|
+
* Set the endpoint used for X/Twitter status URLs.
|
|
44
|
+
*
|
|
45
|
+
* The value is a **prefix**: the tweet id is appended to it, so
|
|
46
|
+
* `https://example.com/tweet/` is fetched as
|
|
47
|
+
* `https://example.com/tweet/1234567890`. Pass `null` to disable the special
|
|
48
|
+
* path entirely, sending tweet URLs through the standard endpoint instead.
|
|
49
|
+
*
|
|
50
|
+
* Optional: hosts implementing this provider themselves may omit it.
|
|
51
|
+
*/
|
|
52
|
+
setTwitterEndpoint?: (endpoint: string | null) => void;
|
|
30
53
|
}
|
|
31
54
|
export declare const LinkPreviewServiceIdentifier: import("../../../global/di/types.js").ServiceIdentifier<LinkPreviewProvider> & (<U extends LinkPreviewProvider = LinkPreviewProvider>(variant: import("../../../global/di/types.js").ServiceVariant) => import("../../../global/di/types.js").ServiceIdentifier<U>);
|
|
32
55
|
export declare class LinkPreviewService extends Extension implements LinkPreviewProvider {
|
|
33
56
|
private readonly _cache;
|
|
34
57
|
static setup(di: Container): void;
|
|
35
58
|
private _endpoint;
|
|
59
|
+
private _headers;
|
|
60
|
+
private _twitterEndpoint;
|
|
36
61
|
constructor(_cache: LinkPreviewCacheProvider);
|
|
37
62
|
get endpoint(): string;
|
|
38
63
|
setEndpoint: (endpoint: string) => void;
|
|
64
|
+
setHeaders: (fn: LinkPreviewHeadersFn | null) => void;
|
|
65
|
+
setTwitterEndpoint: (endpoint: string | null) => void;
|
|
66
|
+
private readonly _resolveHeaders;
|
|
39
67
|
private readonly _fetchTwitterPreview;
|
|
40
68
|
private readonly _fetchStandardPreview;
|
|
41
69
|
private readonly _isTwitterUrl;
|
|
@@ -5,6 +5,8 @@ import { Extension } from '../../../store/index.js';
|
|
|
5
5
|
import { DEFAULT_LINK_PREVIEW_ENDPOINT } from '../../consts/index.js';
|
|
6
6
|
import { isAbortError } from '../../utils/is-abort-error.js';
|
|
7
7
|
import { LinkPreviewCacheIdentifier, } from './link-preview-cache.js';
|
|
8
|
+
/** Third-party endpoint used for X/Twitter status URLs by default. */
|
|
9
|
+
const DEFAULT_TWITTER_PREVIEW_ENDPOINT = 'https://api.fxtwitter.com/status/';
|
|
8
10
|
export const LinkPreviewServiceIdentifier = createIdentifier('AffineLinkPreviewService');
|
|
9
11
|
export class LinkPreviewService extends Extension {
|
|
10
12
|
static setup(di) {
|
|
@@ -16,17 +18,31 @@ export class LinkPreviewService extends Extension {
|
|
|
16
18
|
super();
|
|
17
19
|
this._cache = _cache;
|
|
18
20
|
this._endpoint = DEFAULT_LINK_PREVIEW_ENDPOINT;
|
|
21
|
+
this._headers = null;
|
|
22
|
+
this._twitterEndpoint = DEFAULT_TWITTER_PREVIEW_ENDPOINT;
|
|
19
23
|
this.setEndpoint = (endpoint) => {
|
|
20
24
|
this._endpoint = endpoint;
|
|
21
25
|
};
|
|
26
|
+
this.setHeaders = (fn) => {
|
|
27
|
+
this._headers = fn;
|
|
28
|
+
};
|
|
29
|
+
this.setTwitterEndpoint = (endpoint) => {
|
|
30
|
+
this._twitterEndpoint = endpoint;
|
|
31
|
+
};
|
|
32
|
+
this._resolveHeaders = async () => (this._headers ? await this._headers() : {});
|
|
22
33
|
this._fetchTwitterPreview = async (url, signal) => {
|
|
23
34
|
try {
|
|
24
35
|
const match = /\/status\/(\d+)/.exec(url);
|
|
25
36
|
if (!match) {
|
|
26
37
|
throw new BlockSuiteError(ErrorCode.DefaultRuntimeError, `Invalid tweet URL: ${url}`);
|
|
27
38
|
}
|
|
28
|
-
const
|
|
29
|
-
const
|
|
39
|
+
const endpoint = this._twitterEndpoint ?? DEFAULT_TWITTER_PREVIEW_ENDPOINT;
|
|
40
|
+
const apiUrl = `${endpoint}${match[1]}`;
|
|
41
|
+
// Never leak the host headers (a JWT, typically) to the default third-party endpoint.
|
|
42
|
+
const headers = endpoint === DEFAULT_TWITTER_PREVIEW_ENDPOINT
|
|
43
|
+
? undefined
|
|
44
|
+
: await this._resolveHeaders();
|
|
45
|
+
const response = await fetch(apiUrl, { headers, signal }).then(res => res.json());
|
|
30
46
|
const tweet = response?.tweet;
|
|
31
47
|
if (!tweet) {
|
|
32
48
|
throw new BlockSuiteError(ErrorCode.DefaultRuntimeError, `Invalid tweet response: ${url}`);
|
|
@@ -49,6 +65,7 @@ export class LinkPreviewService extends Extension {
|
|
|
49
65
|
method: 'POST',
|
|
50
66
|
headers: {
|
|
51
67
|
'Content-Type': 'application/json',
|
|
68
|
+
...(await this._resolveHeaders()),
|
|
52
69
|
},
|
|
53
70
|
body: JSON.stringify({ url }),
|
|
54
71
|
signal,
|
|
@@ -87,7 +104,7 @@ export class LinkPreviewService extends Extension {
|
|
|
87
104
|
url.includes('/status/'));
|
|
88
105
|
};
|
|
89
106
|
this._fetchPreview = async (url, signal) => {
|
|
90
|
-
if (this._isTwitterUrl(url)) {
|
|
107
|
+
if (this._twitterEndpoint !== null && this._isTwitterUrl(url)) {
|
|
91
108
|
return this._fetchTwitterPreview(url, signal);
|
|
92
109
|
}
|
|
93
110
|
return this._fetchStandardPreview(url, signal);
|
package/dist/translations.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EXEMPTION_FALLBACK, PROVENANCE_FALLBACK,
|
|
1
|
+
import { EXEMPTION_FALLBACK, PROVENANCE_FALLBACK, SEVERITY_FALLBACK, } from './_pkgs/affine-block-surface/index.js';
|
|
2
2
|
import { CHROME_WORDINGS } from './_pkgs/affine-shared/services/index.js';
|
|
3
3
|
import { collectTranslationKeys, commandCategoryTranslationEntries, commandTranslationEntries, mergeTranslationEntries, } from './_pkgs/std/index.js';
|
|
4
4
|
import { getCommands } from './commands.js';
|
|
@@ -19,7 +19,13 @@ const CHROME_TABLES = [
|
|
|
19
19
|
// a host building a catalogue must not have to come back for a fourth word
|
|
20
20
|
// the day the first org profile ships.
|
|
21
21
|
['com.labre.validation.provenance.', PROVENANCE_FALLBACK],
|
|
22
|
-
|
|
22
|
+
// `com.labre.reading.relations.consumers` / `.suppliers` USED to be here, as
|
|
23
|
+
// a chrome table walked out of the reading widget. They moved to Wardley's
|
|
24
|
+
// own `ReadingProfile` when every framework gained one: the two wordings are
|
|
25
|
+
// a value chain's ("Consumers (above)"), not the panel's, and a BPMN sequence
|
|
26
|
+
// flow names its sides differently. They now arrive with the rest of the
|
|
27
|
+
// declared data, through `wardleyTranslationEntries`, under source `reading`
|
|
28
|
+
// and with the same keys and the same English.
|
|
23
29
|
];
|
|
24
30
|
const chromeTableEntries = () => CHROME_TABLES.flatMap(([prefix, table]) => Object.entries(table).map(([suffix, fallback]) => ({
|
|
25
31
|
key: `${prefix}${suffix}`,
|