@lunora/bindings 1.0.0-alpha.1 → 1.0.0-alpha.2

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.
@@ -1,5 +1,5 @@
1
- import SelectBuilder from './SelectBuilder-BGXfCF0J.mjs';
2
- import { toText } from './Sql-CkDyJ_Sc.mjs';
1
+ import SelectBuilder from './SelectBuilder-DHaXZwn_.mjs';
2
+ import { ident, toText } from './Sql-DceGtcUd.mjs';
3
3
 
4
4
  const API_BASE = "https://api.sql.cloudflarestorage.com/api/v1/accounts";
5
5
  const inferColumns = (rows) => {
@@ -53,12 +53,14 @@ const createR2Sql = (config) => {
53
53
  };
54
54
  };
55
55
  return {
56
- describe: async (table) => exec(`DESCRIBE ${table}`),
56
+ describe: async (table) => exec(`DESCRIBE ${ident(table)}`),
57
57
  explain: async (statement, options) => exec(`EXPLAIN ${options?.format === "json" ? "FORMAT JSON " : ""}${toText(statement)}`),
58
+ // `SelectBuilder`'s constructor validates the table reference (allowing an
59
+ // optional `[AS] alias`), so no pre-validation here.
58
60
  from: (table) => new SelectBuilder(exec, table),
59
61
  query: async (statement) => exec(toText(statement)),
60
62
  showDatabases: async () => exec("SHOW DATABASES"),
61
- showTables: async (namespace) => exec(`SHOW TABLES IN ${namespace}`)
63
+ showTables: async (namespace) => exec(`SHOW TABLES IN ${ident(namespace)}`)
62
64
  };
63
65
  };
64
66
 
@@ -1,6 +1,6 @@
1
- import { renderOrderTerm } from './asc-C6Jbaa6R.mjs';
2
- import SetOperation from './SetOperation-CGRu681M.mjs';
3
- import { toText, lit } from './Sql-CkDyJ_Sc.mjs';
1
+ import { renderOrderTerm } from './asc-Cur-xO8v.mjs';
2
+ import SetOperation from './SetOperation-RDHcxccj.mjs';
3
+ import { tableRef, toText, lit } from './Sql-DceGtcUd.mjs';
4
4
 
