rowstile 0.1.0-alpha.4 → 0.1.0-alpha.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.
package/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # rowstile
2
2
 
3
- Access rules for Postgres: a policy language that the `rowstile` command compiles into row-level security, and
4
- ships as migrations for your app's tool (Prisma, Drizzle Kit, Alembic, SQL files).
3
+ Authorization for Postgres apps: access rules in a policy language that the `rowstile` command compiles into
4
+ row-level security, and ships as migrations for your app's tool (Prisma, Drizzle Kit, Alembic, SQL files).
5
+ Sharing, groups, nested folders and tenants, with no service to run beside the database.
5
6
 
6
7
  npx rowstile init # a first policy from your tables, rowstile.toml, the SDK for your stack
7
8
  npx rowstile dev # on each save: check, apply to the development database, test, write the types
package/bin/rowstile.js CHANGED
@@ -64,7 +64,35 @@ function onPath() {
64
64
  return null;
65
65
  }
66
66
 
67
- const python = process.env.ROWSTILE_PYTHON || process.env.ROWFENCE_PYTHON || bundled() || onPath(); // ROWFENCE_PYTHON: the name before the rename
67
+ /** On Windows, a file of the bundled Python whose path is longer than Windows loads (259 characters, unless long
68
+ * paths are turned on): Python then stops with "DLL load failed ... The filename or extension is too long",
69
+ * from inside node_modules. Null when every file is within the limit.
70
+ * @param {string} exe @returns {string | null} */
71
+ function tooLong(exe) {
72
+ if (process.platform !== "win32") return null;
73
+ try {
74
+ const dlls = path.join(path.dirname(fs.realpathSync.native(exe)), "DLLs");
75
+ const longest = fs.readdirSync(dlls).map((f) => path.join(dlls, f)).sort((a, b) => b.length - a.length)[0];
76
+ if (!longest || longest.length <= 259) return null;
77
+ // with long paths turned on, or when only files the command never loads are past the limit, it runs all
78
+ // the same: ask it for the compiled modules the command uses
79
+ const probe = "import unicodedata, ssl, hashlib, socket, select, zlib, decimal";
80
+ return spawnSync(exe, ["-E", "-s", "-c", probe]).status === 0 ? null : longest;
81
+ } catch {
82
+ return null;
83
+ }
84
+ }
85
+
86
+ const own = process.env.ROWSTILE_PYTHON || process.env.ROWFENCE_PYTHON ? null : bundled(); // ROWFENCE_PYTHON: the name before the rename
87
+ const long = own && tooLong(own);
88
+ if (long && !onPath()) {
89
+ console.error(`rowstile: this project's path is too long for Windows to load the Python that came with the package ` +
90
+ `(${long.length} characters to ${path.basename(long)}; Windows loads up to 259). Move the project to a shorter path, ` +
91
+ "or turn long paths on in Windows (LongPathsEnabled), or install Python 3.11 or later: rowstile then runs on that one");
92
+ process.exit(1);
93
+ }
94
+ // a Python on PATH, when the bundled one can't be loaded from here
95
+ const python = process.env.ROWSTILE_PYTHON || process.env.ROWFENCE_PYTHON || (long ? null : own) || onPath();
68
96
  if (!python) {
69
97
  console.error(`rowstile: no Python to run on. The package for this platform (@rowstile/cli-${key}) isn't installed` +
70
98
  (PLATFORMS.includes(key) ? " (optional dependencies turned off?)" : `, and there is none for ${key}`) +
@@ -12,7 +12,7 @@ class Compiler(TestMixin, DevMixin, OutputMixin):
12
12
 
13
13
 
14
14
  # set with packaging/version.py (the packages copy it); authz.policy_versions records it on each apply
15
- __version__ = "0.1.0-alpha.4"
15
+ __version__ = "0.1.0-alpha.5"
16
16
 
17
17
 
18
18
  def _build() -> str:
@@ -115,7 +115,7 @@ def table_indexes(db: Db, table: str) -> list[tuple[str, ...]]:
115
115
  "SELECT array(SELECT a.attname::text FROM unnest(i.indkey::int2[]) WITH ORDINALITY k(n, o) "
116
116
  "LEFT JOIN pg_catalog.pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = k.n ORDER BY k.o) AS cols "
117
117
  "FROM pg_catalog.pg_index i WHERE i.indrelid = to_regclass($1) AND i.indpred IS NULL AND i.indisvalid",
118
- [table],
118
+ [qt(table)], # quoted: to_regclass folds a bare name to lower case, and "TeamMember" is then not found
119
119
  )
120
120
  out: list[tuple[str, ...]] = []
121
121
  for r in rows:
@@ -354,7 +354,7 @@ def plain_column(db: Db, c: Compiler, t: Type) -> str | None:
354
354
  rows = db.rows(
355
355
  "SELECT attname::text AS a FROM pg_catalog.pg_attribute WHERE attrelid = to_regclass($1) AND attnum > 0 "
356
356
  "AND NOT attisdropped AND attgenerated = '' ORDER BY attnum",
357
- [t.table],
357
+ [qt(t.table)],
358
358
  )
359
359
  return next((text(r, "a") for r in rows if r["a"] not in used), None)
360
360
 
package/package.json CHANGED
@@ -1,8 +1,29 @@
1
1
  {
2
2
  "name": "rowstile",
3
- "version": "0.1.0-alpha.4",
4
- "description": "Access rules for Postgres: the rowstile command (policies compiled to row-level security, shipped as migrations), with its own Python",
3
+ "version": "0.1.0-alpha.5",
4
+ "description": "Authorization for Postgres apps: the rowstile command (access rules compiled to row-level security, shipped as migrations), with its own Python",
5
5
  "license": "Apache-2.0",
6
+ "mcpName": "io.github.rowstile/rowstile",
7
+ "homepage": "https://rowstile.dev",
8
+ "keywords": [
9
+ "rowstile",
10
+ "postgres",
11
+ "postgresql",
12
+ "authorization",
13
+ "row-level-security",
14
+ "rls",
15
+ "permissions",
16
+ "access-control",
17
+ "rbac",
18
+ "rebac",
19
+ "multi-tenant",
20
+ "policy",
21
+ "migrations",
22
+ "cli",
23
+ "prisma",
24
+ "drizzle",
25
+ "alembic"
26
+ ],
6
27
  "repository": {
7
28
  "type": "git",
8
29
  "url": "git+https://github.com/rowstile/rowstile.git",
@@ -20,12 +41,12 @@
20
41
  "node": ">=18"
21
42
  },
22
43
  "optionalDependencies": {
23
- "@rowstile/cli-linux-x64": "0.1.0-alpha.4",
24
- "@rowstile/cli-linux-arm64": "0.1.0-alpha.4",
25
- "@rowstile/cli-linux-x64-musl": "0.1.0-alpha.4",
26
- "@rowstile/cli-linux-arm64-musl": "0.1.0-alpha.4",
27
- "@rowstile/cli-darwin-x64": "0.1.0-alpha.4",
28
- "@rowstile/cli-darwin-arm64": "0.1.0-alpha.4",
29
- "@rowstile/cli-win32-x64": "0.1.0-alpha.4"
44
+ "@rowstile/cli-linux-x64": "0.1.0-alpha.5",
45
+ "@rowstile/cli-linux-arm64": "0.1.0-alpha.5",
46
+ "@rowstile/cli-linux-x64-musl": "0.1.0-alpha.5",
47
+ "@rowstile/cli-linux-arm64-musl": "0.1.0-alpha.5",
48
+ "@rowstile/cli-darwin-x64": "0.1.0-alpha.5",
49
+ "@rowstile/cli-darwin-arm64": "0.1.0-alpha.5",
50
+ "@rowstile/cli-win32-x64": "0.1.0-alpha.5"
30
51
  }
31
52
  }