@supatype/cli 0.1.3 → 0.1.5

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 (85) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-test.log +101 -99
  3. package/.turbo/turbo-typecheck.log +1 -1
  4. package/dist/app-vite-env.d.ts +4 -0
  5. package/dist/app-vite-env.d.ts.map +1 -0
  6. package/dist/app-vite-env.js +22 -0
  7. package/dist/app-vite-env.js.map +1 -0
  8. package/dist/binary-cache.d.ts +7 -5
  9. package/dist/binary-cache.d.ts.map +1 -1
  10. package/dist/binary-cache.js +28 -10
  11. package/dist/binary-cache.js.map +1 -1
  12. package/dist/cli-standalone.d.ts +10 -0
  13. package/dist/cli-standalone.d.ts.map +1 -0
  14. package/dist/cli-standalone.js +56 -0
  15. package/dist/cli-standalone.js.map +1 -0
  16. package/dist/commands/dev.d.ts.map +1 -1
  17. package/dist/commands/dev.js +34 -0
  18. package/dist/commands/dev.js.map +1 -1
  19. package/dist/commands/init.d.ts.map +1 -1
  20. package/dist/commands/init.js +3 -1
  21. package/dist/commands/init.js.map +1 -1
  22. package/dist/commands/keys.d.ts.map +1 -1
  23. package/dist/commands/keys.js +14 -0
  24. package/dist/commands/keys.js.map +1 -1
  25. package/dist/commands/self-update.d.ts +1 -1
  26. package/dist/commands/self-update.d.ts.map +1 -1
  27. package/dist/commands/self-update.js +33 -9
  28. package/dist/commands/self-update.js.map +1 -1
  29. package/dist/commands/update.d.ts.map +1 -1
  30. package/dist/commands/update.js +9 -1
  31. package/dist/commands/update.js.map +1 -1
  32. package/dist/components.d.ts +2 -2
  33. package/dist/components.d.ts.map +1 -1
  34. package/dist/components.js +2 -2
  35. package/dist/components.js.map +1 -1
  36. package/dist/dev-compose.d.ts.map +1 -1
  37. package/dist/dev-compose.js +120 -12
  38. package/dist/dev-compose.js.map +1 -1
  39. package/dist/project-config.d.ts +2 -0
  40. package/dist/project-config.d.ts.map +1 -1
  41. package/dist/project-config.js.map +1 -1
  42. package/dist/realtime-launch.d.ts +11 -0
  43. package/dist/realtime-launch.d.ts.map +1 -0
  44. package/dist/realtime-launch.js +39 -0
  45. package/dist/realtime-launch.js.map +1 -0
  46. package/dist/required-host-components.js +1 -1
  47. package/dist/required-host-components.js.map +1 -1
  48. package/dist/route-manifest.d.ts +3 -0
  49. package/dist/route-manifest.d.ts.map +1 -0
  50. package/dist/route-manifest.js +15 -0
  51. package/dist/route-manifest.js.map +1 -0
  52. package/dist/schema-push-lock.d.ts +17 -0
  53. package/dist/schema-push-lock.d.ts.map +1 -0
  54. package/dist/schema-push-lock.js +106 -0
  55. package/dist/schema-push-lock.js.map +1 -0
  56. package/dist/self-host-compose.d.ts.map +1 -1
  57. package/dist/self-host-compose.js +18 -0
  58. package/dist/self-host-compose.js.map +1 -1
  59. package/dist/type-extractor.d.ts.map +1 -1
  60. package/dist/type-extractor.js +169 -13
  61. package/dist/type-extractor.js.map +1 -1
  62. package/package.json +1 -1
  63. package/scripts/build-release-bundle.mjs +27 -0
  64. package/src/app-vite-env.ts +27 -0
  65. package/src/binary-cache.ts +29 -11
  66. package/src/cli-standalone.ts +62 -0
  67. package/src/commands/dev.ts +38 -0
  68. package/src/commands/init.ts +3 -1
  69. package/src/commands/keys.ts +14 -0
  70. package/src/commands/self-update.ts +34 -13
  71. package/src/commands/update.ts +9 -1
  72. package/src/components.ts +2 -2
  73. package/src/dev-compose.ts +144 -14
  74. package/src/project-config.ts +2 -0
  75. package/src/realtime-launch.ts +52 -0
  76. package/src/required-host-components.ts +1 -1
  77. package/src/route-manifest.ts +17 -0
  78. package/src/schema-push-lock.ts +131 -0
  79. package/src/self-host-compose.ts +18 -0
  80. package/src/type-extractor.ts +213 -13
  81. package/tests/realtime-launch.test.ts +25 -0
  82. package/tests/required-host-components.test.ts +2 -0
  83. package/tests/route-manifest.test.ts +29 -0
  84. package/tests/type-extractor.test.ts +153 -0
  85. package/tsconfig.tsbuildinfo +1 -1
