astro 4.13.3 → 4.14.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.
Files changed (107) hide show
  1. package/components/Code.astro +9 -0
  2. package/dist/@types/astro.d.ts +251 -2
  3. package/dist/actions/consts.d.ts +1 -1
  4. package/dist/actions/consts.js +1 -1
  5. package/dist/actions/index.js +12 -21
  6. package/dist/actions/runtime/virtual/server.js +9 -3
  7. package/dist/actions/runtime/virtual/shared.js +25 -3
  8. package/dist/assets/utils/resolveImports.d.ts +9 -0
  9. package/dist/assets/utils/resolveImports.js +22 -0
  10. package/dist/cli/add/index.d.ts +2 -2
  11. package/dist/cli/add/index.js +2 -2
  12. package/dist/cli/build/index.d.ts +2 -2
  13. package/dist/cli/build/index.js +5 -1
  14. package/dist/cli/check/index.d.ts +2 -2
  15. package/dist/cli/check/index.js +5 -2
  16. package/dist/cli/db/index.d.ts +4 -3
  17. package/dist/cli/db/index.js +10 -3
  18. package/dist/cli/dev/index.d.ts +2 -2
  19. package/dist/cli/dev/index.js +1 -0
  20. package/dist/cli/docs/index.d.ts +2 -2
  21. package/dist/cli/flags.d.ts +3 -1
  22. package/dist/cli/flags.js +2 -1
  23. package/dist/cli/index.d.ts +1 -1
  24. package/dist/cli/index.js +26 -13
  25. package/dist/cli/info/index.d.ts +2 -2
  26. package/dist/cli/preferences/index.d.ts +2 -2
  27. package/dist/cli/preferences/index.js +1 -1
  28. package/dist/cli/preview/index.d.ts +2 -2
  29. package/dist/cli/sync/index.d.ts +2 -2
  30. package/dist/cli/sync/index.js +5 -2
  31. package/dist/cli/telemetry/index.d.ts +2 -2
  32. package/dist/container/index.js +3 -1
  33. package/dist/content/consts.d.ts +16 -2
  34. package/dist/content/consts.js +32 -2
  35. package/dist/content/content-layer.d.ts +40 -0
  36. package/dist/content/content-layer.js +253 -0
  37. package/dist/content/data-store.d.ts +114 -0
  38. package/dist/content/data-store.js +323 -0
  39. package/dist/content/loaders/file.d.ts +7 -0
  40. package/dist/content/loaders/file.js +72 -0
  41. package/dist/content/loaders/glob.d.ts +25 -0
  42. package/dist/content/loaders/glob.js +218 -0
  43. package/dist/content/loaders/index.d.ts +3 -0
  44. package/dist/content/loaders/index.js +7 -0
  45. package/dist/content/loaders/types.d.ts +36 -0
  46. package/dist/content/loaders/types.js +0 -0
  47. package/dist/content/runtime.d.ts +46 -8
  48. package/dist/content/runtime.js +225 -31
  49. package/dist/content/types-generator.js +125 -35
  50. package/dist/content/utils.d.ts +306 -2
  51. package/dist/content/utils.js +93 -7
  52. package/dist/content/vite-plugin-content-assets.js +9 -1
  53. package/dist/content/vite-plugin-content-virtual-mod.js +94 -2
  54. package/dist/core/app/common.js +4 -1
  55. package/dist/core/app/index.js +5 -3
  56. package/dist/core/app/types.d.ts +3 -1
  57. package/dist/core/build/generate.js +4 -2
  58. package/dist/core/build/index.js +17 -8
  59. package/dist/core/build/plugins/plugin-manifest.js +5 -2
  60. package/dist/core/build/plugins/plugin-ssr.js +35 -3
  61. package/dist/core/build/static-build.js +2 -0
  62. package/dist/core/build/types.d.ts +1 -0
  63. package/dist/core/config/config.d.ts +2 -5
  64. package/dist/core/config/config.js +0 -12
  65. package/dist/core/config/index.d.ts +1 -1
  66. package/dist/core/config/index.js +0 -2
  67. package/dist/core/config/schema.d.ts +34 -0
  68. package/dist/core/config/schema.js +6 -2
  69. package/dist/core/config/settings.js +5 -3
  70. package/dist/core/constants.js +1 -1
  71. package/dist/core/create-vite.js +1 -1
  72. package/dist/core/dev/container.js +2 -1
  73. package/dist/core/dev/dev.js +34 -2
  74. package/dist/core/dev/restart.js +25 -10
  75. package/dist/core/encryption.d.ts +24 -0
  76. package/dist/core/encryption.js +64 -0
  77. package/dist/core/errors/errors-data.d.ts +21 -0
  78. package/dist/core/errors/errors-data.js +13 -0
  79. package/dist/core/index.js +1 -1
  80. package/dist/core/messages.js +2 -2
  81. package/dist/core/render-context.js +1 -0
  82. package/dist/core/server-islands/endpoint.js +5 -1
  83. package/dist/core/sync/constants.d.ts +1 -0
  84. package/dist/core/sync/constants.js +4 -0
  85. package/dist/core/sync/index.d.ts +12 -4
  86. package/dist/core/sync/index.js +56 -25
  87. package/dist/core/sync/write-files.d.ts +4 -0
  88. package/dist/core/sync/write-files.js +69 -0
  89. package/dist/core/util.js +1 -1
  90. package/dist/env/sync.js +6 -4
  91. package/dist/integrations/hooks.d.ts +7 -1
  92. package/dist/integrations/hooks.js +54 -0
  93. package/dist/preferences/index.d.ts +1 -1
  94. package/dist/preferences/index.js +2 -2
  95. package/dist/runtime/server/render/server-islands.js +9 -5
  96. package/dist/vite-plugin-astro-server/plugin.js +2 -0
  97. package/dist/vite-plugin-env/index.d.ts +3 -1
  98. package/dist/vite-plugin-env/index.js +11 -1
  99. package/dist/vite-plugin-markdown/content-entry-type.js +25 -2
  100. package/dist/vite-plugin-scanner/index.js +15 -5
  101. package/dist/vite-plugin-scanner/scan.js +1 -1
  102. package/package.json +15 -9
  103. package/templates/content/module.mjs +6 -1
  104. package/templates/content/types.d.ts +18 -5
  105. package/types/content.d.ts +34 -1
  106. package/dist/core/sync/setup-env-ts.d.ts +0 -8
  107. package/dist/core/sync/setup-env-ts.js +0 -79
