astro 5.0.0-beta.1 → 5.0.0-beta.3
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/components/viewtransitions.css +10 -0
- package/dist/actions/consts.d.ts +1 -1
- package/dist/actions/consts.js +1 -1
- package/dist/actions/runtime/middleware.js +15 -6
- package/dist/actions/runtime/virtual/shared.js +14 -4
- package/dist/assets/utils/resolveImports.js +1 -1
- package/dist/cli/add/index.js +12 -14
- package/dist/cli/install-package.js +4 -4
- package/dist/container/index.d.ts +1 -0
- package/dist/container/index.js +9 -6
- package/dist/container/pipeline.js +1 -1
- package/dist/container/polyfill.d.ts +1 -0
- package/dist/container/polyfill.js +2 -0
- package/dist/content/consts.d.ts +5 -3
- package/dist/content/consts.js +7 -3
- package/dist/content/content-layer.d.ts +1 -1
- package/dist/content/content-layer.js +44 -10
- package/dist/content/loaders/file.d.ts +9 -2
- package/dist/content/loaders/file.js +30 -14
- package/dist/content/runtime.d.ts +0 -4
- package/dist/content/runtime.js +6 -7
- package/dist/content/types-generator.js +16 -13
- package/dist/content/utils.d.ts +81 -34
- package/dist/content/utils.js +28 -14
- package/dist/content/vite-plugin-content-virtual-mod.d.ts +1 -3
- package/dist/content/vite-plugin-content-virtual-mod.js +22 -79
- package/dist/core/app/common.js +3 -2
- package/dist/core/app/index.d.ts +1 -1
- package/dist/core/app/index.js +4 -11
- package/dist/core/app/pipeline.d.ts +1 -1
- package/dist/core/app/pipeline.js +1 -1
- package/dist/core/app/types.d.ts +2 -2
- package/dist/core/base-pipeline.d.ts +9 -4
- package/dist/core/base-pipeline.js +22 -0
- package/dist/core/build/generate.js +12 -3
- package/dist/core/build/index.js +1 -10
- package/dist/core/build/internal.d.ts +0 -2
- package/dist/core/build/internal.js +0 -2
- package/dist/core/build/pipeline.d.ts +2 -1
- package/dist/core/build/pipeline.js +9 -2
- package/dist/core/build/plugins/index.js +0 -2
- package/dist/core/build/plugins/plugin-manifest.js +1 -1
- package/dist/core/build/plugins/plugin-ssr.js +1 -1
- package/dist/core/build/static-build.d.ts +1 -1
- package/dist/core/build/static-build.js +6 -42
- package/dist/core/config/schema.d.ts +0 -17
- package/dist/core/config/schema.js +7 -2
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/dev/restart.js +2 -1
- package/dist/core/errors/dev/utils.d.ts +1 -1
- package/dist/core/errors/errors-data.d.ts +54 -0
- package/dist/core/errors/errors-data.js +34 -0
- package/dist/core/messages.js +2 -2
- package/dist/core/middleware/noop-middleware.d.ts +2 -0
- package/dist/core/middleware/noop-middleware.js +4 -0
- package/dist/core/middleware/sequence.js +8 -0
- package/dist/core/render/params-and-props.js +4 -4
- package/dist/core/render-context.d.ts +2 -2
- package/dist/core/render-context.js +23 -13
- package/dist/core/routing/manifest/generator.d.ts +1 -1
- package/dist/core/routing/manifest/generator.js +21 -18
- package/dist/core/util.d.ts +0 -1
- package/dist/core/util.js +1 -6
- package/dist/env/constants.d.ts +1 -1
- package/dist/env/constants.js +1 -1
- package/dist/integrations/hooks.d.ts +2 -2
- package/dist/integrations/hooks.js +12 -10
- package/dist/jsx/rehype.js +6 -2
- package/dist/preferences/constants.d.ts +1 -0
- package/dist/preferences/constants.js +4 -0
- package/dist/preferences/store.js +2 -1
- package/dist/runtime/server/render/util.js +1 -1
- package/dist/transitions/router.js +4 -3
- package/dist/transitions/swap-functions.js +4 -1
- package/dist/types/public/common.d.ts +3 -0
- package/dist/types/public/config.d.ts +0 -18
- package/dist/types/public/integrations.d.ts +1 -1
- package/dist/vite-plugin-astro/index.js +0 -5
- package/dist/vite-plugin-astro-server/pipeline.d.ts +1 -1
- package/dist/vite-plugin-astro-server/pipeline.js +1 -1
- package/dist/vite-plugin-astro-server/plugin.js +7 -3
- package/dist/vite-plugin-astro-server/route.js +4 -3
- package/dist/vite-plugin-markdown/content-entry-type.js +4 -4
- package/dist/vite-plugin-markdown/index.js +3 -8
- package/package.json +21 -24
- package/types/content.d.ts +7 -1
- package/dist/core/build/plugins/plugin-content.d.ts +0 -5
- package/dist/core/build/plugins/plugin-content.js +0 -394
|
@@ -10,12 +10,22 @@
|
|
|
10
10
|
@keyframes astroFadeIn {
|
|
11
11
|
from {
|
|
12
12
|
opacity: 0;
|
|
13
|
+
mix-blend-mode: plus-lighter;
|
|
14
|
+
}
|
|
15
|
+
to {
|
|
16
|
+
opacity: 1;
|
|
17
|
+
mix-blend-mode: plus-lighter;
|
|
13
18
|
}
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
@keyframes astroFadeOut {
|
|
22
|
+
from {
|
|
23
|
+
opacity: 1;
|
|
24
|
+
mix-blend-mode: plus-lighter;
|
|
25
|
+
}
|
|
17
26
|
to {
|
|
18
27
|
opacity: 0;
|
|
28
|
+
mix-blend-mode: plus-lighter;
|
|
19
29
|
}
|
|
20
30
|
}
|
|
21
31
|
|
package/dist/actions/consts.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const VIRTUAL_MODULE_ID = "astro:actions";
|
|
2
2
|
export declare const RESOLVED_VIRTUAL_MODULE_ID: string;
|
|
3
|
-
export declare const ACTIONS_TYPES_FILE = "
|
|
3
|
+
export declare const ACTIONS_TYPES_FILE = "actions.d.ts";
|
|
4
4
|
export declare const VIRTUAL_INTERNAL_MODULE_ID = "astro:internal-actions";
|
|
5
5
|
export declare const RESOLVED_VIRTUAL_INTERNAL_MODULE_ID = "\0astro:internal-actions";
|
|
6
6
|
export declare const NOOP_ACTIONS = "\0noop-actions";
|
package/dist/actions/consts.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const VIRTUAL_MODULE_ID = "astro:actions";
|
|
2
2
|
const RESOLVED_VIRTUAL_MODULE_ID = "\0" + VIRTUAL_MODULE_ID;
|
|
3
|
-
const ACTIONS_TYPES_FILE = "
|
|
3
|
+
const ACTIONS_TYPES_FILE = "actions.d.ts";
|
|
4
4
|
const VIRTUAL_INTERNAL_MODULE_ID = "astro:internal-actions";
|
|
5
5
|
const RESOLVED_VIRTUAL_INTERNAL_MODULE_ID = "\0astro:internal-actions";
|
|
6
6
|
const NOOP_ACTIONS = "\0noop-actions";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { decodeBase64, encodeBase64 } from "@oslojs/encoding";
|
|
1
2
|
import { yellow } from "kleur/colors";
|
|
2
3
|
import { defineMiddleware } from "../../core/middleware/index.js";
|
|
3
4
|
import { ACTION_QUERY_PARAMS } from "../consts.js";
|
|
@@ -6,6 +7,8 @@ import { getAction } from "./virtual/get-action.js";
|
|
|
6
7
|
import {
|
|
7
8
|
serializeActionResult
|
|
8
9
|
} from "./virtual/shared.js";
|
|
10
|
+
const decoder = new TextDecoder();
|
|
11
|
+
const encoder = new TextEncoder();
|
|
9
12
|
const onRequest = defineMiddleware(async (context, next) => {
|
|
10
13
|
if (context.isPrerendered) {
|
|
11
14
|
if (context.request.method === "POST") {
|
|
@@ -18,8 +21,9 @@ const onRequest = defineMiddleware(async (context, next) => {
|
|
|
18
21
|
}
|
|
19
22
|
const locals = context.locals;
|
|
20
23
|
if (locals._actionPayload) return next();
|
|
21
|
-
const
|
|
22
|
-
if (
|
|
24
|
+
const actionPayloadCookie = context.cookies.get(ACTION_QUERY_PARAMS.actionPayload)?.value;
|
|
25
|
+
if (actionPayloadCookie) {
|
|
26
|
+
const actionPayload = JSON.parse(decoder.decode(decodeBase64(actionPayloadCookie)));
|
|
23
27
|
if (!isActionPayload(actionPayload)) {
|
|
24
28
|
throw new Error("Internal: Invalid action payload in cookie.");
|
|
25
29
|
}
|
|
@@ -79,10 +83,15 @@ async function redirectWithResult({
|
|
|
79
83
|
actionName,
|
|
80
84
|
actionResult
|
|
81
85
|
}) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
const cookieValue = encodeBase64(
|
|
87
|
+
encoder.encode(
|
|
88
|
+
JSON.stringify({
|
|
89
|
+
actionName,
|
|
90
|
+
actionResult: serializeActionResult(actionResult)
|
|
91
|
+
})
|
|
92
|
+
)
|
|
93
|
+
);
|
|
94
|
+
context.cookies.set(ACTION_QUERY_PARAMS.actionPayload, cookieValue);
|
|
86
95
|
if (actionResult.error) {
|
|
87
96
|
const referer = context.request.headers.get("Referer");
|
|
88
97
|
if (!referer) {
|
|
@@ -126,14 +126,24 @@ function serializeActionResult(res) {
|
|
|
126
126
|
if (import.meta.env?.DEV) {
|
|
127
127
|
actionResultErrorStack.set(res.error.stack);
|
|
128
128
|
}
|
|
129
|
+
let body2;
|
|
130
|
+
if (res.error instanceof ActionInputError) {
|
|
131
|
+
body2 = {
|
|
132
|
+
type: res.error.type,
|
|
133
|
+
issues: res.error.issues,
|
|
134
|
+
fields: res.error.fields
|
|
135
|
+
};
|
|
136
|
+
} else {
|
|
137
|
+
body2 = {
|
|
138
|
+
...res.error,
|
|
139
|
+
message: res.error.message
|
|
140
|
+
};
|
|
141
|
+
}
|
|
129
142
|
return {
|
|
130
143
|
type: "error",
|
|
131
144
|
status: res.error.status,
|
|
132
145
|
contentType: "application/json",
|
|
133
|
-
body: JSON.stringify(
|
|
134
|
-
...res.error,
|
|
135
|
-
message: res.error.message
|
|
136
|
-
})
|
|
146
|
+
body: JSON.stringify(body2)
|
|
137
147
|
};
|
|
138
148
|
}
|
|
139
149
|
if (res.data === void 0) {
|
|
@@ -4,7 +4,7 @@ import { shorthash } from "../../runtime/server/shorthash.js";
|
|
|
4
4
|
import { VALID_INPUT_FORMATS } from "../consts.js";
|
|
5
5
|
function imageSrcToImportId(imageSrc, filePath) {
|
|
6
6
|
imageSrc = removeBase(imageSrc, IMAGE_IMPORT_PREFIX);
|
|
7
|
-
if (isRemotePath(imageSrc)
|
|
7
|
+
if (isRemotePath(imageSrc)) {
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
10
10
|
const ext = imageSrc.split(".").at(-1);
|
package/dist/cli/add/index.js
CHANGED
|
@@ -6,11 +6,11 @@ import { diffWords } from "diff";
|
|
|
6
6
|
import { bold, cyan, dim, green, magenta, red, yellow } from "kleur/colors";
|
|
7
7
|
import { builders, generateCode, loadFile } from "magicast";
|
|
8
8
|
import { getDefaultExportOptions } from "magicast/helpers";
|
|
9
|
-
import ora from "ora";
|
|
10
9
|
import preferredPM from "preferred-pm";
|
|
11
10
|
import prompts from "prompts";
|
|
12
11
|
import maxSatisfying from "semver/ranges/max-satisfying.js";
|
|
13
12
|
import { exec } from "tinyexec";
|
|
13
|
+
import yoctoSpinner from "yocto-spinner";
|
|
14
14
|
import {
|
|
15
15
|
loadTSConfig,
|
|
16
16
|
resolveConfig,
|
|
@@ -381,9 +381,6 @@ function setAdapter(mod, adapter, exportName) {
|
|
|
381
381
|
from: exportName
|
|
382
382
|
});
|
|
383
383
|
}
|
|
384
|
-
if (!config.output) {
|
|
385
|
-
config.output = "server";
|
|
386
|
-
}
|
|
387
384
|
switch (adapter.id) {
|
|
388
385
|
case "node":
|
|
389
386
|
config.adapter = builders.functionCall(adapterId, { mode: "standalone" });
|
|
@@ -494,7 +491,8 @@ async function resolveRangeToInstallSpecifier(name, range) {
|
|
|
494
491
|
const versions = await fetchPackageVersions(name);
|
|
495
492
|
if (versions instanceof Error) return name;
|
|
496
493
|
const stableVersions = versions.filter((v) => !v.includes("-"));
|
|
497
|
-
const maxStable = maxSatisfying(stableVersions
|
|
494
|
+
const maxStable = maxSatisfying(stableVersions, range) ?? maxSatisfying(versions, range);
|
|
495
|
+
if (!maxStable) return name;
|
|
498
496
|
return `${name}@^${maxStable}`;
|
|
499
497
|
}
|
|
500
498
|
const INHERITED_FLAGS = /* @__PURE__ */ new Set([
|
|
@@ -545,7 +543,7 @@ ${boxen(coloredOutput, {
|
|
|
545
543
|
${message}`
|
|
546
544
|
);
|
|
547
545
|
if (await askToContinue({ flags })) {
|
|
548
|
-
const spinner =
|
|
546
|
+
const spinner = yoctoSpinner({ text: "Installing dependencies..." }).start();
|
|
549
547
|
try {
|
|
550
548
|
await exec(
|
|
551
549
|
installCommand.pm,
|
|
@@ -563,10 +561,10 @@ ${message}`
|
|
|
563
561
|
}
|
|
564
562
|
}
|
|
565
563
|
);
|
|
566
|
-
spinner.
|
|
564
|
+
spinner.success();
|
|
567
565
|
return 1 /* updated */;
|
|
568
566
|
} catch (err) {
|
|
569
|
-
spinner.
|
|
567
|
+
spinner.error();
|
|
570
568
|
logger.debug("add", "Error installing dependencies", err);
|
|
571
569
|
console.error("\n", err.stdout || err.message, "\n");
|
|
572
570
|
return 3 /* failure */;
|
|
@@ -577,7 +575,7 @@ ${message}`
|
|
|
577
575
|
}
|
|
578
576
|
}
|
|
579
577
|
async function validateIntegrations(integrations) {
|
|
580
|
-
const spinner =
|
|
578
|
+
const spinner = yoctoSpinner({ text: "Resolving packages..." }).start();
|
|
581
579
|
try {
|
|
582
580
|
const integrationEntries = await Promise.all(
|
|
583
581
|
integrations.map(async (integration) => {
|
|
@@ -594,9 +592,9 @@ async function validateIntegrations(integrations) {
|
|
|
594
592
|
const firstPartyPkgCheck = await fetchPackageJson("@astrojs", name, tag);
|
|
595
593
|
if (firstPartyPkgCheck instanceof Error) {
|
|
596
594
|
if (firstPartyPkgCheck.message) {
|
|
597
|
-
spinner.
|
|
595
|
+
spinner.warning(yellow(firstPartyPkgCheck.message));
|
|
598
596
|
}
|
|
599
|
-
spinner.
|
|
597
|
+
spinner.warning(yellow(`${bold(integration)} is not an official Astro package.`));
|
|
600
598
|
const response = await prompts({
|
|
601
599
|
type: "confirm",
|
|
602
600
|
name: "askToContinue",
|
|
@@ -621,7 +619,7 @@ async function validateIntegrations(integrations) {
|
|
|
621
619
|
const thirdPartyPkgCheck = await fetchPackageJson(scope, name, tag);
|
|
622
620
|
if (thirdPartyPkgCheck instanceof Error) {
|
|
623
621
|
if (thirdPartyPkgCheck.message) {
|
|
624
|
-
spinner.
|
|
622
|
+
spinner.warning(yellow(thirdPartyPkgCheck.message));
|
|
625
623
|
}
|
|
626
624
|
throw new Error(`Unable to fetch ${bold(integration)}. Does the package exist?`);
|
|
627
625
|
} else {
|
|
@@ -661,11 +659,11 @@ async function validateIntegrations(integrations) {
|
|
|
661
659
|
return { id: integration, packageName, dependencies, type: integrationType };
|
|
662
660
|
})
|
|
663
661
|
);
|
|
664
|
-
spinner.
|
|
662
|
+
spinner.success();
|
|
665
663
|
return integrationEntries;
|
|
666
664
|
} catch (e) {
|
|
667
665
|
if (e instanceof Error) {
|
|
668
|
-
spinner.
|
|
666
|
+
spinner.error(e.message);
|
|
669
667
|
process.exit(1);
|
|
670
668
|
} else {
|
|
671
669
|
throw e;
|
|
@@ -2,11 +2,11 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
import boxen from "boxen";
|
|
3
3
|
import ci from "ci-info";
|
|
4
4
|
import { bold, cyan, dim, magenta } from "kleur/colors";
|
|
5
|
-
import ora from "ora";
|
|
6
5
|
import preferredPM from "preferred-pm";
|
|
7
6
|
import prompts from "prompts";
|
|
8
7
|
import { exec } from "tinyexec";
|
|
9
8
|
import whichPm from "which-pm";
|
|
9
|
+
import yoctoSpinner from "yocto-spinner";
|
|
10
10
|
const require2 = createRequire(import.meta.url);
|
|
11
11
|
async function getPackage(packageName, logger, options, otherDeps = []) {
|
|
12
12
|
try {
|
|
@@ -104,18 +104,18 @@ ${message}`
|
|
|
104
104
|
})).askToContinue;
|
|
105
105
|
}
|
|
106
106
|
if (Boolean(response)) {
|
|
107
|
-
const spinner =
|
|
107
|
+
const spinner = yoctoSpinner({ text: "Installing dependencies..." }).start();
|
|
108
108
|
try {
|
|
109
109
|
await exec(
|
|
110
110
|
installCommand.pm,
|
|
111
111
|
[installCommand.command, ...installCommand.flags, ...installCommand.dependencies],
|
|
112
112
|
{ nodeOptions: { cwd } }
|
|
113
113
|
);
|
|
114
|
-
spinner.
|
|
114
|
+
spinner.success();
|
|
115
115
|
return true;
|
|
116
116
|
} catch (err) {
|
|
117
117
|
logger.debug("add", "Error installing dependencies", err);
|
|
118
|
-
spinner.
|
|
118
|
+
spinner.error();
|
|
119
119
|
return false;
|
|
120
120
|
}
|
|
121
121
|
} else {
|
package/dist/container/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import "./polyfill.js";
|
|
1
2
|
import { posix } from "node:path";
|
|
2
3
|
import { getDefaultClientDirectives } from "../core/client-directive/index.js";
|
|
3
4
|
import { ASTRO_CONFIG_DEFAULTS } from "../core/config/schema.js";
|
|
@@ -5,15 +6,18 @@ import { validateConfig } from "../core/config/validate.js";
|
|
|
5
6
|
import { createKey } from "../core/encryption.js";
|
|
6
7
|
import { Logger } from "../core/logger/core.js";
|
|
7
8
|
import { nodeLogDestination } from "../core/logger/node.js";
|
|
9
|
+
import { NOOP_MIDDLEWARE_FN } from "../core/middleware/noop-middleware.js";
|
|
8
10
|
import { removeLeadingForwardSlash } from "../core/path.js";
|
|
9
11
|
import { RenderContext } from "../core/render-context.js";
|
|
10
12
|
import { getParts, validateSegment } from "../core/routing/manifest/create.js";
|
|
11
13
|
import { getPattern } from "../core/routing/manifest/pattern.js";
|
|
12
14
|
import { ContainerPipeline } from "./pipeline.js";
|
|
13
15
|
function createManifest(manifest, renderers, middleware) {
|
|
14
|
-
|
|
15
|
-
return
|
|
16
|
-
|
|
16
|
+
function middlewareInstance() {
|
|
17
|
+
return {
|
|
18
|
+
onRequest: middleware ?? NOOP_MIDDLEWARE_FN
|
|
19
|
+
};
|
|
20
|
+
}
|
|
17
21
|
return {
|
|
18
22
|
hrefRoot: import.meta.url,
|
|
19
23
|
trailingSlash: manifest?.trailingSlash ?? ASTRO_CONFIG_DEFAULTS.trailingSlash,
|
|
@@ -31,7 +35,7 @@ function createManifest(manifest, renderers, middleware) {
|
|
|
31
35
|
inlinedScripts: manifest?.inlinedScripts ?? /* @__PURE__ */ new Map(),
|
|
32
36
|
i18n: manifest?.i18n,
|
|
33
37
|
checkOrigin: false,
|
|
34
|
-
middleware: manifest?.middleware ??
|
|
38
|
+
middleware: manifest?.middleware ?? middlewareInstance,
|
|
35
39
|
envGetSecretEnabled: false,
|
|
36
40
|
key: createKey()
|
|
37
41
|
};
|
|
@@ -256,11 +260,10 @@ class experimental_AstroContainer {
|
|
|
256
260
|
params: options.params,
|
|
257
261
|
type: routeType
|
|
258
262
|
});
|
|
259
|
-
const renderContext = RenderContext.create({
|
|
263
|
+
const renderContext = await RenderContext.create({
|
|
260
264
|
pipeline: this.#pipeline,
|
|
261
265
|
routeData,
|
|
262
266
|
status: 200,
|
|
263
|
-
middleware: this.#pipeline.middleware,
|
|
264
267
|
request,
|
|
265
268
|
pathname: url.pathname,
|
|
266
269
|
locals: options?.locals ?? {}
|
|
@@ -67,7 +67,7 @@ class ContainerPipeline extends Pipeline {
|
|
|
67
67
|
return Promise.resolve(componentInstance);
|
|
68
68
|
},
|
|
69
69
|
renderers: this.manifest.renderers,
|
|
70
|
-
onRequest: this.
|
|
70
|
+
onRequest: this.resolvedMiddleware
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
73
|
// At the moment it's not used by the container via any public API
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/content/consts.d.ts
CHANGED
|
@@ -17,8 +17,10 @@ export declare const LINKS_PLACEHOLDER = "@@ASTRO-LINKS@@";
|
|
|
17
17
|
export declare const STYLES_PLACEHOLDER = "@@ASTRO-STYLES@@";
|
|
18
18
|
export declare const IMAGE_IMPORT_PREFIX = "__ASTRO_IMAGE_";
|
|
19
19
|
export declare const CONTENT_FLAGS: readonly ["astroContentCollectionEntry", "astroRenderContent", "astroDataCollectionEntry", "astroPropagatedAssets", "astroContentImageFlag", "astroContentModuleFlag"];
|
|
20
|
-
export declare const CONTENT_TYPES_FILE = "
|
|
20
|
+
export declare const CONTENT_TYPES_FILE = "content.d.ts";
|
|
21
21
|
export declare const DATA_STORE_FILE = "data-store.json";
|
|
22
|
-
export declare const ASSET_IMPORTS_FILE = "assets.mjs";
|
|
23
|
-
export declare const MODULES_IMPORTS_FILE = "modules.mjs";
|
|
22
|
+
export declare const ASSET_IMPORTS_FILE = "content-assets.mjs";
|
|
23
|
+
export declare const MODULES_IMPORTS_FILE = "content-modules.mjs";
|
|
24
|
+
export declare const COLLECTIONS_MANIFEST_FILE = "collections/collections.json";
|
|
25
|
+
export declare const COLLECTIONS_DIR = "collections/";
|
|
24
26
|
export declare const CONTENT_LAYER_TYPE = "content_layer";
|
package/dist/content/consts.js
CHANGED
|
@@ -24,15 +24,19 @@ const CONTENT_FLAGS = [
|
|
|
24
24
|
CONTENT_IMAGE_FLAG,
|
|
25
25
|
CONTENT_MODULE_FLAG
|
|
26
26
|
];
|
|
27
|
-
const CONTENT_TYPES_FILE = "
|
|
27
|
+
const CONTENT_TYPES_FILE = "content.d.ts";
|
|
28
28
|
const DATA_STORE_FILE = "data-store.json";
|
|
29
|
-
const ASSET_IMPORTS_FILE = "assets.mjs";
|
|
30
|
-
const MODULES_IMPORTS_FILE = "modules.mjs";
|
|
29
|
+
const ASSET_IMPORTS_FILE = "content-assets.mjs";
|
|
30
|
+
const MODULES_IMPORTS_FILE = "content-modules.mjs";
|
|
31
|
+
const COLLECTIONS_MANIFEST_FILE = "collections/collections.json";
|
|
32
|
+
const COLLECTIONS_DIR = "collections/";
|
|
31
33
|
const CONTENT_LAYER_TYPE = "content_layer";
|
|
32
34
|
export {
|
|
33
35
|
ASSET_IMPORTS_FILE,
|
|
34
36
|
ASSET_IMPORTS_RESOLVED_STUB_ID,
|
|
35
37
|
ASSET_IMPORTS_VIRTUAL_ID,
|
|
38
|
+
COLLECTIONS_DIR,
|
|
39
|
+
COLLECTIONS_MANIFEST_FILE,
|
|
36
40
|
CONTENT_FLAG,
|
|
37
41
|
CONTENT_FLAGS,
|
|
38
42
|
CONTENT_IMAGE_FLAG,
|
|
@@ -34,7 +34,7 @@ export declare class ContentLayer {
|
|
|
34
34
|
}
|
|
35
35
|
export declare function simpleLoader<TData extends {
|
|
36
36
|
id: string;
|
|
37
|
-
}>(handler: () => Array<TData> | Promise<Array<TData
|
|
37
|
+
}>(handler: () => Array<TData> | Promise<Array<TData>> | Record<string, Record<string, unknown>> | Promise<Record<string, Record<string, unknown>>>, context: LoaderContext): Promise<void>;
|
|
38
38
|
/**
|
|
39
39
|
* Get the path to the data store file.
|
|
40
40
|
* During development, this is in the `.astro` directory so that the Vite watcher can see it.
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { promises as fs, existsSync } from "node:fs";
|
|
2
2
|
import * as fastq from "fastq";
|
|
3
3
|
import xxhash from "xxhash-wasm";
|
|
4
|
+
import { AstroError, AstroErrorData } from "../core/errors/index.js";
|
|
4
5
|
import {
|
|
5
6
|
ASSET_IMPORTS_FILE,
|
|
7
|
+
COLLECTIONS_MANIFEST_FILE,
|
|
6
8
|
CONTENT_LAYER_TYPE,
|
|
7
9
|
DATA_STORE_FILE,
|
|
8
10
|
MODULES_IMPORTS_FILE
|
|
@@ -158,14 +160,10 @@ class ContentLayer {
|
|
|
158
160
|
return collection.loader.load(context);
|
|
159
161
|
})
|
|
160
162
|
);
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
163
|
+
await fs.mkdir(this.#settings.config.cacheDir, { recursive: true });
|
|
164
|
+
await fs.mkdir(this.#settings.dotAstroDir, { recursive: true });
|
|
164
165
|
const cacheFile = getDataStoreFile(this.#settings);
|
|
165
166
|
await this.#store.writeToDisk(cacheFile);
|
|
166
|
-
if (!existsSync(this.#settings.dotAstroDir)) {
|
|
167
|
-
await fs.mkdir(this.#settings.dotAstroDir, { recursive: true });
|
|
168
|
-
}
|
|
169
167
|
const assetImportsFile = new URL(ASSET_IMPORTS_FILE, this.#settings.dotAstroDir);
|
|
170
168
|
await this.#store.writeAssetImports(assetImportsFile);
|
|
171
169
|
const modulesImportsFile = new URL(MODULES_IMPORTS_FILE, this.#settings.dotAstroDir);
|
|
@@ -176,7 +174,7 @@ class ContentLayer {
|
|
|
176
174
|
}
|
|
177
175
|
}
|
|
178
176
|
async regenerateCollectionFileManifest() {
|
|
179
|
-
const collectionsManifest = new URL(
|
|
177
|
+
const collectionsManifest = new URL(COLLECTIONS_MANIFEST_FILE, this.#settings.dotAstroDir);
|
|
180
178
|
this.#logger.debug("content", "Regenerating collection file manifest");
|
|
181
179
|
if (existsSync(collectionsManifest)) {
|
|
182
180
|
try {
|
|
@@ -210,10 +208,46 @@ class ContentLayer {
|
|
|
210
208
|
async function simpleLoader(handler, context) {
|
|
211
209
|
const data = await handler();
|
|
212
210
|
context.store.clear();
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
211
|
+
if (Array.isArray(data)) {
|
|
212
|
+
for (const raw of data) {
|
|
213
|
+
if (!raw.id) {
|
|
214
|
+
throw new AstroError({
|
|
215
|
+
...AstroErrorData.ContentLoaderInvalidDataError,
|
|
216
|
+
message: AstroErrorData.ContentLoaderInvalidDataError.message(
|
|
217
|
+
context.collection,
|
|
218
|
+
`Entry missing ID:
|
|
219
|
+
${JSON.stringify({ ...raw, id: void 0 }, null, 2)}`
|
|
220
|
+
)
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
const item = await context.parseData({ id: raw.id, data: raw });
|
|
224
|
+
context.store.set({ id: raw.id, data: item });
|
|
225
|
+
}
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (typeof data === "object") {
|
|
229
|
+
for (const [id, raw] of Object.entries(data)) {
|
|
230
|
+
if (raw.id && raw.id !== id) {
|
|
231
|
+
throw new AstroError({
|
|
232
|
+
...AstroErrorData.ContentLoaderInvalidDataError,
|
|
233
|
+
message: AstroErrorData.ContentLoaderInvalidDataError.message(
|
|
234
|
+
context.collection,
|
|
235
|
+
`Object key ${JSON.stringify(id)} does not match ID ${JSON.stringify(raw.id)}`
|
|
236
|
+
)
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
const item = await context.parseData({ id, data: raw });
|
|
240
|
+
context.store.set({ id, data: item });
|
|
241
|
+
}
|
|
242
|
+
return;
|
|
216
243
|
}
|
|
244
|
+
throw new AstroError({
|
|
245
|
+
...AstroErrorData.ExpectedImageOptions,
|
|
246
|
+
message: AstroErrorData.ContentLoaderInvalidDataError.message(
|
|
247
|
+
context.collection,
|
|
248
|
+
`Invalid data type: ${typeof data}`
|
|
249
|
+
)
|
|
250
|
+
});
|
|
217
251
|
}
|
|
218
252
|
function getDataStoreFile(settings, isDev) {
|
|
219
253
|
isDev ??= process?.env.NODE_ENV === "development";
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { Loader } from './types.js';
|
|
2
|
+
export interface FileOptions {
|
|
3
|
+
/**
|
|
4
|
+
* the parsing function to use for this data
|
|
5
|
+
* @default JSON.parse or yaml.load, depending on the extension of the file
|
|
6
|
+
* */
|
|
7
|
+
parser?: (text: string) => Record<string, Record<string, unknown>> | Array<Record<string, unknown>>;
|
|
8
|
+
}
|
|
2
9
|
/**
|
|
3
10
|
* Loads entries from a JSON file. The file must contain an array of objects that contain unique `id` fields, or an object with string keys.
|
|
4
|
-
* @todo Add support for other file types, such as YAML, CSV etc.
|
|
5
11
|
* @param fileName The path to the JSON file to load, relative to the content directory.
|
|
12
|
+
* @param options Additional options for the file loader
|
|
6
13
|
*/
|
|
7
|
-
export declare function file(fileName: string): Loader;
|
|
14
|
+
export declare function file(fileName: string, options?: FileOptions): Loader;
|
|
@@ -1,43 +1,59 @@
|
|
|
1
1
|
import { promises as fs, existsSync } from "node:fs";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
|
+
import yaml from "js-yaml";
|
|
3
4
|
import { posixRelative } from "../utils.js";
|
|
4
|
-
function file(fileName) {
|
|
5
|
+
function file(fileName, options) {
|
|
5
6
|
if (fileName.includes("*")) {
|
|
6
7
|
throw new Error("Glob patterns are not supported in `file` loader. Use `glob` loader instead.");
|
|
7
8
|
}
|
|
9
|
+
let parse = null;
|
|
10
|
+
const ext = fileName.split(".").at(-1);
|
|
11
|
+
if (ext === "json") {
|
|
12
|
+
parse = JSON.parse;
|
|
13
|
+
} else if (ext === "yml" || ext === "yaml") {
|
|
14
|
+
parse = (text) => yaml.load(text, {
|
|
15
|
+
filename: fileName
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
if (options?.parser) parse = options.parser;
|
|
19
|
+
if (parse === null) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
`No parser found for file '${fileName}'. Try passing a parser to the \`file\` loader.`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
8
24
|
async function syncData(filePath, { logger, parseData, store, config }) {
|
|
9
|
-
let
|
|
25
|
+
let data;
|
|
10
26
|
try {
|
|
11
|
-
const
|
|
12
|
-
|
|
27
|
+
const contents = await fs.readFile(filePath, "utf-8");
|
|
28
|
+
data = parse(contents);
|
|
13
29
|
} catch (error) {
|
|
14
30
|
logger.error(`Error reading data from ${fileName}`);
|
|
15
31
|
logger.debug(error.message);
|
|
16
32
|
return;
|
|
17
33
|
}
|
|
18
34
|
const normalizedFilePath = posixRelative(fileURLToPath(config.root), filePath);
|
|
19
|
-
if (Array.isArray(
|
|
20
|
-
if (
|
|
35
|
+
if (Array.isArray(data)) {
|
|
36
|
+
if (data.length === 0) {
|
|
21
37
|
logger.warn(`No items found in ${fileName}`);
|
|
22
38
|
}
|
|
23
|
-
logger.debug(`Found ${
|
|
39
|
+
logger.debug(`Found ${data.length} item array in ${fileName}`);
|
|
24
40
|
store.clear();
|
|
25
|
-
for (const rawItem of
|
|
41
|
+
for (const rawItem of data) {
|
|
26
42
|
const id = (rawItem.id ?? rawItem.slug)?.toString();
|
|
27
43
|
if (!id) {
|
|
28
44
|
logger.error(`Item in ${fileName} is missing an id or slug field.`);
|
|
29
45
|
continue;
|
|
30
46
|
}
|
|
31
|
-
const
|
|
32
|
-
store.set({ id, data, filePath: normalizedFilePath });
|
|
47
|
+
const parsedData = await parseData({ id, data: rawItem, filePath });
|
|
48
|
+
store.set({ id, data: parsedData, filePath: normalizedFilePath });
|
|
33
49
|
}
|
|
34
|
-
} else if (typeof
|
|
35
|
-
const entries = Object.entries(
|
|
50
|
+
} else if (typeof data === "object") {
|
|
51
|
+
const entries = Object.entries(data);
|
|
36
52
|
logger.debug(`Found object with ${entries.length} entries in ${fileName}`);
|
|
37
53
|
store.clear();
|
|
38
54
|
for (const [id, rawItem] of entries) {
|
|
39
|
-
const
|
|
40
|
-
store.set({ id, data, filePath: normalizedFilePath });
|
|
55
|
+
const parsedData = await parseData({ id, data: rawItem, filePath });
|
|
56
|
+
store.set({ id, data: parsedData, filePath: normalizedFilePath });
|
|
41
57
|
}
|
|
42
58
|
} else {
|
|
43
59
|
logger.error(`Invalid data in ${fileName}. Must be an array or object.`);
|
|
@@ -81,10 +81,6 @@ export declare function renderEntry(entry: DataEntry | {
|
|
|
81
81
|
}>;
|
|
82
82
|
}): Promise<{
|
|
83
83
|
Content: AstroComponentFactory;
|
|
84
|
-
} | {
|
|
85
|
-
Content: any;
|
|
86
|
-
headings: any;
|
|
87
|
-
remarkPluginFrontmatter: any;
|
|
88
84
|
}>;
|
|
89
85
|
export declare function createReference({ lookupMap }: {
|
|
90
86
|
lookupMap: ContentLookupMap;
|
package/dist/content/runtime.js
CHANGED
|
@@ -313,13 +313,12 @@ async function renderEntry(entry) {
|
|
|
313
313
|
if (entry.deferredRender) {
|
|
314
314
|
try {
|
|
315
315
|
const { default: contentModules } = await import("astro:content-module-imports");
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
};
|
|
316
|
+
const renderEntryImport = contentModules.get(entry.filePath);
|
|
317
|
+
return render({
|
|
318
|
+
collection: "",
|
|
319
|
+
id: entry.id,
|
|
320
|
+
renderEntryImport
|
|
321
|
+
});
|
|
323
322
|
} catch (e) {
|
|
324
323
|
console.error(e);
|
|
325
324
|
}
|
|
@@ -9,7 +9,12 @@ import { printNode, zodToTs } from "zod-to-ts";
|
|
|
9
9
|
import { AstroError } from "../core/errors/errors.js";
|
|
10
10
|
import { AstroErrorData } from "../core/errors/index.js";
|
|
11
11
|
import { isRelativePath } from "../core/path.js";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
COLLECTIONS_DIR,
|
|
14
|
+
CONTENT_LAYER_TYPE,
|
|
15
|
+
CONTENT_TYPES_FILE,
|
|
16
|
+
VIRTUAL_MODULE_ID
|
|
17
|
+
} from "./consts.js";
|
|
13
18
|
import {
|
|
14
19
|
getContentEntryIdAndSlug,
|
|
15
20
|
getContentPaths,
|
|
@@ -313,10 +318,8 @@ async function writeContentFiles({
|
|
|
313
318
|
}) {
|
|
314
319
|
let contentTypesStr = "";
|
|
315
320
|
let dataTypesStr = "";
|
|
316
|
-
const collectionSchemasDir = new URL(
|
|
317
|
-
|
|
318
|
-
fs.mkdirSync(collectionSchemasDir, { recursive: true });
|
|
319
|
-
}
|
|
321
|
+
const collectionSchemasDir = new URL(COLLECTIONS_DIR, settings.dotAstroDir);
|
|
322
|
+
fs.mkdirSync(collectionSchemasDir, { recursive: true });
|
|
320
323
|
for (const [collection, config] of Object.entries(contentConfig?.collections ?? {})) {
|
|
321
324
|
collectionEntryMap[JSON.stringify(collection)] ??= {
|
|
322
325
|
type: config.type,
|
|
@@ -391,7 +394,8 @@ async function writeContentFiles({
|
|
|
391
394
|
id: string;
|
|
392
395
|
collection: ${collectionKey};
|
|
393
396
|
data: ${dataType};
|
|
394
|
-
rendered?: RenderedContent
|
|
397
|
+
rendered?: RenderedContent;
|
|
398
|
+
filePath?: string
|
|
395
399
|
}>;
|
|
396
400
|
`;
|
|
397
401
|
break;
|
|
@@ -458,11 +462,8 @@ async function writeContentFiles({
|
|
|
458
462
|
JSON.stringify(contentCollectionManifest, null, 2)
|
|
459
463
|
);
|
|
460
464
|
}
|
|
461
|
-
if (!fs.existsSync(settings.dotAstroDir)) {
|
|
462
|
-
fs.mkdirSync(settings.dotAstroDir, { recursive: true });
|
|
463
|
-
}
|
|
464
465
|
const configPathRelativeToCacheDir = normalizeConfigPath(
|
|
465
|
-
|
|
466
|
+
settings.dotAstroDir.pathname,
|
|
466
467
|
contentPaths.config.url.pathname
|
|
467
468
|
);
|
|
468
469
|
for (const contentEntryType of contentEntryTypes) {
|
|
@@ -477,9 +478,11 @@ async function writeContentFiles({
|
|
|
477
478
|
contentConfig ? `typeof import(${configPathRelativeToCacheDir})` : "never"
|
|
478
479
|
);
|
|
479
480
|
if (settings.injectedTypes.some((t) => t.filename === CONTENT_TYPES_FILE)) {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
481
|
+
await fs.promises.writeFile(
|
|
482
|
+
new URL(CONTENT_TYPES_FILE, settings.dotAstroDir),
|
|
483
|
+
typeTemplateContent,
|
|
484
|
+
"utf-8"
|
|
485
|
+
);
|
|
483
486
|
} else {
|
|
484
487
|
settings.injectedTypes.push({
|
|
485
488
|
filename: CONTENT_TYPES_FILE,
|