@playcademy/sdk 0.0.9 → 0.1.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/index.js CHANGED
@@ -14,14 +14,37 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
14
14
  var isBrowser = () => {
15
15
  const g = globalThis;
16
16
  return typeof g.window !== "undefined" && typeof g.document !== "undefined";
17
- }, colors, shouldUseColor = () => {
18
- const preference = (process.env.LOG_COLOR ?? "auto").toLowerCase();
19
- if (preference === "always")
20
- return true;
21
- if (preference === "never")
22
- return false;
23
- return Boolean(process.stdout && process.stdout.isTTY && true);
24
- }, getLevelColor = (level) => {
17
+ }, isProduction = () => {
18
+ return false;
19
+ }, isDevelopment = () => {
20
+ return true;
21
+ }, isInteractiveTTY = () => {
22
+ return Boolean(process.stdout && process.stdout.isTTY);
23
+ }, detectOutputFormat = () => {
24
+ if (isBrowser()) {
25
+ return "browser";
26
+ }
27
+ if (process.env.LOG_FORMAT === "json") {
28
+ return "json-single-line";
29
+ }
30
+ if (process.env.LOG_PRETTY === "true" && isDevelopment()) {
31
+ return "json-pretty";
32
+ }
33
+ const colorPreference = (process.env.LOG_COLOR ?? "auto").toLowerCase();
34
+ if (colorPreference === "always" && !isProduction()) {
35
+ return "color-tty";
36
+ }
37
+ if (colorPreference === "never") {
38
+ return "json-single-line";
39
+ }
40
+ if (isProduction()) {
41
+ return "json-single-line";
42
+ }
43
+ if (isDevelopment() && isInteractiveTTY()) {
44
+ return "color-tty";
45
+ }
46
+ return "json-single-line";
47
+ }, colors, getLevelColor = (level) => {
25
48
  switch (level) {
26
49
  case "debug":
27
50
  return colors.blue;
@@ -34,7 +57,7 @@ var isBrowser = () => {
34
57
  default:
35
58
  return colors.reset;
36
59
  }
37
- }, logInBrowser = (level, message, context) => {
60
+ }, formatBrowserOutput = (level, message, context) => {
38
61
  const timestamp = new Date().toISOString();
39
62
  const levelUpper = level.toUpperCase();
40
63
  const consoleMethod = getConsoleMethod(level);
@@ -43,22 +66,37 @@ var isBrowser = () => {
43
66
  } else {
44
67
  consoleMethod(`[${timestamp}] ${levelUpper}`, message);
45
68
  }
46
- }, logOnServer = (level, message, context) => {
69
+ }, formatColorTTY = (level, message, context) => {
70
+ const timestamp = new Date().toISOString();
71
+ const levelColor = getLevelColor(level);
72
+ const levelUpper = level.toUpperCase().padEnd(5);
47
73
  const consoleMethod = getConsoleMethod(level);
48
- if (shouldUseColor()) {
49
- const timestamp = new Date().toISOString();
50
- const levelColor = getLevelColor(level);
51
- const levelUpper = level.toUpperCase().padEnd(5);
52
- const coloredPrefix = `${colors.dim}[${timestamp}]${colors.reset} ${levelColor}${levelUpper}${colors.reset}`;
53
- if (context && Object.keys(context).length > 0) {
54
- consoleMethod(`${coloredPrefix} ${message}`, context);
55
- } else {
56
- consoleMethod(`${coloredPrefix} ${message}`);
57
- }
74
+ const coloredPrefix = `${colors.dim}[${timestamp}]${colors.reset} ${levelColor}${levelUpper}${colors.reset}`;
75
+ if (context && Object.keys(context).length > 0) {
76
+ consoleMethod(`${coloredPrefix} ${message}`, context);
58
77
  } else {
59
- const formatted = formatLog(level, message, context);
60
- consoleMethod(formatted);
78
+ consoleMethod(`${coloredPrefix} ${message}`);
61
79
  }
80
+ }, formatJSONSingleLine = (level, message, context) => {
81
+ const timestamp = new Date().toISOString();
82
+ const logEntry = {
83
+ timestamp,
84
+ level: level.toUpperCase(),
85
+ message,
86
+ ...context && Object.keys(context).length > 0 && { context }
87
+ };
88
+ const consoleMethod = getConsoleMethod(level);
89
+ consoleMethod(JSON.stringify(logEntry));
90
+ }, formatJSONPretty = (level, message, context) => {
91
+ const timestamp = new Date().toISOString();
92
+ const logEntry = {
93
+ timestamp,
94
+ level: level.toUpperCase(),
95
+ message,
96
+ ...context && Object.keys(context).length > 0 && { context }
97
+ };
98
+ const consoleMethod = getConsoleMethod(level);
99
+ consoleMethod(JSON.stringify(logEntry, null, 2));
62
100
  }, getConsoleMethod = (level) => {
63
101
  switch (level) {
64
102
  case "debug":
@@ -72,24 +110,24 @@ var isBrowser = () => {
72
110
  default:
73
111
  return console.log;
74
112
  }
75
- }, formatLog = (level, message, context) => {
76
- const timestamp = new Date().toISOString();
77
- const logEntry = {
78
- timestamp,
79
- level: level.toUpperCase(),
80
- message,
81
- ...context && Object.keys(context).length > 0 && { context }
82
- };
83
- if (true) {
84
- return JSON.stringify(logEntry, null, 2);
85
- }
86
- return JSON.stringify(logEntry);
87
113
  }, performLog = (level, message, context) => {
88
- if (level === "debug" && false) {}
89
- if (isBrowser()) {
90
- logInBrowser(level, message, context);
91
- } else {
92
- logOnServer(level, message, context);
114
+ if (level === "debug" && isProduction()) {
115
+ return;
116
+ }
117
+ const outputFormat = detectOutputFormat();
118
+ switch (outputFormat) {
119
+ case "browser":
120
+ formatBrowserOutput(level, message, context);
121
+ break;
122
+ case "color-tty":
123
+ formatColorTTY(level, message, context);
124
+ break;
125
+ case "json-single-line":
126
+ formatJSONSingleLine(level, message, context);
127
+ break;
128
+ case "json-pretty":
129
+ formatJSONPretty(level, message, context);
130
+ break;
93
131
  }
94
132
  }, createLogger = () => {
95
133
  return {
@@ -860,6 +898,22 @@ function createTTLCache(options) {
860
898
  }
861
899
 
862
900
  // src/core/request.ts
901
+ function checkDevWarnings(data) {
902
+ if (!data || typeof data !== "object")
903
+ return;
904
+ const response = data;
905
+ const warningType = response.__playcademyDevWarning;
906
+ if (!warningType)
907
+ return;
908
+ switch (warningType) {
909
+ case "timeback-disabled":
910
+ console.warn("%c⚠️ TimeBack Disabled in Dev", "background: #f59e0b; color: white; padding: 4px 8px; border-radius: 3px; font-weight: bold", `
911
+ ` + (response.__playcademyDevMessage || "TimeBack is disabled in local development"));
912
+ break;
913
+ default:
914
+ console.warn(`[Playcademy Dev Warning] ${warningType}`);
915
+ }
916
+ }
863
917
  async function request({
864
918
  path,
865
919
  baseUrl,
@@ -894,7 +948,9 @@ async function request({
894
948
  const contentType = res.headers.get("content-type") ?? "";
895
949
  if (contentType.includes("application/json")) {
896
950
  try {
897
- return await res.json();
951
+ const parsed = await res.json();
952
+ checkDevWarnings(parsed);
953
+ return parsed;
898
954
  } catch (err) {
899
955
  if (err instanceof SyntaxError)
900
956
  return;
@@ -1185,15 +1241,7 @@ function createDevNamespace(client) {
1185
1241
  throw new Error(`File upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`);
1186
1242
  }
1187
1243
  }
1188
- const baseUrl = (() => {
1189
- const anyClient = client;
1190
- try {
1191
- return typeof anyClient.getBaseUrl === "function" ? anyClient.getBaseUrl() : "/api";
1192
- } catch {
1193
- return "/api";
1194
- }
1195
- })();
1196
- const finalizeUrl = baseUrl.replace(/\/$/, "") + "/games/uploads/finalize/";
1244
+ const finalizeUrl = `${client.baseUrl}/games/uploads/finalize/`;
1197
1245
  const authToken = client.getToken();
1198
1246
  const tokenType = client.getTokenType();
1199
1247
  const headers = {
@@ -1461,801 +1509,18 @@ function createLevelsNamespace(client) {
1461
1509
  }
1462
1510
  var init_levels = () => {};
1463
1511
 
1464
- // ../data/src/domains/game/table.ts
1465
- import {
1466
- boolean,
1467
- jsonb,
1468
- pgEnum,
1469
- pgTable,
1470
- text,
1471
- timestamp,
1472
- uniqueIndex,
1473
- uuid,
1474
- varchar
1475
- } from "drizzle-orm/pg-core";
1476
- var gamePlatformEnum, gameBootModeEnum, gameTypeEnum, games, gameSessions, gameStates, deploymentProviderEnum, gameBackendDeployments;
1477
- var init_table = __esm(() => {
1478
- init_table3();
1479
- init_table4();
1480
- gamePlatformEnum = pgEnum("game_platform", ["web", "godot", "unity"]);
1481
- gameBootModeEnum = pgEnum("game_boot_mode", ["iframe", "module"]);
1482
- gameTypeEnum = pgEnum("game_type", ["hosted", "external"]);
1483
- games = pgTable("games", {
1484
- id: uuid("id").primaryKey().defaultRandom(),
1485
- developerId: text("developer_id").references(() => users.id, {
1486
- onDelete: "set null"
1487
- }),
1488
- slug: varchar("slug", { length: 255 }).notNull().unique(),
1489
- displayName: varchar("display_name", { length: 255 }).notNull(),
1490
- version: varchar("version", { length: 50 }).notNull(),
1491
- gameType: gameTypeEnum("game_type").notNull().default("hosted"),
1492
- assetBundleBase: text("asset_bundle_base"),
1493
- externalUrl: text("external_url"),
1494
- platform: gamePlatformEnum("platform").notNull().default("web"),
1495
- mapElementId: uuid("map_element_id").references(() => mapElements.id, {
1496
- onDelete: "set null"
1497
- }),
1498
- metadata: jsonb("metadata").$type().notNull().default({}),
1499
- createdAt: timestamp("created_at", { withTimezone: true }).defaultNow(),
1500
- updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow()
1501
- });
1502
- gameSessions = pgTable("game_sessions", {
1503
- id: uuid("id").primaryKey().defaultRandom(),
1504
- userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
1505
- gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
1506
- startedAt: timestamp("started_at", { withTimezone: true }).notNull().defaultNow(),
1507
- endedAt: timestamp("ended_at", { withTimezone: true })
1508
- });
1509
- gameStates = pgTable("game_states", {
1510
- userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
1511
- gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
1512
- data: jsonb("data").default("{}"),
1513
- updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow()
1514
- }, (table) => [uniqueIndex("unique_user_game_idx").on(table.userId, table.gameId)]);
1515
- deploymentProviderEnum = pgEnum("deployment_provider", ["cloudflare", "aws"]);
1516
- gameBackendDeployments = pgTable("game_backend_deployments", {
1517
- id: uuid("id").primaryKey().defaultRandom(),
1518
- gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
1519
- deploymentId: text("deployment_id").notNull(),
1520
- provider: deploymentProviderEnum("provider").notNull(),
1521
- url: text("url").notNull(),
1522
- codeHash: text("code_hash"),
1523
- isActive: boolean("is_active").notNull().default(false),
1524
- deployedAt: timestamp("deployed_at", { withTimezone: true }).notNull().defaultNow()
1525
- });
1526
- });
1512
+ // ../constants/src/auth.ts
1513
+ var init_auth = () => {};
1527
1514
 
1528
- // ../data/src/domains/inventory/table.ts
1529
- import { relations, sql } from "drizzle-orm";
1530
- import {
1531
- boolean as boolean2,
1532
- integer,
1533
- jsonb as jsonb2,
1534
- pgEnum as pgEnum2,
1535
- pgTable as pgTable2,
1536
- text as text2,
1537
- timestamp as timestamp2,
1538
- uniqueIndex as uniqueIndex2,
1539
- uuid as uuid2
1540
- } from "drizzle-orm/pg-core";
1541
- var itemTypeEnum, items, inventoryItems, currencies, shopListings, itemsRelations, currenciesRelations, shopListingsRelations, inventoryItemsRelations;
1542
- var init_table2 = __esm(() => {
1543
- init_table();
1544
- init_table3();
1545
- init_table4();
1546
- itemTypeEnum = pgEnum2("item_type", [
1547
- "currency",
1548
- "badge",
1549
- "trophy",
1550
- "collectible",
1551
- "consumable",
1552
- "unlock",
1553
- "upgrade",
1554
- "accessory",
1555
- "other"
1556
- ]);
1557
- items = pgTable2("items", {
1558
- id: uuid2("id").primaryKey().defaultRandom(),
1559
- slug: text2("slug").notNull(),
1560
- gameId: uuid2("game_id").references(() => games.id, {
1561
- onDelete: "cascade"
1562
- }),
1563
- displayName: text2("display_name").notNull(),
1564
- description: text2("description"),
1565
- type: itemTypeEnum("type").notNull().default("other"),
1566
- isPlaceable: boolean2("is_placeable").default(false).notNull(),
1567
- imageUrl: text2("image_url"),
1568
- metadata: jsonb2("metadata").default({}),
1569
- createdAt: timestamp2("created_at").defaultNow().notNull()
1570
- }, (table) => [
1571
- uniqueIndex2("items_game_slug_idx").on(table.gameId, table.slug),
1572
- uniqueIndex2("items_global_slug_idx").on(table.slug).where(sql`game_id IS NULL`)
1573
- ]);
1574
- inventoryItems = pgTable2("inventory_items", {
1575
- id: uuid2("id").primaryKey().defaultRandom(),
1576
- userId: text2("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
1577
- itemId: uuid2("item_id").notNull().references(() => items.id, { onDelete: "cascade" }),
1578
- quantity: integer("quantity").notNull().default(1),
1579
- updatedAt: timestamp2("updated_at", { withTimezone: true }).defaultNow()
1580
- }, (table) => [uniqueIndex2("unique_user_item_idx").on(table.userId, table.itemId)]);
1581
- currencies = pgTable2("currencies", {
1582
- id: uuid2("id").primaryKey().defaultRandom(),
1583
- itemId: uuid2("item_id").notNull().references(() => items.id, { onDelete: "cascade" }),
1584
- symbol: text2("symbol"),
1585
- isPrimary: boolean2("is_primary").default(false).notNull(),
1586
- createdAt: timestamp2("created_at").defaultNow().notNull(),
1587
- updatedAt: timestamp2("updated_at", { withTimezone: true }).defaultNow().$onUpdate(() => new Date)
1588
- }, (table) => [uniqueIndex2("currency_item_id_idx").on(table.itemId)]);
1589
- shopListings = pgTable2("shop_listings", {
1590
- id: uuid2("id").primaryKey().defaultRandom(),
1591
- itemId: uuid2("item_id").notNull().references(() => items.id, { onDelete: "cascade" }),
1592
- currencyId: uuid2("currency_id").notNull().references(() => currencies.id, { onDelete: "restrict" }),
1593
- price: integer("price").notNull(),
1594
- sellBackPercentage: integer("sell_back_percentage"),
1595
- stock: integer("stock"),
1596
- isActive: boolean2("is_active").default(true).notNull(),
1597
- availableFrom: timestamp2("available_from", { withTimezone: true }),
1598
- availableUntil: timestamp2("available_until", { withTimezone: true }),
1599
- createdAt: timestamp2("created_at").defaultNow().notNull(),
1600
- updatedAt: timestamp2("updated_at", { withTimezone: true }).defaultNow().$onUpdate(() => new Date)
1601
- }, (table) => [uniqueIndex2("unique_item_currency_listing_idx").on(table.itemId, table.currencyId)]);
1602
- itemsRelations = relations(items, ({ many }) => ({
1603
- shopListings: many(shopListings),
1604
- inventoryItems: many(inventoryItems),
1605
- mapObjects: many(mapObjects)
1606
- }));
1607
- currenciesRelations = relations(currencies, ({ many }) => ({
1608
- shopListings: many(shopListings)
1609
- }));
1610
- shopListingsRelations = relations(shopListings, ({ one }) => ({
1611
- item: one(items, {
1612
- fields: [shopListings.itemId],
1613
- references: [items.id]
1614
- }),
1615
- currency: one(currencies, {
1616
- fields: [shopListings.currencyId],
1617
- references: [currencies.id]
1618
- })
1619
- }));
1620
- inventoryItemsRelations = relations(inventoryItems, ({ one }) => ({
1621
- item: one(items, {
1622
- fields: [inventoryItems.itemId],
1623
- references: [items.id]
1624
- }),
1625
- user: one(users, {
1626
- fields: [inventoryItems.userId],
1627
- references: [users.id]
1628
- })
1629
- }));
1630
- });
1515
+ // ../constants/src/domains.ts
1516
+ var init_domains = () => {};
1631
1517
 
1632
- // ../data/src/domains/map/table.ts
1633
- import { relations as relations2 } from "drizzle-orm";
1634
- import {
1635
- doublePrecision,
1636
- index,
1637
- integer as integer2,
1638
- jsonb as jsonb3,
1639
- pgEnum as pgEnum3,
1640
- pgTable as pgTable3,
1641
- text as text3,
1642
- timestamp as timestamp3,
1643
- uniqueIndex as uniqueIndex3,
1644
- uuid as uuid3,
1645
- varchar as varchar2
1646
- } from "drizzle-orm/pg-core";
1647
- var interactionTypeEnum, maps, mapElements, mapObjects, mapElementsRelations, mapsRelations, mapObjectsRelations;
1648
- var init_table3 = __esm(() => {
1649
- init_table();
1650
- init_table2();
1651
- init_table4();
1652
- interactionTypeEnum = pgEnum3("interaction_type", [
1653
- "game_entry",
1654
- "game_registry",
1655
- "info",
1656
- "teleport",
1657
- "door_in",
1658
- "door_out",
1659
- "npc_interaction",
1660
- "quest_trigger"
1661
- ]);
1662
- maps = pgTable3("maps", {
1663
- id: uuid3("id").primaryKey().defaultRandom(),
1664
- identifier: varchar2("identifier", { length: 255 }).notNull().unique(),
1665
- displayName: varchar2("display_name", { length: 255 }).notNull(),
1666
- filePath: varchar2("file_path", { length: 255 }).notNull(),
1667
- tilesetBasePath: varchar2("tileset_base_path", { length: 255 }).notNull().default("/tilesets"),
1668
- defaultSpawnTileX: doublePrecision("default_spawn_tile_x").notNull().default(0),
1669
- defaultSpawnTileY: doublePrecision("default_spawn_tile_y").notNull().default(0),
1670
- description: text3("description")
1671
- });
1672
- mapElements = pgTable3("map_elements", {
1673
- id: uuid3("id").primaryKey().defaultRandom(),
1674
- mapId: uuid3("map_id").references(() => maps.id, {
1675
- onDelete: "cascade"
1676
- }),
1677
- elementSlug: varchar2("element_slug", { length: 255 }).notNull(),
1678
- interactionType: interactionTypeEnum("interaction_type").notNull(),
1679
- gameId: uuid3("game_id").references(() => games.id, {
1680
- onDelete: "set null"
1681
- }),
1682
- metadata: jsonb3("metadata").$type().default({})
1683
- }, (table) => [uniqueIndex3("map_id_element_slug_unique_idx").on(table.mapId, table.elementSlug)]);
1684
- mapObjects = pgTable3("map_objects", {
1685
- id: uuid3("id").primaryKey().defaultRandom(),
1686
- userId: text3("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
1687
- mapId: uuid3("map_id").notNull().references(() => maps.id, { onDelete: "cascade" }),
1688
- itemId: uuid3("item_id").notNull().references(() => items.id, { onDelete: "cascade" }),
1689
- worldX: doublePrecision("world_x").notNull(),
1690
- worldY: doublePrecision("world_y").notNull(),
1691
- rotation: integer2("rotation").default(0).notNull(),
1692
- scale: doublePrecision("scale").default(1).notNull(),
1693
- createdAt: timestamp3("created_at").defaultNow().notNull()
1694
- }, (table) => [
1695
- index("map_objects_map_idx").on(table.mapId),
1696
- index("map_objects_spatial_idx").on(table.mapId, table.worldX, table.worldY)
1697
- ]);
1698
- mapElementsRelations = relations2(mapElements, ({ one }) => ({
1699
- game: one(games, {
1700
- fields: [mapElements.gameId],
1701
- references: [games.id]
1702
- }),
1703
- map: one(maps, {
1704
- fields: [mapElements.mapId],
1705
- references: [maps.id]
1706
- })
1707
- }));
1708
- mapsRelations = relations2(maps, ({ many }) => ({
1709
- elements: many(mapElements),
1710
- objects: many(mapObjects)
1711
- }));
1712
- mapObjectsRelations = relations2(mapObjects, ({ one }) => ({
1713
- user: one(users, {
1714
- fields: [mapObjects.userId],
1715
- references: [users.id]
1716
- }),
1717
- map: one(maps, {
1718
- fields: [mapObjects.mapId],
1719
- references: [maps.id]
1720
- }),
1721
- item: one(items, {
1722
- fields: [mapObjects.itemId],
1723
- references: [items.id]
1724
- })
1725
- }));
1726
- });
1518
+ // ../constants/src/env-vars.ts
1519
+ var init_env_vars = () => {};
1727
1520
 
1728
- // ../data/src/domains/user/table.ts
1729
- import { relations as relations3 } from "drizzle-orm";
1730
- import { boolean as boolean3, pgEnum as pgEnum4, pgTable as pgTable4, text as text4, timestamp as timestamp4, uniqueIndex as uniqueIndex4 } from "drizzle-orm/pg-core";
1731
- var userRoleEnum, developerStatusEnum, users, accounts, sessions, verification, ssoProvider, usersRelations;
1732
- var init_table4 = __esm(() => {
1733
- init_table3();
1734
- userRoleEnum = pgEnum4("user_role", ["admin", "player", "developer"]);
1735
- developerStatusEnum = pgEnum4("developer_status", ["none", "pending", "approved"]);
1736
- users = pgTable4("user", {
1737
- id: text4("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
1738
- name: text4("name").notNull(),
1739
- username: text4("username").unique(),
1740
- email: text4("email").notNull().unique(),
1741
- timebackId: text4("timeback_id").unique(),
1742
- emailVerified: boolean3("email_verified").notNull().default(false),
1743
- image: text4("image"),
1744
- role: userRoleEnum("role").notNull().default("player"),
1745
- developerStatus: developerStatusEnum("developer_status").notNull().default("none"),
1746
- characterCreated: boolean3("character_created").notNull().default(false),
1747
- createdAt: timestamp4("created_at", {
1748
- mode: "date",
1749
- withTimezone: true
1750
- }).notNull(),
1751
- updatedAt: timestamp4("updated_at", {
1752
- mode: "date",
1753
- withTimezone: true
1754
- }).notNull()
1755
- });
1756
- accounts = pgTable4("account", {
1757
- id: text4("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
1758
- userId: text4("userId").notNull().references(() => users.id, { onDelete: "cascade" }),
1759
- accountId: text4("account_id").notNull(),
1760
- providerId: text4("provider_id").notNull(),
1761
- accessToken: text4("access_token"),
1762
- refreshToken: text4("refresh_token"),
1763
- idToken: text4("id_token"),
1764
- accessTokenExpiresAt: timestamp4("access_token_expires_at", {
1765
- mode: "date",
1766
- withTimezone: true
1767
- }),
1768
- refreshTokenExpiresAt: timestamp4("refresh_token_expires_at", {
1769
- mode: "date",
1770
- withTimezone: true
1771
- }),
1772
- scope: text4("scope"),
1773
- password: text4("password"),
1774
- createdAt: timestamp4("created_at", {
1775
- mode: "date",
1776
- withTimezone: true
1777
- }).notNull(),
1778
- updatedAt: timestamp4("updated_at", {
1779
- mode: "date",
1780
- withTimezone: true
1781
- }).notNull()
1782
- }, (table) => [uniqueIndex4("account_provider_providerId_idx").on(table.accountId, table.providerId)]);
1783
- sessions = pgTable4("session", {
1784
- id: text4("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
1785
- userId: text4("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
1786
- expiresAt: timestamp4("expires_at", {
1787
- mode: "date",
1788
- withTimezone: true
1789
- }).notNull(),
1790
- token: text4("token").notNull().unique(),
1791
- ipAddress: text4("ip_address"),
1792
- userAgent: text4("user_agent"),
1793
- createdAt: timestamp4("created_at", {
1794
- mode: "date",
1795
- withTimezone: true
1796
- }).notNull(),
1797
- updatedAt: timestamp4("updated_at", {
1798
- mode: "date",
1799
- withTimezone: true
1800
- }).notNull()
1801
- });
1802
- verification = pgTable4("verification", {
1803
- id: text4("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
1804
- identifier: text4("identifier").notNull(),
1805
- value: text4("value").notNull(),
1806
- expiresAt: timestamp4("expires_at", {
1807
- mode: "date",
1808
- withTimezone: true
1809
- }).notNull(),
1810
- createdAt: timestamp4("created_at", {
1811
- mode: "date",
1812
- withTimezone: true
1813
- }).notNull(),
1814
- updatedAt: timestamp4("updated_at", {
1815
- mode: "date",
1816
- withTimezone: true
1817
- }).notNull()
1818
- });
1819
- ssoProvider = pgTable4("sso_provider", {
1820
- id: text4("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
1821
- issuer: text4("issuer").notNull(),
1822
- oidcConfig: text4("oidc_config"),
1823
- samlConfig: text4("saml_config"),
1824
- userId: text4("user_id").references(() => users.id, { onDelete: "cascade" }),
1825
- providerId: text4("provider_id").notNull().unique(),
1826
- organizationId: text4("organization_id"),
1827
- domain: text4("domain").notNull()
1828
- });
1829
- usersRelations = relations3(users, ({ many }) => ({
1830
- mapObjects: many(mapObjects)
1831
- }));
1832
- });
1833
-
1834
- // ../data/src/domains/developer/table.ts
1835
- import { boolean as boolean4, integer as integer3, pgTable as pgTable5, text as text5, timestamp as timestamp5, uuid as uuid4 } from "drizzle-orm/pg-core";
1836
- var apikey;
1837
- var init_table5 = __esm(() => {
1838
- init_table4();
1839
- apikey = pgTable5("api_key", {
1840
- id: uuid4("id").primaryKey().defaultRandom(),
1841
- name: text5("name"),
1842
- start: text5("start"),
1843
- prefix: text5("prefix"),
1844
- key: text5("key").notNull(),
1845
- userId: text5("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
1846
- refillInterval: integer3("refill_interval"),
1847
- refillAmount: integer3("refill_amount"),
1848
- lastRefillAt: timestamp5("last_refill_at", { withTimezone: true }),
1849
- enabled: boolean4("enabled").notNull().default(true),
1850
- rateLimitEnabled: boolean4("rate_limit_enabled").notNull().default(false),
1851
- rateLimitTimeWindow: integer3("rate_limit_time_window"),
1852
- rateLimitMax: integer3("rate_limit_max"),
1853
- requestCount: integer3("request_count").notNull().default(0),
1854
- remaining: integer3("remaining"),
1855
- lastRequest: timestamp5("last_request", { withTimezone: true }),
1856
- expiresAt: timestamp5("expires_at", { withTimezone: true }),
1857
- createdAt: timestamp5("created_at", { withTimezone: true }).notNull().defaultNow(),
1858
- updatedAt: timestamp5("updated_at", { withTimezone: true }).notNull().defaultNow(),
1859
- permissions: text5("permissions"),
1860
- metadata: text5("metadata")
1861
- });
1862
- });
1863
-
1864
- // ../data/src/domains/level/table.ts
1865
- import { relations as relations4 } from "drizzle-orm";
1866
- import {
1867
- doublePrecision as doublePrecision2,
1868
- integer as integer4,
1869
- pgTable as pgTable6,
1870
- text as text6,
1871
- timestamp as timestamp6,
1872
- uniqueIndex as uniqueIndex5,
1873
- uuid as uuid5
1874
- } from "drizzle-orm/pg-core";
1875
- var userLevels, levelConfigs, userLevelsRelations;
1876
- var init_table6 = __esm(() => {
1877
- init_table4();
1878
- userLevels = pgTable6("user_levels", {
1879
- userId: text6("user_id").primaryKey().references(() => users.id, { onDelete: "cascade" }),
1880
- currentLevel: integer4("current_level").notNull().default(1),
1881
- currentXp: doublePrecision2("current_xp").notNull().default(0),
1882
- totalXP: doublePrecision2("total_xp").notNull().default(0),
1883
- lastLevelUpAt: timestamp6("last_level_up_at", { withTimezone: true }),
1884
- createdAt: timestamp6("created_at").defaultNow().notNull(),
1885
- updatedAt: timestamp6("updated_at", { withTimezone: true }).defaultNow().$onUpdate(() => new Date)
1886
- });
1887
- levelConfigs = pgTable6("level_configs", {
1888
- id: uuid5("id").primaryKey().defaultRandom(),
1889
- level: integer4("level").notNull().unique(),
1890
- xpRequired: integer4("xp_required").notNull(),
1891
- creditsReward: integer4("credits_reward").notNull().default(0),
1892
- createdAt: timestamp6("created_at").defaultNow().notNull()
1893
- }, (table) => [uniqueIndex5("unique_level_config_idx").on(table.level)]);
1894
- userLevelsRelations = relations4(userLevels, ({ one }) => ({
1895
- user: one(users, {
1896
- fields: [userLevels.userId],
1897
- references: [users.id]
1898
- })
1899
- }));
1900
- });
1901
-
1902
- // ../data/src/domains/leaderboard/table.ts
1903
- import { relations as relations5 } from "drizzle-orm";
1904
- import { index as index2, integer as integer5, jsonb as jsonb4, pgTable as pgTable7, text as text7, timestamp as timestamp7, uuid as uuid6 } from "drizzle-orm/pg-core";
1905
- var gameScores, gameScoresRelations;
1906
- var init_table7 = __esm(() => {
1907
- init_table();
1908
- init_table4();
1909
- gameScores = pgTable7("game_scores", {
1910
- id: uuid6("id").primaryKey().defaultRandom(),
1911
- userId: text7("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
1912
- gameId: uuid6("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
1913
- score: integer5("score").notNull(),
1914
- metadata: jsonb4("metadata").default("{}"),
1915
- achievedAt: timestamp7("achieved_at", { withTimezone: true }).defaultNow().notNull(),
1916
- sessionId: uuid6("session_id").references(() => gameSessions.id, { onDelete: "set null" })
1917
- }, (table) => [
1918
- index2("game_scores_user_game_idx").on(table.userId, table.gameId),
1919
- index2("game_scores_game_score_idx").on(table.gameId, table.score),
1920
- index2("game_scores_achieved_at_idx").on(table.achievedAt)
1921
- ]);
1922
- gameScoresRelations = relations5(gameScores, ({ one }) => ({
1923
- user: one(users, {
1924
- fields: [gameScores.userId],
1925
- references: [users.id]
1926
- }),
1927
- game: one(games, {
1928
- fields: [gameScores.gameId],
1929
- references: [games.id]
1930
- }),
1931
- session: one(gameSessions, {
1932
- fields: [gameScores.sessionId],
1933
- references: [gameSessions.id]
1934
- })
1935
- }));
1936
- });
1937
-
1938
- // ../data/src/domains/sprite/table.ts
1939
- import { relations as relations6 } from "drizzle-orm";
1940
- import { integer as integer6, pgTable as pgTable8, timestamp as timestamp8, uuid as uuid7, varchar as varchar3 } from "drizzle-orm/pg-core";
1941
- var spriteTemplates, spriteSheets, spriteTemplatesRelations, spriteSheetsRelations;
1942
- var init_table8 = __esm(() => {
1943
- spriteTemplates = pgTable8("sprite_templates", {
1944
- id: uuid7("id").primaryKey().defaultRandom(),
1945
- slug: varchar3("slug", { length: 64 }).notNull().unique(),
1946
- url: varchar3("url", { length: 255 }).notNull(),
1947
- createdAt: timestamp8("created_at", { withTimezone: true }).notNull().defaultNow(),
1948
- updatedAt: timestamp8("updated_at", { withTimezone: true }).notNull().defaultNow()
1949
- });
1950
- spriteSheets = pgTable8("sprite_sheets", {
1951
- id: uuid7("id").primaryKey().defaultRandom(),
1952
- templateId: uuid7("template_id").notNull().references(() => spriteTemplates.id, { onDelete: "cascade" }),
1953
- width: integer6("width").notNull(),
1954
- height: integer6("height").notNull(),
1955
- url: varchar3("url", { length: 255 }).notNull(),
1956
- createdAt: timestamp8("created_at", { withTimezone: true }).notNull().defaultNow(),
1957
- updatedAt: timestamp8("updated_at", { withTimezone: true }).notNull().defaultNow()
1958
- });
1959
- spriteTemplatesRelations = relations6(spriteTemplates, ({ many }) => ({
1960
- sheets: many(spriteSheets)
1961
- }));
1962
- spriteSheetsRelations = relations6(spriteSheets, ({ one }) => ({
1963
- template: one(spriteTemplates, {
1964
- fields: [spriteSheets.templateId],
1965
- references: [spriteTemplates.id]
1966
- })
1967
- }));
1968
- });
1969
-
1970
- // ../data/src/domains/character/table.ts
1971
- import { relations as relations7 } from "drizzle-orm";
1972
- import {
1973
- integer as integer7,
1974
- pgEnum as pgEnum5,
1975
- pgTable as pgTable9,
1976
- text as text8,
1977
- timestamp as timestamp9,
1978
- uniqueIndex as uniqueIndex6,
1979
- uuid as uuid8,
1980
- varchar as varchar4
1981
- } from "drizzle-orm/pg-core";
1982
- var characterComponentTypeEnum, characterComponents, playerCharacters, playerCharacterAccessories, characterComponentsRelations, playerCharactersRelations, playerCharacterAccessoriesRelations;
1983
- var init_table9 = __esm(() => {
1984
- init_table8();
1985
- init_table4();
1986
- characterComponentTypeEnum = pgEnum5("character_component_type", [
1987
- "body",
1988
- "outfit",
1989
- "hairstyle",
1990
- "eyes",
1991
- "accessory"
1992
- ]);
1993
- characterComponents = pgTable9("character_components", {
1994
- id: uuid8("id").primaryKey().defaultRandom(),
1995
- componentType: characterComponentTypeEnum("component_type").notNull(),
1996
- slug: varchar4("slug", { length: 128 }).notNull().unique(),
1997
- displayName: varchar4("display_name", { length: 128 }).notNull(),
1998
- slot: varchar4("slot", { length: 64 }).notNull(),
1999
- spriteSheetId: uuid8("sprite_sheet_id").notNull().references(() => spriteSheets.id, { onDelete: "cascade" }),
2000
- unlockLevel: integer7("unlock_level").notNull().default(0),
2001
- variant: integer7("variant").notNull().default(0),
2002
- createdAt: timestamp9("created_at", { withTimezone: true }).notNull().defaultNow(),
2003
- updatedAt: timestamp9("updated_at", { withTimezone: true }).notNull().defaultNow()
2004
- });
2005
- playerCharacters = pgTable9("player_characters", {
2006
- id: uuid8("id").primaryKey().defaultRandom(),
2007
- userId: text8("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
2008
- bodyComponentId: uuid8("body_component_id").notNull().references(() => characterComponents.id, { onDelete: "restrict" }),
2009
- eyesComponentId: uuid8("eyes_component_id").notNull().references(() => characterComponents.id, { onDelete: "restrict" }),
2010
- hairstyleComponentId: uuid8("hairstyle_component_id").notNull().references(() => characterComponents.id, { onDelete: "restrict" }),
2011
- outfitComponentId: uuid8("outfit_component_id").notNull().references(() => characterComponents.id, { onDelete: "restrict" }),
2012
- createdAt: timestamp9("created_at", { withTimezone: true }).notNull().defaultNow(),
2013
- updatedAt: timestamp9("updated_at", { withTimezone: true }).notNull().defaultNow()
2014
- });
2015
- playerCharacterAccessories = pgTable9("player_character_accessories", {
2016
- id: uuid8("id").primaryKey().defaultRandom(),
2017
- playerCharacterId: uuid8("player_character_id").notNull().references(() => playerCharacters.id, { onDelete: "cascade" }),
2018
- accessoryComponentId: uuid8("accessory_component_id").notNull().references(() => characterComponents.id, { onDelete: "cascade" }),
2019
- slot: varchar4("slot", { length: 64 }).notNull(),
2020
- equippedAt: timestamp9("equipped_at", { withTimezone: true }).notNull().defaultNow(),
2021
- updatedAt: timestamp9("updated_at", { withTimezone: true }).notNull().defaultNow()
2022
- }, (table) => [
2023
- uniqueIndex6("unique_player_character_slot_idx").on(table.playerCharacterId, table.slot),
2024
- uniqueIndex6("player_character_accessory_idx").on(table.playerCharacterId, table.accessoryComponentId)
2025
- ]);
2026
- characterComponentsRelations = relations7(characterComponents, ({ one }) => ({
2027
- sheet: one(spriteSheets, {
2028
- fields: [characterComponents.spriteSheetId],
2029
- references: [spriteSheets.id]
2030
- })
2031
- }));
2032
- playerCharactersRelations = relations7(playerCharacters, ({ one, many }) => ({
2033
- user: one(users, {
2034
- fields: [playerCharacters.userId],
2035
- references: [users.id]
2036
- }),
2037
- body: one(characterComponents, {
2038
- fields: [playerCharacters.bodyComponentId],
2039
- references: [characterComponents.id]
2040
- }),
2041
- eyes: one(characterComponents, {
2042
- fields: [playerCharacters.eyesComponentId],
2043
- references: [characterComponents.id]
2044
- }),
2045
- hair: one(characterComponents, {
2046
- fields: [playerCharacters.hairstyleComponentId],
2047
- references: [characterComponents.id]
2048
- }),
2049
- outfit: one(characterComponents, {
2050
- fields: [playerCharacters.outfitComponentId],
2051
- references: [characterComponents.id]
2052
- }),
2053
- accessories: many(playerCharacterAccessories)
2054
- }));
2055
- playerCharacterAccessoriesRelations = relations7(playerCharacterAccessories, ({ one }) => ({
2056
- playerCharacter: one(playerCharacters, {
2057
- fields: [playerCharacterAccessories.playerCharacterId],
2058
- references: [playerCharacters.id]
2059
- }),
2060
- accessoryComponent: one(characterComponents, {
2061
- fields: [playerCharacterAccessories.accessoryComponentId],
2062
- references: [characterComponents.id]
2063
- })
2064
- }));
2065
- });
2066
-
2067
- // ../data/src/domains/timeback/table.ts
2068
- import { doublePrecision as doublePrecision3, pgTable as pgTable10, text as text9, timestamp as timestamp10, uniqueIndex as uniqueIndex7, uuid as uuid9 } from "drizzle-orm/pg-core";
2069
- var timebackDailyXp, timebackXpEvents, gameTimebackIntegrations;
2070
- var init_table10 = __esm(() => {
2071
- init_table();
2072
- init_table4();
2073
- timebackDailyXp = pgTable10("timeback_daily_xp", {
2074
- userId: text9("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
2075
- date: timestamp10("date", { mode: "date", withTimezone: true }).notNull(),
2076
- xp: doublePrecision3("xp").notNull().default(0),
2077
- createdAt: timestamp10("created_at", { mode: "date", withTimezone: true }).notNull().defaultNow(),
2078
- updatedAt: timestamp10("updated_at", { mode: "date", withTimezone: true }).notNull().defaultNow()
2079
- }, (table) => [uniqueIndex7("timeback_daily_xp_user_date_idx").on(table.userId, table.date)]);
2080
- timebackXpEvents = pgTable10("timeback_xp_event", {
2081
- id: uuid9("id").primaryKey().defaultRandom(),
2082
- userId: text9("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
2083
- occurredAt: timestamp10("occurred_at", { withTimezone: true }).notNull(),
2084
- xpDelta: doublePrecision3("xp_delta").notNull(),
2085
- source: text9("source").notNull(),
2086
- sourceId: text9("source_id"),
2087
- sensor: text9("sensor"),
2088
- appName: text9("app_name"),
2089
- createdAt: timestamp10("created_at", { withTimezone: true }).notNull().defaultNow(),
2090
- updatedAt: timestamp10("updated_at", { withTimezone: true }).notNull().defaultNow()
2091
- }, (table) => [uniqueIndex7("timeback_xp_events_source_id_idx").on(table.source, table.sourceId)]);
2092
- gameTimebackIntegrations = pgTable10("game_timeback_integrations", {
2093
- id: uuid9("id").primaryKey().defaultRandom(),
2094
- gameId: uuid9("game_id").notNull().unique().references(() => games.id, { onDelete: "cascade" }),
2095
- courseId: text9("course_id").notNull(),
2096
- lastVerifiedAt: timestamp10("last_verified_at", { withTimezone: true }),
2097
- createdAt: timestamp10("created_at", { withTimezone: true }).notNull().defaultNow(),
2098
- updatedAt: timestamp10("updated_at", { withTimezone: true }).notNull().defaultNow()
2099
- });
2100
- });
2101
-
2102
- // ../data/src/domains/achievement/table.ts
2103
- import { relations as relations8 } from "drizzle-orm";
2104
- import {
2105
- boolean as boolean5,
2106
- index as index3,
2107
- integer as integer8,
2108
- jsonb as jsonb5,
2109
- pgEnum as pgEnum6,
2110
- pgTable as pgTable11,
2111
- text as text10,
2112
- timestamp as timestamp11,
2113
- uniqueIndex as uniqueIndex8,
2114
- uuid as uuid10,
2115
- varchar as varchar5
2116
- } from "drizzle-orm/pg-core";
2117
- var achievementScopeEnum, achievements, userAchievementProgress, userAchievementClaims, userAchievementProgressRelations, userAchievementClaimsRelations;
2118
- var init_table11 = __esm(() => {
2119
- init_table4();
2120
- achievementScopeEnum = pgEnum6("achievement_scope", [
2121
- "daily",
2122
- "weekly",
2123
- "monthly",
2124
- "yearly",
2125
- "game",
2126
- "global",
2127
- "map",
2128
- "level",
2129
- "event"
2130
- ]);
2131
- achievements = pgTable11("achievements", {
2132
- id: varchar5("id", { length: 255 }).primaryKey(),
2133
- title: varchar5("title", { length: 255 }).notNull(),
2134
- description: text10("description"),
2135
- scope: achievementScopeEnum("scope").notNull(),
2136
- rewardCredits: integer8("reward_credits").notNull().default(0),
2137
- limit: integer8("limit").notNull().default(1),
2138
- completionType: varchar5("completion_type", { length: 50 }).notNull(),
2139
- completionConfig: jsonb5("completion_config").notNull().default({}),
2140
- target: jsonb5("target").notNull().default({}),
2141
- active: boolean5("active").notNull().default(true),
2142
- createdAt: timestamp11("created_at", { withTimezone: true }).defaultNow(),
2143
- updatedAt: timestamp11("updated_at", { withTimezone: true }).defaultNow()
2144
- });
2145
- userAchievementProgress = pgTable11("user_achievement_progress", {
2146
- id: uuid10("id").primaryKey().defaultRandom(),
2147
- userId: text10("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
2148
- achievementId: varchar5("achievement_id", { length: 255 }).notNull().references(() => achievements.id, { onDelete: "cascade" }),
2149
- scopeKey: text10("scope_key").notNull(),
2150
- progress: jsonb5("progress").notNull().default({}),
2151
- updatedAt: timestamp11("updated_at", { withTimezone: true }).defaultNow().notNull()
2152
- }, (table) => [
2153
- index3("user_achievement_progress_idx").on(table.userId, table.achievementId, table.scopeKey)
2154
- ]);
2155
- userAchievementClaims = pgTable11("user_achievement_claims", {
2156
- id: uuid10("id").primaryKey().defaultRandom(),
2157
- userId: text10("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
2158
- achievementId: varchar5("achievement_id", { length: 255 }).notNull().references(() => achievements.id, { onDelete: "cascade" }),
2159
- scopeKey: text10("scope_key").notNull(),
2160
- rewardCredits: integer8("reward_credits").notNull(),
2161
- createdAt: timestamp11("created_at", { withTimezone: true }).defaultNow().notNull()
2162
- }, (table) => [
2163
- uniqueIndex8("user_achievement_claims_unique").on(table.userId, table.achievementId, table.scopeKey)
2164
- ]);
2165
- userAchievementProgressRelations = relations8(userAchievementProgress, ({ one }) => ({
2166
- user: one(users, {
2167
- fields: [userAchievementProgress.userId],
2168
- references: [users.id]
2169
- }),
2170
- achievement: one(achievements, {
2171
- fields: [userAchievementProgress.achievementId],
2172
- references: [achievements.id]
2173
- })
2174
- }));
2175
- userAchievementClaimsRelations = relations8(userAchievementClaims, ({ one }) => ({
2176
- user: one(users, {
2177
- fields: [userAchievementClaims.userId],
2178
- references: [users.id]
2179
- }),
2180
- achievement: one(achievements, {
2181
- fields: [userAchievementClaims.achievementId],
2182
- references: [achievements.id]
2183
- })
2184
- }));
2185
- });
2186
-
2187
- // ../data/src/domains/notification/table.ts
2188
- import { relations as relations9 } from "drizzle-orm";
2189
- import { index as index4, jsonb as jsonb6, pgEnum as pgEnum7, pgTable as pgTable12, text as text11, timestamp as timestamp12, uuid as uuid11, varchar as varchar6 } from "drizzle-orm/pg-core";
2190
- var notificationPriorityEnum, notificationStatusEnum, notifications, notificationsRelations;
2191
- var init_table12 = __esm(() => {
2192
- init_table4();
2193
- notificationPriorityEnum = pgEnum7("notification_priority", [
2194
- "low",
2195
- "normal",
2196
- "high",
2197
- "urgent"
2198
- ]);
2199
- notificationStatusEnum = pgEnum7("notification_status", [
2200
- "pending",
2201
- "delivered",
2202
- "seen",
2203
- "clicked",
2204
- "dismissed",
2205
- "expired"
2206
- ]);
2207
- notifications = pgTable12("notifications", {
2208
- id: uuid11("id").primaryKey().defaultRandom(),
2209
- userId: text11("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
2210
- type: varchar6("type", { length: 50 }).notNull(),
2211
- title: varchar6("title", { length: 255 }).notNull(),
2212
- message: text11("message").notNull(),
2213
- data: jsonb6("data").notNull().default({}),
2214
- priority: notificationPriorityEnum("priority").notNull().default("normal"),
2215
- status: notificationStatusEnum("status").notNull().default("pending"),
2216
- createdAt: timestamp12("created_at", { withTimezone: true }).defaultNow().notNull(),
2217
- deliveredAt: timestamp12("delivered_at", { withTimezone: true }),
2218
- seenAt: timestamp12("seen_at", { withTimezone: true }),
2219
- clickedAt: timestamp12("clicked_at", { withTimezone: true }),
2220
- expiresAt: timestamp12("expires_at", { withTimezone: true }),
2221
- method: varchar6("method", { length: 50 }),
2222
- clickUrl: text11("click_url"),
2223
- metadata: jsonb6("metadata").notNull().default({})
2224
- }, (table) => [
2225
- index4("notifications_user_id_idx").on(table.userId),
2226
- index4("notifications_status_idx").on(table.status),
2227
- index4("notifications_type_idx").on(table.type),
2228
- index4("notifications_created_at_idx").on(table.createdAt),
2229
- index4("notifications_user_status_idx").on(table.userId, table.status)
2230
- ]);
2231
- notificationsRelations = relations9(notifications, ({ one }) => ({
2232
- user: one(users, {
2233
- fields: [notifications.userId],
2234
- references: [users.id]
2235
- })
2236
- }));
2237
- });
2238
-
2239
- // ../data/src/tables.index.ts
2240
- var init_tables_index = __esm(() => {
2241
- init_table4();
2242
- init_table5();
2243
- init_table();
2244
- init_table2();
2245
- init_table3();
2246
- init_table6();
2247
- init_table7();
2248
- init_table8();
2249
- init_table9();
2250
- init_table10();
2251
- init_table11();
2252
- init_table12();
2253
- });
2254
-
2255
- // ../data/src/constants.ts
2256
- var ITEM_SLUGS, CURRENCIES, BADGES, INTERACTION_TYPE;
2257
- var init_constants = __esm(() => {
2258
- init_tables_index();
1521
+ // ../constants/src/overworld.ts
1522
+ var ITEM_SLUGS, CURRENCIES, BADGES;
1523
+ var init_overworld = __esm(() => {
2259
1524
  ITEM_SLUGS = {
2260
1525
  PLAYCADEMY_CREDITS: "PLAYCADEMY_CREDITS",
2261
1526
  PLAYCADEMY_XP: "PLAYCADEMY_XP",
@@ -2278,7 +1543,28 @@ var init_constants = __esm(() => {
2278
1543
  EARLY_ADOPTER: ITEM_SLUGS.EARLY_ADOPTER_BADGE,
2279
1544
  FIRST_GAME: ITEM_SLUGS.FIRST_GAME_BADGE
2280
1545
  };
2281
- INTERACTION_TYPE = Object.fromEntries(interactionTypeEnum.enumValues.map((value) => [value, value]));
1546
+ });
1547
+ // ../constants/src/timeback.ts
1548
+ var TIMEBACK_ROUTES;
1549
+ var init_timeback = __esm(() => {
1550
+ TIMEBACK_ROUTES = {
1551
+ PROGRESS: "/integrations/timeback/progress",
1552
+ SESSION_END: "/integrations/timeback/session-end",
1553
+ AWARD_XP: "/integrations/timeback/award-xp"
1554
+ };
1555
+ });
1556
+
1557
+ // ../constants/src/workers.ts
1558
+ var init_workers = () => {};
1559
+
1560
+ // ../constants/src/index.ts
1561
+ var init_src2 = __esm(() => {
1562
+ init_auth();
1563
+ init_domains();
1564
+ init_env_vars();
1565
+ init_overworld();
1566
+ init_timeback();
1567
+ init_workers();
2282
1568
  });
2283
1569
 
2284
1570
  // src/core/cache/singleton-cache.ts
@@ -2358,7 +1644,7 @@ function createCreditsNamespace(client) {
2358
1644
  };
2359
1645
  }
2360
1646
  var init_credits = __esm(() => {
2361
- init_constants();
1647
+ init_src2();
2362
1648
  });
2363
1649
 
2364
1650
  // src/core/namespaces/leaderboard.ts
@@ -2755,13 +2041,16 @@ var init_achievements = () => {};
2755
2041
  function createTimebackNamespace(client) {
2756
2042
  return {
2757
2043
  recordProgress: (progressData) => {
2758
- return client["request"]("/api/integrations/timeback/progress", "POST", { progressData });
2044
+ return client["requestGameBackend"](TIMEBACK_ROUTES.PROGRESS, "POST", { progressData });
2759
2045
  },
2760
2046
  recordSessionEnd: (sessionData) => {
2761
- return client["request"]("/api/integrations/timeback/session-end", "POST", { sessionData });
2047
+ return client["requestGameBackend"](TIMEBACK_ROUTES.SESSION_END, "POST", { sessionData });
2762
2048
  },
2763
2049
  awardXP: (xpAmount, metadata) => {
2764
- return client["request"]("/api/integrations/timeback/award-xp", "POST", { xpAmount, metadata });
2050
+ return client["requestGameBackend"](TIMEBACK_ROUTES.AWARD_XP, "POST", {
2051
+ xpAmount,
2052
+ metadata
2053
+ });
2765
2054
  },
2766
2055
  management: {
2767
2056
  setup: (request2) => {
@@ -2822,6 +2111,9 @@ function createTimebackNamespace(client) {
2822
2111
  }
2823
2112
  };
2824
2113
  }
2114
+ var init_timeback2 = __esm(() => {
2115
+ init_src2();
2116
+ });
2825
2117
 
2826
2118
  // src/core/namespaces/notifications.ts
2827
2119
  function createNotificationsNamespace(client) {
@@ -2891,6 +2183,33 @@ function createNotificationsNamespace(client) {
2891
2183
  }
2892
2184
  var init_notifications = () => {};
2893
2185
 
2186
+ // src/core/namespaces/backend.ts
2187
+ function createBackendNamespace(client) {
2188
+ function normalizePath(path) {
2189
+ return path.startsWith("/") ? path : `/${path}`;
2190
+ }
2191
+ return {
2192
+ async get(path, headers) {
2193
+ return client["requestGameBackend"](normalizePath(path), "GET", undefined, headers);
2194
+ },
2195
+ async post(path, body, headers) {
2196
+ return client["requestGameBackend"](normalizePath(path), "POST", body, headers);
2197
+ },
2198
+ async put(path, body, headers) {
2199
+ return client["requestGameBackend"](normalizePath(path), "PUT", body, headers);
2200
+ },
2201
+ async patch(path, body, headers) {
2202
+ return client["requestGameBackend"](normalizePath(path), "PATCH", body, headers);
2203
+ },
2204
+ async delete(path, headers) {
2205
+ return client["requestGameBackend"](normalizePath(path), "DELETE", undefined, headers);
2206
+ },
2207
+ async request(path, method, body, headers) {
2208
+ return client["requestGameBackend"](normalizePath(path), method, body, headers);
2209
+ }
2210
+ };
2211
+ }
2212
+
2894
2213
  // src/core/namespaces/index.ts
2895
2214
  var init_namespaces = __esm(() => {
2896
2215
  init_identity();
@@ -2904,6 +2223,7 @@ var init_namespaces = __esm(() => {
2904
2223
  init_sprites();
2905
2224
  init_realtime();
2906
2225
  init_achievements();
2226
+ init_timeback2();
2907
2227
  init_notifications();
2908
2228
  });
2909
2229
 
@@ -2933,6 +2253,9 @@ function buildAllowedOrigins(explicit) {
2933
2253
  return ref ? [ref] : [];
2934
2254
  }
2935
2255
  function isOriginAllowed(origin, allowlist) {
2256
+ if (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1") {
2257
+ return true;
2258
+ }
2936
2259
  if (!allowlist || allowlist.length === 0) {
2937
2260
  console.error("[Playcademy SDK] No allowed origins configured. Consider passing allowedParentOrigins explicitly to init().");
2938
2261
  return false;
@@ -2976,7 +2299,8 @@ async function waitForPlaycademyInit(allowedParentOrigins) {
2976
2299
  function createStandaloneConfig() {
2977
2300
  console.warn("[Playcademy SDK] Standalone mode detected, creating mock context for local development");
2978
2301
  const mockConfig = {
2979
- baseUrl: "/api",
2302
+ baseUrl: "http://localhost:4321",
2303
+ gameUrl: "http://localhost:8788",
2980
2304
  token: "mock-game-token-for-local-dev",
2981
2305
  gameId: "mock-game-id-from-template",
2982
2306
  realtimeUrl: undefined
@@ -2995,6 +2319,7 @@ async function init(options) {
2995
2319
  }
2996
2320
  const client = new PlaycademyClient({
2997
2321
  baseUrl: config.baseUrl,
2322
+ gameUrl: config.gameUrl,
2998
2323
  token: config.token,
2999
2324
  gameId: config.gameId,
3000
2325
  autoStartSession: window.self !== window.top
@@ -3072,6 +2397,7 @@ var init_client = __esm(() => {
3072
2397
  init_static();
3073
2398
  PlaycademyClient = class PlaycademyClient {
3074
2399
  baseUrl;
2400
+ gameUrl;
3075
2401
  authStrategy;
3076
2402
  gameId;
3077
2403
  config;
@@ -3080,7 +2406,8 @@ var init_client = __esm(() => {
3080
2406
  authContext;
3081
2407
  initPayload;
3082
2408
  constructor(config) {
3083
- this.baseUrl = config?.baseUrl || "/api";
2409
+ this.baseUrl = config?.baseUrl?.endsWith("/api") ? config.baseUrl : `${config?.baseUrl}/api`;
2410
+ this.gameUrl = config?.gameUrl;
3084
2411
  this.gameId = config?.gameId;
3085
2412
  this.config = config || {};
3086
2413
  this.authStrategy = createAuthStrategy(config?.token ?? null, config?.tokenType);
@@ -3092,6 +2419,15 @@ var init_client = __esm(() => {
3092
2419
  const isBrowser2 = typeof window !== "undefined";
3093
2420
  return isRelative && isBrowser2 ? `${window.location.origin}${this.baseUrl}` : this.baseUrl;
3094
2421
  }
2422
+ getGameBackendUrl() {
2423
+ if (!this.gameUrl) {
2424
+ throw new PlaycademyError("Game backend URL not configured. gameUrl must be set to use game backend features.");
2425
+ }
2426
+ const isRelative = this.gameUrl.startsWith("/");
2427
+ const isBrowser2 = typeof window !== "undefined";
2428
+ const effectiveGameUrl = isRelative && isBrowser2 ? `${window.location.origin}${this.gameUrl}` : this.gameUrl;
2429
+ return `${effectiveGameUrl}/api`;
2430
+ }
3095
2431
  ping() {
3096
2432
  return "pong";
3097
2433
  }
@@ -3136,6 +2472,19 @@ var init_client = __esm(() => {
3136
2472
  extraHeaders: effectiveHeaders
3137
2473
  });
3138
2474
  }
2475
+ async requestGameBackend(path, method, body, headers) {
2476
+ const effectiveHeaders = {
2477
+ ...headers,
2478
+ ...this.authStrategy.getHeaders()
2479
+ };
2480
+ return request({
2481
+ path,
2482
+ method,
2483
+ body,
2484
+ baseUrl: this.getGameBackendUrl(),
2485
+ extraHeaders: effectiveHeaders
2486
+ });
2487
+ }
3139
2488
  _ensureGameId() {
3140
2489
  if (!this.gameId) {
3141
2490
  throw new PlaycademyError("This operation requires a gameId, but none was provided when initializing the client.");
@@ -3185,6 +2534,7 @@ var init_client = __esm(() => {
3185
2534
  realtime = createRealtimeNamespace(this);
3186
2535
  achievements = createAchievementsNamespace(this);
3187
2536
  notifications = createNotificationsNamespace(this);
2537
+ backend = createBackendNamespace(this);
3188
2538
  static init = init;
3189
2539
  static login = login2;
3190
2540
  static identity = identity;
@@ -3194,25 +2544,8 @@ var init_client = __esm(() => {
3194
2544
  // src/index.ts
3195
2545
  init_client();
3196
2546
  init_messaging();
3197
-
3198
- // src/constants.ts
3199
- var CURRENCIES2 = {
3200
- PRIMARY: "PLAYCADEMY_CREDITS",
3201
- XP: "PLAYCADEMY_XP"
3202
- };
3203
- var BADGES2 = {
3204
- FOUNDING_MEMBER: "FOUNDING_MEMBER_BADGE",
3205
- EARLY_ADOPTER: "EARLY_ADOPTER_BADGE",
3206
- FIRST_GAME: "FIRST_GAME_BADGE"
3207
- };
3208
- var AuthProvider = {
3209
- TIMEBACK: "TIMEBACK"
3210
- };
3211
2547
  export {
3212
2548
  messaging,
3213
2549
  PlaycademyClient,
3214
- MessageEvents,
3215
- CURRENCIES2 as CURRENCIES,
3216
- BADGES2 as BADGES,
3217
- AuthProvider
2550
+ MessageEvents
3218
2551
  };