@holo-js/adapter-shared 0.3.19 → 0.3.21

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/build.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  declare function compileBrowserValidation(source: string, fileName?: string): string | undefined;
2
2
 
3
+ declare function compileNextRoute(source: string, filename: string): string;
4
+
3
5
  type RealtimeDefinitionSourceMap = {
4
6
  readonly version: 3;
5
7
  readonly file: string;
@@ -19,4 +21,4 @@ declare function stripRealtimeServerHandlers(source: string): string;
19
21
  declare function createRealtimeClientDefinitionModule(source: string, importTarget: string): string;
20
22
  declare function createRealtimeClientDefinitionTransform(source: string, importTarget: string, options?: RealtimeDefinitionTransformOptions): RealtimeDefinitionTransformResult;
21
23
 
22
- export { type RealtimeDefinitionSourceMap, type RealtimeDefinitionTransformOptions, type RealtimeDefinitionTransformResult, compileBrowserValidation, createRealtimeClientDefinitionModule, createRealtimeClientDefinitionTransform, stripRealtimeServerHandlers };
24
+ export { type RealtimeDefinitionSourceMap, type RealtimeDefinitionTransformOptions, type RealtimeDefinitionTransformResult, compileBrowserValidation, compileNextRoute, createRealtimeClientDefinitionModule, createRealtimeClientDefinitionTransform, stripRealtimeServerHandlers };
package/dist/build.mjs CHANGED
@@ -1,11 +1,13 @@
1
1
  import {
2
2
  compileBrowserValidation,
3
+ compileNextRoute,
3
4
  createRealtimeClientDefinitionModule,
4
5
  createRealtimeClientDefinitionTransform,
5
6
  stripRealtimeServerHandlers
6
- } from "./chunk-4DGYQBYZ.mjs";
7
+ } from "./chunk-6FHRFQPC.mjs";
7
8
  export {
8
9
  compileBrowserValidation,
10
+ compileNextRoute,
9
11
  createRealtimeClientDefinitionModule,
10
12
  createRealtimeClientDefinitionTransform,
11
13
  stripRealtimeServerHandlers
@@ -1,5 +1,5 @@
1
1
  // src/build.ts
2
- import ts2 from "typescript";
2
+ import ts3 from "typescript";
3
3
 
4
4
  // src/validation-transform.ts
5
5
  import ts from "typescript";
@@ -143,10 +143,107 @@ import * as ${runtime} from '@holo-js/validation/internal/compiled'
143
143
  `;
144
144
  }
145
145
 
146
+ // src/next-route-transform.ts
147
+ import ts2 from "typescript";
148
+ var METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "OPTIONS", "POST", "PUT", "PATCH", "DELETE"]);
149
+ var runtimeName = "__holoRouteRuntime";
150
+ function wrap(handler) {
151
+ return ts2.factory.createCallExpression(
152
+ ts2.factory.createPropertyAccessExpression(ts2.factory.createIdentifier(runtimeName), "routeHandler"),
153
+ void 0,
154
+ [handler]
155
+ );
156
+ }
157
+ function exportHandler(name, handler) {
158
+ return ts2.factory.createVariableStatement(
159
+ [ts2.factory.createModifier(ts2.SyntaxKind.ExportKeyword)],
160
+ ts2.factory.createVariableDeclarationList([
161
+ ts2.factory.createVariableDeclaration(name, void 0, void 0, wrap(handler))
162
+ ], ts2.NodeFlags.Const)
163
+ );
164
+ }
165
+ function compileNextRoute(source, filename) {
166
+ const file = ts2.createSourceFile(filename, source, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TS);
167
+ let changed = false;
168
+ const statements = file.statements.flatMap((statement) => {
169
+ if (ts2.isFunctionDeclaration(statement) && statement.name && METHODS.has(statement.name.text) && statement.modifiers?.some((modifier) => modifier.kind === ts2.SyntaxKind.ExportKeyword)) {
170
+ changed = true;
171
+ const name = statement.name.text;
172
+ const localName = ts2.factory.createIdentifier(`__holoOriginal${name}`);
173
+ return [ts2.factory.updateFunctionDeclaration(
174
+ statement,
175
+ statement.modifiers.filter((modifier) => modifier.kind !== ts2.SyntaxKind.ExportKeyword),
176
+ statement.asteriskToken,
177
+ localName,
178
+ statement.typeParameters,
179
+ statement.parameters,
180
+ statement.type,
181
+ statement.body
182
+ ), exportHandler(name, localName)];
183
+ }
184
+ if (ts2.isVariableStatement(statement) && statement.modifiers?.some((modifier) => modifier.kind === ts2.SyntaxKind.ExportKeyword)) {
185
+ const declarations = statement.declarationList.declarations.map((declaration) => {
186
+ if (!ts2.isIdentifier(declaration.name) || !METHODS.has(declaration.name.text) || !declaration.initializer) return declaration;
187
+ changed = true;
188
+ return ts2.factory.updateVariableDeclaration(
189
+ declaration,
190
+ declaration.name,
191
+ declaration.exclamationToken,
192
+ declaration.type,
193
+ wrap(declaration.initializer)
194
+ );
195
+ });
196
+ return [ts2.factory.updateVariableStatement(
197
+ statement,
198
+ statement.modifiers,
199
+ ts2.factory.updateVariableDeclarationList(statement.declarationList, declarations)
200
+ )];
201
+ }
202
+ if (ts2.isExportDeclaration(statement) && statement.exportClause && ts2.isNamedExports(statement.exportClause)) {
203
+ const handlers = statement.exportClause.elements.filter((element) => METHODS.has(element.name.text));
204
+ if (handlers.length === 0) return [statement];
205
+ changed = true;
206
+ const result = [];
207
+ const remaining = statement.exportClause.elements.filter((element) => !METHODS.has(element.name.text));
208
+ if (remaining.length) result.push(ts2.factory.updateExportDeclaration(
209
+ statement,
210
+ statement.modifiers,
211
+ statement.isTypeOnly,
212
+ ts2.factory.updateNamedExports(statement.exportClause, remaining),
213
+ statement.moduleSpecifier,
214
+ statement.attributes
215
+ ));
216
+ for (const handler of handlers) {
217
+ const imported = handler.propertyName ?? handler.name;
218
+ const local = ts2.factory.createIdentifier(statement.moduleSpecifier ? `__holoOriginal${handler.name.text}` : imported.text);
219
+ if (statement.moduleSpecifier) result.push(ts2.factory.createImportDeclaration(
220
+ void 0,
221
+ ts2.factory.createImportClause(false, void 0, ts2.factory.createNamedImports([
222
+ ts2.factory.createImportSpecifier(false, imported, local)
223
+ ])),
224
+ statement.moduleSpecifier
225
+ ));
226
+ result.push(exportHandler(handler.name.text, local));
227
+ }
228
+ return result;
229
+ }
230
+ return [statement];
231
+ });
232
+ if (!changed) return source;
233
+ const runtimeImport = ts2.factory.createImportDeclaration(
234
+ void 0,
235
+ ts2.factory.createImportClause(false, void 0, ts2.factory.createNamedImports([
236
+ ts2.factory.createImportSpecifier(false, ts2.factory.createIdentifier("adapterNextRuntimeInternals"), ts2.factory.createIdentifier(runtimeName))
237
+ ])),
238
+ ts2.factory.createStringLiteral("@holo-js/adapter-next/runtime")
239
+ );
240
+ return ts2.createPrinter().printFile(ts2.factory.updateSourceFile(file, [runtimeImport, ...statements]));
241
+ }
242
+
146
243
  // src/build.ts
147
244
  function propertyName(property) {
148
245
  if (!("name" in property) || !property.name) return void 0;
149
- return ts2.isIdentifier(property.name) || ts2.isStringLiteral(property.name) ? property.name.text : void 0;
246
+ return ts3.isIdentifier(property.name) || ts3.isStringLiteral(property.name) ? property.name.text : void 0;
150
247
  }
151
248
  function collectRealtimeFactories(sourceFile) {
152
249
  const factories = /* @__PURE__ */ new Map([
@@ -154,9 +251,9 @@ function collectRealtimeFactories(sourceFile) {
154
251
  ["mutation", "mutation"]
155
252
  ]);
156
253
  for (const statement of sourceFile.statements) {
157
- if (!ts2.isImportDeclaration(statement) || !statement.importClause?.namedBindings) continue;
158
- if (!ts2.isStringLiteral(statement.moduleSpecifier) || statement.moduleSpecifier.text !== "@holo-js/realtime") continue;
159
- if (!ts2.isNamedImports(statement.importClause.namedBindings)) continue;
254
+ if (!ts3.isImportDeclaration(statement) || !statement.importClause?.namedBindings) continue;
255
+ if (!ts3.isStringLiteral(statement.moduleSpecifier) || statement.moduleSpecifier.text !== "@holo-js/realtime") continue;
256
+ if (!ts3.isNamedImports(statement.importClause.namedBindings)) continue;
160
257
  for (const element of statement.importClause.namedBindings.elements) {
161
258
  const importedName = element.propertyName?.text ?? element.name.text;
162
259
  if (importedName === "query" || importedName === "mutation") {
@@ -170,17 +267,17 @@ function collectDefinitions(sourceFile) {
170
267
  const definitions = [];
171
268
  const factories = collectRealtimeFactories(sourceFile);
172
269
  for (const statement of sourceFile.statements) {
173
- if (!ts2.isVariableStatement(statement) || !statement.modifiers?.some((modifier) => modifier.kind === ts2.SyntaxKind.ExportKeyword)) continue;
270
+ if (!ts3.isVariableStatement(statement) || !statement.modifiers?.some((modifier) => modifier.kind === ts3.SyntaxKind.ExportKeyword)) continue;
174
271
  for (const declaration of statement.declarationList.declarations) {
175
- if (!ts2.isIdentifier(declaration.name) || !declaration.initializer || !ts2.isCallExpression(declaration.initializer)) continue;
272
+ if (!ts3.isIdentifier(declaration.name) || !declaration.initializer || !ts3.isCallExpression(declaration.initializer)) continue;
176
273
  const factoryNode = declaration.initializer.expression;
177
- if (!ts2.isIdentifier(factoryNode)) continue;
274
+ if (!ts3.isIdentifier(factoryNode)) continue;
178
275
  const factory = factories.get(factoryNode.text);
179
276
  if (!factory) continue;
180
277
  const definitionNode = declaration.initializer.arguments[0];
181
- if (!definitionNode || !ts2.isObjectLiteralExpression(definitionNode)) continue;
278
+ if (!definitionNode || !ts3.isObjectLiteralExpression(definitionNode)) continue;
182
279
  const nameProperty = definitionNode.properties.find((property) => propertyName(property) === "name");
183
- const name = nameProperty && ts2.isPropertyAssignment(nameProperty) ? nameProperty.initializer.getText(sourceFile) : void 0;
280
+ const name = nameProperty && ts3.isPropertyAssignment(nameProperty) ? nameProperty.initializer.getText(sourceFile) : void 0;
184
281
  const sourceLine = sourceFile.getLineAndCharacterOfPosition(declaration.getStart(sourceFile)).line;
185
282
  definitions.push({ exportedName: declaration.name.text, factory, sourceLine, ...name ? { name } : {} });
186
283
  }
@@ -217,36 +314,36 @@ function createSourceMap(source, sourceLines) {
217
314
  };
218
315
  }
219
316
  function parseRealtimeSource(source) {
220
- const result = ts2.transpileModule(source, {
221
- compilerOptions: { module: ts2.ModuleKind.ESNext, target: ts2.ScriptTarget.ESNext },
317
+ const result = ts3.transpileModule(source, {
318
+ compilerOptions: { module: ts3.ModuleKind.ESNext, target: ts3.ScriptTarget.ESNext },
222
319
  reportDiagnostics: true
223
320
  });
224
- const diagnostic = result.diagnostics?.find((entry) => entry.category === ts2.DiagnosticCategory.Error);
321
+ const diagnostic = result.diagnostics?.find((entry) => entry.category === ts3.DiagnosticCategory.Error);
225
322
  if (diagnostic) {
226
- throw new SyntaxError(ts2.flattenDiagnosticMessageText(diagnostic.messageText, "\n"));
323
+ throw new SyntaxError(ts3.flattenDiagnosticMessageText(diagnostic.messageText, "\n"));
227
324
  }
228
- return ts2.createSourceFile("realtime.ts", source, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TS);
325
+ return ts3.createSourceFile("realtime.ts", source, ts3.ScriptTarget.Latest, true, ts3.ScriptKind.TS);
229
326
  }
230
327
  function retargetRealtimeImports(source, importTarget) {
231
328
  const sourceFile = parseRealtimeSource(source);
232
329
  const transformer = (context) => (root) => {
233
330
  const visit = (node) => {
234
- if (ts2.isImportDeclaration(node) && ts2.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === "@holo-js/realtime") {
235
- return ts2.factory.updateImportDeclaration(
331
+ if (ts3.isImportDeclaration(node) && ts3.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === "@holo-js/realtime") {
332
+ return ts3.factory.updateImportDeclaration(
236
333
  node,
237
334
  node.modifiers,
238
335
  node.importClause,
239
- ts2.factory.createStringLiteral(importTarget),
336
+ ts3.factory.createStringLiteral(importTarget),
240
337
  node.attributes
241
338
  );
242
339
  }
243
- return ts2.visitEachChild(node, visit, context);
340
+ return ts3.visitEachChild(node, visit, context);
244
341
  };
245
- return ts2.visitNode(root, visit);
342
+ return ts3.visitNode(root, visit);
246
343
  };
247
- const result = ts2.transform(sourceFile, [transformer]);
344
+ const result = ts3.transform(sourceFile, [transformer]);
248
345
  try {
249
- return ts2.createPrinter({ newLine: ts2.NewLineKind.LineFeed }).printFile(result.transformed[0]);
346
+ return ts3.createPrinter({ newLine: ts3.NewLineKind.LineFeed }).printFile(result.transformed[0]);
250
347
  } finally {
251
348
  result.dispose();
252
349
  }
@@ -255,19 +352,19 @@ function stripRealtimeServerHandlers(source) {
255
352
  const sourceFile = parseRealtimeSource(source);
256
353
  const transformer = (context) => (root) => {
257
354
  const visit = (node) => {
258
- if (ts2.isPropertyAssignment(node) && (propertyName(node) === "handler" || propertyName(node) === "authorize")) {
259
- return ts2.factory.updatePropertyAssignment(node, node.name, ts2.factory.createIdentifier("undefined"));
355
+ if (ts3.isPropertyAssignment(node) && (propertyName(node) === "handler" || propertyName(node) === "authorize")) {
356
+ return ts3.factory.updatePropertyAssignment(node, node.name, ts3.factory.createIdentifier("undefined"));
260
357
  }
261
- if (ts2.isMethodDeclaration(node) && (propertyName(node) === "handler" || propertyName(node) === "authorize")) {
262
- return ts2.factory.createPropertyAssignment(node.name, ts2.factory.createIdentifier("undefined"));
358
+ if (ts3.isMethodDeclaration(node) && (propertyName(node) === "handler" || propertyName(node) === "authorize")) {
359
+ return ts3.factory.createPropertyAssignment(node.name, ts3.factory.createIdentifier("undefined"));
263
360
  }
264
- return ts2.visitEachChild(node, visit, context);
361
+ return ts3.visitEachChild(node, visit, context);
265
362
  };
266
- return ts2.visitNode(root, visit);
363
+ return ts3.visitNode(root, visit);
267
364
  };
268
- const result = ts2.transform(sourceFile, [transformer]);
365
+ const result = ts3.transform(sourceFile, [transformer]);
269
366
  try {
270
- return ts2.createPrinter({ newLine: ts2.NewLineKind.LineFeed }).printFile(result.transformed[0]);
367
+ return ts3.createPrinter({ newLine: ts3.NewLineKind.LineFeed }).printFile(result.transformed[0]);
271
368
  } finally {
272
369
  result.dispose();
273
370
  }
@@ -318,6 +415,7 @@ function createRealtimeClientDefinitionTransform(source, importTarget, options =
318
415
 
319
416
  export {
320
417
  compileBrowserValidation,
418
+ compileNextRoute,
321
419
  stripRealtimeServerHandlers,
322
420
  createRealtimeClientDefinitionModule,
323
421
  createRealtimeClientDefinitionTransform
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { HoloHttpErrorStatus, NormalizedHoloHttpError, isHoloHttpErrorStatus, normalizeHoloHttpError } from '@holo-js/kernel/http-errors';
2
2
  export { ClientErrorPageOptions, renderClientHttpErrorPage } from './client.js';
3
- export { RealtimeDefinitionSourceMap, RealtimeDefinitionTransformOptions, RealtimeDefinitionTransformResult, compileBrowserValidation, createRealtimeClientDefinitionModule, createRealtimeClientDefinitionTransform, stripRealtimeServerHandlers } from './build.js';
3
+ export { RealtimeDefinitionSourceMap, RealtimeDefinitionTransformOptions, RealtimeDefinitionTransformResult, compileBrowserValidation, compileNextRoute, createRealtimeClientDefinitionModule, createRealtimeClientDefinitionTransform, stripRealtimeServerHandlers } from './build.js';
package/dist/index.mjs CHANGED
@@ -5,12 +5,14 @@ import {
5
5
  } from "./chunk-3GNER7MY.mjs";
6
6
  import {
7
7
  compileBrowserValidation,
8
+ compileNextRoute,
8
9
  createRealtimeClientDefinitionModule,
9
10
  createRealtimeClientDefinitionTransform,
10
11
  stripRealtimeServerHandlers
11
- } from "./chunk-4DGYQBYZ.mjs";
12
+ } from "./chunk-6FHRFQPC.mjs";
12
13
  export {
13
14
  compileBrowserValidation,
15
+ compileNextRoute,
14
16
  createRealtimeClientDefinitionModule,
15
17
  createRealtimeClientDefinitionTransform,
16
18
  isHoloHttpErrorStatus,
@@ -0,0 +1,15 @@
1
+ type RateLimitFailure = {
2
+ readonly ok: false;
3
+ readonly valid: false;
4
+ readonly status: 429;
5
+ readonly bag: 'default';
6
+ readonly message: string;
7
+ readonly errors: {
8
+ readonly _root: readonly string[];
9
+ };
10
+ readonly values: Readonly<Record<string, never>>;
11
+ readonly retryAfterSeconds?: number;
12
+ };
13
+ declare function serializeRateLimitError(error: unknown): RateLimitFailure | undefined;
14
+
15
+ export { serializeRateLimitError };
@@ -0,0 +1,24 @@
1
+ // src/server-errors.ts
2
+ import { normalizeHoloHttpError } from "@holo-js/kernel/http-errors";
3
+ function serializeRateLimitError(error) {
4
+ const normalized = normalizeHoloHttpError(error);
5
+ if (!normalized || normalized.status !== 429) return void 0;
6
+ const retryAfterSeconds = error && typeof error === "object" && "retryAfterSeconds" in error && typeof error.retryAfterSeconds === "number" && Number.isFinite(error.retryAfterSeconds) ? error.retryAfterSeconds : void 0;
7
+ if (retryAfterSeconds === void 0 && error && typeof error === "object" && "cause" in error) {
8
+ const cause = serializeRateLimitError(error.cause);
9
+ if (cause) return cause;
10
+ }
11
+ return {
12
+ ok: false,
13
+ valid: false,
14
+ status: 429,
15
+ bag: "default",
16
+ message: normalized.message,
17
+ errors: { _root: [normalized.message] },
18
+ values: {},
19
+ ...retryAfterSeconds === void 0 ? {} : { retryAfterSeconds }
20
+ };
21
+ }
22
+ export {
23
+ serializeRateLimitError
24
+ };
package/package.json CHANGED
@@ -1,10 +1,15 @@
1
1
  {
2
2
  "name": "@holo-js/adapter-shared",
3
- "version": "0.3.19",
3
+ "version": "0.3.21",
4
4
  "description": "Holo-JS Framework - shared framework adapter infrastructure",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "exports": {
8
+ "./server-errors": {
9
+ "types": "./dist/server-errors.d.ts",
10
+ "import": "./dist/server-errors.mjs",
11
+ "default": "./dist/server-errors.mjs"
12
+ },
8
13
  ".": {
9
14
  "types": "./dist/index.d.ts",
10
15
  "import": "./dist/index.mjs",
@@ -46,7 +51,7 @@
46
51
  "test": "vitest --run"
47
52
  },
48
53
  "dependencies": {
49
- "@holo-js/kernel": "^0.3.19",
54
+ "@holo-js/kernel": "^0.3.21",
50
55
  "typescript": "^5.7.2"
51
56
  },
52
57
  "devDependencies": {