@geekity/plugin-wordpress 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +148 -2
- package/dist/bundle/index.js +160334 -0
- package/dist/bundle/plugin.json +8 -0
- package/dist/command.d.ts +17 -0
- package/dist/command.d.ts.map +1 -0
- package/dist/command.js +194 -0
- package/dist/command.js.map +1 -0
- package/dist/federation.d.ts +30 -0
- package/dist/federation.d.ts.map +1 -0
- package/dist/federation.js +162 -0
- package/dist/federation.js.map +1 -0
- package/dist/import.d.ts +123 -0
- package/dist/import.d.ts.map +1 -0
- package/dist/import.js +461 -0
- package/dist/import.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/records.d.ts +87 -0
- package/dist/records.d.ts.map +1 -0
- package/dist/records.js +176 -0
- package/dist/records.js.map +1 -0
- package/dist/screen.d.ts +14 -0
- package/dist/screen.d.ts.map +1 -0
- package/dist/screen.js +78 -0
- package/dist/screen.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +51 -3
package/dist/records.js
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the plugin keeps in its data folder, `data/plugins/@geekity/plugin-wordpress/`:
|
|
3
|
+
* the number the WordPress ActivityPub plugin gave each person, and when each
|
|
4
|
+
* of its old paths was last asked for.
|
|
5
|
+
*
|
|
6
|
+
* Files rather than a table, because the database is a cache a site may delete
|
|
7
|
+
* (decision-9), and both of these are facts the site cannot work out again.
|
|
8
|
+
*/
|
|
9
|
+
/** Where the plugin's REST namespace lives, on the site's origin. */
|
|
10
|
+
export const WORDPRESS_ACTIVITYPUB_BASE = '/wp-json/activitypub/1.0';
|
|
11
|
+
/** The plugin's actor path. Its identifier is the WordPress user's number. */
|
|
12
|
+
export const WORDPRESS_ACTOR_PATH = `${WORDPRESS_ACTIVITYPUB_BASE}/actors/{identifier}`;
|
|
13
|
+
/** The actor's inbox, outbox and two follow collections, as the plugin spells them. */
|
|
14
|
+
export const WORDPRESS_INBOX_PATH = `${WORDPRESS_ACTOR_PATH}/inbox`;
|
|
15
|
+
export const WORDPRESS_OUTBOX_PATH = `${WORDPRESS_ACTOR_PATH}/outbox`;
|
|
16
|
+
export const WORDPRESS_FOLLOWERS_PATH = `${WORDPRESS_ACTOR_PATH}/followers`;
|
|
17
|
+
export const WORDPRESS_FOLLOWING_PATH = `${WORDPRESS_ACTOR_PATH}/following`;
|
|
18
|
+
/** The plugin's instance-wide inbox, which its `sharedInbox` endpoint names. */
|
|
19
|
+
export const WORDPRESS_SHARED_INBOX_PATH = `${WORDPRESS_ACTIVITYPUB_BASE}/inbox`;
|
|
20
|
+
/** The file mapping each username to its WordPress number. */
|
|
21
|
+
export const ACTORS_FILE = 'actors.json';
|
|
22
|
+
/** The file holding when each path was last asked for. */
|
|
23
|
+
export const REQUESTS_FILE = 'requests.json';
|
|
24
|
+
/** Every per-person path, in the order the plugin's actor names them. */
|
|
25
|
+
export const WORDPRESS_ROUTES = [
|
|
26
|
+
'actor',
|
|
27
|
+
'inbox',
|
|
28
|
+
'outbox',
|
|
29
|
+
'followers',
|
|
30
|
+
'following',
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* The compatibility path a request asks for, or `undefined` for anything else.
|
|
34
|
+
*
|
|
35
|
+
* Matched here rather than left to Fedify because the record of what was last
|
|
36
|
+
* asked for is written whether or not a user answers: a delivery to a number
|
|
37
|
+
* nobody carries is still a peer holding the old URL. Fedify's router still
|
|
38
|
+
* decides what is served.
|
|
39
|
+
*/
|
|
40
|
+
export function wordPressRequestTarget(pathname) {
|
|
41
|
+
if (pathname === WORDPRESS_SHARED_INBOX_PATH)
|
|
42
|
+
return { route: 'sharedInbox' };
|
|
43
|
+
const under = `${WORDPRESS_ACTIVITYPUB_BASE}/actors/`;
|
|
44
|
+
if (!pathname.startsWith(under))
|
|
45
|
+
return undefined;
|
|
46
|
+
const [number, name, ...rest] = pathname.slice(under.length).split('/');
|
|
47
|
+
if (number === undefined || number === '' || rest.length > 0)
|
|
48
|
+
return undefined;
|
|
49
|
+
if (name === undefined || name === '')
|
|
50
|
+
return { route: 'actor', wordpressActorId: number };
|
|
51
|
+
if (isWordPressRoute(name) && name !== 'actor')
|
|
52
|
+
return { route: name, wordpressActorId: number };
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
/** Thrown when a WordPress number already belongs to another user. */
|
|
56
|
+
export class ConflictingWordPressIdError extends Error {
|
|
57
|
+
name = 'ConflictingWordPressIdError';
|
|
58
|
+
/** The user who already has it. */
|
|
59
|
+
username;
|
|
60
|
+
constructor(username, wordpressActorId) {
|
|
61
|
+
super(`WordPress actor ${String(wordpressActorId)} already belongs to "${username}".`);
|
|
62
|
+
this.username = username;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export function wordPressRecords(data) {
|
|
66
|
+
function actors() {
|
|
67
|
+
return actorsFrom(parseOrUndefined(data.read(ACTORS_FILE)));
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
actors,
|
|
71
|
+
userByNumber(site, identifier) {
|
|
72
|
+
if (!/^[1-9][0-9]*$/.test(identifier))
|
|
73
|
+
return undefined;
|
|
74
|
+
const wanted = Number(identifier);
|
|
75
|
+
const known = new Set(site.users().map((user) => user.username));
|
|
76
|
+
for (const [username, number] of actors()) {
|
|
77
|
+
if (number === wanted && known.has(username))
|
|
78
|
+
return username;
|
|
79
|
+
}
|
|
80
|
+
return undefined;
|
|
81
|
+
},
|
|
82
|
+
async setNumber(username, wordpressActorId) {
|
|
83
|
+
let changed = false;
|
|
84
|
+
await data.update(ACTORS_FILE, (current) => {
|
|
85
|
+
const held = actorsFrom(parseOrUndefined(current));
|
|
86
|
+
for (const [other, number] of held) {
|
|
87
|
+
if (other !== username && number === wordpressActorId) {
|
|
88
|
+
throw new ConflictingWordPressIdError(other, wordpressActorId);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
changed = held.get(username) !== wordpressActorId;
|
|
92
|
+
held.set(username, wordpressActorId);
|
|
93
|
+
return `${JSON.stringify(Object.fromEntries(held), null, 2)}\n`;
|
|
94
|
+
});
|
|
95
|
+
return changed;
|
|
96
|
+
},
|
|
97
|
+
requests: () => requestsFrom(parseOrUndefined(data.read(REQUESTS_FILE))),
|
|
98
|
+
async recordRequest({ target, username, at }) {
|
|
99
|
+
if (target.route !== 'sharedInbox' && username === undefined)
|
|
100
|
+
return;
|
|
101
|
+
const instant = at.toISOString();
|
|
102
|
+
await data.update(REQUESTS_FILE, (current) => {
|
|
103
|
+
const requests = requestsFrom(parseOrUndefined(current));
|
|
104
|
+
const next = target.route === 'sharedInbox'
|
|
105
|
+
? { ...requests, sharedInbox: instant }
|
|
106
|
+
: {
|
|
107
|
+
...requests,
|
|
108
|
+
users: {
|
|
109
|
+
...requests.users,
|
|
110
|
+
[username ?? '']: { ...requests.users[username ?? ''], [target.route]: instant },
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
return `${JSON.stringify(next, null, 2)}\n`;
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/** The bytes of a file as whatever JSON they hold, or nothing usable. */
|
|
119
|
+
function parseOrUndefined(source) {
|
|
120
|
+
if (source === undefined)
|
|
121
|
+
return undefined;
|
|
122
|
+
try {
|
|
123
|
+
return JSON.parse(source);
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* The numbers a file holds, keeping only whole positive ones: anything else
|
|
131
|
+
* could never appear in one of the plugin's paths.
|
|
132
|
+
*/
|
|
133
|
+
function actorsFrom(value) {
|
|
134
|
+
const actors = new Map();
|
|
135
|
+
if (!isRecord(value))
|
|
136
|
+
return actors;
|
|
137
|
+
for (const [username, number] of Object.entries(value)) {
|
|
138
|
+
if (typeof number === 'number' && Number.isInteger(number) && number > 0) {
|
|
139
|
+
actors.set(username, number);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return actors;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Whatever the file held as the instants this version understands. Read key
|
|
146
|
+
* by key and dropped rather than refused: a damaged record should cost the
|
|
147
|
+
* screen a column, not the site a request.
|
|
148
|
+
*/
|
|
149
|
+
function requestsFrom(value) {
|
|
150
|
+
if (!isRecord(value))
|
|
151
|
+
return { users: {} };
|
|
152
|
+
const users = {};
|
|
153
|
+
const listed = value['users'];
|
|
154
|
+
if (isRecord(listed)) {
|
|
155
|
+
for (const [username, routes] of Object.entries(listed)) {
|
|
156
|
+
if (!isRecord(routes))
|
|
157
|
+
continue;
|
|
158
|
+
const kept = {};
|
|
159
|
+
for (const [name, instant] of Object.entries(routes)) {
|
|
160
|
+
if (typeof instant === 'string' && isWordPressRoute(name))
|
|
161
|
+
kept[name] = instant;
|
|
162
|
+
}
|
|
163
|
+
if (Object.keys(kept).length > 0)
|
|
164
|
+
users[username] = kept;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const shared = value['sharedInbox'];
|
|
168
|
+
return { ...(typeof shared === 'string' ? { sharedInbox: shared } : {}), users };
|
|
169
|
+
}
|
|
170
|
+
function isWordPressRoute(name) {
|
|
171
|
+
return WORDPRESS_ROUTES.includes(name);
|
|
172
|
+
}
|
|
173
|
+
function isRecord(value) {
|
|
174
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=records.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"records.js","sourceRoot":"","sources":["../src/records.ts"],"names":[],"mappings":"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"}
|
package/dist/screen.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PluginScreen } from '@geekity/cms/plugin';
|
|
2
|
+
import type { WordPressRecords } from './records.ts';
|
|
3
|
+
/**
|
|
4
|
+
* The plugin's screen under Plugins: every path it answers, and when each was
|
|
5
|
+
* last asked for.
|
|
6
|
+
*
|
|
7
|
+
* The whole point of the screen. The plugin can be disabled once no
|
|
8
|
+
* follower's server is delivering to the old URLs any more, and only the
|
|
9
|
+
* record of what was asked for can say so. A route nobody has ever asked for
|
|
10
|
+
* is listed too, saying never: an empty table would read as "no such path"
|
|
11
|
+
* rather than as "nobody is using it".
|
|
12
|
+
*/
|
|
13
|
+
export declare function wordPressScreen(records: WordPressRecords): PluginScreen;
|
|
14
|
+
//# sourceMappingURL=screen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../src/screen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,qBAAqB,CAAC;AAO1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,YAAY,CAoEvE"}
|
package/dist/screen.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { WORDPRESS_ACTIVITYPUB_BASE, WORDPRESS_ROUTES, WORDPRESS_SHARED_INBOX_PATH, } from './records.js';
|
|
2
|
+
/**
|
|
3
|
+
* The plugin's screen under Plugins: every path it answers, and when each was
|
|
4
|
+
* last asked for.
|
|
5
|
+
*
|
|
6
|
+
* The whole point of the screen. The plugin can be disabled once no
|
|
7
|
+
* follower's server is delivering to the old URLs any more, and only the
|
|
8
|
+
* record of what was asked for can say so. A route nobody has ever asked for
|
|
9
|
+
* is listed too, saying never: an empty table would read as "no such path"
|
|
10
|
+
* rather than as "nobody is using it".
|
|
11
|
+
*/
|
|
12
|
+
export function wordPressScreen(records) {
|
|
13
|
+
return {
|
|
14
|
+
title: 'WordPress',
|
|
15
|
+
render({ site }) {
|
|
16
|
+
const requests = records.requests();
|
|
17
|
+
const known = new Set(site.users().map((user) => user.username));
|
|
18
|
+
const rows = [];
|
|
19
|
+
for (const [username, number] of records.actors()) {
|
|
20
|
+
if (!known.has(username))
|
|
21
|
+
continue;
|
|
22
|
+
const asked = requests.users[username] ?? {};
|
|
23
|
+
const actor = `${WORDPRESS_ACTIVITYPUB_BASE}/actors/${String(number)}`;
|
|
24
|
+
for (const route of WORDPRESS_ROUTES) {
|
|
25
|
+
rows.push([
|
|
26
|
+
{ code: route === 'actor' ? actor : `${actor}/${route}` },
|
|
27
|
+
username,
|
|
28
|
+
{ time: asked[route] ?? null },
|
|
29
|
+
]);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (rows.length === 0) {
|
|
33
|
+
return [
|
|
34
|
+
{
|
|
35
|
+
title: 'WordPress paths',
|
|
36
|
+
blocks: [
|
|
37
|
+
{
|
|
38
|
+
paragraph: [
|
|
39
|
+
'No user carries a WordPress actor id, so these paths would serve nothing. ',
|
|
40
|
+
{ code: 'geekity import wordpress-actor' },
|
|
41
|
+
' sets one.',
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
}
|
|
48
|
+
rows.push([
|
|
49
|
+
{ code: WORDPRESS_SHARED_INBOX_PATH },
|
|
50
|
+
'every user',
|
|
51
|
+
{ time: requests.sharedInbox ?? null },
|
|
52
|
+
]);
|
|
53
|
+
return [
|
|
54
|
+
{
|
|
55
|
+
title: 'WordPress paths',
|
|
56
|
+
blocks: [
|
|
57
|
+
{
|
|
58
|
+
table: {
|
|
59
|
+
caption: 'WordPress paths',
|
|
60
|
+
columns: ['Path', 'For', 'Last asked for'],
|
|
61
|
+
rows,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
paragraph: [
|
|
66
|
+
"Once every one of these has been quiet for long enough that every follower's " +
|
|
67
|
+
'server has refetched the actor, disable this plugin: these paths are a cache ' +
|
|
68
|
+
"other servers hold, not this site's identity, and the site carries them only " +
|
|
69
|
+
'until the caches have moved on.',
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=screen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screen.js","sourceRoot":"","sources":["../src/screen.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,cAAc,CAAC;AAGtB;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,OAAyB;IACvD,OAAO;QACL,KAAK,EAAE,WAAW;QAClB,MAAM,CAAC,EAAE,IAAI,EAAE;YACb,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YACjE,MAAM,IAAI,GAAyB,EAAE,CAAC;YAEtC,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;gBAClD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;oBAAE,SAAS;gBACnC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC7C,MAAM,KAAK,GAAG,GAAG,0BAA0B,WAAW,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;gBACvE,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;oBACrC,IAAI,CAAC,IAAI,CAAC;wBACR,EAAE,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,KAAK,EAAE,EAAE;wBACzD,QAAQ;wBACR,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE;qBAC/B,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,OAAO;oBACL;wBACE,KAAK,EAAE,iBAAiB;wBACxB,MAAM,EAAE;4BACN;gCACE,SAAS,EAAE;oCACT,4EAA4E;oCAC5E,EAAE,IAAI,EAAE,gCAAgC,EAAE;oCAC1C,YAAY;iCACb;6BACF;yBACF;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,IAAI,CAAC;gBACR,EAAE,IAAI,EAAE,2BAA2B,EAAE;gBACrC,YAAY;gBACZ,EAAE,IAAI,EAAE,QAAQ,CAAC,WAAW,IAAI,IAAI,EAAE;aACvC,CAAC,CAAC;YAEH,OAAO;gBACL;oBACE,KAAK,EAAE,iBAAiB;oBACxB,MAAM,EAAE;wBACN;4BACE,KAAK,EAAE;gCACL,OAAO,EAAE,iBAAiB;gCAC1B,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC;gCAC1C,IAAI;6BACL;yBACF;wBACD;4BACE,SAAS,EAAE;gCACT,+EAA+E;oCAC7E,+EAA+E;oCAC/E,+EAA+E;oCAC/E,iCAAiC;6BACpC;yBACF;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,2BAA2B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,54 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geekity/plugin-wordpress",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"description": "
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Geekity CMS plugin for a site that moved from the WordPress ActivityPub plugin: its old inbox and collection paths, and the import that brings each person across.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=24"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./package.json": "./package.json"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
24
|
+
"geekity": {
|
|
25
|
+
"plugin": true,
|
|
26
|
+
"hostApi": 1,
|
|
27
|
+
"requires": {}
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@fedify/fedify": "^2.4.0",
|
|
31
|
+
"@fedify/vocab": "^2.4.0"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"@geekity/cms": "^0.25.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@fedify/cli": "2.4.0",
|
|
38
|
+
"@geekity/cms": "0.25.0",
|
|
39
|
+
"@hono/node-server": "^2.1.3",
|
|
40
|
+
"@types/node": "^26.6.4",
|
|
41
|
+
"esbuild": "^0.28.2",
|
|
42
|
+
"tsx": "^4.23.15",
|
|
43
|
+
"typescript": "^7.0.2"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsc -p tsconfig.build.json && node ../../scripts/build-plugin-bundle.js",
|
|
47
|
+
"test": "tsx --import ../cms/src/__testing__/offline.ts --test \"test/*.test.ts\"",
|
|
48
|
+
"prefed:smoke": "pnpm --filter @geekity/cms build",
|
|
49
|
+
"fed:smoke": "tsx scripts/fed-smoke.ts",
|
|
50
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
51
|
+
"lint": "eslint .",
|
|
52
|
+
"lint:fix": "eslint . --fix"
|
|
53
|
+
}
|
|
6
54
|
}
|