tthr 0.0.6 → 0.0.7

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 (2) hide show
  1. package/dist/index.js +105 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -124,7 +124,10 @@ async function deploySchemaToServer(projectId, token, dryRun) {
124
124
  },
125
125
  body: JSON.stringify({
126
126
  sql,
127
- tables: tables.map((t) => t.name)
127
+ tables: tables.map((t) => ({
128
+ name: t.name,
129
+ source: t.source
130
+ }))
128
131
  })
129
132
  });
130
133
  if (!response.ok) {
@@ -223,11 +226,32 @@ function parseSchema(source) {
223
226
  const schemaMatch = source.match(/defineSchema\s*\(\s*\{([\s\S]*)\}\s*\)/);
224
227
  if (!schemaMatch) return tables;
225
228
  const schemaContent = schemaMatch[1];
226
- const tableRegex = /(\w+)\s*:\s*\{([^}]+(?:\{[^}]*\}[^}]*)*)\}/g;
229
+ const schemaStartIndex = source.indexOf(schemaMatch[0]) + "defineSchema({".length;
230
+ const tableStartRegex = /(\w+)\s*:\s*\{/g;
227
231
  let match;
228
- while ((match = tableRegex.exec(schemaContent)) !== null) {
232
+ while ((match = tableStartRegex.exec(schemaContent)) !== null) {
229
233
  const tableName = match[1];
230
- const columnsContent = match[2];
234
+ const startOffset = match.index + match[0].length;
235
+ let braceCount = 1;
236
+ let endOffset = startOffset;
237
+ for (let i = startOffset; i < schemaContent.length && braceCount > 0; i++) {
238
+ const char = schemaContent[i];
239
+ if (char === "{") braceCount++;
240
+ else if (char === "}") braceCount--;
241
+ endOffset = i;
242
+ }
243
+ const columnsContent = schemaContent.slice(startOffset, endOffset);
244
+ const lines = columnsContent.split("\n");
245
+ const nonEmptyLines = lines.filter((line) => line.trim().length > 0);
246
+ const minIndent = nonEmptyLines.reduce((min, line) => {
247
+ const match2 = line.match(/^(\s*)/);
248
+ const indent = match2 ? match2[1].length : 0;
249
+ return Math.min(min, indent);
250
+ }, Infinity);
251
+ const normalisedContent = lines.map((line) => line.slice(minIndent === Infinity ? 0 : minIndent)).join("\n").trim();
252
+ const tableSource = `{
253
+ ${normalisedContent.split("\n").join("\n ")}
254
+ }`;
231
255
  const columns = {};
232
256
  const columnRegex = /(\w+)\s*:\s*(\w+)\s*\(\s*\)([^,\n]*)/g;
233
257
  let colMatch;
@@ -244,7 +268,7 @@ function parseSchema(source) {
244
268
  references: modifiers.match(/\.references\s*\(\s*['"]([^'"]+)['"]\s*\)/)?.[1]
245
269
  };
246
270
  }
247
- tables.push({ name: tableName, columns });
271
+ tables.push({ name: tableName, columns, source: tableSource });
248
272
  }
249
273
  return tables;
250
274
  }
@@ -723,6 +747,75 @@ export const remove = mutation({
723
747
  });
724
748
  },
725
749
  });
