astro 1.0.0-beta.23 → 1.0.0-beta.26
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 +1 -2
- package/dist/@types/serialize-javascript.d.js +0 -0
- package/dist/cli/index.js +8 -8
- package/dist/core/app/index.js +5 -7
- package/dist/core/build/static-build.js +12 -2
- package/dist/core/create-vite.js +6 -0
- package/dist/core/dev/index.js +1 -1
- package/dist/core/messages.js +2 -2
- package/dist/core/render/core.js +2 -1
- package/dist/core/render/dev/index.js +2 -1
- package/dist/core/render/result.js +13 -1
- package/dist/integrations/index.js +2 -1
- package/dist/runtime/server/hydration.js +2 -2
- package/dist/runtime/server/index.js +34 -1
- package/dist/types/@types/astro.d.ts +29 -2
- package/dist/types/core/render/core.d.ts +1 -0
- package/dist/types/core/render/dev/index.d.ts +1 -0
- package/dist/types/integrations/index.d.ts +3 -1
- package/dist/vite-plugin-astro-server/index.js +5 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<br/>
|
|
2
2
|
<p align="center">
|
|
3
|
-
<img src="../../assets/
|
|
4
|
-
<img src="../../assets/brand/logo-square-white.png#gh-dark-mode-only" alt="Astro logo" width="120">
|
|
3
|
+
<img src="../../assets/social/banner-minimal.png" alt="Astro logo">
|
|
5
4
|
<br/><br/>
|
|
6
5
|
<a href="https://astro.build">Astro</a> is a website build tool for the modern web —
|
|
7
6
|
<br/>
|
|
File without changes
|
package/dist/cli/index.js
CHANGED
|
@@ -40,7 +40,7 @@ function printAstroHelp() {
|
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
42
|
async function printVersion() {
|
|
43
|
-
const version = "1.0.0-beta.
|
|
43
|
+
const version = "1.0.0-beta.26";
|
|
44
44
|
console.log();
|
|
45
45
|
console.log(` ${colors.bgGreen(colors.black(` astro `))} ${colors.green(`v${version}`)}`);
|
|
46
46
|
}
|
|
@@ -83,7 +83,7 @@ async function cli(args) {
|
|
|
83
83
|
} else if (flags.silent) {
|
|
84
84
|
logging.level = "silent";
|
|
85
85
|
}
|
|
86
|
-
const telemetry = new AstroTelemetry({ version: "1.0.0-beta.
|
|
86
|
+
const telemetry = new AstroTelemetry({ version: "1.0.0-beta.26" });
|
|
87
87
|
if (cmd === "telemetry") {
|
|
88
88
|
try {
|
|
89
89
|
const subcommand = (_a = flags._[3]) == null ? void 0 : _a.toString();
|
|
@@ -97,7 +97,7 @@ async function cli(args) {
|
|
|
97
97
|
try {
|
|
98
98
|
const packages = flags._.slice(3);
|
|
99
99
|
telemetry.record(event.eventCliSession({
|
|
100
|
-
astroVersion: "1.0.0-beta.
|
|
100
|
+
astroVersion: "1.0.0-beta.26",
|
|
101
101
|
cliCommand: "add"
|
|
102
102
|
}));
|
|
103
103
|
return await add(packages, { cwd: root, flags, logging, telemetry });
|
|
@@ -108,7 +108,7 @@ async function cli(args) {
|
|
|
108
108
|
case "dev": {
|
|
109
109
|
try {
|
|
110
110
|
const config = await loadConfig({ cwd: root, flags, cmd });
|
|
111
|
-
telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.
|
|
111
|
+
telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.26", cliCommand: "dev" }, config));
|
|
112
112
|
await devServer(config, { logging, telemetry });
|
|
113
113
|
return await new Promise(() => {
|
|
114
114
|
});
|
|
@@ -119,7 +119,7 @@ async function cli(args) {
|
|
|
119
119
|
case "build": {
|
|
120
120
|
try {
|
|
121
121
|
const config = await loadConfig({ cwd: root, flags, cmd });
|
|
122
|
-
telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.
|
|
122
|
+
telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.26", cliCommand: "build" }, config));
|
|
123
123
|
return await build(config, { logging, telemetry });
|
|
124
124
|
} catch (err) {
|
|
125
125
|
return throwAndExit(err);
|
|
@@ -127,14 +127,14 @@ async function cli(args) {
|
|
|
127
127
|
}
|
|
128
128
|
case "check": {
|
|
129
129
|
const config = await loadConfig({ cwd: root, flags, cmd });
|
|
130
|
-
telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.
|
|
130
|
+
telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.26", cliCommand: "check" }, config));
|
|
131
131
|
const ret = await check(config);
|
|
132
132
|
return process.exit(ret);
|
|
133
133
|
}
|
|
134
134
|
case "preview": {
|
|
135
135
|
try {
|
|
136
136
|
const config = await loadConfig({ cwd: root, flags, cmd });
|
|
137
|
-
telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.
|
|
137
|
+
telemetry.record(event.eventCliSession({ astroVersion: "1.0.0-beta.26", cliCommand: "preview" }, config));
|
|
138
138
|
const server = await preview(config, { logging, telemetry });
|
|
139
139
|
return await server.closed();
|
|
140
140
|
} catch (err) {
|
|
@@ -144,7 +144,7 @@ async function cli(args) {
|
|
|
144
144
|
case "docs": {
|
|
145
145
|
try {
|
|
146
146
|
await telemetry.record(event.eventCliSession({
|
|
147
|
-
astroVersion: "1.0.0-beta.
|
|
147
|
+
astroVersion: "1.0.0-beta.26",
|
|
148
148
|
cliCommand: "docs"
|
|
149
149
|
}));
|
|
150
150
|
return await openInBrowser("https://docs.astro.build/");
|
package/dist/core/app/index.js
CHANGED
|
@@ -119,14 +119,12 @@ renderPage_fn = async function(request, routeData, mod) {
|
|
|
119
119
|
return result.response;
|
|
120
120
|
}
|
|
121
121
|
let html = result.html;
|
|
122
|
+
let init = result.response;
|
|
123
|
+
let headers = init.headers;
|
|
122
124
|
let bytes = __privateGet(this, _encoder).encode(html);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
"Content-Type": "text/html",
|
|
127
|
-
"Content-Length": bytes.byteLength.toString()
|
|
128
|
-
}
|
|
129
|
-
});
|
|
125
|
+
headers.set("Content-Type", "text/html");
|
|
126
|
+
headers.set("Content-Length", bytes.byteLength.toString());
|
|
127
|
+
return new Response(bytes, init);
|
|
130
128
|
};
|
|
131
129
|
_callEndpoint = new WeakSet();
|
|
132
130
|
callEndpoint_fn = async function(request, routeData, mod) {
|
|
@@ -137,7 +137,12 @@ async function ssrBuild(opts, internals, input) {
|
|
|
137
137
|
ssr: viteConfig.ssr,
|
|
138
138
|
resolve: viteConfig.resolve
|
|
139
139
|
};
|
|
140
|
-
await runHookBuildSetup({
|
|
140
|
+
await runHookBuildSetup({
|
|
141
|
+
config: astroConfig,
|
|
142
|
+
pages: internals.pagesByComponent,
|
|
143
|
+
vite: viteBuildConfig,
|
|
144
|
+
target: "server"
|
|
145
|
+
});
|
|
141
146
|
return await vite.build(viteBuildConfig);
|
|
142
147
|
}
|
|
143
148
|
async function clientBuild(opts, internals, input) {
|
|
@@ -188,7 +193,12 @@ ${bgGreen(black(" building client "))}`);
|
|
|
188
193
|
server: viteConfig.server,
|
|
189
194
|
base: astroConfig.base
|
|
190
195
|
};
|
|
191
|
-
await runHookBuildSetup({
|
|
196
|
+
await runHookBuildSetup({
|
|
197
|
+
config: astroConfig,
|
|
198
|
+
pages: internals.pagesByComponent,
|
|
199
|
+
vite: viteBuildConfig,
|
|
200
|
+
target: "client"
|
|
201
|
+
});
|
|
192
202
|
const buildResult = await vite.build(viteBuildConfig);
|
|
193
203
|
info(opts.logging, null, dim(`Completed in ${getTimeStat(timer, performance.now())}.
|
|
194
204
|
`));
|
package/dist/core/create-vite.js
CHANGED
|
@@ -15,6 +15,7 @@ const ALWAYS_EXTERNAL = /* @__PURE__ */ new Set([
|
|
|
15
15
|
...builtinModules.map((name) => `node:${name}`),
|
|
16
16
|
"@sveltejs/vite-plugin-svelte",
|
|
17
17
|
"micromark-util-events-to-acorn",
|
|
18
|
+
"serialize-javascript",
|
|
18
19
|
"node-fetch",
|
|
19
20
|
"prismjs",
|
|
20
21
|
"shiki",
|
|
@@ -61,6 +62,11 @@ async function createVite(commandConfig, { astroConfig, logging, mode }) {
|
|
|
61
62
|
css: {
|
|
62
63
|
postcss: astroConfig.style.postcss || {}
|
|
63
64
|
},
|
|
65
|
+
resolve: {
|
|
66
|
+
alias: {
|
|
67
|
+
randombytes: "randombytes/browser"
|
|
68
|
+
}
|
|
69
|
+
},
|
|
64
70
|
ssr: {
|
|
65
71
|
external: [...ALWAYS_EXTERNAL],
|
|
66
72
|
noExternal: [...ALWAYS_NOEXTERNAL, ...astroPackages]
|
package/dist/core/dev/index.js
CHANGED
|
@@ -36,7 +36,7 @@ async function dev(config, options) {
|
|
|
36
36
|
site,
|
|
37
37
|
https: !!((_a = viteConfig.server) == null ? void 0 : _a.https)
|
|
38
38
|
}));
|
|
39
|
-
const currentVersion = "1.0.0-beta.
|
|
39
|
+
const currentVersion = "1.0.0-beta.26";
|
|
40
40
|
if (currentVersion.includes("-")) {
|
|
41
41
|
warn(options.logging, null, msg.prerelease({ currentVersion }));
|
|
42
42
|
}
|
package/dist/core/messages.js
CHANGED
|
@@ -47,7 +47,7 @@ function devStart({
|
|
|
47
47
|
https,
|
|
48
48
|
site
|
|
49
49
|
}) {
|
|
50
|
-
const version = "1.0.0-beta.
|
|
50
|
+
const version = "1.0.0-beta.26";
|
|
51
51
|
const rootPath = site ? site.pathname : "/";
|
|
52
52
|
const localPrefix = `${dim("\u2503")} Local `;
|
|
53
53
|
const networkPrefix = `${dim("\u2503")} Network `;
|
|
@@ -199,7 +199,7 @@ function printHelp({
|
|
|
199
199
|
};
|
|
200
200
|
let message = [];
|
|
201
201
|
if (headline) {
|
|
202
|
-
message.push(linebreak(), ` ${bgGreen(black(` ${commandName} `))} ${green(`v${"1.0.0-beta.
|
|
202
|
+
message.push(linebreak(), ` ${bgGreen(black(` ${commandName} `))} ${green(`v${"1.0.0-beta.26"}`)} ${headline}`);
|
|
203
203
|
}
|
|
204
204
|
if (usage) {
|
|
205
205
|
message.push(linebreak(), ` ${green(commandName)} ${bold(usage)}`);
|
package/dist/core/render/core.js
CHANGED
|
@@ -110,6 +110,16 @@ function createResult(args) {
|
|
|
110
110
|
const { markdown, params, pathname, renderers, request, resolve, site } = args;
|
|
111
111
|
const url = new URL(request.url);
|
|
112
112
|
const canonicalURL = createCanonicalURL("." + pathname, site ?? url.origin);
|
|
113
|
+
const response = {
|
|
114
|
+
status: 200,
|
|
115
|
+
statusText: "OK",
|
|
116
|
+
headers: new Headers()
|
|
117
|
+
};
|
|
118
|
+
Object.defineProperty(response, "headers", {
|
|
119
|
+
value: response.headers,
|
|
120
|
+
enumerable: true,
|
|
121
|
+
writable: false
|
|
122
|
+
});
|
|
113
123
|
const result = {
|
|
114
124
|
styles: /* @__PURE__ */ new Set(),
|
|
115
125
|
scripts: args.scripts ?? /* @__PURE__ */ new Set(),
|
|
@@ -154,6 +164,7 @@ or consider make it a module like so:
|
|
|
154
164
|
${extra}`);
|
|
155
165
|
return "";
|
|
156
166
|
},
|
|
167
|
+
response,
|
|
157
168
|
slots: astroSlots
|
|
158
169
|
};
|
|
159
170
|
Object.defineProperty(Astro, "__renderMarkdown", {
|
|
@@ -177,7 +188,8 @@ ${extra}`);
|
|
|
177
188
|
_metadata: {
|
|
178
189
|
renderers,
|
|
179
190
|
pathname
|
|
180
|
-
}
|
|
191
|
+
},
|
|
192
|
+
response
|
|
181
193
|
};
|
|
182
194
|
return result;
|
|
183
195
|
}
|
|
@@ -111,11 +111,12 @@ async function runHookBuildStart({
|
|
|
111
111
|
async function runHookBuildSetup({
|
|
112
112
|
config,
|
|
113
113
|
vite,
|
|
114
|
+
pages,
|
|
114
115
|
target
|
|
115
116
|
}) {
|
|
116
117
|
for (const integration of config.integrations) {
|
|
117
118
|
if (integration.hooks["astro:build:setup"]) {
|
|
118
|
-
await integration.hooks["astro:build:setup"]({ vite, target });
|
|
119
|
+
await integration.hooks["astro:build:setup"]({ vite, pages, target });
|
|
119
120
|
}
|
|
120
121
|
}
|
|
121
122
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { hydrationSpecifier, serializeListValue } from "./util.js";
|
|
2
|
-
import
|
|
2
|
+
import serializeJavaScript from "serialize-javascript";
|
|
3
3
|
function serializeProps(value) {
|
|
4
|
-
return
|
|
4
|
+
return serializeJavaScript(value);
|
|
5
5
|
}
|
|
6
6
|
const HydrationDirectives = ["load", "idle", "media", "visible", "only"];
|
|
7
7
|
function extractDirectives(inputProps) {
|
|
@@ -329,7 +329,40 @@ async function renderEndpoint(mod, request, params) {
|
|
|
329
329
|
if (!handler || typeof handler !== "function") {
|
|
330
330
|
throw new Error(`Endpoint handler not found! Expected an exported function for "${chosenMethod}"`);
|
|
331
331
|
}
|
|
332
|
-
|
|
332
|
+
if (handler.length > 1) {
|
|
333
|
+
console.warn(`
|
|
334
|
+
API routes with 2 arguments have been deprecated. Instead they take a single argument in the form of:
|
|
335
|
+
|
|
336
|
+
export function get({ params, request }) {
|
|
337
|
+
//...
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
Update your code to remove this warning.`);
|
|
341
|
+
}
|
|
342
|
+
const context = {
|
|
343
|
+
request,
|
|
344
|
+
params
|
|
345
|
+
};
|
|
346
|
+
const proxy = new Proxy(context, {
|
|
347
|
+
get(target, prop) {
|
|
348
|
+
if (prop in target) {
|
|
349
|
+
return Reflect.get(target, prop);
|
|
350
|
+
} else if (prop in params) {
|
|
351
|
+
console.warn(`
|
|
352
|
+
API routes no longer pass params as the first argument. Instead an object containing a params property is provided in the form of:
|
|
353
|
+
|
|
354
|
+
export function get({ params }) {
|
|
355
|
+
// ...
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
Update your code to remove this warning.`);
|
|
359
|
+
return Reflect.get(params, prop);
|
|
360
|
+
} else {
|
|
361
|
+
return void 0;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
return await handler.call(mod, proxy, request);
|
|
333
366
|
}
|
|
334
367
|
async function replaceHeadInjection(result, html) {
|
|
335
368
|
let template = html;
|
|
@@ -8,6 +8,7 @@ import type { AstroConfigSchema } from '../core/config';
|
|
|
8
8
|
import type { AstroComponentFactory, Metadata } from '../runtime/server';
|
|
9
9
|
import type { ViteConfigWithSSR } from '../core/create-vite';
|
|
10
10
|
import type { SerializedSSRManifest } from '../core/app/types';
|
|
11
|
+
import type { PageBuildData } from '../core/build/types';
|
|
11
12
|
export type { SSRManifest } from '../core/app/types';
|
|
12
13
|
export interface AstroBuiltinProps {
|
|
13
14
|
'client:load'?: boolean;
|
|
@@ -113,6 +114,18 @@ export interface AstroGlobal extends AstroGlobalPartial {
|
|
|
113
114
|
* [Astro reference](https://docs.astro.build/en/reference/api-reference/#astrorequest)
|
|
114
115
|
*/
|
|
115
116
|
request: Request;
|
|
117
|
+
/** Information about the outgoing response. This is a standard [ResponseInit](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#init) object
|
|
118
|
+
*
|
|
119
|
+
* For example, to change the status code you can set a different status on this object:
|
|
120
|
+
* ```typescript
|
|
121
|
+
* Astro.response.status = 404;
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* [Astro reference](https://docs.astro.build/en/reference/api-reference/#astroresponse)
|
|
125
|
+
*/
|
|
126
|
+
response: ResponseInit & {
|
|
127
|
+
readonly headers: Headers;
|
|
128
|
+
};
|
|
116
129
|
/** Redirect to another page (**SSR Only**)
|
|
117
130
|
*
|
|
118
131
|
* Example usage:
|
|
@@ -774,11 +787,23 @@ export interface AstroAdapter {
|
|
|
774
787
|
exports?: string[];
|
|
775
788
|
args?: any;
|
|
776
789
|
}
|
|
790
|
+
export interface APIContext {
|
|
791
|
+
params: Params;
|
|
792
|
+
request: Request;
|
|
793
|
+
}
|
|
777
794
|
export interface EndpointOutput<Output extends Body = Body> {
|
|
778
795
|
body: Output;
|
|
779
796
|
}
|
|
797
|
+
interface APIRoute {
|
|
798
|
+
(context: APIContext): EndpointOutput | Response;
|
|
799
|
+
/**
|
|
800
|
+
* @deprecated
|
|
801
|
+
* Use { context: APIRouteContext } object instead.
|
|
802
|
+
*/
|
|
803
|
+
(params: Params, request: Request): EndpointOutput | Response;
|
|
804
|
+
}
|
|
780
805
|
export interface EndpointHandler {
|
|
781
|
-
[method: string]:
|
|
806
|
+
[method: string]: APIRoute;
|
|
782
807
|
}
|
|
783
808
|
export interface AstroRenderer {
|
|
784
809
|
/** Name of the renderer. */
|
|
@@ -831,8 +856,9 @@ export interface AstroIntegration {
|
|
|
831
856
|
}) => void | Promise<void>;
|
|
832
857
|
'astro:build:setup'?: (options: {
|
|
833
858
|
vite: ViteConfigWithSSR;
|
|
859
|
+
pages: Map<string, PageBuildData>;
|
|
834
860
|
target: 'client' | 'server';
|
|
835
|
-
}) => void
|
|
861
|
+
}) => void | Promise<void>;
|
|
836
862
|
'astro:build:done'?: (options: {
|
|
837
863
|
pages: {
|
|
838
864
|
pathname: string;
|
|
@@ -925,5 +951,6 @@ export interface SSRResult {
|
|
|
925
951
|
links: Set<SSRElement>;
|
|
926
952
|
createAstro(Astro: AstroGlobalPartial, props: Record<string, any>, slots: Record<string, any> | null): AstroGlobal;
|
|
927
953
|
resolve: (s: string) => Promise<string>;
|
|
954
|
+
response: ResponseInit;
|
|
928
955
|
_metadata: SSRMetadata;
|
|
929
956
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import type { AddressInfo } from 'net';
|
|
3
3
|
import type { ViteDevServer } from 'vite';
|
|
4
4
|
import type { SerializedSSRManifest } from '../core/app/types';
|
|
5
|
+
import type { PageBuildData } from '../core/build/types';
|
|
5
6
|
import { AstroConfig, BuildConfig, RouteData } from '../@types/astro.js';
|
|
6
7
|
import type { ViteConfigWithSSR } from '../core/create-vite.js';
|
|
7
8
|
export declare function runHookConfigSetup({ config: _config, command, }: {
|
|
@@ -26,9 +27,10 @@ export declare function runHookBuildStart({ config, buildConfig, }: {
|
|
|
26
27
|
config: AstroConfig;
|
|
27
28
|
buildConfig: BuildConfig;
|
|
28
29
|
}): Promise<void>;
|
|
29
|
-
export declare function runHookBuildSetup({ config, vite, target, }: {
|
|
30
|
+
export declare function runHookBuildSetup({ config, vite, pages, target, }: {
|
|
30
31
|
config: AstroConfig;
|
|
31
32
|
vite: ViteConfigWithSSR;
|
|
33
|
+
pages: Map<string, PageBuildData>;
|
|
32
34
|
target: 'server' | 'client';
|
|
33
35
|
}): Promise<void>;
|
|
34
36
|
export declare function runHookBuildSsr({ config, manifest, }: {
|
|
@@ -67,8 +67,11 @@ async function writeSSRResult(result, res, statusCode) {
|
|
|
67
67
|
await writeWebResponse(res, response);
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
70
|
-
const { html } = result;
|
|
71
|
-
|
|
70
|
+
const { html, response: init } = result;
|
|
71
|
+
const headers = init.headers;
|
|
72
|
+
headers.set("Content-Type", "text/html; charset=utf-8");
|
|
73
|
+
headers.set("Content-Length", Buffer.byteLength(html, "utf-8").toString());
|
|
74
|
+
return writeWebResponse(res, new Response(html, init));
|
|
72
75
|
}
|
|
73
76
|
async function handle404Response(origin, config, req, res) {
|
|
74
77
|
const site = config.site ? new URL(config.base, config.site) : void 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.26",
|
|
4
4
|
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "withastro",
|
|
@@ -83,7 +83,6 @@
|
|
|
83
83
|
"ci-info": "^3.3.0",
|
|
84
84
|
"common-ancestor-path": "^1.0.1",
|
|
85
85
|
"debug": "^4.3.4",
|
|
86
|
-
"devalue": "^2.0.1",
|
|
87
86
|
"diff": "^5.0.0",
|
|
88
87
|
"eol": "^0.9.1",
|
|
89
88
|
"es-module-lexer": "^0.10.5",
|
|
@@ -112,6 +111,7 @@
|
|
|
112
111
|
"resolve": "^1.22.0",
|
|
113
112
|
"rollup": "^2.70.2",
|
|
114
113
|
"semver": "^7.3.7",
|
|
114
|
+
"serialize-javascript": "^6.0.0",
|
|
115
115
|
"shiki": "^0.10.1",
|
|
116
116
|
"sirv": "^2.0.2",
|
|
117
117
|
"slash": "^4.0.0",
|