5
5
  const JOIN_KEYWORDS = {
6
6
  cross: "CROSS JOIN",
@@ -24,7 +24,7 @@ class SelectBuilder {
24
24
  limitValue;
25
25
  constructor(exec, table) {
26
26
  this.exec = exec;
27
- this.table = table;
27
+ this.table = tableRef(table);
28
28
  }
29
29
  /** The `SELECT` list. Omit/empty for `SELECT *`. Items are columns, expressions, or aliased window fragments (`fn.rowNumber().over(...).as("rk")`). */
30
30
  select(...items) {
@@ -156,7 +156,7 @@ class SelectBuilder {
156
156
  return this.distinctFlag ? "SELECT DISTINCT" : "SELECT";
157
157
  }
158
158
  addJoin(kind, table, on) {
159
- this.joins.push({ kind, on, table });
159
+ this.joins.push({ kind, on, table: tableRef(table) });
160
160
  return this;
161
161
  }
162
162
  setOperation(operator, other) {
@@ -1,5 +1,5 @@
1
- import { renderOrderTerm } from './asc-C6Jbaa6R.mjs';
2
- import { lit } from './Sql-CkDyJ_Sc.mjs';
1
+ import { renderOrderTerm } from './asc-Cur-xO8v.mjs';
2
+ import { lit } from './Sql-DceGtcUd.mjs';
3
3
 
4
4
  const renderMember = (query) => {
5
5
  const text = query.toSQL();
@@ -1,4 +1,6 @@
1
1
  const quoteString = (value) => `'${value.replaceAll("'", "''")}'`;
2
+ const IDENTIFIER_RE = /^\w+(?:\.\w+)*$/;
3
+ const TABLE_REF_RE = /^\w+(?:\.\w+)*(?:\s+(?:as\s+)?\w+)?$/i;
2
4
  class Sql {
3
5
  text;
4
6
  constructor(text) {
@@ -11,6 +13,18 @@ class Sql {
11
13
  const isSql = (value) => value instanceof Sql;
12
14
  const raw = (text) => new Sql(text);
13
15
  const toText = (value) => isSql(value) ? value.text : value;
16
+ const ident = (name) => {
17
+ if (typeof name !== "string" || !IDENTIFIER_RE.test(name)) {
18
+ throw new TypeError(`r2sql: invalid identifier ${JSON.stringify(name)} — expected dotted [A-Za-z0-9_] segments (e.g. "namespace.table").`);
19
+ }
20
+ return name;
21
+ };
22
+ const tableRef = (ref) => {
23
+ if (typeof ref !== "string" || !TABLE_REF_RE.test(ref)) {
24
+ throw new TypeError(`r2sql: invalid table reference ${JSON.stringify(ref)} — expected "namespace.table" with an optional "[AS] alias".`);
25
+ }
26
+ return ref;
27
+ };
14
28
  const lit = (value) => {
15
29
  if (value === null || value === void 0) {
16
30
  return "NULL";
@@ -51,4 +65,4 @@ const sql = (strings, ...values) => {
51
65
  };
52
66
  const joinSql = (parts, separator) => new Sql(parts.map((part) => toText(part)).join(separator));
53
67
 
54
- export { Sql, isSql, joinSql, lit, raw, sql, toText };
68
+ export { Sql, ident, isSql, joinSql, lit, raw, sql, tableRef, toText };
@@ -1,4 +1,4 @@
1
- import { Sql, lit } from './Sql-CkDyJ_Sc.mjs';
1
+ import { Sql, lit } from './Sql-DceGtcUd.mjs';
2
2
 
3
3
  const IDENTIFIER = /^[A-Z_][\w$]*$/i;
4
4
  const assertIdent = (name) => {
@@ -1,6 +1,6 @@
1
- import { renderOrderTerm } from './asc-C6Jbaa6R.mjs';
2
- import { lit, toText } from './Sql-CkDyJ_Sc.mjs';
3
- import WindowExpression from './WindowExpression-C2vj7oNX.mjs';
1
+ import { renderOrderTerm } from './asc-Cur-xO8v.mjs';
2
+ import { lit, toText } from './Sql-DceGtcUd.mjs';
3
+ import WindowExpression from './WindowExpression-Cg9s2xcr.mjs';
4
4
 
5
5
  const toArray = (value) => {
6
6
  if (value === void 0) {
@@ -1,4 +1,4 @@
1
- import { Sql, toText } from './Sql-CkDyJ_Sc.mjs';
1
+ import { Sql, toText } from './Sql-DceGtcUd.mjs';
2
2
 
3
3
  const asc = (expr) => {
4
4
  return { dir: "ASC", expr };
@@ -1,7 +1,7 @@
1
- export { default as SelectBuilder } from '../packem_shared/SelectBuilder-BGXfCF0J.mjs';
2
- export { R2SqlError, createR2Sql } from '../packem_shared/R2SqlError-DkQZ4Omg.mjs';
3
- export { asc, desc, renderOrderTerm } from '../packem_shared/asc-C6Jbaa6R.mjs';
4
- export { default as SetOperation } from '../packem_shared/SetOperation-CGRu681M.mjs';
5
- export { Sql, isSql, joinSql, lit, raw, sql, toText } from '../packem_shared/Sql-CkDyJ_Sc.mjs';
6
- export { WindowFunction, fn } from '../packem_shared/WindowFunction-CuKHfZX3.mjs';
7
- export { default as WindowExpression } from '../packem_shared/WindowExpression-C2vj7oNX.mjs';
1
+ export { default as SelectBuilder } from '../packem_shared/SelectBuilder-DHaXZwn_.mjs';
2
+ export { R2SqlError, createR2Sql } from '../packem_shared/R2SqlError-DlDd_SrE.mjs';
3
+ export { asc, desc, renderOrderTerm } from '../packem_shared/asc-Cur-xO8v.mjs';
4
+ export { default as SetOperation } from '../packem_shared/SetOperation-RDHcxccj.mjs';
5
+ export { Sql, isSql, joinSql, lit, raw, sql, toText } from '../packem_shared/Sql-DceGtcUd.mjs';
6
+ export { WindowFunction, fn } from '../packem_shared/WindowFunction-DA3pGC3N.mjs';
7
+ export { default as WindowExpression } from '../packem_shared/WindowExpression-Cg9s2xcr.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/bindings",
3
- "version": "1.0.0-alpha.1",
3
+ "version": "1.0.0-alpha.2",
4
4
  "description": "Lightweight Cloudflare binding helpers for Lunora — ctx.kv, ctx.images, ctx.analytics, ctx.pipelines, ctx.vectors, ctx.r2sql — one install, per-binding subpaths",
5
5
  "keywords": [
6
6
  "analytics",