750
+ `
751
+ );
752
+ await fs3.writeFile(
753
+ path3.join(projectPath, "tether", "functions", "comments.ts"),
754
+ `import { query, mutation, z } from '@tthr/server';
755
+
756
+ // List all comments
757
+ export const list = query({
758
+ args: z.object({
759
+ limit: z.number().optional().default(100),
760
+ }),
761
+ handler: async ({ args, db }) => {
762
+ return db.comments.findMany({
763
+ orderBy: { createdAt: 'desc' },
764
+ limit: args.limit,
765
+ });
766
+ },
767
+ });
768
+
769
+ // List comments for a specific post
770
+ export const listByPost = query({
771
+ args: z.object({
772
+ postId: z.string(),
773
+ limit: z.number().optional().default(50),
774
+ }),
775
+ handler: async ({ args, db }) => {
776
+ return db.comments.findMany({
777
+ where: { postId: args.postId },
778
+ orderBy: { createdAt: 'asc' },
779
+ limit: args.limit,
780
+ });
781
+ },
782
+ });
783
+
784
+ // Create a new comment
785
+ export const create = mutation({
786
+ args: z.object({
787
+ postId: z.string(),
788
+ content: z.string().min(1),
789
+ }),
790
+ handler: async ({ args, ctx, db }) => {
791
+ const id = crypto.randomUUID();
792
+ const now = new Date().toISOString();
793
+
794
+ await db.comments.create({
795
+ data: {
796
+ id,
797
+ postId: args.postId,
798
+ content: args.content,
799
+ authorId: ctx.userId,
800
+ createdAt: now,
801
+ },
802
+ });
803
+
804
+ return { id };
805
+ },
806
+ });
807
+
808
+ // Delete a comment
809
+ export const remove = mutation({
810
+ args: z.object({
811
+ id: z.string(),
812
+ }),
813
+ handler: async ({ args, db }) => {
814
+ await db.comments.delete({
815
+ where: { id: args.id },
816
+ });
817
+ },
818
+ });
726
819
  `
727
820
  );
728
821
  const envContent = `# Tether Configuration
@@ -897,7 +990,7 @@ async function installTetherPackages(projectPath, template) {
897
990
  getLatestVersion("@tthr/client"),
898
991
  getLatestVersion("@tthr/schema"),
899
992
  getLatestVersion("@tthr/server"),
900
- getLatestVersion("@tthr/cli")
993
+ getLatestVersion("tthr")
901
994
  ]);
902
995
  const packages = [
903
996
  `@tthr/client@${tthrClientVersion}`,
@@ -905,7 +998,7 @@ async function installTetherPackages(projectPath, template) {
905
998
  `@tthr/server@${tthrServerVersion}`
906
999
  ];
907
1000
  const devPackages = [
908
- `@tthr/cli@${tthrCliVersion}`
1001
+ `tthr@${tthrCliVersion}`
909
1002
  ];
910
1003
  if (template === "nuxt") {
911
1004
  const tthrVueVersion = await getLatestVersion("@tthr/vue");
@@ -1600,9 +1693,10 @@ async function showStatus(migrationsDir) {
1600
1693
  // src/commands/login.ts
1601
1694
  import chalk7 from "chalk";
1602
1695
  import ora6 from "ora";
1696
+ import os from "os";
1603
1697
  var isDev3 = process.env.NODE_ENV === "development" || process.env.TETHER_DEV === "true";
1604
- var API_URL3 = isDev3 ? "http://localhost:3001/api/v1" : "https://tthr.io/api/v1";
1605
- var AUTH_URL = isDev3 ? "http://localhost:3000/cli" : "https://tthr.io/cli";
1698
+ var API_URL3 = isDev3 ? "http://localhost:3001/api/v1" : "https://tether-api.strands.gg/api/v1";
1699
+ var AUTH_URL = isDev3 ? "http://localhost:3000/cli" : "https://tether.strands.gg/cli";
1606
1700
  async function loginCommand() {
1607
1701
  console.log(chalk7.bold("\u26A1 Login to Tether\n"));
1608
1702
  const existing = await getCredentials();
@@ -1687,10 +1781,11 @@ function generateUserCode() {
1687
1781
  async function requestDeviceCode() {
1688
1782
  const userCode = generateUserCode();
1689
1783
  const deviceCode = crypto.randomUUID();
1784
+ const deviceName = os.hostname();
1690
1785
  const response = await fetch(`${API_URL3}/auth/device`, {
1691
1786
  method: "POST",
1692
1787
  headers: { "Content-Type": "application/json" },
1693
- body: JSON.stringify({ userCode, deviceCode })
1788
+ body: JSON.stringify({ userCode, deviceCode, deviceName })
1694
1789
  }).catch(() => null);
1695
1790
  if (response?.ok) {
1696
1791
  return await response.json();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tthr",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "Tether CLI - project scaffolding, migrations, and deployment",
5
5
  "type": "module",
6
6
  "bin": {