@stardeck-customer-apps/data-store-sdk 0.1.0-preview.2 → 0.1.0-preview.4

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/SKILL.md CHANGED
@@ -13,11 +13,21 @@ This guide helps AI agents understand and implement data store features using `@
13
13
 
14
14
  **Two Access Patterns**:
15
15
 
16
- 1. **DataStoreClient** — Platform API client for schema management and dynamic queries (no generated types needed)
17
- 2. **createDataStore()** — Direct Kysely connection for type-safe queries (requires generated types + DATA_STORE_URL)
16
+ 1. **createDataStore()** (Recommended) Direct Kysely connection for type-safe queries with compile-time checking. Use this for all application CRUD.
17
+ 2. **DataStoreClient** — Platform API client for schema management, dynamic queries, and storage file operations. Use this for DDL, agent-driven access, and storage-type data stores.
18
18
 
19
19
  ## Architecture Overview
20
20
 
21
+ **Type-Safe Queries (Direct Connection — Recommended for database stores):**
22
+
23
+ ```
24
+ Server Code
25
+ ↓ (Kysely with DATA_STORE_{NAME}_URL)
26
+ Data Store Neon Database (direct connection)
27
+ ```
28
+
29
+ `DATA_STORE_{NAME}_URL` is automatically injected in all environments (production, preview, sandbox).
30
+
21
31
  **Schema Management (via Platform API):**
22
32
 
23
33
  ```
@@ -38,21 +48,13 @@ Platform API (/api/data-stores/{storeId}/query or /mutate)
38
48
  Data Store Neon Database
39
49
  ```
40
50
 
41
- **Type-Safe Queries (Direct Connection):**
42
-
43
- ```
44
- Server Code
45
- ↓ (Kysely with DATA_STORE_URL)
46
- Data Store Neon Database (direct connection)
47
- ```
48
-
49
51
  ## Setup
50
52
 
51
53
  ### 1. Install Dependencies
52
54
 
53
55
  ```bash
54
56
  npm install @stardeck-customer-apps/data-store-sdk
55
- # For direct Kysely access (optional):
57
+ # For direct Kysely access (recommended for database stores):
56
58
  npm install kysely kysely-neon @neondatabase/serverless
57
59
  ```
58
60
 
@@ -203,9 +205,8 @@ npx stardeck-data-store generate-types --connection-string $DATA_STORE_MYSTORE_U
203
205
  import { createDataStore } from "@stardeck-customer-apps/data-store-sdk/server";
204
206
  import type { DB } from "@/generated/data-store-types";
205
207
 
206
- export const db = await createDataStore<DB>({
207
- connectionString: process.env.DATA_STORE_MYSTORE_URL,
208
- });
208
+ // storeName auto-reads DATA_STORE_MYSTORE_URL from env
209
+ export const db = await createDataStore<DB>({ storeName: "mystore" });
209
210
  ```
210
211
 
211
212
  ### Query with Full Type Safety
