@spacefast/wpcloud-sdk 0.0.5 → 0.0.6
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/fake/index.d.ts +1 -3
- package/dist/fake/index.d.ts.map +1 -1
- package/dist/fake/index.js +1 -3
- package/dist/fake/router.d.ts.map +1 -1
- package/dist/fake/router.js +57 -5
- package/dist/fake/server.d.ts +11 -0
- package/dist/fake/server.d.ts.map +1 -1
- package/dist/fake/server.js +12 -2
- package/dist/fake/store.d.ts +33 -3
- package/dist/fake/store.d.ts.map +1 -1
- package/dist/fake/store.js +56 -3
- package/package.json +6 -1
package/dist/fake/index.d.ts
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
export { makeFakeAtomic,
|
|
2
|
-
export { FakeAtomicStore, type FakeSite } from "./store.js";
|
|
3
|
-
export { routeFakeRequest, type FakeResult } from "./router.js";
|
|
1
|
+
export { makeFakeAtomic, makeFakeAtomicWithStore } from "./server.js";
|
|
4
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/fake/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fake/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fake/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/fake/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/fake/router.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,MAAM,UAAU,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/fake/router.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,MAAM,UAAU,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AA6C3D;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,UAAU,CAqMZ"}
|
package/dist/fake/router.js
CHANGED
|
@@ -10,17 +10,19 @@ const fail = (status, message) => ({
|
|
|
10
10
|
body: { message, data: [] },
|
|
11
11
|
});
|
|
12
12
|
const RESTRICTED_DOMAINS = new Set(["wordpress.com", "wp.com", "automattic.com"]);
|
|
13
|
-
function isRecord(value) {
|
|
14
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
15
|
-
}
|
|
16
13
|
function asStringMap(value) {
|
|
17
14
|
const out = {};
|
|
18
|
-
if (
|
|
15
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
19
16
|
for (const [k, v] of Object.entries(value))
|
|
20
17
|
out[k] = String(v);
|
|
21
18
|
}
|
|
22
19
|
return out;
|
|
23
20
|
}
|
|
21
|
+
/** The `data` form field of `POST /site-persist-data/{site}` — a bag of per-key
|
|
22
|
+
* set/delete operations, matching `FakeAtomicStore#applyPersistentData`. */
|
|
23
|
+
function isPersistDataOperations(value) {
|
|
24
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25
|
+
}
|
|
24
26
|
const READABLE_CLIENT_META_KEYS = new Set([
|
|
25
27
|
"webhook_url",
|
|
26
28
|
"client_ssh_default_from",
|
|
@@ -89,7 +91,9 @@ export function routeFakeRequest(store, method, path, body) {
|
|
|
89
91
|
return ok({ status: "success" });
|
|
90
92
|
// POST /site-persist-data/{site}
|
|
91
93
|
if (method === "POST" && head === "site-persist-data") {
|
|
92
|
-
const data =
|
|
94
|
+
const data = isPersistDataOperations(body.data)
|
|
95
|
+
? store.applyPersistentData(seg[1] ?? "", body.data)
|
|
96
|
+
: null;
|
|
93
97
|
if (!data)
|
|
94
98
|
return fail(404, "Site not found.");
|
|
95
99
|
return ok({
|
|
@@ -126,6 +130,46 @@ export function routeFakeRequest(store, method, path, body) {
|
|
|
126
130
|
return ok([]);
|
|
127
131
|
}
|
|
128
132
|
}
|
|
133
|
+
// /crontab/{site}/add|list|update/{cron_id}|remove — matches the documented
|
|
134
|
+
// envelope exactly (docs/wpcloud/openapi.json): add/update return
|
|
135
|
+
// {cron_id}, list returns the array of entries verbatim, remove returns [].
|
|
136
|
+
if (head === "crontab") {
|
|
137
|
+
const id = seg[1] ?? "";
|
|
138
|
+
const action = seg[2];
|
|
139
|
+
if (method === "POST" && action === "add") {
|
|
140
|
+
const schedule = String(body.schedule ?? "");
|
|
141
|
+
const command = String(body.command ?? "");
|
|
142
|
+
if (!schedule || !command)
|
|
143
|
+
return fail(400, "Invalid or empty schedule or command.");
|
|
144
|
+
const cron = store.addCron(id, { schedule, command });
|
|
145
|
+
if (!cron)
|
|
146
|
+
return fail(404, "Site not found.");
|
|
147
|
+
return ok({ cron_id: cron.cronId });
|
|
148
|
+
}
|
|
149
|
+
if (method === "GET" && action === "list") {
|
|
150
|
+
if (!store.get(id))
|
|
151
|
+
return fail(404, "Site not found.");
|
|
152
|
+
return ok(store.listCrons(id).map((cron) => ({
|
|
153
|
+
cron_id: cron.cronId,
|
|
154
|
+
schedule: cron.schedule,
|
|
155
|
+
requested_schedule: cron.requestedSchedule,
|
|
156
|
+
command: cron.command,
|
|
157
|
+
})));
|
|
158
|
+
}
|
|
159
|
+
if (method === "POST" && action === "update") {
|
|
160
|
+
const cronId = Number(seg[3] ?? "");
|
|
161
|
+
const command = String(body.command ?? "");
|
|
162
|
+
if (!command)
|
|
163
|
+
return fail(400, "Invalid or empty command.");
|
|
164
|
+
return store.updateCron(id, cronId, command)
|
|
165
|
+
? ok({ cron_id: cronId })
|
|
166
|
+
: fail(404, "Cron entry not found.");
|
|
167
|
+
}
|
|
168
|
+
if (method === "POST" && action === "remove") {
|
|
169
|
+
const cronId = Number(body.cron_id ?? "");
|
|
170
|
+
return store.removeCron(id, cronId) ? ok([]) : fail(404, "Cron entry not found.");
|
|
171
|
+
}
|
|
172
|
+
}
|
|
129
173
|
// /edge-cache/{id}/{op}/{host} — lean: benign success so publish/serve never trips on it.
|
|
130
174
|
// Real edge-cache behavior is covered by the gated `direct/` suites, not the fake.
|
|
131
175
|
if (head === "edge-cache") {
|
|
@@ -183,6 +227,14 @@ export function routeFakeRequest(store, method, path, body) {
|
|
|
183
227
|
return ok([]);
|
|
184
228
|
}
|
|
185
229
|
}
|
|
230
|
+
// POST /metrics/{type}/{key}[/summarize]
|
|
231
|
+
if (method === "POST" && head === "metrics") {
|
|
232
|
+
const type = decodeURIComponent(seg[1] ?? "");
|
|
233
|
+
const key = decodeURIComponent(seg[2] ?? "");
|
|
234
|
+
const summarize = seg[3] === "summarize";
|
|
235
|
+
store.recordMetricsRequest({ type, key, summarize, body });
|
|
236
|
+
return ok(store.metricsResponse(type, key));
|
|
237
|
+
}
|
|
186
238
|
// Anything the control plane calls that we don't model: surface it loudly, don't silently pass.
|
|
187
239
|
return fail(404, `fake_endpoint_not_implemented: ${method} /${path}`);
|
|
188
240
|
}
|
package/dist/fake/server.d.ts
CHANGED
|
@@ -4,6 +4,17 @@
|
|
|
4
4
|
* `defaultFakeFetch` is a process-global instance for env-driven `WP_CLOUD_PROVIDER_MODE=fake`.
|
|
5
5
|
*/
|
|
6
6
|
import type { WpCloudFakeFetch } from "../runtime.js";
|
|
7
|
+
import { FakeAtomicStore } from "./store.js";
|
|
8
|
+
/**
|
|
9
|
+
* Same fake as `makeFakeAtomic()`, but also hands back the underlying store
|
|
10
|
+
* so a test can assert on recorded state directly (house rule: assert the
|
|
11
|
+
* effect, not that a mock was called) — e.g. crontab registration, aliases,
|
|
12
|
+
* persistent data.
|
|
13
|
+
*/
|
|
14
|
+
export declare function makeFakeAtomicWithStore(): {
|
|
15
|
+
fetch: WpCloudFakeFetch;
|
|
16
|
+
store: FakeAtomicStore;
|
|
17
|
+
};
|
|
7
18
|
export declare function makeFakeAtomic(): WpCloudFakeFetch;
|
|
8
19
|
/** Process-global fake for `WP_CLOUD_PROVIDER_MODE=fake` (no per-suite override installed). */
|
|
9
20
|
export declare const defaultFakeFetch: WpCloudFakeFetch;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/fake/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/fake/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA2C7C;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI;IAAE,KAAK,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,eAAe,CAAA;CAAE,CAkB7F;AAED,wBAAgB,cAAc,IAAI,gBAAgB,CAEjD;AAED,+FAA+F;AAC/F,eAAO,MAAM,gBAAgB,EAAE,gBAAmC,CAAC"}
|
package/dist/fake/server.js
CHANGED
|
@@ -42,9 +42,15 @@ async function readBody(input, init) {
|
|
|
42
42
|
}
|
|
43
43
|
return raw ? parseNestedForm(raw) : {};
|
|
44
44
|
}
|
|
45
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Same fake as `makeFakeAtomic()`, but also hands back the underlying store
|
|
47
|
+
* so a test can assert on recorded state directly (house rule: assert the
|
|
48
|
+
* effect, not that a mock was called) — e.g. crontab registration, aliases,
|
|
49
|
+
* persistent data.
|
|
50
|
+
*/
|
|
51
|
+
export function makeFakeAtomicWithStore() {
|
|
46
52
|
const store = new FakeAtomicStore();
|
|
47
|
-
|
|
53
|
+
const fetch = async (input, init) => {
|
|
48
54
|
const rawUrl = input instanceof Request ? input.url : String(input);
|
|
49
55
|
const url = new URL(rawUrl);
|
|
50
56
|
// path after /api/v1.0/, trailing slash trimmed; segments stay encoded (router decodes its own)
|
|
@@ -57,6 +63,10 @@ export function makeFakeAtomic() {
|
|
|
57
63
|
headers: { "content-type": "application/json" },
|
|
58
64
|
});
|
|
59
65
|
};
|
|
66
|
+
return { fetch, store };
|
|
67
|
+
}
|
|
68
|
+
export function makeFakeAtomic() {
|
|
69
|
+
return makeFakeAtomicWithStore().fetch;
|
|
60
70
|
}
|
|
61
71
|
/** Process-global fake for `WP_CLOUD_PROVIDER_MODE=fake` (no per-suite override installed). */
|
|
62
72
|
export const defaultFakeFetch = makeFakeAtomic();
|
package/dist/fake/store.d.ts
CHANGED
|
@@ -1,28 +1,46 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* In-memory state for the lean wp.cloud fake. Models only the lifecycle we captured real shapes for
|
|
3
|
-
* (sites, jobs, aliases, meta) — see internal-docs/testing-system-plan.html §4. Edge-cache /
|
|
4
|
-
* domain-claim are answered leniently by the router but not modelled here; their real behavior
|
|
5
|
-
* in the gated `direct/` suites.
|
|
3
|
+
* (sites, jobs, aliases, meta, crontab) — see internal-docs/testing-system-plan.html §4. Edge-cache /
|
|
4
|
+
* SSL / domain-claim are answered leniently by the router but not modelled here; their real behavior
|
|
5
|
+
* lives in the gated `direct/` suites.
|
|
6
6
|
*/
|
|
7
|
+
export type FakeCronEntry = {
|
|
8
|
+
cronId: number;
|
|
9
|
+
schedule: string;
|
|
10
|
+
requestedSchedule: string;
|
|
11
|
+
command: string;
|
|
12
|
+
};
|
|
7
13
|
export type FakeSite = {
|
|
8
14
|
atomicSiteId: string;
|
|
9
15
|
domainName: string;
|
|
10
16
|
meta: Record<string, string>;
|
|
11
17
|
persistentData: Record<string, string>;
|
|
18
|
+
persistentDataEnv: Record<string, boolean>;
|
|
12
19
|
aliases: Set<string>;
|
|
20
|
+
crons: FakeCronEntry[];
|
|
13
21
|
};
|
|
14
22
|
export type FakeSiteSnapshot = {
|
|
15
23
|
atomicSiteId: string;
|
|
16
24
|
domainName: string;
|
|
17
25
|
meta: Record<string, string>;
|
|
18
26
|
persistentData: Record<string, string>;
|
|
27
|
+
persistentDataEnv: Record<string, boolean>;
|
|
19
28
|
aliases: string[];
|
|
20
29
|
};
|
|
30
|
+
export type FakeMetricsRequest = {
|
|
31
|
+
type: string;
|
|
32
|
+
key: string;
|
|
33
|
+
summarize: boolean;
|
|
34
|
+
body: Record<string, unknown>;
|
|
35
|
+
};
|
|
21
36
|
export declare class FakeAtomicStore {
|
|
22
37
|
private readonly sites;
|
|
23
38
|
private readonly clientMeta;
|
|
39
|
+
private readonly metricsResponses;
|
|
40
|
+
private readonly metricRequestLog;
|
|
24
41
|
private siteSeq;
|
|
25
42
|
private jobSeq;
|
|
43
|
+
private cronSeq;
|
|
26
44
|
datacenters(): string[];
|
|
27
45
|
phpVersions(): string[];
|
|
28
46
|
nextJobId(): number;
|
|
@@ -39,6 +57,7 @@ export declare class FakeAtomicStore {
|
|
|
39
57
|
domainName: string;
|
|
40
58
|
meta?: Record<string, string>;
|
|
41
59
|
persistentData?: Record<string, string>;
|
|
60
|
+
persistentDataEnv?: Record<string, boolean>;
|
|
42
61
|
aliases?: Iterable<string>;
|
|
43
62
|
}): FakeSite;
|
|
44
63
|
snapshot(): FakeSiteSnapshot[];
|
|
@@ -52,10 +71,21 @@ export declare class FakeAtomicStore {
|
|
|
52
71
|
addAlias(id: string, domain: string): void;
|
|
53
72
|
removeAlias(id: string, domain: string): void;
|
|
54
73
|
aliases(id: string): string[];
|
|
74
|
+
addCron(id: string, input: {
|
|
75
|
+
schedule: string;
|
|
76
|
+
command: string;
|
|
77
|
+
}): FakeCronEntry | null;
|
|
78
|
+
listCrons(id: string): FakeCronEntry[];
|
|
79
|
+
updateCron(id: string, cronId: number, command: string): boolean;
|
|
80
|
+
removeCron(id: string, cronId: number): boolean;
|
|
55
81
|
accessLogs(id: string): Array<Record<string, unknown>> | null;
|
|
56
82
|
setClientMeta(key: string, value: string): void;
|
|
57
83
|
getClientMeta(key: string): string | undefined;
|
|
58
84
|
deleteClientMeta(key: string): boolean;
|
|
85
|
+
setMetricsResponse(type: string, key: string, response: Record<string, unknown>): void;
|
|
86
|
+
metricsResponse(type: string, key: string): Record<string, unknown>;
|
|
87
|
+
recordMetricsRequest(request: FakeMetricsRequest): void;
|
|
88
|
+
metricsRequests(): FakeMetricsRequest[];
|
|
59
89
|
applyPersistentData(id: string, operations: Record<string, unknown>): Record<string, string> | null;
|
|
60
90
|
persistentData(id: string): Record<string, string> | null;
|
|
61
91
|
/** `GET /get-site/{id}/extra` shape — note `_data` is intentionally ABSENT (faithful to the real
|
package/dist/fake/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/fake/store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,QAAQ,GAAG;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/fake/store.ts"],"names":[],"mappings":"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"}
|
package/dist/fake/store.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* In-memory state for the lean wp.cloud fake. Models only the lifecycle we captured real shapes for
|
|
3
|
-
* (sites, jobs, aliases, meta) — see internal-docs/testing-system-plan.html §4. Edge-cache /
|
|
4
|
-
* domain-claim are answered leniently by the router but not modelled here; their real behavior
|
|
5
|
-
* in the gated `direct/` suites.
|
|
3
|
+
* (sites, jobs, aliases, meta, crontab) — see internal-docs/testing-system-plan.html §4. Edge-cache /
|
|
4
|
+
* SSL / domain-claim are answered leniently by the router but not modelled here; their real behavior
|
|
5
|
+
* lives in the gated `direct/` suites.
|
|
6
6
|
*/
|
|
7
7
|
const DATACENTERS = ["ams", "bur", "dca", "dfw"];
|
|
8
8
|
const PHP_VERSIONS = ["8.2", "8.3", "8.4", "8.5"];
|
|
@@ -12,8 +12,11 @@ function formFlag(value) {
|
|
|
12
12
|
export class FakeAtomicStore {
|
|
13
13
|
sites = new Map();
|
|
14
14
|
clientMeta = new Map();
|
|
15
|
+
metricsResponses = new Map();
|
|
16
|
+
metricRequestLog = [];
|
|
15
17
|
siteSeq = 151_000_000;
|
|
16
18
|
jobSeq = 154_000_000;
|
|
19
|
+
cronSeq = 900_000;
|
|
17
20
|
datacenters() {
|
|
18
21
|
return [...DATACENTERS];
|
|
19
22
|
}
|
|
@@ -30,7 +33,9 @@ export class FakeAtomicStore {
|
|
|
30
33
|
domainName: input.domainName,
|
|
31
34
|
meta: { ...input.meta },
|
|
32
35
|
persistentData: {},
|
|
36
|
+
persistentDataEnv: {},
|
|
33
37
|
aliases: new Set(),
|
|
38
|
+
crons: [],
|
|
34
39
|
});
|
|
35
40
|
return {
|
|
36
41
|
job_id: this.nextJobId(),
|
|
@@ -48,7 +53,9 @@ export class FakeAtomicStore {
|
|
|
48
53
|
domainName: input.domainName,
|
|
49
54
|
meta: input.meta ? { ...input.meta } : {},
|
|
50
55
|
persistentData: input.persistentData ? { ...input.persistentData } : {},
|
|
56
|
+
persistentDataEnv: input.persistentDataEnv ? { ...input.persistentDataEnv } : {},
|
|
51
57
|
aliases: new Set(input.aliases ?? []),
|
|
58
|
+
crons: [],
|
|
52
59
|
};
|
|
53
60
|
this.sites.set(input.atomicSiteId, site);
|
|
54
61
|
return site;
|
|
@@ -59,6 +66,7 @@ export class FakeAtomicStore {
|
|
|
59
66
|
domainName: site.domainName,
|
|
60
67
|
meta: { ...site.meta },
|
|
61
68
|
persistentData: { ...site.persistentData },
|
|
69
|
+
persistentDataEnv: { ...site.persistentDataEnv },
|
|
62
70
|
aliases: [...site.aliases],
|
|
63
71
|
}));
|
|
64
72
|
}
|
|
@@ -89,6 +97,37 @@ export class FakeAtomicStore {
|
|
|
89
97
|
aliases(id) {
|
|
90
98
|
return [...(this.sites.get(id)?.aliases ?? [])];
|
|
91
99
|
}
|
|
100
|
+
addCron(id, input) {
|
|
101
|
+
const site = this.sites.get(id);
|
|
102
|
+
if (!site)
|
|
103
|
+
return null;
|
|
104
|
+
const cron = {
|
|
105
|
+
cronId: ++this.cronSeq,
|
|
106
|
+
schedule: input.schedule,
|
|
107
|
+
requestedSchedule: input.schedule,
|
|
108
|
+
command: input.command,
|
|
109
|
+
};
|
|
110
|
+
site.crons.push(cron);
|
|
111
|
+
return cron;
|
|
112
|
+
}
|
|
113
|
+
listCrons(id) {
|
|
114
|
+
return [...(this.sites.get(id)?.crons ?? [])];
|
|
115
|
+
}
|
|
116
|
+
updateCron(id, cronId, command) {
|
|
117
|
+
const cron = this.sites.get(id)?.crons.find((entry) => entry.cronId === cronId);
|
|
118
|
+
if (!cron)
|
|
119
|
+
return false;
|
|
120
|
+
cron.command = command;
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
removeCron(id, cronId) {
|
|
124
|
+
const site = this.sites.get(id);
|
|
125
|
+
if (!site)
|
|
126
|
+
return false;
|
|
127
|
+
const before = site.crons.length;
|
|
128
|
+
site.crons = site.crons.filter((entry) => entry.cronId !== cronId);
|
|
129
|
+
return site.crons.length < before;
|
|
130
|
+
}
|
|
92
131
|
accessLogs(id) {
|
|
93
132
|
const site = this.sites.get(id);
|
|
94
133
|
if (!site)
|
|
@@ -114,6 +153,18 @@ export class FakeAtomicStore {
|
|
|
114
153
|
deleteClientMeta(key) {
|
|
115
154
|
return this.clientMeta.delete(key);
|
|
116
155
|
}
|
|
156
|
+
setMetricsResponse(type, key, response) {
|
|
157
|
+
this.metricsResponses.set(`${type}:${key}`, response);
|
|
158
|
+
}
|
|
159
|
+
metricsResponse(type, key) {
|
|
160
|
+
return this.metricsResponses.get(`${type}:${key}`) ?? { periods: [] };
|
|
161
|
+
}
|
|
162
|
+
recordMetricsRequest(request) {
|
|
163
|
+
this.metricRequestLog.push(request);
|
|
164
|
+
}
|
|
165
|
+
metricsRequests() {
|
|
166
|
+
return [...this.metricRequestLog];
|
|
167
|
+
}
|
|
117
168
|
applyPersistentData(id, operations) {
|
|
118
169
|
const site = this.sites.get(id);
|
|
119
170
|
if (!site)
|
|
@@ -124,9 +175,11 @@ export class FakeAtomicStore {
|
|
|
124
175
|
const record = operation;
|
|
125
176
|
if (formFlag(record.delete)) {
|
|
126
177
|
delete site.persistentData[key];
|
|
178
|
+
delete site.persistentDataEnv[key];
|
|
127
179
|
continue;
|
|
128
180
|
}
|
|
129
181
|
site.persistentData[key] = String(record.value ?? "");
|
|
182
|
+
site.persistentDataEnv[key] = formFlag(record.env);
|
|
130
183
|
}
|
|
131
184
|
return this.persistentData(id);
|
|
132
185
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spacefast/wpcloud-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Generated TypeScript client for the WP.Cloud API.",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/spacefast/monorepo.git",
|
|
9
|
+
"directory": "packages/wpcloud-sdk"
|
|
10
|
+
},
|
|
6
11
|
"type": "module",
|
|
7
12
|
"publishConfig": {
|
|
8
13
|
"access": "public"
|