@holo-js/adapter-nuxt 0.2.6 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/module.d.mts CHANGED
@@ -42,6 +42,12 @@ type HoloStorageRuntimeConfig = {
42
42
  routePrefix: string;
43
43
  disks: Record<string, RuntimeDiskConfig>;
44
44
  };
45
+ type StorageModule = {
46
+ applyNitroStorageConfig(nitro: NuxtOptionsWithNitro, config: HoloStorageRuntimeConfig, s3Driver: string): void;
47
+ hasPublicLocalDisk(config: HoloStorageRuntimeConfig): boolean;
48
+ mergeModuleOptions(base: StorageModuleOptions | undefined, overrides: StorageModuleOptions | undefined): StorageModuleOptions;
49
+ normalizeModuleOptions(options: StorageModuleOptions | undefined): HoloStorageRuntimeConfig;
50
+ };
45
51
  type StorageS3Module = {
46
52
  default: unknown;
47
53
  };
@@ -60,6 +66,17 @@ interface NuxtOptionsWithNitro {
60
66
  nitro: {
61
67
  storage: Record<string, unknown>;
62
68
  errorHandler?: string | string[];
69
+ externals?: {
70
+ external?: unknown[];
71
+ inline?: unknown[];
72
+ trace?: boolean;
73
+ traceInclude?: string[];
74
+ [key: string]: unknown;
75
+ };
76
+ rollupConfig?: {
77
+ preserveSymlinks?: boolean;
78
+ [key: string]: unknown;
79
+ };
63
80
  virtual?: Record<string, () => string>;
64
81
  experimental?: {
65
82
  asyncContext?: boolean;
@@ -92,11 +109,31 @@ interface NuxtOptionsWithNitro {
92
109
  _holoCoreRuntimeRegistered?: boolean;
93
110
  _holoTypesRegistered?: boolean;
94
111
  }
112
+ declare function hasProjectPackage(rootDir: string, packageName: string, resolvePackage?: (packageName: string) => string): boolean;
113
+ declare function resolveProjectPackageEntry(rootDir: string, packageName: string, resolvePackage?: (packageName: string) => string): string | undefined;
114
+ declare function resolveProjectPackageTraceEntry(rootDir: string, packageName: string): string | undefined;
115
+ declare function isProjectPackageLinked(rootDir: string, packageRootName: string): boolean;
116
+ declare function addNitroRuntimeTraceIncludes(opts: NuxtOptionsWithNitro, rootDir: string, pluginPackages?: readonly string[], resolvePackage?: (rootDir: string, packageName: string) => string | undefined): void;
95
117
  declare function resolveClientOptimizeDeps(rootDir: string): string[];
96
118
  declare function addViteOptimizeDeps(opts: NuxtOptionsWithNitro, deps: readonly string[]): void;
119
+ declare function isRealtimeDefinitionModule(_rootDir: string, id: string): boolean;
120
+ declare function resolveExistingRealtimeDefinitionFile(path: string): string | undefined;
121
+ declare function existsFile(path: string): boolean;
122
+ declare function resolveRealtimeDefinitionImport(source: string, importer: string | undefined): string | undefined;
123
+ declare function createRealtimeDefinitionVitePlugin(rootDir: string): unknown;
124
+ declare function addVitePlugin(vite: NuxtViteOptions, plugin: unknown): void;
125
+ declare function addNitroErrorHandler(opts: NuxtOptionsWithNitro, handler: string): void;
97
126
  declare function importOptionalStorageS3Module(): Promise<StorageS3Module | undefined>;
98
127
  declare function hasLoadedConfigFile(loaded: LoadedHoloConfig<HoloConfigMap>, configName: string): boolean;
99
128
  declare function toStorageModuleOptions(loaded: LoadedHoloConfig<HoloConfigMap>): StorageModuleOptions;
129
+ declare function resolveStorageSetup(storageModule: StorageModule | undefined, loaded: LoadedHoloConfig<HoloConfigMap>): {
130
+ readonly options: StorageModuleOptions | undefined;
131
+ readonly normalized: HoloStorageRuntimeConfig | undefined;
132
+ };
133
+ declare function finalizeStorageSetup(storageModule: StorageModule, opts: NuxtOptionsWithNitro, resolver: {
134
+ resolve(path: string): string;
135
+ }, s3Driver: string): void;
136
+ declare function applyStorageRuntimeConfig(runtimeConfig: Record<string, unknown>, normalized: HoloStorageRuntimeConfig | undefined): void;
100
137
  declare const _default: {
101
138
  meta?: {
102
139
  name?: string;
@@ -107,11 +144,26 @@ declare const _default: {
107
144
 
108
145
  declare const moduleInternals: {
109
146
  addViteOptimizeDeps: typeof addViteOptimizeDeps;
147
+ addVitePlugin: typeof addVitePlugin;
148
+ addNitroErrorHandler: typeof addNitroErrorHandler;
149
+ addNitroRuntimeTraceIncludes: typeof addNitroRuntimeTraceIncludes;
150
+ createRealtimeDefinitionVitePlugin: typeof createRealtimeDefinitionVitePlugin;
151
+ existsFile: typeof existsFile;
152
+ hasProjectPackage: typeof hasProjectPackage;
110
153
  hasModuleNotFoundCode: typeof hasModuleNotFoundCode;
111
154
  hasLoadedConfigFile: typeof hasLoadedConfigFile;
112
155
  importOptionalStorageS3Module: typeof importOptionalStorageS3Module;
156
+ applyStorageRuntimeConfig: typeof applyStorageRuntimeConfig;
157
+ finalizeStorageSetup: typeof finalizeStorageSetup;
158
+ resolveStorageSetup: typeof resolveStorageSetup;
113
159
  isModuleResolutionFailure: typeof isModuleResolutionFailure;
160
+ resolveProjectPackageEntry: typeof resolveProjectPackageEntry;
161
+ resolveProjectPackageTraceEntry: typeof resolveProjectPackageTraceEntry;
162
+ isProjectPackageLinked: typeof isProjectPackageLinked;
163
+ isRealtimeDefinitionModule: typeof isRealtimeDefinitionModule;
114
164
  resolveClientOptimizeDeps: typeof resolveClientOptimizeDeps;
165
+ resolveExistingRealtimeDefinitionFile: typeof resolveExistingRealtimeDefinitionFile;
166
+ resolveRealtimeDefinitionImport: typeof resolveRealtimeDefinitionImport;
115
167
  };
116
168
  declare const adapterNuxtInternals: {
117
169
  toStorageModuleOptions: typeof toStorageModuleOptions;
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@holo-js/adapter-nuxt",
3
3
  "configKey": "@holo-js/adapter-nuxt",
4
- "version": "0.2.6",
4
+ "version": "0.3.1",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -1,249 +1,17 @@
1
- import { readFileSync } from 'node:fs';
1
+ import { lstatSync, readFileSync } from 'node:fs';
2
2
  import { readdir, mkdir, writeFile, access } from 'node:fs/promises';
3
3
  import { createRequire } from 'node:module';
4
4
  import { resolve, extname, relative, basename, dirname } from 'node:path';
5
5
  import { defineNuxtModule, createResolver, addServerPlugin, addServerImportsDir, addServerHandler, addPlugin } from '@nuxt/kit';
6
6
  import { loadConfigDirectory } from '@holo-js/config';
7
+ import '@holo-js/db/config';
8
+ import { createRealtimeClientDefinitionTransform as createRealtimeClientDefinitionTransform$1, createRealtimeClientDefinitionModule as createRealtimeClientDefinitionModule$1 } from '@holo-js/adapter-shared';
7
9
 
8
- const serverOnlyRealtimeProperties = /* @__PURE__ */ new Set(["handler", "authorize"]);
9
- function isIdentifierBoundary(value) {
10
- return !value || !/[$\w]/.test(value);
11
- }
12
- function skipString(source, index, quote) {
13
- let cursor = index + 1;
14
- while (cursor < source.length) {
15
- const char = source[cursor];
16
- if (char === "\\") {
17
- cursor += 2;
18
- continue;
19
- }
20
- if (char === quote) {
21
- return cursor + 1;
22
- }
23
- cursor += 1;
24
- }
25
- return cursor;
26
- }
27
- function skipLineComment(source, index) {
28
- const end = source.indexOf("\n", index + 2);
29
- return end === -1 ? source.length : end + 1;
30
- }
31
- function skipBlockComment(source, index) {
32
- const end = source.indexOf("*/", index + 2);
33
- return end === -1 ? source.length : end + 2;
34
- }
35
- function skipSyntax(source, index) {
36
- const char = source[index];
37
- const next = source[index + 1];
38
- if (char === '"' || char === "'" || char === "`") {
39
- return skipString(source, index, char);
40
- }
41
- if (char === "/" && next === "/") {
42
- return skipLineComment(source, index);
43
- }
44
- if (char === "/" && next === "*") {
45
- return skipBlockComment(source, index);
46
- }
47
- return void 0;
48
- }
49
- function findRealtimePropertyValueEnd(source, index) {
50
- let cursor = index;
51
- let braceDepth = 0;
52
- let bracketDepth = 0;
53
- let parenDepth = 0;
54
- while (cursor < source.length) {
55
- const syntaxEnd = skipSyntax(source, cursor);
56
- if (typeof syntaxEnd === "number") {
57
- cursor = syntaxEnd;
58
- continue;
59
- }
60
- const char = source[cursor];
61
- if (char === "{") {
62
- braceDepth += 1;
63
- } else if (char === "}") {
64
- if (braceDepth === 0 && bracketDepth === 0 && parenDepth === 0) {
65
- return cursor;
66
- }
67
- braceDepth -= 1;
68
- } else if (char === "[") {
69
- bracketDepth += 1;
70
- } else if (char === "]") {
71
- bracketDepth -= 1;
72
- } else if (char === "(") {
73
- parenDepth += 1;
74
- } else if (char === ")") {
75
- parenDepth -= 1;
76
- } else if (char === "," && braceDepth === 0 && bracketDepth === 0 && parenDepth === 0) {
77
- return cursor;
78
- }
79
- cursor += 1;
80
- }
81
- return source.length;
82
- }
83
- function findClosingBrace(source, index) {
84
- let cursor = index;
85
- let depth = 0;
86
- while (cursor < source.length) {
87
- const syntaxEnd = skipSyntax(source, cursor);
88
- if (typeof syntaxEnd === "number") {
89
- cursor = syntaxEnd;
90
- continue;
91
- }
92
- const char = source[cursor];
93
- if (char === "{") {
94
- depth += 1;
95
- } else if (char === "}") {
96
- depth -= 1;
97
- if (depth === 0) {
98
- return cursor;
99
- }
100
- }
101
- cursor += 1;
102
- }
103
- return -1;
104
- }
105
- function applyReplacements(source, replacements) {
106
- if (replacements.length === 0) {
107
- return source;
108
- }
109
- let output = "";
110
- let cursor = 0;
111
- const ordered = [...replacements].sort((left, right) => left.start - right.start);
112
- for (const replacement of ordered) {
113
- output += source.slice(cursor, replacement.start);
114
- output += replacement.text;
115
- cursor = replacement.end;
116
- }
117
- return output + source.slice(cursor);
118
- }
119
- function extractObjectPropertyValue(objectSource, propertyName) {
120
- let cursor = 1;
121
- while (cursor < objectSource.length - 1) {
122
- const syntaxEnd = skipSyntax(objectSource, cursor);
123
- if (typeof syntaxEnd === "number") {
124
- cursor = syntaxEnd;
125
- continue;
126
- }
127
- const match = objectSource.slice(cursor).match(/^[$A-Z_a-z][$\w]*/);
128
- const name = match?.[0];
129
- if (!name || name !== propertyName) {
130
- cursor += 1;
131
- continue;
132
- }
133
- const afterName = cursor + name.length;
134
- if (!isIdentifierBoundary(objectSource[cursor - 1]) || !isIdentifierBoundary(objectSource[afterName])) {
135
- cursor += name.length;
136
- continue;
137
- }
138
- let colon = afterName;
139
- while (/\s/.test(objectSource[colon] ?? "")) {
140
- colon += 1;
141
- }
142
- if (objectSource[colon] !== ":") {
143
- cursor += name.length;
144
- continue;
145
- }
146
- const valueStart = colon + 1;
147
- const valueEnd = findRealtimePropertyValueEnd(objectSource, valueStart);
148
- return objectSource.slice(valueStart, valueEnd).trim();
149
- }
150
- return void 0;
151
- }
152
- function collectRealtimeDefinitionExports(source) {
153
- const definitions = [];
154
- let cursor = 0;
155
- while (cursor < source.length) {
156
- const syntaxEnd = skipSyntax(source, cursor);
157
- if (typeof syntaxEnd === "number") {
158
- cursor = syntaxEnd;
159
- continue;
160
- }
161
- const match = source.slice(cursor).match(/^export\s+const\s+([$A-Z_a-z][$\w]*)\s*=\s*(query|mutation)\s*\(/);
162
- const exportedName = match?.[1];
163
- const factoryName = match?.[2];
164
- if (!exportedName || !factoryName) {
165
- cursor += 1;
166
- continue;
167
- }
168
- let objectStart = cursor + match[0].length;
169
- while (/\s/.test(source[objectStart] ?? "")) {
170
- objectStart += 1;
171
- }
172
- if (source[objectStart] !== "{") {
173
- cursor += match[0].length;
174
- continue;
175
- }
176
- const objectEnd = findClosingBrace(source, objectStart);
177
- if (objectEnd === -1) {
178
- cursor += match[0].length;
179
- continue;
180
- }
181
- const objectSource = source.slice(objectStart, objectEnd + 1);
182
- definitions.push({
183
- exportedName,
184
- factoryName,
185
- nameValue: extractObjectPropertyValue(objectSource, "name")
186
- });
187
- cursor = objectEnd + 1;
188
- }
189
- return definitions;
190
- }
191
10
  function createRealtimeClientDefinitionModule(source) {
192
- const definitions = collectRealtimeDefinitionExports(source);
193
- if (definitions.length === 0) {
194
- return stripRealtimeServerHandlers(source);
195
- }
196
- const factories = [...new Set(definitions.map((definition) => definition.factoryName))];
197
- return [
198
- `import { ${factories.join(", ")} } from '@holo-js/adapter-nuxt/realtime'`,
199
- "",
200
- ...definitions.flatMap((definition) => [
201
- `export const ${definition.exportedName} = ${definition.factoryName}({`,
202
- ...definition.nameValue ? [` name: ${definition.nameValue},`] : [],
203
- " handler: undefined,",
204
- "})",
205
- ""
206
- ])
207
- ].join("\n");
11
+ return createRealtimeClientDefinitionModule$1(source, "@holo-js/adapter-nuxt/realtime");
208
12
  }
209
- function stripRealtimeServerHandlers(source) {
210
- const replacements = [];
211
- let cursor = 0;
212
- while (cursor < source.length) {
213
- const syntaxEnd = skipSyntax(source, cursor);
214
- if (typeof syntaxEnd === "number") {
215
- cursor = syntaxEnd;
216
- continue;
217
- }
218
- const match = source.slice(cursor).match(/^[$A-Z_a-z][$\w]*/);
219
- const name = match?.[0];
220
- if (!name || !serverOnlyRealtimeProperties.has(name)) {
221
- cursor += 1;
222
- continue;
223
- }
224
- const afterName = cursor + name.length;
225
- if (!isIdentifierBoundary(source[cursor - 1]) || !isIdentifierBoundary(source[afterName])) {
226
- cursor += name.length;
227
- continue;
228
- }
229
- let colon = afterName;
230
- while (/\s/.test(source[colon] ?? "")) {
231
- colon += 1;
232
- }
233
- if (source[colon] !== ":") {
234
- cursor += name.length;
235
- continue;
236
- }
237
- const valueStart = colon + 1;
238
- const valueEnd = findRealtimePropertyValueEnd(source, valueStart);
239
- replacements.push({
240
- start: valueStart,
241
- end: valueEnd,
242
- text: " undefined"
243
- });
244
- cursor = valueEnd;
245
- }
246
- return applyReplacements(source, replacements);
13
+ function createRealtimeClientDefinitionTransform(source) {
14
+ return createRealtimeClientDefinitionTransform$1(source, "@holo-js/adapter-nuxt/realtime");
247
15
  }
248
16
 
249
17
  const MODEL_FILE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"]);
@@ -259,6 +27,68 @@ const CLIENT_OPTIMIZE_DEPS = [
259
27
  include: `${HOLO_PACKAGE_SCOPE}validation > valibot`
260
28
  }
261
29
  ];
30
+ const NITRO_RUNTIME_TRACE_IMPORTS = [
31
+ "@holo-js/auth-clerk",
32
+ "@holo-js/auth-social",
33
+ "@holo-js/auth-workos",
34
+ "@holo-js/authorization",
35
+ "@holo-js/broadcast",
36
+ "@holo-js/cache",
37
+ "@holo-js/cache-db",
38
+ "@holo-js/cache-redis",
39
+ "@holo-js/db-mysql",
40
+ "@holo-js/db-postgres",
41
+ "@holo-js/db-sqlite",
42
+ "@holo-js/events",
43
+ "@holo-js/mail",
44
+ "@holo-js/media",
45
+ "@holo-js/notifications",
46
+ "@holo-js/queue",
47
+ "@holo-js/queue-db",
48
+ "@holo-js/queue-redis",
49
+ "@holo-js/security",
50
+ "@holo-js/security/drivers/redis-adapter",
51
+ "@holo-js/session",
52
+ "@holo-js/session/drivers/redis-adapter",
53
+ "@holo-js/storage",
54
+ "@holo-js/storage/runtime",
55
+ "@holo-js/storage-s3"
56
+ ];
57
+ const NITRO_RUNTIME_EXTERNALS = [
58
+ "@holo-js/auth",
59
+ "@holo-js/auth-clerk",
60
+ "@holo-js/auth-social",
61
+ "@holo-js/auth-workos",
62
+ "@holo-js/authorization",
63
+ "@holo-js/broadcast",
64
+ "@holo-js/cache",
65
+ "@holo-js/cache-db",
66
+ "@holo-js/cache-redis",
67
+ "@holo-js/config",
68
+ "@holo-js/core",
69
+ "@holo-js/db",
70
+ "@holo-js/db-mysql",
71
+ "@holo-js/db-postgres",
72
+ "@holo-js/db-sqlite",
73
+ "@holo-js/events",
74
+ "@holo-js/kernel",
75
+ "@holo-js/mail",
76
+ "@holo-js/media",
77
+ "@holo-js/notifications",
78
+ "@holo-js/queue",
79
+ "@holo-js/queue-db",
80
+ "@holo-js/queue-redis",
81
+ "@holo-js/realtime",
82
+ "@holo-js/security",
83
+ "@holo-js/session",
84
+ "@holo-js/storage",
85
+ "@holo-js/storage-s3",
86
+ "@holo-js/validation"
87
+ ];
88
+ const NITRO_RUNTIME_INLINE_IMPORTS = [
89
+ "@holo-js/auth/nuxt",
90
+ "@holo-js/auth/nuxt/server"
91
+ ];
262
92
  function escapeRegExp(value) {
263
93
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
264
94
  }
@@ -289,18 +119,59 @@ function isModuleResolutionFailure(error) {
289
119
  }
290
120
  return "code" in error && (error.code === "MODULE_NOT_FOUND" || error.code === "ERR_MODULE_NOT_FOUND");
291
121
  }
292
- function hasProjectPackage(rootDir, packageName) {
293
- const projectRequire = createRequire(resolve(rootDir, "package.json"));
122
+ function hasProjectPackage(rootDir, packageName, resolvePackage = createRequire(resolve(rootDir, "package.json")).resolve) {
123
+ return typeof resolveProjectPackageEntry(rootDir, packageName, resolvePackage) === "string";
124
+ }
125
+ function resolveProjectPackageEntry(rootDir, packageName, resolvePackage = createRequire(resolve(rootDir, "package.json")).resolve) {
294
126
  try {
295
- projectRequire.resolve(packageName);
296
- return true;
127
+ return resolvePackage(packageName);
297
128
  } catch (error) {
298
129
  if (isModuleResolutionFailure(error)) {
299
- return false;
130
+ return void 0;
300
131
  }
301
132
  throw error;
302
133
  }
303
134
  }
135
+ function resolveProjectPackageTraceEntry(rootDir, packageName) {
136
+ const packageSegments = packageName.split("/");
137
+ const packageRootName = packageName.startsWith("@") ? packageSegments.slice(0, 2).join("/") : packageSegments[0];
138
+ if (!packageRootName) {
139
+ return void 0;
140
+ }
141
+ if (isProjectPackageLinked(rootDir, packageRootName)) {
142
+ return void 0;
143
+ }
144
+ return resolveProjectPackageEntry(rootDir, packageName);
145
+ }
146
+ function isProjectPackageLinked(rootDir, packageRootName) {
147
+ const projectPackageRoot = resolve(rootDir, "node_modules", packageRootName);
148
+ return lstatSync(projectPackageRoot, { throwIfNoEntry: false })?.isSymbolicLink() === true;
149
+ }
150
+ function addNitroRuntimeTraceIncludes(opts, rootDir, pluginPackages = [], resolvePackage = resolveProjectPackageTraceEntry) {
151
+ const externals = opts.nitro.externals ?? {};
152
+ const external = new Set(externals.external ?? []);
153
+ const inline = new Set(externals.inline ?? []);
154
+ const traceInclude = new Set(externals.traceInclude ?? []);
155
+ for (const specifier of NITRO_RUNTIME_EXTERNALS) {
156
+ external.add(specifier);
157
+ }
158
+ for (const specifier of NITRO_RUNTIME_INLINE_IMPORTS) {
159
+ inline.add(specifier);
160
+ }
161
+ for (const specifier of [...NITRO_RUNTIME_TRACE_IMPORTS, ...pluginPackages]) {
162
+ const packageEntry = resolvePackage(rootDir, specifier);
163
+ if (packageEntry) {
164
+ traceInclude.add(packageEntry);
165
+ }
166
+ }
167
+ opts.nitro.externals = {
168
+ ...externals,
169
+ external: [...external],
170
+ inline: [...inline],
171
+ trace: isProjectPackageLinked(rootDir, "@holo-js/core") ? false : externals.trace,
172
+ traceInclude: [...traceInclude]
173
+ };
174
+ }
304
175
  function resolveClientOptimizeDeps(rootDir) {
305
176
  const projectRequire = createRequire(resolve(rootDir, "package.json"));
306
177
  const deps = [];
@@ -330,7 +201,8 @@ function addViteOptimizeDeps(opts, deps) {
330
201
  ];
331
202
  }
332
203
  function isRealtimeDefinitionModule(_rootDir, id) {
333
- const normalizedId = id.split("?")[0]?.replaceAll("\\", "/") ?? "";
204
+ const [sourcePath = ""] = id.split("?");
205
+ const normalizedId = sourcePath.replaceAll("\\", "/");
334
206
  return normalizedId.includes("/server/realtime/") && MODEL_FILE_EXTENSIONS.has(extname(normalizedId));
335
207
  }
336
208
  function resolveExistingRealtimeDefinitionFile(path) {
@@ -356,7 +228,7 @@ function resolveRealtimeDefinitionImport(source, importer) {
356
228
  if (!source.includes("server/realtime") && !source.includes("server\\realtime")) {
357
229
  return void 0;
358
230
  }
359
- const basePath = source.startsWith(".") ? importer ? resolve(dirname(importer.split("?")[0] ?? importer), source) : void 0 : resolve(source);
231
+ const basePath = source.startsWith(".") ? importer ? resolve(dirname(importer.split("?")[0]), source) : void 0 : resolve(source);
360
232
  return basePath ? resolveExistingRealtimeDefinitionFile(basePath) : void 0;
361
233
  }
362
234
  function createRealtimeDefinitionVitePlugin(rootDir) {
@@ -381,10 +253,7 @@ function createRealtimeDefinitionVitePlugin(rootDir) {
381
253
  if (options?.ssr || !isRealtimeDefinitionModule(rootDir, id)) {
382
254
  return null;
383
255
  }
384
- return {
385
- code: createRealtimeClientDefinitionModule(code),
386
- map: null
387
- };
256
+ return createRealtimeClientDefinitionTransform(code);
388
257
  }
389
258
  };
390
259
  }
@@ -441,6 +310,36 @@ function toStorageModuleOptions(loaded) {
441
310
  disks: { ...loaded.storage.disks }
442
311
  };
443
312
  }
313
+ function resolveStorageSetup(storageModule, loaded) {
314
+ if (!storageModule) {
315
+ if (hasLoadedConfigFile(loaded, "storage")) {
316
+ throw new Error("[@holo-js/adapter-nuxt] Storage config requires @holo-js/storage to be installed.");
317
+ }
318
+ return { options: void 0, normalized: void 0 };
319
+ }
320
+ const options = storageModule.mergeModuleOptions(void 0, toStorageModuleOptions(loaded));
321
+ return {
322
+ options,
323
+ normalized: storageModule.normalizeModuleOptions(options)
324
+ };
325
+ }
326
+ function finalizeStorageSetup(storageModule, opts, resolver, s3Driver) {
327
+ const normalized = storageModule.normalizeModuleOptions(opts._holoStorageModuleOptions);
328
+ opts.runtimeConfig = opts.runtimeConfig || {};
329
+ opts.runtimeConfig.holoStorage = normalized;
330
+ storageModule.applyNitroStorageConfig(opts, normalized, s3Driver);
331
+ if (storageModule.hasPublicLocalDisk(normalized)) {
332
+ addServerHandler({
333
+ route: `${normalized.routePrefix}/**`,
334
+ handler: resolver.resolve("./runtime/server/routes/storage.get")
335
+ });
336
+ }
337
+ }
338
+ function applyStorageRuntimeConfig(runtimeConfig, normalized) {
339
+ if (normalized) {
340
+ runtimeConfig.holoStorage = normalized;
341
+ }
342
+ }
444
343
  async function createServerModelImports(sourceDir, modelsRelativePath, generatedSchemaRelativePath) {
445
344
  const modelsDir = resolve(sourceDir, modelsRelativePath);
446
345
  const generatedSchemaPath = resolve(sourceDir, generatedSchemaRelativePath);
@@ -499,15 +398,22 @@ const module$1 = defineNuxtModule({
499
398
  const authorizationTypesPath = resolve(rootDir, ".holo-js/generated/authorization/types.d.ts");
500
399
  const modelRegistryTypesPath = resolve(rootDir, ".holo-js/generated/model-registry.d.ts");
501
400
  addViteOptimizeDeps(opts, resolveClientOptimizeDeps(rootDir));
401
+ const storageModule = await importOptionalStorageModule();
502
402
  const loaded = await loadConfigDirectory(rootDir, {
503
403
  preferCache: process.env.NODE_ENV === "production",
504
404
  processEnv: process.env
505
405
  });
506
- const storageModule = await importOptionalStorageModule();
507
- const loadedStorageOptions = toStorageModuleOptions(loaded);
406
+ const storageSetup = resolveStorageSetup(storageModule, loaded);
508
407
  const s3Driver = resolver.resolve("./runtime/drivers/s3.js");
509
408
  opts.nitro = opts.nitro || { storage: {} };
510
409
  opts.nitro.storage = opts.nitro.storage || {};
410
+ if (isProjectPackageLinked(rootDir, "@holo-js/core")) {
411
+ opts.nitro.rollupConfig = {
412
+ ...opts.nitro.rollupConfig,
413
+ preserveSymlinks: true
414
+ };
415
+ }
416
+ addNitroRuntimeTraceIncludes(opts, rootDir, loaded.app.plugins);
511
417
  addNitroErrorHandler(opts, resolver.resolve("./runtime/server/error"));
512
418
  opts.nitro.experimental = {
513
419
  ...opts.nitro.experimental || {},
@@ -526,21 +432,15 @@ const module$1 = defineNuxtModule({
526
432
  projectRoot: rootDir
527
433
  };
528
434
  opts.runtimeConfig.db = loaded.database;
529
- const storageConfigured = hasLoadedConfigFile(loaded, "storage");
530
- if (!storageModule && storageConfigured) {
531
- throw new Error("[@holo-js/adapter-nuxt] Storage config requires @holo-js/storage to be installed.");
532
- }
533
- const mergedStorageOptions = storageModule?.mergeModuleOptions(void 0, loadedStorageOptions);
534
- const normalizedStorage = mergedStorageOptions ? storageModule?.normalizeModuleOptions(mergedStorageOptions) : void 0;
435
+ const mergedStorageOptions = storageSetup.options;
436
+ const normalizedStorage = storageSetup.normalized;
535
437
  opts._holoStorageModuleOptions = mergedStorageOptions;
536
438
  if (normalizedStorage && Object.values(normalizedStorage.disks).some((disk) => disk.driver === "s3")) {
537
439
  if (!await importOptionalStorageS3Module()) {
538
440
  throw new Error("[@holo-js/adapter-nuxt] S3 storage disks require @holo-js/storage-s3 to be installed.");
539
441
  }
540
442
  }
541
- if (normalizedStorage) {
542
- opts.runtimeConfig.holoStorage = normalizedStorage;
543
- }
443
+ applyStorageRuntimeConfig(opts.runtimeConfig, normalizedStorage);
544
444
  if (!opts._holoCoreRuntimeRegistered) {
545
445
  addServerPlugin(resolver.resolve("./runtime/plugins/init"));
546
446
  addServerPlugin(resolver.resolve("./runtime/plugins/forms"));
@@ -591,22 +491,15 @@ const module$1 = defineNuxtModule({
591
491
  storageModule.applyNitroStorageConfig(opts, normalizedStorage, s3Driver);
592
492
  }
593
493
  const runtimePath = resolver.resolve("./runtime");
594
- if (!opts.build.transpile.includes(runtimePath)) {
595
- opts.build.transpile.push(runtimePath);
494
+ for (const packageName of [runtimePath, "@holo-js/auth"]) {
495
+ if (!opts.build.transpile.includes(packageName)) {
496
+ opts.build.transpile.push(packageName);
497
+ }
596
498
  }
597
499
  if (storageModule && !opts._holoStorageFinalizeRegistered) {
598
500
  opts._holoStorageFinalizeRegistered = true;
599
501
  nuxt.hook("modules:done", () => {
600
- const finalNormalized = storageModule.normalizeModuleOptions(opts._holoStorageModuleOptions);
601
- opts.runtimeConfig = opts.runtimeConfig || {};
602
- opts.runtimeConfig.holoStorage = finalNormalized;
603
- storageModule.applyNitroStorageConfig(opts, finalNormalized, s3Driver);
604
- if (storageModule.hasPublicLocalDisk(finalNormalized)) {
605
- addServerHandler({
606
- route: `${finalNormalized.routePrefix}/**`,
607
- handler: resolver.resolve("./runtime/server/routes/storage.get")
608
- });
609
- }
502
+ finalizeStorageSetup(storageModule, opts, resolver, s3Driver);
610
503
  });
611
504
  }
612
505
  if (!opts._holoTypesRegistered) {
@@ -625,11 +518,26 @@ const module$1 = defineNuxtModule({
625
518
  });
626
519
  const moduleInternals = {
627
520
  addViteOptimizeDeps,
521
+ addVitePlugin,
522
+ addNitroErrorHandler,
523
+ addNitroRuntimeTraceIncludes,
524
+ createRealtimeDefinitionVitePlugin,
525
+ existsFile,
526
+ hasProjectPackage,
628
527
  hasModuleNotFoundCode,
629
528
  hasLoadedConfigFile,
630
529
  importOptionalStorageS3Module,
530
+ applyStorageRuntimeConfig,
531
+ finalizeStorageSetup,
532
+ resolveStorageSetup,
631
533
  isModuleResolutionFailure,
632
- resolveClientOptimizeDeps
534
+ resolveProjectPackageEntry,
535
+ resolveProjectPackageTraceEntry,
536
+ isProjectPackageLinked,
537
+ isRealtimeDefinitionModule,
538
+ resolveClientOptimizeDeps,
539
+ resolveExistingRealtimeDefinitionFile,
540
+ resolveRealtimeDefinitionImport
633
541
  };
634
542
  const adapterNuxtInternals = {
635
543
  toStorageModuleOptions
@@ -1,6 +1,6 @@
1
1
  import { onScopeDispose, reactive, shallowRef, watchEffect } from "vue";
2
2
  import { useCookie } from "#app";
3
- import { normalizeHoloHttpError } from "@holo-js/core/errors";
3
+ import { normalizeHoloHttpError } from "@holo-js/adapter-shared";
4
4
  import { DEFAULT_VALIDATION_BAG, createErrorBag } from "@holo-js/validation";
5
5
  import {
6
6
  createFormClient
@@ -105,10 +105,10 @@ function createHttpHandledFormOptions(options) {
105
105
  }
106
106
  export function useValidationErrors(bag = DEFAULT_VALIDATION_BAG) {
107
107
  const payload = parseFlashedValidationPayload();
108
- if (!payload || (payload.bag ?? DEFAULT_VALIDATION_BAG) !== bag) {
108
+ if (!payload || payload.bag !== bag) {
109
109
  return createErrorBag();
110
110
  }
111
- return createErrorBag(payload.errors ?? {});
111
+ return createErrorBag(payload.errors);
112
112
  }
113
113
  function getValueAtPath(root, path) {
114
114
  const parts = path.split(".").map((part) => part.trim()).filter(Boolean);
@@ -157,11 +157,9 @@ function createArrayMutationView(source, path, getForm, version, cache) {
157
157
  return false;
158
158
  }
159
159
  const next = current.slice();
160
- const updated = Reflect.set(next, key, value);
161
- if (updated) {
162
- void getForm().setValue(path, next);
163
- }
164
- return updated;
160
+ Reflect.set(next, key, value);
161
+ void getForm().setValue(path, next);
162
+ return true;
165
163
  },
166
164
  deleteProperty(_target, key) {
167
165
  const current = getValueAtPath(getForm().values, path);
@@ -169,11 +167,9 @@ function createArrayMutationView(source, path, getForm, version, cache) {
169
167
  return false;
170
168
  }
171
169
  const next = current.slice();
172
- const deleted = Reflect.deleteProperty(next, key);
173
- if (deleted) {
174
- void getForm().setValue(path, next);
175
- }
176
- return deleted;
170
+ Reflect.deleteProperty(next, key);
171
+ void getForm().setValue(path, next);
172
+ return true;
177
173
  }
178
174
  });
179
175
  cache.set(source, proxy);
@@ -240,12 +236,7 @@ export function useForm(schemaDefinition, options = {}) {
240
236
  const values = reactive(rawValues);
241
237
  const arrayCache = /* @__PURE__ */ new WeakMap();
242
238
  let activeForm;
243
- const getActiveForm = () => {
244
- if (!activeForm) {
245
- throw new TypeError("Expected form to be initialized.");
246
- }
247
- return activeForm;
248
- };
239
+ const getActiveForm = () => activeForm;
249
240
  const currentForm = () => {
250
241
  const current = form.value;
251
242
  if (!current) {
@@ -322,3 +313,16 @@ export function useForm(schemaDefinition, options = {}) {
322
313
  }
323
314
  });
324
315
  }
316
+ export const nuxtFormInternals = {
317
+ isLeafValue,
318
+ readBrowserCookie,
319
+ readCookie,
320
+ parseFlashedValidationPayload,
321
+ getHttpFailureMessage,
322
+ renderFormHttpFailure,
323
+ createHttpHandledFormOptions,
324
+ getValueAtPath,
325
+ createArrayMutationView,
326
+ defineLeafAccessor,
327
+ syncValuesView
328
+ };
@@ -1,5 +1,5 @@
1
1
  import { onScopeDispose, reactive } from "vue";
2
- import { normalizeHoloHttpError } from "@holo-js/core/errors";
2
+ import { normalizeHoloHttpError } from "@holo-js/adapter-shared";
3
3
  import {
4
4
  configureRealtimeClientRuntime,
5
5
  configureRealtimeClientTransport,
@@ -57,6 +57,11 @@ function replaceRealtimeReactiveValue(target, value) {
57
57
  }
58
58
  return value;
59
59
  }
60
+ function connectRealtimeStoreInBrowser(store) {
61
+ if ("window" in globalThis) {
62
+ store.connect();
63
+ }
64
+ }
60
65
  function useReactiveRealtimeQuery(definition, args) {
61
66
  const store = getRealtimeQueryStore(definition, args);
62
67
  const initialData = store.snapshot?.data;
@@ -67,9 +72,7 @@ function useReactiveRealtimeQuery(definition, args) {
67
72
  current = replaceRealtimeReactiveValue(current, nextData);
68
73
  }
69
74
  });
70
- if ("window" in globalThis) {
71
- store.connect();
72
- }
75
+ connectRealtimeStoreInBrowser(store);
73
76
  onScopeDispose(unsubscribe);
74
77
  return current;
75
78
  }
@@ -78,4 +81,12 @@ configureRealtimeClientRuntime({
78
81
  useQuery: useReactiveRealtimeQuery
79
82
  });
80
83
  configureRealtimeClientTransport(createBroadcastRealtimeTransport());
84
+ export const nuxtRealtimeInternals = {
85
+ emitRealtimeError,
86
+ replaceReactiveObject,
87
+ replaceReactiveArray,
88
+ createRealtimeReactiveValue,
89
+ replaceRealtimeReactiveValue,
90
+ connectRealtimeStoreInBrowser
91
+ };
81
92
  export {};
@@ -13,7 +13,7 @@ function findValidationException(error) {
13
13
  }
14
14
  return findValidationException(error.cause);
15
15
  }
16
- export default defineNitroErrorHandler(async (error, event) => {
16
+ export default async function handleValidationError(error, event) {
17
17
  const validationError = findValidationException(error);
18
18
  if (!validationError) {
19
19
  return;
@@ -29,4 +29,4 @@ export default defineNitroErrorHandler(async (error, event) => {
29
29
  setResponseStatus(event, payload.status);
30
30
  setHeader(event, "content-type", "application/json; charset=utf-8");
31
31
  await send(event, JSON.stringify(payload), "application/json");
32
- });
32
+ }
@@ -98,3 +98,6 @@ export function applyFormFailureRedirect(event, response, failure) {
98
98
  setHeader(event, response, "content-type", "text/html; charset=utf-8");
99
99
  appendSetCookie(event, response, serializeFormFailureCookie(failure));
100
100
  }
101
+ export const formFailureInternals = {
102
+ appendSetCookie
103
+ };
@@ -1,5 +1,6 @@
1
1
  import { open, realpath, stat } from "node:fs/promises";
2
2
  import { extname, resolve, sep } from "node:path";
3
+ import { createError, defineEventHandler, getRequestURL, setResponseHeader } from "h3";
3
4
  import { useRuntimeConfig } from "#imports";
4
5
  const NAMED_PUBLIC_DISK_ROUTE_SEGMENT = "__holo";
5
6
  function normalizeRequestPath(value) {
@@ -40,14 +41,9 @@ function resolveContentType(absolutePath) {
40
41
  return "text/css; charset=utf-8";
41
42
  case ".gif":
42
43
  return "image/gif";
43
- case ".html":
44
- return "text/html; charset=utf-8";
45
44
  case ".jpeg":
46
45
  case ".jpg":
47
46
  return "image/jpeg";
48
- case ".js":
49
- case ".mjs":
50
- return "text/javascript; charset=utf-8";
51
47
  case ".json":
52
48
  return "application/json; charset=utf-8";
53
49
  case ".mp3":
@@ -56,8 +52,6 @@ function resolveContentType(absolutePath) {
56
52
  return "application/pdf";
57
53
  case ".png":
58
54
  return "image/png";
59
- case ".svg":
60
- return "image/svg+xml";
61
55
  case ".txt":
62
56
  return "text/plain; charset=utf-8";
63
57
  case ".webp":
@@ -75,15 +75,6 @@ declare global {
75
75
  ): Record<string, TModule>
76
76
  }
77
77
 
78
- function createError(input: { statusCode: number, statusMessage: string }): Error
79
- function defineNitroErrorHandler<T>(handler: T): T
80
- function defineNitroPlugin<T>(plugin: T): T
81
- function defineEventHandler<T>(
82
- handler: (event: unknown) => T | Promise<T>,
83
- ): (event: unknown) => T | Promise<T>
84
- function getRequestURL(event: unknown): URL
85
- function setResponseHeader(event: unknown, name: string, value: string): void
86
- function useRuntimeConfig(): HoloRuntimeConfig
87
78
  }
88
79
 
89
80
  export {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holo-js/adapter-nuxt",
3
- "version": "0.2.6",
3
+ "version": "0.3.1",
4
4
  "description": "Holo-JS Framework - Nuxt adapter",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -38,19 +38,20 @@
38
38
  "test": "vitest --run"
39
39
  },
40
40
  "dependencies": {
41
+ "@holo-js/adapter-shared": "^0.3.1",
41
42
  "@nuxt/kit": "^4.4.4",
42
- "@holo-js/config": "^0.2.6",
43
- "@holo-js/core": "^0.2.6",
44
- "@holo-js/db": "^0.2.6",
45
- "@holo-js/validation": "^0.2.6",
43
+ "@holo-js/config": "^0.3.1",
44
+ "@holo-js/core": "^0.3.1",
45
+ "@holo-js/db": "^0.3.1",
46
+ "@holo-js/validation": "^0.3.1",
46
47
  "h3": "^1.15.11"
47
48
  },
48
49
  "peerDependencies": {
49
- "@holo-js/broadcast": "^0.2.6",
50
- "@holo-js/forms": "^0.2.6",
51
- "@holo-js/realtime": "^0.2.6",
52
- "@holo-js/storage": "^0.2.6",
53
- "@holo-js/storage-s3": "^0.2.6"
50
+ "@holo-js/broadcast": "^0.3.1",
51
+ "@holo-js/forms": "^0.3.1",
52
+ "@holo-js/realtime": "^0.3.1",
53
+ "@holo-js/storage": "^0.3.1",
54
+ "@holo-js/storage-s3": "^0.3.1"
54
55
  },
55
56
  "peerDependenciesMeta": {
56
57
  "@holo-js/broadcast": {
@@ -70,9 +71,9 @@
70
71
  }
71
72
  },
72
73
  "devDependencies": {
73
- "@holo-js/broadcast": "^0.2.6",
74
- "@holo-js/realtime": "^0.2.6",
75
- "@holo-js/storage-s3": "^0.2.6",
74
+ "@holo-js/broadcast": "^0.3.1",
75
+ "@holo-js/realtime": "^0.3.1",
76
+ "@holo-js/storage-s3": "^0.3.1",
76
77
  "@nuxt/module-builder": "^1.0.2",
77
78
  "@types/node": "^22.10.2",
78
79
  "nuxt": "^4.4.4",