@atscript/typescript 0.1.44 → 0.1.46

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/utils.cjs CHANGED
@@ -219,7 +219,7 @@ else flatUnion.item(existing);
219
219
 
220
220
  //#endregion
221
221
  //#region packages/typescript/src/runtime/serialize.ts
222
- const SERIALIZE_VERSION = 1;
222
+ const SERIALIZE_VERSION = 2;
223
223
  function serializeAnnotatedType(type, options) {
224
224
  const visited = new Set();
225
225
  const result = serializeNode(type, [], options, visited);
@@ -243,6 +243,17 @@ function serializeNode(def, path, options, visited) {
243
243
  };
244
244
  if (def.optional) result.optional = true;
245
245
  if (def.id) result.id = def.id;
246
+ const refDepth = options?.refDepth ?? 0;
247
+ if (refDepth > 0 && def.ref) {
248
+ const refTarget = def.ref.type();
249
+ if (refTarget) result.ref = {
250
+ type: serializeNode(refTarget, [], {
251
+ ...options,
252
+ refDepth: refDepth - 1
253
+ }, visited),
254
+ field: def.ref.field
255
+ };
256
+ }
246
257
  return result;
247
258
  }
248
259
  function serializeTypeDef(def, path, options, visited) {
@@ -332,18 +343,56 @@ function serializeMetadata(metadata, path, kind, options) {
332
343
  }
333
344
  function deserializeAnnotatedType(data) {
334
345
  if (data.$v !== SERIALIZE_VERSION) throw new Error(`Unsupported serialized type version: ${data.$v} (expected ${SERIALIZE_VERSION})`);
335
- return deserializeNode(data);
346
+ const resolved = new Map();
347
+ return deserializeNode(data, resolved);
336
348
  }
337
- function deserializeNode(data) {
349
+ function deserializeNode(data, resolved) {
350
+ if (data.type.kind === "$ref") {
351
+ const refId = data.type.id;
352
+ return resolved.get(refId) || require_json_schema.createAnnotatedTypeNode({
353
+ kind: "object",
354
+ props: new Map(),
355
+ propsPatterns: [],
356
+ tags: new Set()
357
+ }, new Map(), { id: refId });
358
+ }
338
359
  const metadata = new Map(Object.entries(data.metadata));
339
- const type = deserializeTypeDef(data.type);
340
- const result = require_json_schema.createAnnotatedTypeNode(type, metadata, {
360
+ let result;
361
+ if (data.id) {
362
+ const existing = resolved.get(data.id);
363
+ if (existing) return existing;
364
+ result = require_json_schema.createAnnotatedTypeNode({
365
+ kind: "object",
366
+ props: new Map(),
367
+ propsPatterns: [],
368
+ tags: new Set()
369
+ }, metadata, {
370
+ optional: data.optional || undefined,
371
+ id: data.id
372
+ });
373
+ resolved.set(data.id, result);
374
+ }
375
+ const type = deserializeTypeDef(data.type, resolved);
376
+ let ref;
377
+ if (data.ref) {
378
+ const deserializedRefTarget = deserializeNode(data.ref.type, resolved);
379
+ ref = {
380
+ type: () => deserializedRefTarget,
381
+ field: data.ref.field
382
+ };
383
+ }
384
+ if (result) {
385
+ result.type = type;
386
+ if (ref) result.ref = ref;
387
+ return result;
388
+ }
389
+ return require_json_schema.createAnnotatedTypeNode(type, metadata, {
341
390
  optional: data.optional || undefined,
342
- id: data.id || undefined
391
+ id: data.id || undefined,
392
+ ref
343
393
  });
344
- return result;
345
394
  }
346
- function deserializeTypeDef(t) {
395
+ function deserializeTypeDef(t, resolved) {
347
396
  const tags = "tags" in t ? new Set(t.tags) : new Set();
348
397
  switch (t.kind) {
349
398
  case "": {
@@ -357,10 +406,10 @@ function deserializeTypeDef(t) {
357
406
  }
358
407
  case "object": {
359
408
  const props = new Map();
360
- for (const [key, val] of Object.entries(t.props)) props.set(key, deserializeNode(val));
409
+ for (const [key, val] of Object.entries(t.props)) props.set(key, deserializeNode(val, resolved));
361
410
  const propsPatterns = t.propsPatterns.map((pp) => ({
362
411
  pattern: new RegExp(pp.pattern.source, pp.pattern.flags),
363
- def: deserializeNode(pp.def)
412
+ def: deserializeNode(pp.def, resolved)
364
413
  }));
365
414
  return {
366
415
  kind: "object",
@@ -371,22 +420,26 @@ function deserializeTypeDef(t) {
371
420
  }
372
421
  case "array": return {
373
422
  kind: "array",
374
- of: deserializeNode(t.of),
423
+ of: deserializeNode(t.of, resolved),
375
424
  tags
376
425
  };
377
426
  case "union":
378
427
  case "intersection":
379
428
  case "tuple": return {
380
429
  kind: t.kind,
381
- items: t.items.map((item) => deserializeNode(item)),
382
- tags
383
- };
384
- case "$ref": return {
385
- kind: "object",
386
- props: new Map(),
387
- propsPatterns: [],
430
+ items: t.items.map((item) => deserializeNode(item, resolved)),
388
431
  tags
389
432
  };
433
+ case "$ref": {
434
+ const existing = resolved.get(t.id);
435
+ if (existing) return existing.type;
436
+ return {
437
+ kind: "object",
438
+ props: new Map(),
439
+ propsPatterns: [],
440
+ tags
441
+ };
442
+ }
390
443
  default: throw new Error(`Unknown serialized type kind "${t.kind}"`);
391
444
  }
392
445
  }
package/dist/utils.d.ts CHANGED
@@ -479,7 +479,7 @@ type AtscriptQueryNode = AtscriptQueryComparison | {
479
479
  };
480
480
 
481
481
  /** Current serialization format version. Bumped on breaking changes to the serialized shape. */
482
- declare const SERIALIZE_VERSION = 1;
482
+ declare const SERIALIZE_VERSION = 2;
483
483
  /** Top-level serialized annotated type. JSON-safe representation of a {@link TAtscriptAnnotatedType}. */
484
484
  interface TSerializedAnnotatedType extends TSerializedAnnotatedTypeInner {
485
485
  /** Format version for forward compatibility */
@@ -491,6 +491,11 @@ interface TSerializedAnnotatedTypeInner {
491
491
  metadata: Record<string, unknown>;
492
492
  optional?: boolean;
493
493
  id?: string;
494
+ /** FK reference — present when serialized with `refDepth > 0` */
495
+ ref?: {
496
+ type: TSerializedAnnotatedTypeInner;
497
+ field: string;
498
+ };
494
499
  }
495
500
  interface TSerializedTypeFinal {
496
501
  kind: '';
@@ -549,6 +554,13 @@ interface TSerializeOptions {
549
554
  key: string;
550
555
  value: unknown;
551
556
  } | undefined | void;
557
+ /**
558
+ * How many levels of `.ref` (FK references) to expand during serialization.
559
+ * - `0` (default): refs are stripped (backward-compatible)
560
+ * - `1`: immediate refs are serialized, but refs inside referenced types are stripped
561
+ * - `2+`: deeper expansion
562
+ */
563
+ refDepth?: number;
552
564
  }
553
565
  /**
554
566
  * Converts a runtime {@link TAtscriptAnnotatedType} into a plain JSON-safe object.
package/dist/utils.mjs CHANGED
@@ -218,7 +218,7 @@ else flatUnion.item(existing);
218
218
 
219
219
  //#endregion
220
220
  //#region packages/typescript/src/runtime/serialize.ts
221
- const SERIALIZE_VERSION = 1;
221
+ const SERIALIZE_VERSION = 2;
222
222
  function serializeAnnotatedType(type, options) {
223
223
  const visited = new Set();
224
224
  const result = serializeNode(type, [], options, visited);
@@ -242,6 +242,17 @@ function serializeNode(def, path, options, visited) {
242
242
  };
243
243
  if (def.optional) result.optional = true;
244
244
  if (def.id) result.id = def.id;
245
+ const refDepth = options?.refDepth ?? 0;
246
+ if (refDepth > 0 && def.ref) {
247
+ const refTarget = def.ref.type();
248
+ if (refTarget) result.ref = {
249
+ type: serializeNode(refTarget, [], {
250
+ ...options,
251
+ refDepth: refDepth - 1
252
+ }, visited),
253
+ field: def.ref.field
254
+ };
255
+ }
245
256
  return result;
246
257
  }
247
258
  function serializeTypeDef(def, path, options, visited) {
@@ -331,18 +342,56 @@ function serializeMetadata(metadata, path, kind, options) {
331
342
  }
332
343
  function deserializeAnnotatedType(data) {
333
344
  if (data.$v !== SERIALIZE_VERSION) throw new Error(`Unsupported serialized type version: ${data.$v} (expected ${SERIALIZE_VERSION})`);
334
- return deserializeNode(data);
345
+ const resolved = new Map();
346
+ return deserializeNode(data, resolved);
335
347
  }
336
- function deserializeNode(data) {
348
+ function deserializeNode(data, resolved) {
349
+ if (data.type.kind === "$ref") {
350
+ const refId = data.type.id;
351
+ return resolved.get(refId) || createAnnotatedTypeNode({
352
+ kind: "object",
353
+ props: new Map(),
354
+ propsPatterns: [],
355
+ tags: new Set()
356
+ }, new Map(), { id: refId });
357
+ }
337
358
  const metadata = new Map(Object.entries(data.metadata));
338
- const type = deserializeTypeDef(data.type);
339
- const result = createAnnotatedTypeNode(type, metadata, {
359
+ let result;
360
+ if (data.id) {
361
+ const existing = resolved.get(data.id);
362
+ if (existing) return existing;
363
+ result = createAnnotatedTypeNode({
364
+ kind: "object",
365
+ props: new Map(),
366
+ propsPatterns: [],
367
+ tags: new Set()
368
+ }, metadata, {
369
+ optional: data.optional || undefined,
370
+ id: data.id
371
+ });
372
+ resolved.set(data.id, result);
373
+ }
374
+ const type = deserializeTypeDef(data.type, resolved);
375
+ let ref;
376
+ if (data.ref) {
377
+ const deserializedRefTarget = deserializeNode(data.ref.type, resolved);
378
+ ref = {
379
+ type: () => deserializedRefTarget,
380
+ field: data.ref.field
381
+ };
382
+ }
383
+ if (result) {
384
+ result.type = type;
385
+ if (ref) result.ref = ref;
386
+ return result;
387
+ }
388
+ return createAnnotatedTypeNode(type, metadata, {
340
389
  optional: data.optional || undefined,
341
- id: data.id || undefined
390
+ id: data.id || undefined,
391
+ ref
342
392
  });
343
- return result;
344
393
  }
345
- function deserializeTypeDef(t) {
394
+ function deserializeTypeDef(t, resolved) {
346
395
  const tags = "tags" in t ? new Set(t.tags) : new Set();
347
396
  switch (t.kind) {
348
397
  case "": {
@@ -356,10 +405,10 @@ function deserializeTypeDef(t) {
356
405
  }
357
406
  case "object": {
358
407
  const props = new Map();
359
- for (const [key, val] of Object.entries(t.props)) props.set(key, deserializeNode(val));
408
+ for (const [key, val] of Object.entries(t.props)) props.set(key, deserializeNode(val, resolved));
360
409
  const propsPatterns = t.propsPatterns.map((pp) => ({
361
410
  pattern: new RegExp(pp.pattern.source, pp.pattern.flags),
362
- def: deserializeNode(pp.def)
411
+ def: deserializeNode(pp.def, resolved)
363
412
  }));
364
413
  return {
365
414
  kind: "object",
@@ -370,22 +419,26 @@ function deserializeTypeDef(t) {
370
419
  }
371
420
  case "array": return {
372
421
  kind: "array",
373
- of: deserializeNode(t.of),
422
+ of: deserializeNode(t.of, resolved),
374
423
  tags
375
424
  };
376
425
  case "union":
377
426
  case "intersection":
378
427
  case "tuple": return {
379
428
  kind: t.kind,
380
- items: t.items.map((item) => deserializeNode(item)),
381
- tags
382
- };
383
- case "$ref": return {
384
- kind: "object",
385
- props: new Map(),
386
- propsPatterns: [],
429
+ items: t.items.map((item) => deserializeNode(item, resolved)),
387
430
  tags
388
431
  };
432
+ case "$ref": {
433
+ const existing = resolved.get(t.id);
434
+ if (existing) return existing.type;
435
+ return {
436
+ kind: "object",
437
+ props: new Map(),
438
+ propsPatterns: [],
439
+ tags
440
+ };
441
+ }
389
442
  default: throw new Error(`Unknown serialized type kind "${t.kind}"`);
390
443
  }
391
444
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atscript/typescript",
3
- "version": "0.1.44",
3
+ "version": "0.1.46",
4
4
  "description": "Atscript: typescript-gen support.",
5
5
  "keywords": [
6
6
  "annotations",
@@ -66,7 +66,7 @@
66
66
  },
67
67
  "peerDependencies": {
68
68
  "@atscript/db": "^0.1.41",
69
- "@atscript/core": "^0.1.44"
69
+ "@atscript/core": "^0.1.46"
70
70
  },
71
71
  "peerDependenciesMeta": {
72
72
  "@atscript/db": {
@@ -213,6 +213,9 @@ serializeAnnotatedType(User, {
213
213
  if (ctx.key.startsWith('mongo.')) return undefined
214
214
  return { key: ctx.key, value: ctx.value }
215
215
  },
216
+
217
+ // Include FK references (0 = strip, 1 = immediate refs, 2+ = deeper)
218
+ refDepth: 1,
216
219
  })
217
220
  ```
218
221
 
@@ -236,7 +239,7 @@ Throws if the serialized version doesn't match `SERIALIZE_VERSION`. The `id` fie
236
239
 
237
240
  ### `SERIALIZE_VERSION`
238
241
 
239
- Current serialization format version (currently `1`). Used for forward compatibility:
242
+ Current serialization format version (currently `2`). Used for forward compatibility:
240
243
 
241
244
  ```ts
242
245
  import { SERIALIZE_VERSION } from '@atscript/typescript/utils'