@@ -47,9 +47,11 @@ const ASTRO_CONFIG_DEFAULTS = {
47
47
  clientPrerender: false,
48
48
  globalRoutePriority: false,
49
49
  serverIslands: false,
50
+ contentIntellisense: false,
50
51
  env: {
51
52
  validateSecrets: false
52
- }
53
+ },
54
+ contentLayer: false
53
55
  }
54
56
  };
55
57
  const AstroConfigSchema = z.object({
@@ -332,7 +334,9 @@ const AstroConfigSchema = z.object({
332
334
  schema: EnvSchema.optional(),
333
335
  validateSecrets: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.env.validateSecrets)
334
336
  }).strict().optional(),
335
- serverIslands: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.serverIslands)
337
+ serverIslands: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.serverIslands),
338
+ contentIntellisense: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.contentIntellisense),
339
+ contentLayer: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.contentLayer)
336
340
  }).strict(
337
341
  `Invalid or outdated experimental feature.
338
342
  Check for incorrect spelling or outdated Astro version.
@@ -12,7 +12,8 @@ import { AstroTimer } from "./timer.js";
12
12
  import { loadTSConfig } from "./tsconfig.js";
13
13
  function createBaseSettings(config) {
14
14
  const { contentDir } = getContentPaths(config);
15
- const preferences = createPreferences(config);
15
+ const dotAstroDir = new URL(".astro/", config.root);
16
+ const preferences = createPreferences(config, dotAstroDir);
16
17
  return {
17
18
  config,
18
19
  preferences,
@@ -94,9 +95,10 @@ function createBaseSettings(config) {
94
95
  watchFiles: [],
95
96
  devToolbarApps: [],
96
97
  timer: new AstroTimer(),
97
- dotAstroDir: new URL(".astro/", config.root),
98
- latestAstroVersion: void 0
98
+ dotAstroDir,
99
+ latestAstroVersion: void 0,
99
100
  // Will be set later if applicable when the dev server starts
101
+ injectedTypes: []
100
102
  };
101
103
  }
102
104
  async function createSettings(config, cwd) {
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "4.13.3";
1
+ const ASTRO_VERSION = "4.14.0";
2
2
  const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute";
3
3
  const REWRITE_DIRECTIVE_HEADER_KEY = "X-Astro-Rewrite";
4
4
  const REWRITE_DIRECTIVE_HEADER_VALUE = "yes";
@@ -102,7 +102,7 @@ async function createVite(commandConfig, { settings, logger, mode, command, fs =
102
102
  // The server plugin is for dev only and having it run during the build causes
103
103
  // the build to run very slow as the filewatcher is triggered often.
104
104
  mode !== "build" && vitePluginAstroServer({ settings, logger, fs }),
105
- envVitePlugin({ settings }),
105
+ envVitePlugin({ settings, logger }),
106
106
  astroEnv({ settings, mode, fs, sync }),
107
107
  markdownVitePlugin({ settings, logger }),
108
108
  htmlVitePlugin(),
@@ -49,7 +49,8 @@ async function createContainer({
49
49
  logger,
50
50
  skip: {
51
51
  content: true
52
- }
52
+ },
53
+ force: inlineConfig?.force
53
54
  });
54
55
  const viteServer = await vite.createServer(viteConfig);
55
56
  const container = {
@@ -1,8 +1,12 @@
1
- import fs from "node:fs";
1
+ import fs, { existsSync } from "node:fs";
2
2
  import { green } from "kleur/colors";
3
3
  import { performance } from "perf_hooks";
4
4
  import { gt, major, minor, patch } from "semver";
5
+ import { DATA_STORE_FILE } from "../../content/consts.js";
6
+ import { globalContentLayer } from "../../content/content-layer.js";
7
+ import { DataStore, globalDataStore } from "../../content/data-store.js";
5
8
  import { attachContentServerListeners } from "../../content/index.js";
9
+ import { globalContentConfigObserver } from "../../content/utils.js";
6
10
  import { telemetry } from "../../events/index.js";
7
11
  import * as msg from "../messages.js";
8
12
  import { ensureProcessNodeEnv } from "../util.js";
@@ -19,7 +23,7 @@ async function dev(inlineConfig) {
19
23
  await telemetry.record([]);
20
24
  const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
21
25
  const logger = restart.container.logger;
22
- const currentVersion = "4.13.3";
26
+ const currentVersion = "4.14.0";
23
27
  const isPrerelease = currentVersion.includes("-");
24
28
  if (!isPrerelease) {
25
29
  try {
@@ -64,6 +68,34 @@ async function dev(inlineConfig) {
64
68
  logger.warn("SKIP_FORMAT", msg.fsStrictWarning());
65
69
  }
66
70
  await attachContentServerListeners(restart.container);
71
+ let store;
72
+ try {
73
+ const dataStoreFile = new URL(DATA_STORE_FILE, restart.container.settings.config.cacheDir);
74
+ if (existsSync(dataStoreFile)) {
75
+ store = await DataStore.fromFile(dataStoreFile);
76
+ globalDataStore.set(store);
77
+ }
78
+ } catch (err) {
79
+ logger.error("content", err.message);
80
+ }
81
+ if (!store) {
82
+ store = new DataStore();
83
+ globalDataStore.set(store);
84
+ }
85
+ const config = globalContentConfigObserver.get();
86
+ if (config.status === "error") {
87
+ logger.error("content", config.error.message);
88
+ }
89
+ if (config.status === "loaded") {
90
+ const contentLayer = globalContentLayer.init({
91
+ settings: restart.container.settings,
92
+ logger,
93
+ watcher: restart.container.viteServer.watcher,
94
+ store
95
+ });
96
+ contentLayer.watchContentConfig();
97
+ await contentLayer.sync();
98
+ }
67
99
  logger.info(null, green("watching for file changes..."));
68
100
  return {
69
101
  address: devServerAddressInfo,
@@ -1,5 +1,6 @@
1
1
  import { fileURLToPath } from "node:url";
2
2
  import * as vite from "vite";
3
+ import { globalContentLayer } from "../../content/content-layer.js";
3
4
  import { eventCliSession, telemetry } from "../../events/index.js";
4
5
  import { createNodeLogger, createSettings, resolveConfig } from "../config/index.js";
5
6
  import { collectErrorMetadata } from "../errors/dev/utils.js";
@@ -20,16 +21,18 @@ async function createRestartedContainer(container, settings) {
20
21
  return newContainer;
21
22
  }
22
23
  const configRE = /.*astro.config.(?:mjs|cjs|js|ts)$/;
23
- const preferencesRE = /.*\.astro\/settings.json$/;
24
24
  function shouldRestartContainer({ settings, inlineConfig, restartInFlight }, changedFile) {
25
25
  if (restartInFlight) return false;
26
26
  let shouldRestart = false;
27
+ const normalizedChangedFile = vite.normalizePath(changedFile);
27
28
  if (inlineConfig.configFile) {
28
- shouldRestart = vite.normalizePath(inlineConfig.configFile) === vite.normalizePath(changedFile);
29
+ shouldRestart = vite.normalizePath(inlineConfig.configFile) === normalizedChangedFile;
29
30
  } else {
30
- const normalizedChangedFile = vite.normalizePath(changedFile);
31
31
  shouldRestart = configRE.test(normalizedChangedFile);
32
- if (preferencesRE.test(normalizedChangedFile)) {
32
+ const settingsPath = vite.normalizePath(
33
+ fileURLToPath(new URL("settings.json", settings.dotAstroDir))
34
+ );
35
+ if (settingsPath.endsWith(normalizedChangedFile)) {
33
36
  shouldRestart = settings.preferences.ignoreNextPreferenceReload ? false : true;
34
37
  settings.preferences.ignoreNextPreferenceReload = false;
35
38
  }
@@ -116,13 +119,25 @@ async function createContainerWithAutomaticRestart({
116
119
  watcher.on("unlink", handleChangeRestart("Configuration file removed."));
117
120
  watcher.on("add", handleChangeRestart("Configuration file added."));
118
121
  restart.container.viteServer.restart = () => handleServerRestart();
122
+ const customShortcuts = [
123
+ // Disable default Vite shortcuts that don't work well with Astro
124
+ { key: "r", description: "" },
125
+ { key: "u", description: "" },
126
+ { key: "c", description: "" }
127
+ ];
128
+ if (restart.container.settings.config.experimental.contentLayer) {
129
+ customShortcuts.push({
130
+ key: "s",
131
+ description: "sync content layer",
132
+ action: () => {
133
+ if (globalContentLayer.initialized()) {
134
+ globalContentLayer.get().sync();
135
+ }
136
+ }
137
+ });
138
+ }
119
139
  restart.container.viteServer.bindCLIShortcuts({
120
- customShortcuts: [
121
- // Disable Vite's builtin "r" (restart server), "u" (print server urls) and "c" (clear console) shortcuts
122
- { key: "r", description: "" },
123
- { key: "u", description: "" },
124
- { key: "c", description: "" }
125
- ]
140
+ customShortcuts
126
141
  });
127
142
  }
128
143
  setupContainer();
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Creates a CryptoKey object that can be used to encrypt any string.
3
+ */
4
+ export declare function createKey(): Promise<CryptoKey>;
5
+ /**
6
+ * Takes a key that has been serialized to an array of bytes and returns a CryptoKey
7
+ */
8
+ export declare function importKey(bytes: Uint8Array): Promise<CryptoKey>;
9
+ /**
10
+ * Encodes a CryptoKey to base64 string, so that it can be embedded in JSON / JavaScript
11
+ */
12
+ export declare function encodeKey(key: CryptoKey): Promise<string>;
13
+ /**
14
+ * Decodes a base64 string into bytes and then imports the key.
15
+ */
16
+ export declare function decodeKey(encoded: string): Promise<CryptoKey>;
17
+ /**
18
+ * Using a CryptoKey, encrypt a string into a base64 string.
19
+ */
20
+ export declare function encryptString(key: CryptoKey, raw: string): Promise<string>;
21
+ /**
22
+ * Takes a base64 encoded string, decodes it and returns the decrypted text.
23
+ */
24
+ export declare function decryptString(key: CryptoKey, encoded: string): Promise<string>;
@@ -0,0 +1,64 @@
1
+ import { decodeBase64, decodeHex, encodeBase64, encodeHexUpperCase } from "@oslojs/encoding";
2
+ const ALGORITHM = "AES-GCM";
3
+ async function createKey() {
4
+ const key = await crypto.subtle.generateKey(
5
+ {
6
+ name: ALGORITHM,
7
+ length: 256
8
+ },
9
+ true,
10
+ ["encrypt", "decrypt"]
11
+ );
12
+ return key;
13
+ }
14
+ async function importKey(bytes) {
15
+ const key = await crypto.subtle.importKey("raw", bytes, ALGORITHM, true, ["encrypt", "decrypt"]);
16
+ return key;
17
+ }
18
+ async function encodeKey(key) {
19
+ const exported = await crypto.subtle.exportKey("raw", key);
20
+ const encodedKey = encodeBase64(new Uint8Array(exported));
21
+ return encodedKey;
22
+ }
23
+ async function decodeKey(encoded) {
24
+ const bytes = decodeBase64(encoded);
25
+ return crypto.subtle.importKey("raw", bytes, ALGORITHM, true, ["encrypt", "decrypt"]);
26
+ }
27
+ const encoder = new TextEncoder();
28
+ const decoder = new TextDecoder();
29
+ const IV_LENGTH = 24;
30
+ async function encryptString(key, raw) {
31
+ const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH / 2));
32
+ const data = encoder.encode(raw);
33
+ const buffer = await crypto.subtle.encrypt(
34
+ {
35
+ name: ALGORITHM,
36
+ iv
37
+ },
38
+ key,
39
+ data
40
+ );
41
+ return encodeHexUpperCase(iv) + encodeBase64(new Uint8Array(buffer));
42
+ }
43
+ async function decryptString(key, encoded) {
44
+ const iv = decodeHex(encoded.slice(0, IV_LENGTH));
45
+ const dataArray = decodeBase64(encoded.slice(IV_LENGTH));
46
+ const decryptedBuffer = await crypto.subtle.decrypt(
47
+ {
48
+ name: ALGORITHM,
49
+ iv
50
+ },
51
+ key,
52
+ dataArray
53
+ );
54
+ const decryptedString = decoder.decode(decryptedBuffer);
55
+ return decryptedString;
56
+ }
57
+ export {
58
+ createKey,
59
+ decodeKey,
60
+ decryptString,
61
+ encodeKey,
62
+ encryptString,
63
+ importKey
64
+ };
@@ -1151,6 +1151,16 @@ export declare const RewriteWithBodyUsed: {
1151
1151
  title: string;
1152
1152
  message: string;
1153
1153
  };
1154
+ /**
1155
+ * @docs
1156
+ * @description
1157
+ * An unknown error occurred while reading or writing files to disk. It can be caused by many things, eg. missing permissions or a file not existing we attempt to read.
1158
+ */
1159
+ export declare const UnknownFilesystemError: {
1160
+ name: string;
1161
+ title: string;
1162
+ hint: string;
1163
+ };
1154
1164
  /**
1155
1165
  * @docs
1156
1166
  * @kind heading
@@ -1320,6 +1330,17 @@ export declare const UnknownContentCollectionError: {
1320
1330
  name: string;
1321
1331
  title: string;
1322
1332
  };
1333
+ /**
1334
+ * @docs
1335
+ * @description
1336
+ * The `getDataEntryById` and `getEntryBySlug` functions are deprecated and cannot be used with content layer collections. Use the `getEntry` function instead.
1337
+ */
1338
+ export declare const GetEntryDeprecationError: {
1339
+ name: string;
1340
+ title: string;
1341
+ message: (collection: string, method: string) => string;
1342
+ hint: string;
1343
+ };
1323
1344
  /**
1324
1345
  * @docs
1325
1346
  * @message
@@ -419,6 +419,11 @@ const RewriteWithBodyUsed = {
419
419
  title: "Cannot use Astro.rewrite after the request body has been read",
420
420
  message: "Astro.rewrite() cannot be used if the request body has already been read. If you need to read the body, first clone the request."
421
421
  };
422
+ const UnknownFilesystemError = {
423
+ name: "UnknownFilesystemError",
424
+ title: "An unknown error occurred while reading or writing files to disk.",
425
+ hint: "It can be caused by many things, eg. missing permissions or a file not existing we attempt to read. Check the error cause for more details."
426
+ };
422
427
  const UnknownCSSError = {
423
428
  name: "UnknownCSSError",
424
429
  title: "Unknown CSS Error."
@@ -476,6 +481,12 @@ const UnknownContentCollectionError = {
476
481
  name: "UnknownContentCollectionError",
477
482
  title: "Unknown Content Collection Error."
478
483
  };
484
+ const GetEntryDeprecationError = {
485
+ name: "GetEntryDeprecationError",
486
+ title: "Invalid use of `getDataEntryById` or `getEntryBySlug` function.",
487
+ message: (collection, method) => `The \`${method}\` function is deprecated and cannot be used to query the "${collection}" collection. Use \`getEntry\` instead.`,
488
+ hint: "Use the `getEntry` or `getCollection` functions to query content layer collections."
489
+ };
479
490
  const InvalidContentEntryFrontmatterError = {
480
491
  name: "InvalidContentEntryFrontmatterError",
481
492
  title: "Content entry frontmatter does not match schema.",
@@ -602,6 +613,7 @@ export {
602
613
  FailedToFindPageMapSSR,
603
614
  FailedToLoadModuleSSR,
604
615
  GenerateContentTypesError,
616
+ GetEntryDeprecationError,
605
617
  GetStaticPathsExpectedParams,
606
618
  GetStaticPathsInvalidRouteParam,
607
619
  GetStaticPathsRemovedRSSHelper,
@@ -664,6 +676,7 @@ export {
664
676
  UnknownConfigError,
665
677
  UnknownContentCollectionError,
666
678
  UnknownError,
679
+ UnknownFilesystemError,
667
680
  UnknownMarkdownError,
668
681
  UnknownViteError,
669
682
  UnsupportedConfigTransformError,
@@ -3,7 +3,7 @@ import { default as _sync } from "./sync/index.js";
3
3
  import { default as default2 } from "./dev/index.js";
4
4
  import { default as default3 } from "./preview/index.js";
5
5
  const build = (inlineConfig) => _build(inlineConfig);
6
- const sync = (inlineConfig) => _sync({ inlineConfig });
6
+ const sync = (inlineConfig) => _sync(inlineConfig);
7
7
  export {
8
8
  build,
9
9
  default2 as dev,
@@ -38,7 +38,7 @@ function serverStart({
38
38
  host,
39
39
  base
40
40
  }) {
41
- const version = "4.13.3";
41
+ const version = "4.14.0";
42
42
  const localPrefix = `${dim("\u2503")} Local `;
43
43
  const networkPrefix = `${dim("\u2503")} Network `;
44
44
  const emptyPrefix = " ".repeat(11);
@@ -270,7 +270,7 @@ function printHelp({
270
270
  message.push(
271
271
  linebreak(),
272
272
  ` ${bgGreen(black(` ${commandName} `))} ${green(
273
- `v${"4.13.3"}`
273
+ `v${"4.14.0"}`
274
274
  )} ${headline}`
275
275
  );
276
276
  }
@@ -279,6 +279,7 @@ class RenderContext {
279
279
  styles,
280
280
  actionResult,
281
281
  serverIslandNameMap: manifest.serverIslandNameMap ?? /* @__PURE__ */ new Map(),
282
+ key: manifest.key,
282
283
  trailingSlash: manifest.trailingSlash,
283
284
  _metadata: {
284
285
  hasHydrationScript: false,
@@ -3,6 +3,7 @@ import {
3
3
  renderTemplate
4
4
  } from "../../runtime/server/index.js";
5
5
  import { createSlotValueFromString } from "../../runtime/server/render/slot.js";
6
+ import { decryptString } from "../encryption.js";
6
7
  import { getPattern } from "../routing/manifest/pattern.js";
7
8
  const SERVER_ISLAND_ROUTE = "/_server-islands/[name]";
8
9
  const SERVER_ISLAND_COMPONENT = "_server-islands.astro";
@@ -51,7 +52,10 @@ function createEndpoint(manifest) {
51
52
  statusText: "Not found"
52
53
  });
53
54
  }
54
- const props = data.props;
55
+ const key = await manifest.key;
56
+ const encryptedProps = data.encryptedProps;
57
+ const propString = await decryptString(key, encryptedProps);
58
+ const props = JSON.parse(propString);
55
59
  const componentModule = await imp();
56
60
  const Component = componentModule[data.componentExport];
57
61
  const slots = {};
@@ -0,0 +1 @@
1
+ export declare const REFERENCE_FILE = "./types.d.ts";
@@ -0,0 +1,4 @@
1
+ const REFERENCE_FILE = "./types.d.ts";
2
+ export {
3
+ REFERENCE_FILE
4
+ };
@@ -1,22 +1,30 @@
1
1
  import fsMod from 'node:fs';
2
- import type { AstroInlineConfig, AstroSettings } from '../../@types/astro.js';
2
+ import type { AstroConfig, AstroInlineConfig, AstroSettings } from '../../@types/astro.js';
3
3
  import type { Logger } from '../logger/core.js';
4
4
  export type SyncOptions = {
5
5
  logger: Logger;
6
6
  settings: AstroSettings;
7
+ force?: boolean;
7
8
  skip?: {
8
9
  content?: boolean;
9
10
  };
10
11
  };
11
- export default function sync({ inlineConfig, fs, telemetry: _telemetry, }: {
12
- inlineConfig: AstroInlineConfig;
12
+ export default function sync(inlineConfig: AstroInlineConfig, { fs, telemetry: _telemetry }?: {
13
13
  fs?: typeof fsMod;
14
14
  telemetry?: boolean;
15
15
  }): Promise<void>;
16
+ /**
17
+ * Clears the content layer and content collection cache, forcing a full rebuild.
18
+ */
19
+ export declare function clearContentLayerCache({ astroConfig, logger, fs, }: {
20
+ astroConfig: AstroConfig;
21
+ logger: Logger;
22
+ fs?: typeof fsMod;
23
+ }): Promise<void>;
16
24
  /**
17
25
  * Generates TypeScript types for all Astro modules. This sets up a `src/env.d.ts` file for type inferencing,
18
26
  * and defines the `astro:content` module for the Content Collections API.
19
27
  *
20
28
  * @experimental The JavaScript API is experimental
21
29
  */
22
- export declare function syncInternal({ logger, fs, settings, skip, }: SyncOptions): Promise<void>;
30
+ export declare function syncInternal({ logger, fs, settings, skip, force, }: SyncOptions): Promise<void>;
@@ -1,15 +1,16 @@
1
- import fsMod from "node:fs";
1
+ import fsMod, { existsSync } from "node:fs";
2
2
  import { performance } from "node:perf_hooks";
3
- import { fileURLToPath } from "node:url";
4
3
  import { dim } from "kleur/colors";
5
4
  import { createServer } from "vite";
6
- import { getPackage } from "../../cli/install-package.js";
5
+ import { CONTENT_TYPES_FILE, DATA_STORE_FILE } from "../../content/consts.js";
6
+ import { globalContentLayer } from "../../content/content-layer.js";
7
+ import { DataStore, globalDataStore } from "../../content/data-store.js";
7
8
  import { createContentTypesGenerator } from "../../content/index.js";
8
- import { globalContentConfigObserver } from "../../content/utils.js";
9
+ import { getContentPaths, globalContentConfigObserver } from "../../content/utils.js";
9
10
  import { syncAstroEnv } from "../../env/sync.js";
10
11
  import { telemetry } from "../../events/index.js";
11
12
  import { eventCliSession } from "../../events/session.js";
12
- import { runHookConfigSetup } from "../../integrations/hooks.js";
13
+ import { runHookConfigDone, runHookConfigSetup } from "../../integrations/hooks.js";
13
14
  import { getTimeStat } from "../build/util.js";
14
15
  import { resolveConfig } from "../config/config.js";
15
16
  import { createNodeLogger } from "../config/logging.js";
@@ -25,12 +26,8 @@ import {
25
26
  } from "../errors/index.js";
26
27
  import { formatErrorMessage } from "../messages.js";
27
28
  import { ensureProcessNodeEnv } from "../util.js";
28
- import { setUpEnvTs } from "./setup-env-ts.js";
29
- async function sync({
30
- inlineConfig,
31
- fs,
32
- telemetry: _telemetry = false
33
- }) {
29
+ import { writeFiles } from "./write-files.js";
30
+ async function sync(inlineConfig, { fs, telemetry: _telemetry = false } = {}) {
34
31
  ensureProcessNodeEnv("production");
35
32
  const logger = createNodeLogger(inlineConfig);
36
33
  const { astroConfig, userConfig } = await resolveConfig(inlineConfig ?? {}, "sync");
@@ -43,32 +40,65 @@ async function sync({
43
40
  settings,
44
41
  logger
45
42
  });
46
- return await syncInternal({ settings, logger, fs });
43
+ await runHookConfigDone({ settings, logger });
44
+ return await syncInternal({ settings, logger, fs, force: inlineConfig.force });
45
+ }
46
+ async function clearContentLayerCache({
47
+ astroConfig,
48
+ logger,
49
+ fs = fsMod
50
+ }) {
51
+ const dataStore = new URL(DATA_STORE_FILE, astroConfig.cacheDir);
52
+ if (fs.existsSync(dataStore)) {
53
+ logger.debug("content", "clearing data store");
54
+ await fs.promises.rm(dataStore, { force: true });
55
+ logger.warn("content", "data store cleared (force)");
56
+ }
47
57
  }
48
58
  async function syncInternal({
49
59
  logger,
50
60
  fs = fsMod,
51
61
  settings,
52
- skip
62
+ skip,
63
+ force
53
64
  }) {
54
- const cwd = fileURLToPath(settings.config.root);
65
+ if (force) {
66
+ await clearContentLayerCache({ astroConfig: settings.config, logger, fs });
67
+ }
55
68
  const timerStart = performance.now();
56
- const dbPackage = await getPackage(
57
- "@astrojs/db",
58
- logger,
59
- {
60
- optional: true,
61
- cwd
62
- },
63
- []
64
- );
65
69
  try {
66
- await dbPackage?.typegen?.(settings.config);
67
70
  if (!skip?.content) {
68
71
  await syncContentCollections(settings, { fs, logger });
72
+ settings.timer.start("Sync content layer");
73
+ let store;
74
+ try {
75
+ const dataStoreFile = new URL(DATA_STORE_FILE, settings.config.cacheDir);
76
+ if (existsSync(dataStoreFile)) {
77
+ store = await DataStore.fromFile(dataStoreFile);
78
+ globalDataStore.set(store);
79
+ }
80
+ } catch (err) {
81
+ logger.error("content", err.message);
82
+ }
83
+ if (!store) {
84
+ store = new DataStore();
85
+ globalDataStore.set(store);
86
+ }
87
+ const contentLayer = globalContentLayer.init({
88
+ settings,
89
+ logger,
90
+ store
91
+ });
92
+ await contentLayer.sync();
93
+ settings.timer.end("Sync content layer");
94
+ } else if (fs.existsSync(getContentPaths(settings.config, fs).contentDir.href)) {
95
+ settings.injectedTypes.push({
96
+ filename: CONTENT_TYPES_FILE,
97
+ content: ""
98
+ });
69
99
  }
70
100
  syncAstroEnv(settings, fs);
71
- await setUpEnvTs({ settings, logger, fs });
101
+ await writeFiles(settings, fs, logger);
72
102
  logger.info("types", `Generated ${dim(getTimeStat(timerStart, performance.now()))}`);
73
103
  } catch (err) {
74
104
  const error = createSafeError(err);
@@ -137,6 +167,7 @@ async function syncContentCollections(settings, { logger, fs }) {
137
167
  }
138
168
  }
139
169
  export {
170
+ clearContentLayerCache,
140
171
  sync as default,
141
172
  syncInternal
142
173
  };
@@ -0,0 +1,4 @@
1
+ import type fsMod from 'node:fs';
2
+ import type { AstroSettings } from '../../@types/astro.js';
3
+ import type { Logger } from '../logger/core.js';
4
+ export declare function writeFiles(settings: AstroSettings, fs: typeof fsMod, logger: Logger): Promise<void>;
@@ -0,0 +1,69 @@
1
+ import { dirname, relative } from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import { bold } from "kleur/colors";
4
+ import { normalizePath } from "vite";
5
+ import { AstroError, AstroErrorData } from "../errors/index.js";
6
+ import { REFERENCE_FILE } from "./constants.js";
7
+ async function writeFiles(settings, fs, logger) {
8
+ try {
9
+ writeInjectedTypes(settings, fs);
10
+ await setUpEnvTs(settings, fs, logger);
11
+ } catch (e) {
12
+ throw new AstroError(AstroErrorData.UnknownFilesystemError, { cause: e });
13
+ }
14
+ }
15
+ function getTsReference(type, value) {
16
+ return `/// <reference ${type}=${JSON.stringify(value)} />`;
17
+ }
18
+ const CLIENT_TYPES_REFERENCE = getTsReference("types", "astro/client");
19
+ function writeInjectedTypes(settings, fs) {
20
+ const references = [];
21
+ for (const { filename, content } of settings.injectedTypes) {
22
+ const filepath = normalizePath(fileURLToPath(new URL(filename, settings.dotAstroDir)));
23
+ fs.mkdirSync(dirname(filepath), { recursive: true });
24
+ fs.writeFileSync(filepath, content, "utf-8");
25
+ references.push(normalizePath(relative(fileURLToPath(settings.dotAstroDir), filepath)));
26
+ }
27
+ const astroDtsContent = `${CLIENT_TYPES_REFERENCE}
28
+ ${references.map((reference) => getTsReference("path", reference)).join("\n")}`;
29
+ if (references.length === 0) {
30
+ fs.mkdirSync(settings.dotAstroDir, { recursive: true });
31
+ }
32
+ fs.writeFileSync(
33
+ normalizePath(fileURLToPath(new URL(REFERENCE_FILE, settings.dotAstroDir))),
34
+ astroDtsContent,
35
+ "utf-8"
36
+ );
37
+ }
38
+ async function setUpEnvTs(settings, fs, logger) {
39
+ const envTsPath = normalizePath(fileURLToPath(new URL("env.d.ts", settings.config.srcDir)));
40
+ const envTsPathRelativetoRoot = normalizePath(
41
+ relative(fileURLToPath(settings.config.root), envTsPath)
42
+ );
43
+ const relativePath = normalizePath(
44
+ relative(
45
+ fileURLToPath(settings.config.srcDir),
46
+ fileURLToPath(new URL(REFERENCE_FILE, settings.dotAstroDir))
47
+ )
48
+ );
49
+ const expectedTypeReference = getTsReference("path", relativePath);
50
+ if (fs.existsSync(envTsPath)) {
51
+ const initialEnvContents = await fs.promises.readFile(envTsPath, "utf-8");
52
+ let typesEnvContents = initialEnvContents;
53
+ if (!typesEnvContents.includes(expectedTypeReference)) {
54
+ typesEnvContents = `${expectedTypeReference}
55
+ ${typesEnvContents}`;
56
+ }
57
+ if (initialEnvContents !== typesEnvContents) {
58
+ logger.info("types", `Updated ${bold(envTsPathRelativetoRoot)} type declarations.`);
59
+ await fs.promises.writeFile(envTsPath, typesEnvContents, "utf-8");
60
+ }
61
+ } else {
62
+ await fs.promises.mkdir(settings.config.srcDir, { recursive: true });
63
+ await fs.promises.writeFile(envTsPath, expectedTypeReference, "utf-8");
64
+ logger.info("types", `Added ${bold(envTsPathRelativetoRoot)} type declarations`);
65
+ }
66
+ }
67
+ export {
68
+ writeFiles
69
+ };