@absolutejs/sync-pack-utils 0.1.1 → 0.1.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.
- package/dist/index.js +16 -1
- package/dist/index.js.map +2 -2
- package/dist/manifest.d.ts +1 -0
- package/dist/manifest.js +8523 -0
- package/dist/manifest.js.map +123 -0
- package/dist/manifest.json +36 -0
- package/package.json +24 -4
package/dist/index.js
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
|
|
2
17
|
// src/index.ts
|
|
3
18
|
import {
|
|
4
19
|
UnauthorizedError
|
|
@@ -75,5 +90,5 @@ export {
|
|
|
75
90
|
createInMemoryStore
|
|
76
91
|
};
|
|
77
92
|
|
|
78
|
-
//# debugId=
|
|
93
|
+
//# debugId=D8470548C2FCAD2164756E2164756E21
|
|
79
94
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"/**\n * `@absolutejs/sync-pack-utils` — shared helpers extracted from the six\n * official `@absolutejs/sync` packs.\n *\n * Each helper closes one repeated pattern. The goal is to make new packs\n * (first- and third-party) cheaper to write and stop drift from the\n * standard shapes already shipped by presence / comments / digest /\n * notifications / favorites / counters.\n */\n\nimport {\n\tUnauthorizedError,\n\ttype CollectionContext,\n\ttype TableReader,\n\ttype TableWriter\n} from '@absolutejs/sync/engine';\n\n// ─── Actor resolution ────────────────────────────────────────────────────────\n\n/**\n * The conventional default — `(ctx) => ctx.userId`. Use as the fallback when\n * a pack's config doesn't supply its own `getActorId`.\n *\n * @example\n * const getActorId = config.getActorId ?? defaultGetActorId<MyCtx>();\n */\nexport const defaultGetActorId = <\n\tCtx = CollectionContext\n>(): ((ctx: Ctx) => string | undefined) =>\n\t(ctx) => (ctx as { userId?: string }).userId;\n\n/**\n * Resolve the caller's actor id from a ctx, or throw {@link UnauthorizedError}\n * with a descriptive message. Use inside mutation handlers that require an\n * actor; the message embeds your `context` string so error reports name the\n * pack and operation.\n *\n * @example\n * const actorId = resolveActor(getActorId, ctx, 'comments:create');\n */\nexport const resolveActor = <Ctx = CollectionContext>(\n\tgetActorId: (ctx: Ctx) => string | undefined,\n\tctx: unknown,\n\tcontext: string\n): string => {\n\tconst actorId = getActorId(ctx as Ctx);\n\tif (actorId === undefined || actorId === '') {\n\t\tthrow new UnauthorizedError(`${context} (no actor id)`);\n\t}\n\treturn actorId;\n};\n\n// ─── Permission builders ─────────────────────────────────────────────────────\n\n/**\n * Permission validator that requires `row[actorIdField] === getActorId(ctx)`.\n * Use for `insert` and `update` on rows the actor owns; the handler stamps\n * the actor on the row, so this is the canonical row-ownership check.\n *\n * @example\n * permissions: {\n * notifications: {\n * insert: requireRowOwner(getActorId, 'actorId'),\n * update: requireRowOwner(getActorId, 'actorId'),\n * },\n * },\n */\nexport const requireRowOwner =\n\t<Ctx = CollectionContext>(\n\t\tgetActorId: (ctx: Ctx) => string | undefined,\n\t\tactorIdField: string = 'actorId'\n\t) =>\n\t(ctx: unknown, row: unknown): boolean => {\n\t\tconst callerId = getActorId(ctx as Ctx);\n\t\tif (callerId === undefined) return false;\n\t\tconst rowActor = (row as Record<string, unknown>)[actorIdField];\n\t\treturn rowActor === callerId;\n\t};\n\n/**\n * Permission validator for delete (or any op) that accepts the row OR\n * just its id. Falls back to `store.getById(row.id)` when the row's actor\n * field isn't on the supplied subject — sync's engine passes only the\n * key to `actions.delete({ id })`, so this pattern is needed for every\n * owner-gated delete.\n *\n * Returns true when the row's owner matches the caller OR `canModerate(ctx)`\n * is `true`.\n *\n * @example\n * permissions: {\n * notifications: {\n * delete: requireOwnerOrModerator({\n * getActorId,\n * canModerate,\n * store, // { getById }\n * actorIdField: 'actorId',\n * }),\n * },\n * },\n */\nexport const requireOwnerOrModerator =\n\t<Ctx = CollectionContext>(options: {\n\t\tgetActorId: (ctx: Ctx) => string | undefined;\n\t\tcanModerate?: (ctx: Ctx) => boolean;\n\t\tstore: { getById: (id: string) => unknown };\n\t\tactorIdField?: string;\n\t}) =>\n\t(ctx: unknown, row: unknown): boolean => {\n\t\tconst {\n\t\t\tgetActorId,\n\t\t\tcanModerate,\n\t\t\tstore,\n\t\t\tactorIdField = 'actorId'\n\t\t} = options;\n\t\tconst callerId = getActorId(ctx as Ctx);\n\t\tif (callerId === undefined) return false;\n\t\tconst supplied = row as Record<string, unknown>;\n\t\tconst ownerId =\n\t\t\tsupplied[actorIdField] !== undefined\n\t\t\t\t? supplied[actorIdField]\n\t\t\t\t: (() => {\n\t\t\t\t\t\tconst id = supplied.id;\n\t\t\t\t\t\tif (typeof id !== 'string') return undefined;\n\t\t\t\t\t\tconst stored = store.getById(id) as\n\t\t\t\t\t\t\t| Record<string, unknown>\n\t\t\t\t\t\t\t| undefined;\n\t\t\t\t\t\treturn stored?.[actorIdField];\n\t\t\t\t\t})();\n\t\tif (ownerId === undefined) return false;\n\t\tif (ownerId === callerId) return true;\n\t\treturn canModerate !== undefined ? canModerate(ctx as Ctx) : false;\n\t};\n\n// ─── In-memory store ────────────────────────────────────────────────────────\n\n/**\n * Standard in-memory store for a pack table. Every row needs an `id: string`\n * (the table's primary key); the writer is upsert-by-id. Used by every\n * official pack as the default backing store.\n */\nexport type InMemoryStore<Row extends { id: string }> = {\n\treader: TableReader<CollectionContext>;\n\twriter: TableWriter<Row, CollectionContext, unknown>;\n\t/** Lookup by id — convenient for permission and mutation handlers. */\n\tgetById: (id: string) => Row | undefined;\n\t/** Direct read of the underlying Map for advanced use; treat as read-only. */\n\trows: Map<string, Row>;\n};\n\n/**\n * Build a fresh, isolated in-memory store. Each call gets its own Map, so\n * two pack instances on the same engine don't share state.\n *\n * @example\n * const store = config.store ?? createInMemoryStore<NotificationRow>();\n */\nexport const createInMemoryStore = <\n\tRow extends { id: string }\n>(): InMemoryStore<Row> => {\n\tconst rows = new Map<string, Row>();\n\treturn {\n\t\tgetById: (id) => rows.get(id),\n\t\treader: {\n\t\t\tall: () => [...rows.values()]\n\t\t},\n\t\trows,\n\t\twriter: {\n\t\t\tdelete: (row) => {\n\t\t\t\trows.delete((row as { id: string }).id);\n\t\t\t},\n\t\t\tinsert: (data) => {\n\t\t\t\trows.set(data.id, data);\n\t\t\t\treturn data;\n\t\t\t},\n\t\t\tupdate: (data) => {\n\t\t\t\tconst prior = rows.get(data.id);\n\t\t\t\tconst merged = { ...(prior ?? {}), ...data } as Row;\n\t\t\t\trows.set(data.id, merged);\n\t\t\t\treturn merged;\n\t\t\t}\n\t\t}\n\t};\n};\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;AAUA;AAAA;AAAA;AAgBO,IAAM,oBAAoB,MAGhC,CAAC,QAAS,IAA4B;AAWhC,IAAM,eAAe,CAC3B,YACA,KACA,YACY;AAAA,EACZ,MAAM,UAAU,WAAW,GAAU;AAAA,EACrC,IAAI,YAAY,aAAa,YAAY,IAAI;AAAA,IAC5C,MAAM,IAAI,kBAAkB,GAAG,uBAAuB;AAAA,EACvD;AAAA,EACA,OAAO;AAAA;AAkBD,IAAM,kBACZ,CACC,YACA,eAAuB,cAExB,CAAC,KAAc,QAA0B;AAAA,EACxC,MAAM,WAAW,WAAW,GAAU;AAAA,EACtC,IAAI,aAAa;AAAA,IAAW,OAAO;AAAA,EACnC,MAAM,WAAY,IAAgC;AAAA,EAClD,OAAO,aAAa;AAAA;AAyBf,IAAM,0BACZ,CAA0B,YAM1B,CAAC,KAAc,QAA0B;AAAA,EACxC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe;AAAA,MACZ;AAAA,EACJ,MAAM,WAAW,WAAW,GAAU;AAAA,EACtC,IAAI,aAAa;AAAA,IAAW,OAAO;AAAA,EACnC,MAAM,WAAW;AAAA,EACjB,MAAM,UACL,SAAS,kBAAkB,YACxB,SAAS,iBACR,MAAM;AAAA,IACP,MAAM,KAAK,SAAS;AAAA,IACpB,IAAI,OAAO,OAAO;AAAA,MAAU;AAAA,IAC5B,MAAM,SAAS,MAAM,QAAQ,EAAE;AAAA,IAG/B,OAAO,SAAS;AAAA,KACd;AAAA,EACN,IAAI,YAAY;AAAA,IAAW,OAAO;AAAA,EAClC,IAAI,YAAY;AAAA,IAAU,OAAO;AAAA,EACjC,OAAO,gBAAgB,YAAY,YAAY,GAAU,IAAI;AAAA;AA0BxD,IAAM,sBAAsB,MAER;AAAA,EAC1B,MAAM,OAAO,IAAI;AAAA,EACjB,OAAO;AAAA,IACN,SAAS,CAAC,OAAO,KAAK,IAAI,EAAE;AAAA,IAC5B,QAAQ;AAAA,MACP,KAAK,MAAM,CAAC,GAAG,KAAK,OAAO,CAAC;AAAA,IAC7B;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,MACP,QAAQ,CAAC,QAAQ;AAAA,QAChB,KAAK,OAAQ,IAAuB,EAAE;AAAA;AAAA,MAEvC,QAAQ,CAAC,SAAS;AAAA,QACjB,KAAK,IAAI,KAAK,IAAI,IAAI;AAAA,QACtB,OAAO;AAAA;AAAA,MAER,QAAQ,CAAC,SAAS;AAAA,QACjB,MAAM,QAAQ,KAAK,IAAI,KAAK,EAAE;AAAA,QAC9B,MAAM,SAAS,KAAM,SAAS,CAAC,MAAO,KAAK;AAAA,QAC3C,KAAK,IAAI,KAAK,IAAI,MAAM;AAAA,QACxB,OAAO;AAAA;AAAA,IAET;AAAA,EACD;AAAA;",
|
|
8
|
+
"debugId": "D8470548C2FCAD2164756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const manifest: import("@absolutejs/manifest").PackageManifest<Record<never, never>, never>;
|