@@ -277,14 +278,14 @@ try {
277
278
 
278
279
  ## When to Use Which Pattern
279
280
 
280
- | Scenario | Pattern |
281
- | ----------------------------------------- | ------------------ |
282
- | Application CRUD with known schema | Kysely (type-safe) |
283
- | Agent building features dynamically | DataStoreClient |
284
- | Schema management (create/alter tables) | DataStoreClient |
285
- | Edge functions / serverless | DataStoreClient |
286
- | Complex queries (joins, CTEs, subqueries) | Kysely |
287
- | Storage file operations | DataStoreClient |
281
+ | Scenario | Pattern |
282
+ | ----------------------------------------- | -------------------- |
283
+ | Application CRUD with known schema | Kysely (recommended) |
284
+ | Complex queries (joins, CTEs, subqueries) | Kysely |
285
+ | Edge functions / serverless | Kysely |
286
+ | Agent building features dynamically | DataStoreClient |
287
+ | Schema management (create/alter tables) | DataStoreClient |
288
+ | Storage file operations | DataStoreClient |
288
289
 
289
290
  ## Important Notes
290
291
 
@@ -91,6 +91,13 @@ declare function signDeploymentRequest(deploymentSecret: string, payload: {
91
91
  * import { createDataStore } from "@stardeck-customer-apps/data-store-sdk/server";
92
92
  * import type { DB } from "./generated/data-store-types";
93
93
  *
94
+ * // Option 1: Use storeName to auto-read DATA_STORE_MYSTORE_URL from env
95
+ * const db = await createDataStore<DB>({ storeName: "mystore" });
96
+ *
97
+ * // Option 2: Pass connection string directly
98
+ * const db = await createDataStore<DB>({ connectionString: process.env.DATA_STORE_MYSTORE_URL });
99
+ *
100
+ * // Option 3: Falls back to DATA_STORE_URL env var
94
101
  * const db = await createDataStore<DB>();
95
102
  *
96
103
  * const users = await db
@@ -102,6 +109,7 @@ declare function signDeploymentRequest(deploymentSecret: string, payload: {
102
109
  */
103
110
  declare function createDataStore<DB>(options?: {
104
111
  connectionString?: string;
112
+ storeName?: string;
105
113
  kyselyConfig?: Partial<KyselyConfig>;
106
114
  }): Promise<Kysely<DB>>;
107
115
 
@@ -91,6 +91,13 @@ declare function signDeploymentRequest(deploymentSecret: string, payload: {
91
91
  * import { createDataStore } from "@stardeck-customer-apps/data-store-sdk/server";
92
92
  * import type { DB } from "./generated/data-store-types";
93
93
  *
94
+ * // Option 1: Use storeName to auto-read DATA_STORE_MYSTORE_URL from env
95
+ * const db = await createDataStore<DB>({ storeName: "mystore" });
96
+ *
97
+ * // Option 2: Pass connection string directly
98
+ * const db = await createDataStore<DB>({ connectionString: process.env.DATA_STORE_MYSTORE_URL });
99
+ *
100
+ * // Option 3: Falls back to DATA_STORE_URL env var
94
101
  * const db = await createDataStore<DB>();
95
102
  *
96
103
  * const users = await db
@@ -102,6 +109,7 @@ declare function signDeploymentRequest(deploymentSecret: string, payload: {
102
109
  */
103
110
  declare function createDataStore<DB>(options?: {
104
111
  connectionString?: string;
112
+ storeName?: string;
105
113
  kyselyConfig?: Partial<KyselyConfig>;
106
114
  }): Promise<Kysely<DB>>;
107
115
 
@@ -247,16 +247,24 @@ var DataStoreClient = class {
247
247
  // src/server/kysely.ts
248
248
  var import_kysely = require("kysely");
249
249
  async function createDataStore(options) {
250
- const connectionString = options?.connectionString ?? (typeof process !== "undefined" ? process.env?.DATA_STORE_URL : void 0);
250
+ const connectionString = options?.connectionString ?? (typeof process !== "undefined" && options?.storeName ? process.env?.[`DATA_STORE_${options.storeName.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_URL`] : void 0) ?? (typeof process !== "undefined" ? process.env?.DATA_STORE_URL : void 0);
251
251
  if (!connectionString) {
252
+ const envHint = options?.storeName ? `DATA_STORE_${options.storeName.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_URL` : "DATA_STORE_URL";
252
253
  throw new Error(
253
- "DATA_STORE_URL environment variable is required, or pass connectionString in options"
254
+ `${envHint} environment variable is required, or pass connectionString in options`
254
255
  );
255
256
  }
256
257
  const { Kysely: KyselyClass } = await import("kysely");
257
258
  const { NeonDialect } = await import("kysely-neon");
258
- const { neon } = await import("@neondatabase/serverless");
259
- const sql = neon(connectionString);
259
+ const { neon, types } = await import("@neondatabase/serverless");
260
+ const customTypes = {
261
+ ...types,
262
+ getTypeParser: ((oid, format) => {
263
+ if (oid === 1700) return (val) => parseFloat(val);
264
+ return types.getTypeParser(oid, format);
265
+ })
266
+ };
267
+ const sql = neon(connectionString, { types: customTypes });
260
268
  const dialect = new NeonDialect({ neon: sql });
261
269
  return new KyselyClass({
262
270
  dialect,
@@ -196,16 +196,24 @@ var DataStoreClient = class {
196
196
  // src/server/kysely.ts
197
197
  import "kysely";
198
198
  async function createDataStore(options) {
199
- const connectionString = options?.connectionString ?? (typeof process !== "undefined" ? process.env?.DATA_STORE_URL : void 0);
199
+ const connectionString = options?.connectionString ?? (typeof process !== "undefined" && options?.storeName ? process.env?.[`DATA_STORE_${options.storeName.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_URL`] : void 0) ?? (typeof process !== "undefined" ? process.env?.DATA_STORE_URL : void 0);
200
200
  if (!connectionString) {
201
+ const envHint = options?.storeName ? `DATA_STORE_${options.storeName.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_URL` : "DATA_STORE_URL";
201
202
  throw new Error(
202
- "DATA_STORE_URL environment variable is required, or pass connectionString in options"
203
+ `${envHint} environment variable is required, or pass connectionString in options`
203
204
  );
204
205
  }
205
206
  const { Kysely: KyselyClass } = await import("kysely");
206
207
  const { NeonDialect } = await import("kysely-neon");
207
- const { neon } = await import("@neondatabase/serverless");
208
- const sql = neon(connectionString);
208
+ const { neon, types } = await import("@neondatabase/serverless");
209
+ const customTypes = {
210
+ ...types,
211
+ getTypeParser: ((oid, format) => {
212
+ if (oid === 1700) return (val) => parseFloat(val);
213
+ return types.getTypeParser(oid, format);
214
+ })
215
+ };
216
+ const sql = neon(connectionString, { types: customTypes });
209
217
  const dialect = new NeonDialect({ neon: sql });
210
218
  return new KyselyClass({
211
219
  dialect,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stardeck-customer-apps/data-store-sdk",
3
- "version": "0.1.0-preview.2",
3
+ "version": "0.1.0-preview.4",
4
4
  "description": "SDK for accessing Stardeck data stores from deployed projects",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",