alchemy 0.46.1 → 0.48.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/bin/alchemy.mjs +560 -98
- package/lib/alchemy.d.ts +9 -3
- package/lib/alchemy.d.ts.map +1 -1
- package/lib/alchemy.js +19 -39
- package/lib/alchemy.js.map +1 -1
- package/lib/build-date.d.ts +1 -1
- package/lib/build-date.js +1 -1
- package/lib/cloudflare/astro.d.ts.map +1 -1
- package/lib/cloudflare/astro.js +3 -0
- package/lib/cloudflare/astro.js.map +1 -1
- package/lib/cloudflare/container.js +1 -1
- package/lib/cloudflare/container.js.map +1 -1
- package/lib/cloudflare/nuxt.d.ts.map +1 -1
- package/lib/cloudflare/nuxt.js +3 -0
- package/lib/cloudflare/nuxt.js.map +1 -1
- package/lib/cloudflare/oauth.d.ts.map +1 -1
- package/lib/cloudflare/oauth.js +4 -3
- package/lib/cloudflare/oauth.js.map +1 -1
- package/lib/cloudflare/pipeline.d.ts.map +1 -1
- package/lib/cloudflare/pipeline.js +1 -3
- package/lib/cloudflare/pipeline.js.map +1 -1
- package/lib/cloudflare/react-router.d.ts.map +1 -1
- package/lib/cloudflare/react-router.js +3 -0
- package/lib/cloudflare/react-router.js.map +1 -1
- package/lib/cloudflare/vite.d.ts.map +1 -1
- package/lib/cloudflare/vite.js +0 -1
- package/lib/cloudflare/vite.js.map +1 -1
- package/lib/cloudflare/website.d.ts +0 -1
- package/lib/cloudflare/website.d.ts.map +1 -1
- package/lib/cloudflare/website.js +13 -7
- package/lib/cloudflare/website.js.map +1 -1
- package/lib/cloudflare/worker-metadata.d.ts +6 -0
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.js +1 -0
- package/lib/cloudflare/worker-metadata.js.map +1 -1
- package/lib/cloudflare/worker.d.ts +33 -3
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +91 -70
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/zone.d.ts +1 -1
- package/lib/cloudflare/zone.d.ts.map +1 -1
- package/lib/cloudflare/zone.js +38 -56
- package/lib/cloudflare/zone.js.map +1 -1
- package/lib/scope.d.ts +14 -2
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +8 -3
- package/lib/scope.js.map +1 -1
- package/lib/util/safe-fetch.d.ts.map +1 -1
- package/lib/util/safe-fetch.js +1 -0
- package/lib/util/safe-fetch.js.map +1 -1
- package/lib/util/telemetry/constants.js +2 -2
- package/lib/util/telemetry/constants.js.map +1 -1
- package/package.json +4 -2
- package/src/alchemy.ts +28 -49
- package/src/build-date.ts +1 -1
- package/src/cloudflare/astro.ts +3 -0
- package/src/cloudflare/container.ts +1 -1
- package/src/cloudflare/nuxt.ts +3 -0
- package/src/cloudflare/oauth.ts +5 -4
- package/src/cloudflare/pipeline.ts +1 -3
- package/src/cloudflare/react-router.ts +3 -0
- package/src/cloudflare/vite.ts +0 -1
- package/src/cloudflare/website.ts +14 -8
- package/src/cloudflare/worker-metadata.ts +7 -0
- package/src/cloudflare/worker.ts +138 -102
- package/src/cloudflare/zone.ts +50 -70
- package/src/scope.ts +21 -4
- package/src/util/safe-fetch.ts +1 -0
- package/src/util/telemetry/constants.ts +2 -2
- package/templates/react-router/package.json +1 -1
- package/templates/react-router/tsconfig.cloudflare.json +5 -1
- package/templates/react-router/tsconfig.json +0 -3
- package/templates/react-router/tsconfig.node.json +0 -4
- package/lib/util/xdg-paths.d.ts +0 -9
- package/lib/util/xdg-paths.d.ts.map +0 -1
- package/lib/util/xdg-paths.js +0 -41
- package/lib/util/xdg-paths.js.map +0 -1
- package/src/util/xdg-paths.ts +0 -48
package/src/cloudflare/zone.ts
CHANGED
|
@@ -74,7 +74,7 @@ export interface ZoneProps extends CloudflareApiOptions {
|
|
|
74
74
|
/**
|
|
75
75
|
* Enable Always Use HTTPS
|
|
76
76
|
* Redirects all HTTP traffic to HTTPS
|
|
77
|
-
* @default "off"
|
|
77
|
+
* @default "on" (unless explicitly set to "off")
|
|
78
78
|
*/
|
|
79
79
|
alwaysUseHttps?: AlwaysUseHTTPSValue;
|
|
80
80
|
|
|
@@ -339,6 +339,7 @@ export const Zone = Resource(
|
|
|
339
339
|
return this.destroy();
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
+
let zoneData: CloudflareZone;
|
|
342
343
|
if (this.phase === "update" && this.output?.id) {
|
|
343
344
|
// Get zone details to verify it exists
|
|
344
345
|
const response = await api.get(`/zones/${this.output.id}`);
|
|
@@ -349,84 +350,63 @@ export const Zone = Resource(
|
|
|
349
350
|
);
|
|
350
351
|
}
|
|
351
352
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
return this({
|
|
363
|
-
id: zoneData.id,
|
|
364
|
-
name: zoneData.name,
|
|
365
|
-
type: zoneData.type,
|
|
366
|
-
status: zoneData.status,
|
|
367
|
-
paused: zoneData.paused,
|
|
368
|
-
accountId: zoneData.account.id,
|
|
369
|
-
nameservers: zoneData.name_servers,
|
|
370
|
-
originalNameservers: zoneData.original_name_servers,
|
|
371
|
-
createdAt: new Date(zoneData.created_on).getTime(),
|
|
372
|
-
modifiedAt: new Date(zoneData.modified_on).getTime(),
|
|
373
|
-
activatedAt: zoneData.activated_on
|
|
374
|
-
? new Date(zoneData.activated_on).getTime()
|
|
375
|
-
: null,
|
|
376
|
-
settings: await getZoneSettings(api, zoneData.id),
|
|
353
|
+
zoneData = ((await response.json()) as { result: CloudflareZone }).result;
|
|
354
|
+
} else {
|
|
355
|
+
const response = await api.post("/zones", {
|
|
356
|
+
name: props.name,
|
|
357
|
+
type: props.type || "full",
|
|
358
|
+
jump_start: props.jumpStart !== false,
|
|
359
|
+
account: {
|
|
360
|
+
id: api.accountId,
|
|
361
|
+
},
|
|
377
362
|
});
|
|
378
|
-
}
|
|
379
|
-
// Create new zone
|
|
380
|
-
|
|
381
|
-
const response = await api.post("/zones", {
|
|
382
|
-
name: props.name,
|
|
383
|
-
type: props.type || "full",
|
|
384
|
-
jump_start: props.jumpStart !== false,
|
|
385
|
-
account: {
|
|
386
|
-
id: api.accountId,
|
|
387
|
-
},
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
const body = await response.text();
|
|
391
|
-
let zoneData;
|
|
392
|
-
if (!response.ok) {
|
|
393
|
-
if (response.status === 400 && body.includes("already exists")) {
|
|
394
|
-
// Zone already exists, fetch it instead
|
|
395
|
-
logger.warn(
|
|
396
|
-
`Zone '${props.name}' already exists during Zone create, adopting it...`,
|
|
397
|
-
);
|
|
398
|
-
const getResponse = await api.get(`/zones?name=${props.name}`);
|
|
399
363
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
364
|
+
const body = await response.text();
|
|
365
|
+
if (!response.ok) {
|
|
366
|
+
if (response.status === 400 && body.includes("already exists")) {
|
|
367
|
+
// Zone already exists, fetch it instead
|
|
368
|
+
logger.warn(
|
|
369
|
+
`Zone '${props.name}' already exists during Zone create, adopting it...`,
|
|
403
370
|
);
|
|
404
|
-
|
|
371
|
+
const getResponse = await api.get(`/zones?name=${props.name}`);
|
|
405
372
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
373
|
+
if (!getResponse.ok) {
|
|
374
|
+
throw new Error(
|
|
375
|
+
`Error fetching existing zone '${props.name}': ${getResponse.statusText}`,
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const zones = (
|
|
380
|
+
(await getResponse.json()) as { result: CloudflareZone[] }
|
|
381
|
+
).result;
|
|
382
|
+
if (zones.length === 0) {
|
|
383
|
+
throw new Error(
|
|
384
|
+
`Zone '${props.name}' does not exist, but the name is reserved for another user.`,
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
zoneData = zones[0];
|
|
388
|
+
} else {
|
|
410
389
|
throw new Error(
|
|
411
|
-
`
|
|
390
|
+
`Error creating zone '${props.name}': ${response.statusText}\n${body}`,
|
|
412
391
|
);
|
|
413
392
|
}
|
|
414
|
-
zoneData = zones[0];
|
|
415
393
|
} else {
|
|
416
|
-
|
|
417
|
-
`Error creating zone '${props.name}': ${response.statusText}\n${body}`,
|
|
418
|
-
);
|
|
394
|
+
zoneData = (JSON.parse(body) as { result: CloudflareZone }).result;
|
|
419
395
|
}
|
|
420
|
-
} else {
|
|
421
|
-
zoneData = (JSON.parse(body) as { result: CloudflareZone }).result;
|
|
422
396
|
}
|
|
423
397
|
|
|
424
|
-
//
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
398
|
+
// Apply defaults to settings
|
|
399
|
+
const settingsToApply = {
|
|
400
|
+
...props.settings,
|
|
401
|
+
alwaysUseHttps: props.settings?.alwaysUseHttps ?? "on",
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
await updateZoneSettings(api, zoneData.id, settingsToApply);
|
|
405
|
+
|
|
406
|
+
// Add a small delay to ensure settings are propagated
|
|
407
|
+
// TODO(michael): do we need this?
|
|
408
|
+
// https://github.com/sam-goodwin/alchemy/issues/681
|
|
409
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
430
410
|
|
|
431
411
|
return this({
|
|
432
412
|
id: zoneData.id,
|
|
@@ -451,7 +431,7 @@ export const Zone = Resource(
|
|
|
451
431
|
* Helper function to update zone settings
|
|
452
432
|
*/
|
|
453
433
|
async function updateZoneSettings(
|
|
454
|
-
api:
|
|
434
|
+
api: CloudflareApi,
|
|
455
435
|
zoneId: string,
|
|
456
436
|
settings: ZoneProps["settings"],
|
|
457
437
|
): Promise<void> {
|
|
@@ -508,7 +488,7 @@ async function updateZoneSettings(
|
|
|
508
488
|
* Helper function to get current zone settings
|
|
509
489
|
*/
|
|
510
490
|
async function getZoneSettings(
|
|
511
|
-
api:
|
|
491
|
+
api: CloudflareApi,
|
|
512
492
|
zoneId: string,
|
|
513
493
|
): Promise<Zone["settings"]> {
|
|
514
494
|
const settingsResponse = await api.get(`/zones/${zoneId}/settings`);
|
package/src/scope.ts
CHANGED
|
@@ -38,7 +38,18 @@ export interface ScopeOptions {
|
|
|
38
38
|
stateStore?: StateStoreType;
|
|
39
39
|
quiet?: boolean;
|
|
40
40
|
phase?: Phase;
|
|
41
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Determines if resources should be simulated locally (where possible)
|
|
43
|
+
*
|
|
44
|
+
* @default - `true` if ran with `alchemy dev` or `bun ./alchemy.run.ts --dev`
|
|
45
|
+
*/
|
|
46
|
+
local?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Determines if local changes to resources should be reactively pushed to the local or remote environment.
|
|
49
|
+
*
|
|
50
|
+
* @default - `true` if ran with `alchemy dev`, `alchemy watch`, `bun --watch ./alchemy.run.ts`
|
|
51
|
+
*/
|
|
52
|
+
watch?: boolean;
|
|
42
53
|
telemetryClient?: ITelemetryClient;
|
|
43
54
|
logger?: LoggerApi;
|
|
44
55
|
}
|
|
@@ -107,7 +118,8 @@ export class Scope {
|
|
|
107
118
|
public readonly stateStore: StateStoreType;
|
|
108
119
|
public readonly quiet: boolean;
|
|
109
120
|
public readonly phase: Phase;
|
|
110
|
-
public readonly
|
|
121
|
+
public readonly local: boolean;
|
|
122
|
+
public readonly watch: boolean;
|
|
111
123
|
public readonly logger: LoggerApi;
|
|
112
124
|
public readonly telemetryClient: ITelemetryClient;
|
|
113
125
|
public readonly dataMutex: AsyncMutex;
|
|
@@ -162,9 +174,10 @@ export class Scope {
|
|
|
162
174
|
options.logger,
|
|
163
175
|
);
|
|
164
176
|
|
|
165
|
-
this.
|
|
177
|
+
this.local = options.local ?? this.parent?.local ?? false;
|
|
178
|
+
this.watch = options.watch ?? this.parent?.watch ?? false;
|
|
166
179
|
|
|
167
|
-
if (this.
|
|
180
|
+
if (this.local) {
|
|
168
181
|
this.logger.warnOnce(
|
|
169
182
|
"Development mode is in beta. Please report any issues to https://github.com/sam-goodwin/alchemy/issues.",
|
|
170
183
|
);
|
|
@@ -415,6 +428,10 @@ export class Scope {
|
|
|
415
428
|
await this.rootTelemetryClient?.finalize()?.catch((error) => {
|
|
416
429
|
this.logger.warn("Telemetry finalization failed:", error);
|
|
417
430
|
});
|
|
431
|
+
|
|
432
|
+
if (!this.parent && process.env.ALCHEMY_TEST_KILL_ON_FINALIZE) {
|
|
433
|
+
process.exit(0);
|
|
434
|
+
}
|
|
418
435
|
}
|
|
419
436
|
|
|
420
437
|
public async destroyPendingDeletions() {
|
package/src/util/safe-fetch.ts
CHANGED
|
@@ -11,7 +11,11 @@
|
|
|
11
11
|
"composite": true,
|
|
12
12
|
"strict": true,
|
|
13
13
|
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
|
14
|
-
"types": [
|
|
14
|
+
"types": [
|
|
15
|
+
"vite/client",
|
|
16
|
+
"@cloudflare/workers-types",
|
|
17
|
+
"./types/env.d.ts"
|
|
18
|
+
],
|
|
15
19
|
"target": "ES2022",
|
|
16
20
|
"module": "ES2022",
|
|
17
21
|
"moduleResolution": "bundler",
|
package/lib/util/xdg-paths.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Vendored XDG Base Directory Specification implementation
|
|
3
|
-
* Provides cross-platform directory paths for config and state
|
|
4
|
-
*/
|
|
5
|
-
export declare function createXdgAppPaths(appName: string): {
|
|
6
|
-
config: () => string;
|
|
7
|
-
state: () => string;
|
|
8
|
-
};
|
|
9
|
-
//# sourceMappingURL=xdg-paths.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"xdg-paths.d.ts","sourceRoot":"","sources":["../../src/util/xdg-paths.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM;kBAI5B,MAAM;iBAgBP,MAAM;EAoBzB"}
|
package/lib/util/xdg-paths.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
/**
|
|
4
|
-
* Vendored XDG Base Directory Specification implementation
|
|
5
|
-
* Provides cross-platform directory paths for config and state
|
|
6
|
-
*/
|
|
7
|
-
export function createXdgAppPaths(appName) {
|
|
8
|
-
const platform = process.platform;
|
|
9
|
-
const home = homedir();
|
|
10
|
-
function config() {
|
|
11
|
-
if (platform === "win32") {
|
|
12
|
-
return join(process.env.LOCALAPPDATA || join(home, "AppData", "Local"), appName);
|
|
13
|
-
}
|
|
14
|
-
else if (platform === "darwin") {
|
|
15
|
-
return join(home, "Library", "Preferences", appName);
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
// Linux/Unix - follow XDG Base Directory Specification
|
|
19
|
-
const xdgConfigHome = process.env.XDG_CONFIG_HOME || join(home, ".config");
|
|
20
|
-
return join(xdgConfigHome, appName);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
function state() {
|
|
24
|
-
if (platform === "win32") {
|
|
25
|
-
return join(process.env.LOCALAPPDATA || join(home, "AppData", "Local"), appName);
|
|
26
|
-
}
|
|
27
|
-
else if (platform === "darwin") {
|
|
28
|
-
return join(home, "Library", "Application Support", appName);
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
// Linux/Unix - follow XDG Base Directory Specification
|
|
32
|
-
const xdgStateHome = process.env.XDG_STATE_HOME || join(home, ".local", "state");
|
|
33
|
-
return join(xdgStateHome, appName);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return {
|
|
37
|
-
config,
|
|
38
|
-
state,
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=xdg-paths.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"xdg-paths.js","sourceRoot":"","sources":["../../src/util/xdg-paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,SAAS,MAAM;QACb,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,OAAO,IAAI,CACT,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,EAC1D,OAAO,CACR,CAAC;QACJ,CAAC;aAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,uDAAuD;YACvD,MAAM,aAAa,GACjB,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YACvD,OAAO,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,SAAS,KAAK;QACZ,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,OAAO,IAAI,CACT,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,EAC1D,OAAO,CACR,CAAC;QACJ,CAAC;aAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,OAAO,CAAC,CAAC;QAC/D,CAAC;aAAM,CAAC;YACN,uDAAuD;YACvD,MAAM,YAAY,GAChB,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,OAAO;QACL,MAAM;QACN,KAAK;KACN,CAAC;AACJ,CAAC"}
|
package/src/util/xdg-paths.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Vendored XDG Base Directory Specification implementation
|
|
6
|
-
* Provides cross-platform directory paths for config and state
|
|
7
|
-
*/
|
|
8
|
-
export function createXdgAppPaths(appName: string) {
|
|
9
|
-
const platform = process.platform;
|
|
10
|
-
const home = homedir();
|
|
11
|
-
|
|
12
|
-
function config(): string {
|
|
13
|
-
if (platform === "win32") {
|
|
14
|
-
return join(
|
|
15
|
-
process.env.LOCALAPPDATA || join(home, "AppData", "Local"),
|
|
16
|
-
appName,
|
|
17
|
-
);
|
|
18
|
-
} else if (platform === "darwin") {
|
|
19
|
-
return join(home, "Library", "Preferences", appName);
|
|
20
|
-
} else {
|
|
21
|
-
// Linux/Unix - follow XDG Base Directory Specification
|
|
22
|
-
const xdgConfigHome =
|
|
23
|
-
process.env.XDG_CONFIG_HOME || join(home, ".config");
|
|
24
|
-
return join(xdgConfigHome, appName);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function state(): string {
|
|
29
|
-
if (platform === "win32") {
|
|
30
|
-
return join(
|
|
31
|
-
process.env.LOCALAPPDATA || join(home, "AppData", "Local"),
|
|
32
|
-
appName,
|
|
33
|
-
);
|
|
34
|
-
} else if (platform === "darwin") {
|
|
35
|
-
return join(home, "Library", "Application Support", appName);
|
|
36
|
-
} else {
|
|
37
|
-
// Linux/Unix - follow XDG Base Directory Specification
|
|
38
|
-
const xdgStateHome =
|
|
39
|
-
process.env.XDG_STATE_HOME || join(home, ".local", "state");
|
|
40
|
-
return join(xdgStateHome, appName);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
config,
|
|
46
|
-
state,
|
|
47
|
-
};
|
|
48
|
-
}
|