@somewhere-tech/cli 0.33.0 → 0.33.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/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@somewhere-tech/cli",
|
|
3
|
-
"version": "0.33.
|
|
3
|
+
"version": "0.33.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@somewhere-tech/cli",
|
|
9
|
-
"version": "0.33.
|
|
9
|
+
"version": "0.33.1",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"@modelcontextprotocol/sdk",
|
|
12
12
|
"chokidar",
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"esbuild": "0.24.0",
|
|
3
3
|
"source_files": {
|
|
4
|
-
"worker/containers/compile/declared-data-contract.cjs": "
|
|
4
|
+
"worker/containers/compile/declared-data-contract.cjs": "b91609429f4e54d54a80848db8cf13b5e1965625c45f423f56e51e941c5daf9c",
|
|
5
5
|
"worker/containers/compile/runtime-types.cjs": "a458232f605ac60202b58c6cae725a813d22479498f436668b8ad553678576ef",
|
|
6
|
-
"worker/containers/compile/schema-types.cjs": "
|
|
6
|
+
"worker/containers/compile/schema-types.cjs": "d6985d40a1f4462615eb65e0350fdd23d53de7c4beaa3ff574e45a036fbdec3e",
|
|
7
7
|
"worker/containers/compile/typed-data.cjs": "57b458e16a373e42d48a0e527317fcdf609299ae368eb539a8b582b9a47abb15",
|
|
8
|
-
"worker/src/utils/authority/scope-enforcement.ts": "
|
|
8
|
+
"worker/src/utils/authority/scope-enforcement.ts": "25c4aa81f0d2dd4b58784c0ada03c041ce48b66728b52cfee3790a841aba766c",
|
|
9
9
|
"worker/src/utils/db-schema-deploy/client-contract-source.ts": "fc37a8d18affc0d814f40357884e1764eb4bcc9af446626933729b7021fa3c6d",
|
|
10
10
|
"worker/src/utils/db-schema-deploy/client-permissions.ts": "05b1d68afae151569abfa16b452834a96b3c0a2bf4b04f63d322f05548827222",
|
|
11
|
-
"worker/src/utils/db-schema-deploy/extract-schema-ts.ts": "
|
|
11
|
+
"worker/src/utils/db-schema-deploy/extract-schema-ts.ts": "0da51e6884afbbf9b04104f9bf669f0d0163d7cb2b5723a6e9df05b661115a1e",
|
|
12
12
|
"worker/src/utils/db-schema-deploy/schema-ownership.ts": "e6c811a87bc657707be3518dfe547c6d97718ac073108b126eb7f791c9c08202"
|
|
13
13
|
},
|
|
14
|
-
"sha256": "
|
|
14
|
+
"sha256": "b9f9cf5b17aa489ddc8ba9937a268a369ec73c91769f90eb20ab38ebc750f4c9"
|
|
15
15
|
}
|
|
@@ -54,9 +54,11 @@ var require_declared_data_contract = __commonJS({
|
|
|
54
54
|
if (value.k === "o" && keys === "c,k" && identifier.test(value.c)) return { k: "o", c: value.c };
|
|
55
55
|
if (value.k === "m" && keys === "k,m") {
|
|
56
56
|
record(value.m, label + ".member");
|
|
57
|
-
const { g, m, u, mg } = value.m;
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
const { g, m, u, mg, o } = value.m;
|
|
58
|
+
const memberKeys = Object.keys(value.m).sort().join(",");
|
|
59
|
+
if (!["g,m,mg,u", "g,m,mg,o,u"].includes(memberKeys) || !identifier.test(m) || !identifier.test(u) || !Array.isArray(g) || !g.length || !Array.isArray(mg) || g.length !== mg.length || [...g, ...mg].some((field) => typeof field !== "string" || !identifier.test(field)) || o !== void 0 && (!Array.isArray(o) || JSON.stringify(o) !== JSON.stringify(["read", "create", "update", "delete"].filter((operation) => o.includes(operation))) || !o.includes("read") && (o.includes("update") || o.includes("delete")))) fail(label);
|
|
60
|
+
const normalizedOperations = o?.length === 4 ? void 0 : o;
|
|
61
|
+
return { k: "m", m: { g: [...g], m, u, mg: [...mg], ...normalizedOperations !== void 0 ? { o: [...normalizedOperations] } : {} } };
|
|
60
62
|
}
|
|
61
63
|
if (value.k === "a" && keys === "k,p" && Array.isArray(value.p) && value.p.length === 2) {
|
|
62
64
|
const left = policy(value.p[0], label), right = policy(value.p[1], label);
|
|
@@ -146,12 +148,14 @@ var require_declared_data_contract = __commonJS({
|
|
|
146
148
|
let member = null;
|
|
147
149
|
if (intent === "member") {
|
|
148
150
|
record(table.member, `${name}.member`);
|
|
149
|
-
const { g, m, u, mg } = table.member;
|
|
151
|
+
const { g, m, u, mg, o } = table.member;
|
|
150
152
|
if (typeof m !== "string" || typeof u !== "string" || !identifier.test(m) || !identifier.test(u) || !Array.isArray(mg) || mg.some((field) => typeof field !== "string" || !identifier.test(field))) fail(`${name}.member`);
|
|
151
153
|
fields(g, seen, `${name}.member.g`);
|
|
152
154
|
if (g.length !== mg.length || new Set(mg).size !== mg.length) fail(`${name}.member`);
|
|
153
155
|
if ((update || []).some((field) => g.includes(field))) fail(`${name} membership writes`);
|
|
154
|
-
|
|
156
|
+
if (o !== void 0 && (!Array.isArray(o) || JSON.stringify(o) !== JSON.stringify(["read", "create", "update", "delete"].filter((operation) => o.includes(operation))) || !o.includes("read") && (o.includes("update") || o.includes("delete")))) fail(`${name}.member operations`);
|
|
157
|
+
const normalizedOperations = o?.length === 4 ? void 0 : o;
|
|
158
|
+
member = { g: [...g], m, u, mg: [...mg], ...normalizedOperations !== void 0 ? { o: [...normalizedOperations] } : {} };
|
|
155
159
|
}
|
|
156
160
|
const normalizedPolicy = intent === "policy" ? policy(table.policy, `${name}.policy`) : null;
|
|
157
161
|
if (normalizedPolicy && !["a", "p"].includes(normalizedPolicy.k)) fail(`${name}.policy root`);
|
|
@@ -346,7 +350,7 @@ function blob(options?: SomewhereSchemaDeclaration.ColumnOptions<never>): Somewh
|
|
|
346
350
|
function owner(options?: { column?: string; visitors?: boolean }): SomewhereSchemaDeclaration.OwnerScope;
|
|
347
351
|
function shared(): SomewhereSchemaDeclaration.Scope;
|
|
348
352
|
function serverOnly(): SomewhereSchemaDeclaration.Scope;
|
|
349
|
-
function member(options: { group: string | string[]; membership: string; member_user: string; member_group: string | string[] }): SomewhereSchemaDeclaration.MemberScope;
|
|
353
|
+
function member(options: { group: string | string[]; membership: string; member_user: string; member_group: string | string[]; operations?: Array<'read' | 'create' | 'update' | 'delete'> }): SomewhereSchemaDeclaration.MemberScope;
|
|
350
354
|
function hasMany(table: string, foreignKey: string): SomewhereSchemaDeclaration.Relation;
|
|
351
355
|
function removed(): SomewhereSchemaDeclaration.ColumnMarker;
|
|
352
356
|
function removedTable(): SomewhereSchemaDeclaration.TableMarker;
|
|
@@ -732,7 +736,15 @@ function bakedMemberFromDeclared(scope) {
|
|
|
732
736
|
if (!g || !mg || g.length !== mg.length) return null;
|
|
733
737
|
if (typeof s.membership !== "string" || !SAFE_SCOPE_IDENTIFIER.test(s.membership)) return null;
|
|
734
738
|
if (typeof s.memberUser !== "string" || !SAFE_SCOPE_IDENTIFIER.test(s.memberUser)) return null;
|
|
735
|
-
|
|
739
|
+
let o;
|
|
740
|
+
if (s.operations !== void 0) {
|
|
741
|
+
if (!Array.isArray(s.operations)) return null;
|
|
742
|
+
const operations = s.operations;
|
|
743
|
+
const allowed = ["read", "create", "update", "delete"];
|
|
744
|
+
if (JSON.stringify(operations) !== JSON.stringify(allowed.filter((operation) => operations.includes(operation))) || !operations.includes("read") && (operations.includes("update") || operations.includes("delete"))) return null;
|
|
745
|
+
o = operations.length === allowed.length ? void 0 : operations;
|
|
746
|
+
}
|
|
747
|
+
return { g, m: s.membership.toLowerCase(), u: s.memberUser.toLowerCase(), mg, ...o !== void 0 ? { o } : {} };
|
|
736
748
|
}
|
|
737
749
|
|
|
738
750
|
// worker/src/utils/db-schema-deploy/extract-schema-ts.ts
|
|
@@ -771,6 +783,7 @@ var MAX_INDEX_COLUMNS = 8;
|
|
|
771
783
|
var MAX_NAME_LENGTH = 64;
|
|
772
784
|
var MAX_SOURCE_BYTES = 256 * 1024;
|
|
773
785
|
var DEFAULT_OWNER_COLUMN = "user_id";
|
|
786
|
+
var MEMBER_OPERATIONS = ["read", "create", "update", "delete"];
|
|
774
787
|
var SchemaTsError = class extends Error {
|
|
775
788
|
};
|
|
776
789
|
function tokenize(source) {
|
|
@@ -1166,12 +1179,33 @@ function validateMemberColumns(names, optionLabel, tableName, line) {
|
|
|
1166
1179
|
seen.add(name);
|
|
1167
1180
|
}
|
|
1168
1181
|
}
|
|
1182
|
+
function readMemberOperations(r, tableName) {
|
|
1183
|
+
r.expectPunct("[", `for member({ operations }) on table "${tableName}"`);
|
|
1184
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1185
|
+
while (!r.tryPunct("]")) {
|
|
1186
|
+
const token = r.next();
|
|
1187
|
+
if (token.kind !== "string" || !MEMBER_OPERATIONS.includes(token.value)) {
|
|
1188
|
+
throw new SchemaTsError(`line ${token.line}: member({ operations }) on table "${tableName}" only accepts 'read', 'create', 'update', and 'delete'.`);
|
|
1189
|
+
}
|
|
1190
|
+
seen.add(token.value);
|
|
1191
|
+
if (!r.tryPunct(",")) {
|
|
1192
|
+
r.expectPunct("]", `closing member({ operations }) on table "${tableName}"`);
|
|
1193
|
+
break;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
const normalized = MEMBER_OPERATIONS.filter((operation) => seen.has(operation));
|
|
1197
|
+
if (!seen.has("read") && (seen.has("update") || seen.has("delete"))) {
|
|
1198
|
+
throw new SchemaTsError(`member({ operations }) on table "${tableName}" must include 'read' when it includes 'update' or 'delete', because mutations return the affected row.`);
|
|
1199
|
+
}
|
|
1200
|
+
return normalized.length === MEMBER_OPERATIONS.length ? void 0 : normalized;
|
|
1201
|
+
}
|
|
1169
1202
|
function readMemberScope(r, tableName, scopeLine) {
|
|
1170
1203
|
r.expectPunct("{", `in member() options for table "${tableName}" \u2014 member() needs { group, membership, member_user, member_group }`);
|
|
1171
1204
|
let group = null;
|
|
1172
1205
|
let membership = null;
|
|
1173
1206
|
let memberUser = null;
|
|
1174
1207
|
let memberGroup = null;
|
|
1208
|
+
let operations, operationsSeen = false;
|
|
1175
1209
|
while (!r.tryPunct("}")) {
|
|
1176
1210
|
const key = r.readKey(`for a member() option of table "${tableName}"`);
|
|
1177
1211
|
r.expectPunct(":", `after "${key.name}" in member() for table "${tableName}"`);
|
|
@@ -1183,9 +1217,13 @@ function readMemberScope(r, tableName, scopeLine) {
|
|
|
1183
1217
|
memberUser = readSingleColumn(r, `member({ member_user }) on table "${tableName}"`);
|
|
1184
1218
|
} else if (key.name === "member_group") {
|
|
1185
1219
|
memberGroup = readColumnOrColumnList(r, `member({ member_group }) on table "${tableName}"`);
|
|
1220
|
+
} else if (key.name === "operations") {
|
|
1221
|
+
if (operationsSeen) throw new SchemaTsError(`line ${key.line}: member() on table "${tableName}" declares operations more than once.`);
|
|
1222
|
+
operationsSeen = true;
|
|
1223
|
+
operations = readMemberOperations(r, tableName);
|
|
1186
1224
|
} else {
|
|
1187
1225
|
throw new SchemaTsError(
|
|
1188
|
-
`line ${key.line}: member() on table "${tableName}" has an unknown option "${key.name}". Allowed: group, membership, member_user, member_group.`
|
|
1226
|
+
`line ${key.line}: member() on table "${tableName}" has an unknown option "${key.name}". Allowed: group, membership, member_user, member_group, operations.`
|
|
1189
1227
|
);
|
|
1190
1228
|
}
|
|
1191
1229
|
if (!r.tryPunct(",")) {
|
|
@@ -1215,7 +1253,7 @@ function readMemberScope(r, tableName, scopeLine) {
|
|
|
1215
1253
|
`line ${scopeLine}: member() on table "${tableName}" has a ${group.length}-column group but a ${memberGroup.length}-column member_group. The group key must have the same number of columns on both sides.`
|
|
1216
1254
|
);
|
|
1217
1255
|
}
|
|
1218
|
-
return { kind: "member", group, membership, memberUser, memberGroup };
|
|
1256
|
+
return { kind: "member", group, membership, memberUser, memberGroup, ...operations !== void 0 ? { operations } : {} };
|
|
1219
1257
|
}
|
|
1220
1258
|
function readPolicyOwner(r, tableName, line) {
|
|
1221
1259
|
r.expectPunct("(", 'after "owner"');
|