@@ -581,6 +581,159 @@ export type Post = Model<WithTimestamps<{
581
581
  expect(post?.options.singleton).toBeUndefined()
582
582
  })
583
583
 
584
+ it("extracts models that use intersection `} & Timestamps` with relational fields", () => {
585
+ const dir = mkdtempSync(join(tmpdir(), "supatype-intersection-timestamps-"))
586
+ dirs.push(dir)
587
+ const schemaPath = join(dir, "schema.ts")
588
+ writeFileSync(
589
+ schemaPath,
590
+ `
591
+ import type {
592
+ Model, LoggedIn, Owner, Public, RelatedTo, Unique, Optional, MaxLength, Timestamps, UUID,
593
+ } from "@supatype/types"
594
+
595
+ export type Profile = Model<{
596
+ id: UUID
597
+ display_name: string
598
+ }, {
599
+ access: { read: LoggedIn; create: Owner<"id">; update: Owner<"id">; delete: Owner<"id"> }
600
+ }>
601
+
602
+ export type Room = Model<{
603
+ id: UUID
604
+ name: Unique<string>
605
+ topic: Optional<string>
606
+ created_by: RelatedTo<Profile, { required: true }>
607
+ } & Timestamps, {
608
+ access: { read: Public; create: LoggedIn; update: Owner<"created_by_id">; delete: Owner<"created_by_id"> }
609
+ }>
610
+
611
+ export type Message = Model<{
612
+ id: UUID
613
+ room: RelatedTo<Room, { required: true, onDelete: "cascade" }>
614
+ author: RelatedTo<Profile, { required: true }>
615
+ body: MaxLength<string, 2000>
616
+ } & Timestamps, {
617
+ access: { read: Public; create: LoggedIn; update: Owner<"author_id">; delete: Owner<"author_id"> }
618
+ indexes: [{ fields: ["room_id", "created_at"] }]
619
+ }>
620
+ `,
621
+ "utf8",
622
+ )
623
+
624
+ const ast = extractSchemaAstFromTypes(schemaPath, dir)
625
+ expect(ast).not.toBeNull()
626
+ expect(ast?.models).toHaveLength(3)
627
+
628
+ const room = ast?.models.find((m) => m.name === "Room")
629
+ const message = ast?.models.find((m) => m.name === "Message")
630
+
631
+ expect(room).toBeDefined()
632
+ expect(tableName(room)).toBe("room")
633
+ expect(room?.options.timestamps).toBe(true)
634
+ expect(room?.fields["created_by"]).toMatchObject({
635
+ kind: "relation",
636
+ cardinality: "belongsTo",
637
+ target: "Profile",
638
+ required: true,
639
+ annotations: { db: { foreignKey: "created_by_id" } },
640
+ })
641
+ expect(room?.fields["created_at"]).toMatchObject({ kind: "datetime" })
642
+ expect(room?.fields["updated_at"]).toMatchObject({ kind: "datetime" })
643
+
644
+ expect(message).toBeDefined()
645
+ expect(tableName(message)).toBe("message")
646
+ expect(message?.options.timestamps).toBe(true)
647
+ expect(message?.fields["room"]).toMatchObject({
648
+ kind: "relation",
649
+ cardinality: "belongsTo",
650
+ target: "Room",
651
+ required: true,
652
+ onDelete: "cascade",
653
+ annotations: { db: { foreignKey: "room_id" } },
654
+ })
655
+ expect(message?.fields["author"]).toMatchObject({
656
+ kind: "relation",
657
+ cardinality: "belongsTo",
658
+ target: "Profile",
659
+ required: true,
660
+ })
661
+ expect(message?.fields["body"]).toMatchObject({
662
+ kind: "text",
663
+ check: 'char_length("{name}") <= 2000',
664
+ })
665
+ const messageIndexes = message?.annotations.db.indexes as Array<Record<string, unknown>>
666
+ expect(messageIndexes).toHaveLength(1)
667
+ expect(messageIndexes?.[0]).toMatchObject({
668
+ using: "btree",
669
+ unique: false,
670
+ fields: ["room_id", "created_at"],
671
+ })
672
+ })
673
+
674
+ it("extracts ManyToMany relations with through table option", () => {
675
+ const dir = mkdtempSync(join(tmpdir(), "supatype-many-to-many-"))
676
+ dirs.push(dir)
677
+ const schemaPath = join(dir, "schema.ts")
678
+ writeFileSync(
679
+ schemaPath,
680
+ `
681
+ import type { Model, UUID, ManyToMany, Public, LoggedIn } from "@supatype/types"
682
+
683
+ export type Course = Model<{
684
+ id: UUID
685
+ title: string
686
+ }, {
687
+ access: { read: Public; create: LoggedIn }
688
+ }>
689
+
690
+ export type Student = Model<{
691
+ id: UUID
692
+ name: string
693
+ courses: ManyToMany<Course, { through: "enrollments" }>
694
+ }, {
695
+ access: { read: Public; create: LoggedIn }
696
+ }>
697
+ `,
698
+ "utf8",
699
+ )
700
+
701
+ const ast = extractSchemaAstFromTypes(schemaPath, dir)
702
+ const student = ast?.models.find((m) => m.name === "Student")
703
+ expect(student?.fields["courses"]).toMatchObject({
704
+ kind: "relation",
705
+ cardinality: "manyToMany",
706
+ target: "Course",
707
+ through: "enrollments",
708
+ })
709
+ })
710
+
711
+ it("extracts models with `} & SoftDelete` intersection", () => {
712
+ const dir = mkdtempSync(join(tmpdir(), "supatype-intersection-softdelete-"))
713
+ dirs.push(dir)
714
+ const schemaPath = join(dir, "schema.ts")
715
+ writeFileSync(
716
+ schemaPath,
717
+ `
718
+ import type { Model, UUID, SoftDelete, Public, LoggedIn } from "@supatype/types"
719
+
720
+ export type Post = Model<{
721
+ id: UUID
722
+ title: string
723
+ } & SoftDelete, {
724
+ access: { read: Public; create: LoggedIn }
725
+ }>
726
+ `,
727
+ "utf8",
728
+ )
729
+
730
+ const ast = extractSchemaAstFromTypes(schemaPath, dir)
731
+ const post = ast?.models.find((m) => m.name === "Post")
732
+ expect(post).toBeDefined()
733
+ expect(post?.fields["deleted_at"]).toMatchObject({ kind: "datetime", required: false })
734
+ expect(post?.options.softDelete).toBe(true)
735
+ })
736
+
584
737
  it("extracts LocaleConfig into schema AST locales", () => {
585
738
  const dir = mkdtempSync(join(tmpdir(), "supatype-types-locale-config-"))
586
739
  dirs.push(dir)