@mauroandre/weave-sdk 0.0.1 → 0.0.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/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # @mauroandre/weave-sdk
2
+
3
+ Typed object client for [Weave](https://github.com/mauro-andre/weave) — a code-first
4
+ object abstraction over PostgreSQL. You think in nested objects; the SDK speaks HTTP
5
+ to the Weave server for you. **No SQL, no REST plumbing, no hand-written result types.**
6
+
7
+ The Weave server itself runs as a container (`ghcr.io/mauro-andre/weave`) — it holds
8
+ your entities, data, and access rules. This package is what your application installs
9
+ to talk to it.
10
+
11
+ ```bash
12
+ npm install @mauroandre/weave-sdk
13
+ ```
14
+
15
+ ## Quick start
16
+
17
+ ```ts
18
+ import { createClient } from "@mauroandre/weave-sdk";
19
+ import { product, category } from "./weave/entities";
20
+
21
+ const weave = createClient({
22
+ url: process.env.WEAVE_URL!,
23
+ key: process.env.WEAVE_KEY!,
24
+ entities: { product, category },
25
+ });
26
+
27
+ const cat = await weave.category.create({ name: "Books" });
28
+ const p = await weave.product.create({ name: "Clean Code", price: 80, categoryId: cat.id });
29
+
30
+ const found = await weave.product.find({
31
+ where: { price: { gte: 50 }, category: { name: { ilike: "%book%" } } },
32
+ orderBy: { price: "desc" },
33
+ expand: { category: true },
34
+ });
35
+
36
+ found[0].price; // number — inferred
37
+ found[0].createdAt; // Date — revived from JSON
38
+ found[0].category.name; // string — typed & present, only because you expanded it
39
+ ```
40
+
41
+ CRUD per entity: `create` · `get` · `find` · `findOne` · `paginate` · `update` ·
42
+ `delete`. The return type **self-types by your `expand`**, so you never write a
43
+ result type by hand.
44
+
45
+ ## One query language
46
+
47
+ `where` / `orderBy` / `expand` are the same object language everywhere — the GUI
48
+ click, the SDK call, and the stored access rule all speak it. A taste:
49
+
50
+ ```ts
51
+ await weave.order.find({
52
+ where: {
53
+ or: [{ status: { eq: "paid" } }, { total: { gte: 1000 } }],
54
+ items: { some: { product: { name: { ilike: "%pro%" } } } }, // any item matches
55
+ },
56
+ orderBy: { customer: { name: "asc" } }, // nested sort
57
+ });
58
+ ```
59
+
60
+ ## Entities as code
61
+
62
+ Declare entities with the same builders the server uses — one file, one entity:
63
+
64
+ ```ts
65
+ // weave/entities/product.ts
66
+ import { defineEntity, text, int4, reference } from "@mauroandre/weave-sdk";
67
+ import category from "./category.js";
68
+
69
+ export default defineEntity("product", {
70
+ name: text().notNull(),
71
+ price: int4(),
72
+ category: reference(category),
73
+ });
74
+ ```
75
+
76
+ ## The CLI — code ↔ server
77
+
78
+ `url`/`key` come from the environment (`WEAVE_URL`, `WEAVE_KEY`). A `weave.config.ts`
79
+ holds structural decisions — where the generated folder lives (default `weave/`):
80
+
81
+ ```ts
82
+ import { defineConfig } from "@mauroandre/weave-sdk";
83
+ export default defineConfig({ dir: "weave" });
84
+ ```
85
+
86
+ ```bash
87
+ weave push # entities (plan → apply) + scopes, then re-gen locally
88
+ weave push --confirm product.legacy # confirm a destructive drop
89
+ weave push --fill product.sku="N/A" # backfill a new required field
90
+ weave push --rename product.name=title # a rename: data preserved, not drop+add
91
+ weave push --no-gen # apply to the server but don't touch local files (CI)
92
+ weave gen # regenerate the whole weave/ folder from the server
93
+ ```
94
+
95
+ The server is the source of truth. `weave push` sends your code to it (the server
96
+ diffs and applies, with risk buckets: 🟢 auto · 🔴 confirm · 🟡 needs value · ⛔
97
+ blocked). `weave gen` mirrors the server back into readable `.ts` — entity files
98
+ (each field carrying its stable `$id`), scope files, barrels, and a ready `weave`
99
+ client. You can author in the GUI **or** in code, mixed.
100
+
101
+ ## Access control as code
102
+
103
+ A scope shapes access per entity — which **verbs**, which **rows**, which **fields**.
104
+ You write it by name; the server stores it by stable field-id (rename-proof).
105
+
106
+ ```ts
107
+ // weave/scopes/storefront.ts
108
+ import { defineScope } from "@mauroandre/weave-sdk";
109
+
110
+ export default defineScope("storefront", {
111
+ product: { verbs: ["read"], where: { active: { eq: true } }, fields: { exclude: ["cost"] } },
112
+ });
113
+ ```
114
+
115
+ Act under a scope at request time:
116
+
117
+ ```ts
118
+ const tenant = weave.as("storefront", { tenantId: ctx.tenant });
119
+ await tenant.product.find(); // server enforces the scope's rows + fields
120
+ ```
121
+
122
+ ## License
123
+
124
+ MIT © Mauro André
package/dist/cli.js CHANGED
@@ -9,7 +9,9 @@ import {
9
9
 
10
10
  // src/cli.ts
11
11
  import path2 from "path";
12
+ import { realpathSync } from "fs";
12
13
  import { pathToFileURL as pathToFileURL2 } from "url";
14
+ import { createJiti } from "jiti";
13
15
 
14
16
  // src/discover.ts
15
17
  import fs from "fs/promises";
@@ -52,6 +54,18 @@ async function defaultClean(dir) {
52
54
  const fs2 = await import("fs/promises");
53
55
  await fs2.rm(dir, { recursive: true, force: true });
54
56
  }
57
+ var jiti = null;
58
+ var defaultLoad = (p) => {
59
+ jiti ??= createJiti(import.meta.url);
60
+ return jiti.import(p);
61
+ };
62
+ function loadEnv(cwd) {
63
+ try {
64
+ process.loadEnvFile(path2.resolve(cwd, ".env"));
65
+ } catch {
66
+ }
67
+ return process.env;
68
+ }
55
69
  function splitEntity(s) {
56
70
  if (!s) return ["", ""];
57
71
  const i = s.indexOf(".");
@@ -82,9 +96,9 @@ var riskIcon = (r) => r === "auto" ? "\u{1F7E2}" : r === "confirm" ? "\u{1F534}"
82
96
  async function runCli(argv, deps = {}) {
83
97
  const args = parseArgs(argv);
84
98
  const log = deps.log ?? ((m) => console.log(m));
85
- const load = deps.load ?? ((p) => import(pathToFileURL2(p).href));
86
99
  const cwd = deps.cwd ?? process.cwd();
87
- const env = deps.env ?? process.env;
100
+ const load = deps.load ?? defaultLoad;
101
+ const env = deps.env ?? loadEnv(cwd);
88
102
  if (!["push", "pull", "gen"].includes(args.command)) {
89
103
  log(`Unknown command '${args.command}'. Try: weave push | pull | gen`);
90
104
  return 1;
@@ -156,8 +170,12 @@ async function runCli(argv, deps = {}) {
156
170
  async function main() {
157
171
  process.exit(await runCli(process.argv.slice(2)));
158
172
  }
159
- if (process.argv[1] && import.meta.url === pathToFileURL2(process.argv[1]).href) {
160
- void main();
173
+ if (process.argv[1]) {
174
+ try {
175
+ const invoked = pathToFileURL2(realpathSync(process.argv[1])).href;
176
+ if (invoked === import.meta.url) void main();
177
+ } catch {
178
+ }
161
179
  }
162
180
  export {
163
181
  discoverEntities,
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/discover.ts"],"sourcesContent":["#!/usr/bin/env node\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { discoverEntities, discoverScopes, type ModuleLoader } from \"./discover.js\";\nimport { pushEntities } from \"./push.js\";\nimport { pushScopes } from \"./scope.js\";\nimport { pullEntities, genProject } from \"./gen.js\";\nimport { DEFAULT_DIR, type WeaveConfig } from \"./config.js\";\n\n// Barrel node-only (`@mauroandre/weave-sdk/cli`): a descoberta usa `node:fs`, então\n// fica fora do barrel principal (que é portável p/ browser).\nexport { discoverEntities, discoverScopes, type ModuleLoader } from \"./discover.js\";\n\n/** Escreve um arquivo (criando dirs). Injetável pra teste. */\nasync function defaultWrite(file: string, content: string): Promise<void> {\n const fs = await import(\"node:fs/promises\");\n await fs.mkdir(path.dirname(file), { recursive: true });\n await fs.writeFile(file, content, \"utf8\");\n}\n\n/** Apaga uma pasta recursivamente (idempotente). Injetável pra teste. */\nasync function defaultClean(dir: string): Promise<void> {\n const fs = await import(\"node:fs/promises\");\n await fs.rm(dir, { recursive: true, force: true });\n}\nimport type { FetchLike } from \"./client.js\";\n\n// CLI `weave`. Comandos: `gen` (server → pasta weave/: entidades com $id, scopes,\n// barrels e client — overwrite cego), `push` (código → server, plan/apply em ordem\n// de dep), `pull` (legado: só entidades). url/key vêm do ambiente (WEAVE_URL/\n// WEAVE_KEY); a pasta de destino do `weave.config.ts` (`dir`, default \"weave\").\n// Flags: --config, --confirm, --fill, --rename. Carrega TS via runtime TS-capaz\n// (Node 22.6+ com --experimental-strip-types, ou tsx/jiti).\n\nexport interface ParsedArgs {\n command: string;\n config: string;\n confirm: Record<string, string[]>;\n fill: Record<string, Record<string, unknown>>;\n renames: Record<string, Record<string, string>>;\n /** `--no-gen`: após o push, NÃO re-sincroniza os arquivos locais (CI, read-only). */\n noGen: boolean;\n}\n\n/** \"product.legacy\" → [\"product\", \"legacy\"]; \"product.items.qty\" → [\"product\",\"items.qty\"]. */\nfunction splitEntity(s: string | undefined): [string, string] {\n if (!s) return [\"\", \"\"];\n const i = s.indexOf(\".\");\n return i < 0 ? [s, \"\"] : [s.slice(0, i), s.slice(i + 1)];\n}\n\nexport function parseArgs(argv: string[]): ParsedArgs {\n const out: ParsedArgs = { command: argv[0] ?? \"\", config: \"weave.config.ts\", confirm: {}, fill: {}, renames: {}, noGen: false };\n for (let i = 1; i < argv.length; i++) {\n const a = argv[i];\n if (a === \"--config\") out.config = argv[++i] ?? out.config;\n else if (a === \"--no-gen\") out.noGen = true;\n else if (a === \"--confirm\") {\n const [e, p] = splitEntity(argv[++i]);\n if (e && p) (out.confirm[e] ??= []).push(p);\n } else if (a === \"--fill\") {\n const [ep, v = \"\"] = (argv[++i] ?? \"\").split(/=(.*)/s);\n const [e, p] = splitEntity(ep);\n if (e && p) (out.fill[e] ??= {})[p] = v;\n } else if (a === \"--rename\") {\n const [ep, to = \"\"] = (argv[++i] ?? \"\").split(/=(.*)/s);\n const [e, p] = splitEntity(ep);\n if (e && p && to) (out.renames[e] ??= {})[p] = to;\n }\n }\n return out;\n}\n\nexport interface CliDeps {\n /** Importador de módulo (config + entidades). Default: dynamic import. */\n load?: ModuleLoader;\n /** Transporte HTTP. Default: globalThis.fetch. */\n fetch?: FetchLike;\n /** Escreve arquivo (pull/gen). Default: fs. */\n write?: (file: string, content: string) => Promise<void>;\n /** Apaga pasta (gen, antes de reescrever). Default: fs.rm. */\n clean?: (dir: string) => Promise<void>;\n /** Variáveis de ambiente (WEAVE_URL/WEAVE_KEY). Default: process.env. */\n env?: Record<string, string | undefined>;\n cwd?: string;\n log?: (msg: string) => void;\n}\n\nconst riskIcon = (r: string): string =>\n r === \"auto\" ? \"🟢\" : r === \"confirm\" ? \"🔴\" : r === \"needsValue\" ? \"🟡\" : \"⛔\";\n\n/** Roda o CLI. Devolve o exit code (0 ok; 1 erro / precisa de revisão). */\nexport async function runCli(argv: string[], deps: CliDeps = {}): Promise<number> {\n const args = parseArgs(argv);\n const log = deps.log ?? ((m: string) => console.log(m));\n const load: ModuleLoader = deps.load ?? ((p) => import(pathToFileURL(p).href));\n const cwd = deps.cwd ?? process.cwd();\n const env = deps.env ?? process.env;\n\n if (![\"push\", \"pull\", \"gen\"].includes(args.command)) {\n log(`Unknown command '${args.command}'. Try: weave push | pull | gen`);\n return 1;\n }\n\n const url = env[\"WEAVE_URL\"];\n const key = env[\"WEAVE_KEY\"];\n if (!url || !key) {\n log(\"Set WEAVE_URL and WEAVE_KEY in the environment.\");\n return 1;\n }\n\n // Config é opcional (só `dir`, default \"weave\"); ausente/ilegível → defaults.\n const configPath = path.resolve(cwd, args.config);\n let config: WeaveConfig = {};\n try {\n config = ((await load(configPath)).default ?? {}) as WeaveConfig;\n } catch {\n /* sem weave.config.ts — usa defaults */\n }\n const dirRel = config.dir ?? DEFAULT_DIR;\n const dir = path.resolve(cwd, dirRel);\n const entitiesDir = path.join(dir, \"entities\");\n const net = { url, key, ...(deps.fetch ? { fetch: deps.fetch } : {}) };\n const write = deps.write ?? defaultWrite;\n const clean = deps.clean ?? defaultClean;\n\n // Regenera a pasta weave/ a partir do server (overwrite cego). Usado pelo `gen`\n // e ao fim do `push` (re-sincroniza os $id recém-cunhados), salvo `--no-gen`.\n const regen = async (): Promise<void> => {\n const { files, entities, scopes } = await genProject(net);\n await clean(path.join(dir, \"entities\"));\n await clean(path.join(dir, \"scopes\"));\n for (const [rel, content] of Object.entries(files)) await write(path.join(dir, rel), content);\n log(`✓ generated ${entities.length} ${entities.length === 1 ? \"entity\" : \"entities\"}, ${scopes.length} ${scopes.length === 1 ? \"scope\" : \"scopes\"} → ${dirRel}/`);\n };\n\n // gen: server → pasta weave/ inteira (arquivos com $id, scopes resolvidos, barrels, client).\n if (args.command === \"gen\") {\n await regen();\n return 0;\n }\n\n // pull (legado): puxa os IRs remotos → escreve os arquivos de entidade (sem $id).\n if (args.command === \"pull\") {\n const { files, names } = await pullEntities(net);\n for (const [file, content] of Object.entries(files)) await write(path.join(entitiesDir, file), content);\n log(`✓ pulled ${names.length} ${names.length === 1 ? \"entity\" : \"entities\"} → ${dirRel}/entities`);\n return 0;\n }\n\n // push: tudo vai — entidades primeiro (cunham/fixam ids), depois scopes (resolvem\n // nome→id contra o server), e por fim o gen re-sincroniza os arquivos locais.\n const entities = await discoverEntities(entitiesDir, load);\n if (Object.keys(entities).length === 0) {\n log(`No entities found in ${dirRel}/entities.`);\n return 1;\n }\n\n const res = await pushEntities(entities, {\n ...net,\n confirm: args.confirm,\n fill: args.fill,\n renames: args.renames,\n });\n\n for (const n of res.applied) log(` 🟢 ${n} applied`);\n for (const r of res.review) {\n log(` ⚠ ${r.name} — needs review:`);\n for (const c of r.plan.changes) log(` ${riskIcon(c.risk)} ${c.op} ${c.path} (${c.risk})`);\n }\n // Mudanças bloqueadas no gate → para aqui; scopes/gen ficam pra quando aplicar.\n if (res.review.length > 0) {\n log(\"Run again with --confirm / --fill / --rename to apply the gated changes.\");\n return 1;\n }\n log(`✓ pushed ${res.applied.length} ${res.applied.length === 1 ? \"entity\" : \"entities\"}.`);\n\n // Scopes (só depois das entidades aplicadas — o push resolve nome→id no server).\n const scopes = await discoverScopes(path.join(dir, \"scopes\"), load);\n if (Object.keys(scopes).length > 0) {\n const { pushed } = await pushScopes(scopes, net);\n log(`✓ pushed ${pushed.length} ${pushed.length === 1 ? \"scope\" : \"scopes\"}.`);\n }\n\n // Re-sincroniza os arquivos locais (ids recém-cunhados), salvo --no-gen.\n if (!args.noGen) await regen();\n return 0;\n}\n\nexport async function main(): Promise<void> {\n process.exit(await runCli(process.argv.slice(2)));\n}\n\n// Executado direto (bin) → roda o main.\nif (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {\n void main();\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { Entity, ShapeRecord } from \"@mauroandre/weave-core\";\nimport type { ScopeDef } from \"./scope.js\";\n\n// Descoberta por pasta (file-based, igual o VeloJS acha rotas): cada arquivo é uma\n// entidade, exportada como `default`. Node-only (usa fs) — fora do barrel do SDK.\n\n/** Importa um módulo por caminho absoluto. Injetável (a CLI usa um loader de TS). */\nexport type ModuleLoader = (absPath: string) => Promise<{ default?: unknown }>;\n\nconst isEntity = (v: unknown): v is Entity<string, ShapeRecord> =>\n !!v && typeof v === \"object\" && \"name\" in v && \"columns\" in v;\n\n/**\n * Lê a pasta de entidades, importa o `default` de cada arquivo, e monta o objeto\n * `entities` chaveado pelo nome da entidade — o mesmo que o `pushEntities`/`createClient`\n * consomem. Ignora arquivos sem `export default defineEntity(...)`.\n */\nexport async function discoverEntities(\n entitiesDir: string,\n load: ModuleLoader = (p) => import(pathToFileURL(p).href),\n): Promise<Record<string, Entity<string, ShapeRecord>>> {\n const files = (await fs.readdir(entitiesDir))\n .filter((f) => /\\.(ts|tsx|mts|js|mjs)$/.test(f) && !f.endsWith(\".d.ts\"))\n .sort();\n\n const entities: Record<string, Entity<string, ShapeRecord>> = {};\n for (const f of files) {\n const mod = await load(path.resolve(entitiesDir, f));\n if (isEntity(mod.default)) entities[mod.default.name] = mod.default;\n }\n return entities;\n}\n\nconst isScope = (v: unknown): v is ScopeDef =>\n !!v && typeof v === \"object\" && \"name\" in v && \"entities\" in v && !(\"columns\" in v);\n\n/**\n * Lê a pasta de scopes (1 arquivo = 1 scope, `export default defineScope(...)`),\n * chaveando pelo nome do scope. Pasta ausente → `{}` (scopes são opcionais). O\n * barrel `index.ts` não tem default export, então é ignorado naturalmente.\n */\nexport async function discoverScopes(\n scopesDir: string,\n load: ModuleLoader = (p) => import(pathToFileURL(p).href),\n): Promise<Record<string, ScopeDef>> {\n let names: string[];\n try {\n names = await fs.readdir(scopesDir);\n } catch {\n return {}; // sem pasta de scopes\n }\n const files = names.filter((f) => /\\.(ts|tsx|mts|js|mjs)$/.test(f) && !f.endsWith(\".d.ts\")).sort();\n\n const scopes: Record<string, ScopeDef> = {};\n for (const f of files) {\n const mod = await load(path.resolve(scopesDir, f));\n if (isScope(mod.default)) scopes[mod.default.name] = mod.default;\n }\n return scopes;\n}\n"],"mappings":"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","names":["path","pathToFileURL","fs","path","pathToFileURL","entities","scopes"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/discover.ts"],"sourcesContent":["#!/usr/bin/env node\nimport path from \"node:path\";\nimport { realpathSync } from \"node:fs\";\nimport { pathToFileURL } from \"node:url\";\nimport { createJiti } from \"jiti\";\nimport { discoverEntities, discoverScopes, type ModuleLoader } from \"./discover.js\";\nimport { pushEntities } from \"./push.js\";\nimport { pushScopes } from \"./scope.js\";\nimport { pullEntities, genProject } from \"./gen.js\";\nimport { DEFAULT_DIR, type WeaveConfig } from \"./config.js\";\n\n// Barrel node-only (`@mauroandre/weave-sdk/cli`): a descoberta usa `node:fs`, então\n// fica fora do barrel principal (que é portável p/ browser).\nexport { discoverEntities, discoverScopes, type ModuleLoader } from \"./discover.js\";\n\n/** Escreve um arquivo (criando dirs). Injetável pra teste. */\nasync function defaultWrite(file: string, content: string): Promise<void> {\n const fs = await import(\"node:fs/promises\");\n await fs.mkdir(path.dirname(file), { recursive: true });\n await fs.writeFile(file, content, \"utf8\");\n}\n\n/** Apaga uma pasta recursivamente (idempotente). Injetável pra teste. */\nasync function defaultClean(dir: string): Promise<void> {\n const fs = await import(\"node:fs/promises\");\n await fs.rm(dir, { recursive: true, force: true });\n}\n\n// Loader padrão: jiti carrega os `.ts` do dev (weave.config.ts + entidades) em\n// runtime — resolve type-stripping e o `import \"./x.js\"` → `x.ts` que o Node puro\n// não faz. Criado uma vez, sob demanda. Injetável (os testes passam o próprio load).\nlet jiti: ReturnType<typeof createJiti> | null = null;\nconst defaultLoad: ModuleLoader = (p) => {\n jiti ??= createJiti(import.meta.url);\n return jiti.import(p) as Promise<{ default?: unknown }>;\n};\n\n/** Carrega o `.env` do projeto pro process.env (built-in do Node). Silencioso se não houver. */\nfunction loadEnv(cwd: string): Record<string, string | undefined> {\n try {\n process.loadEnvFile(path.resolve(cwd, \".env\"));\n } catch {\n /* sem .env — segue com o ambiente atual */\n }\n return process.env;\n}\nimport type { FetchLike } from \"./client.js\";\n\n// CLI `weave`. Comandos: `gen` (server → pasta weave/: entidades com $id, scopes,\n// barrels e client — overwrite cego), `push` (código → server, plan/apply em ordem\n// de dep), `pull` (legado: só entidades). url/key vêm do ambiente (WEAVE_URL/\n// WEAVE_KEY); a pasta de destino do `weave.config.ts` (`dir`, default \"weave\").\n// Flags: --config, --confirm, --fill, --rename. Carrega TS via runtime TS-capaz\n// (Node 22.6+ com --experimental-strip-types, ou tsx/jiti).\n\nexport interface ParsedArgs {\n command: string;\n config: string;\n confirm: Record<string, string[]>;\n fill: Record<string, Record<string, unknown>>;\n renames: Record<string, Record<string, string>>;\n /** `--no-gen`: após o push, NÃO re-sincroniza os arquivos locais (CI, read-only). */\n noGen: boolean;\n}\n\n/** \"product.legacy\" → [\"product\", \"legacy\"]; \"product.items.qty\" → [\"product\",\"items.qty\"]. */\nfunction splitEntity(s: string | undefined): [string, string] {\n if (!s) return [\"\", \"\"];\n const i = s.indexOf(\".\");\n return i < 0 ? [s, \"\"] : [s.slice(0, i), s.slice(i + 1)];\n}\n\nexport function parseArgs(argv: string[]): ParsedArgs {\n const out: ParsedArgs = { command: argv[0] ?? \"\", config: \"weave.config.ts\", confirm: {}, fill: {}, renames: {}, noGen: false };\n for (let i = 1; i < argv.length; i++) {\n const a = argv[i];\n if (a === \"--config\") out.config = argv[++i] ?? out.config;\n else if (a === \"--no-gen\") out.noGen = true;\n else if (a === \"--confirm\") {\n const [e, p] = splitEntity(argv[++i]);\n if (e && p) (out.confirm[e] ??= []).push(p);\n } else if (a === \"--fill\") {\n const [ep, v = \"\"] = (argv[++i] ?? \"\").split(/=(.*)/s);\n const [e, p] = splitEntity(ep);\n if (e && p) (out.fill[e] ??= {})[p] = v;\n } else if (a === \"--rename\") {\n const [ep, to = \"\"] = (argv[++i] ?? \"\").split(/=(.*)/s);\n const [e, p] = splitEntity(ep);\n if (e && p && to) (out.renames[e] ??= {})[p] = to;\n }\n }\n return out;\n}\n\nexport interface CliDeps {\n /** Importador de módulo (config + entidades). Default: dynamic import. */\n load?: ModuleLoader;\n /** Transporte HTTP. Default: globalThis.fetch. */\n fetch?: FetchLike;\n /** Escreve arquivo (pull/gen). Default: fs. */\n write?: (file: string, content: string) => Promise<void>;\n /** Apaga pasta (gen, antes de reescrever). Default: fs.rm. */\n clean?: (dir: string) => Promise<void>;\n /** Variáveis de ambiente (WEAVE_URL/WEAVE_KEY). Default: process.env. */\n env?: Record<string, string | undefined>;\n cwd?: string;\n log?: (msg: string) => void;\n}\n\nconst riskIcon = (r: string): string =>\n r === \"auto\" ? \"🟢\" : r === \"confirm\" ? \"🔴\" : r === \"needsValue\" ? \"🟡\" : \"⛔\";\n\n/** Roda o CLI. Devolve o exit code (0 ok; 1 erro / precisa de revisão). */\nexport async function runCli(argv: string[], deps: CliDeps = {}): Promise<number> {\n const args = parseArgs(argv);\n const log = deps.log ?? ((m: string) => console.log(m));\n const cwd = deps.cwd ?? process.cwd();\n const load: ModuleLoader = deps.load ?? defaultLoad;\n const env = deps.env ?? loadEnv(cwd);\n\n if (![\"push\", \"pull\", \"gen\"].includes(args.command)) {\n log(`Unknown command '${args.command}'. Try: weave push | pull | gen`);\n return 1;\n }\n\n const url = env[\"WEAVE_URL\"];\n const key = env[\"WEAVE_KEY\"];\n if (!url || !key) {\n log(\"Set WEAVE_URL and WEAVE_KEY in the environment.\");\n return 1;\n }\n\n // Config é opcional (só `dir`, default \"weave\"); ausente/ilegível → defaults.\n const configPath = path.resolve(cwd, args.config);\n let config: WeaveConfig = {};\n try {\n config = ((await load(configPath)).default ?? {}) as WeaveConfig;\n } catch {\n /* sem weave.config.ts — usa defaults */\n }\n const dirRel = config.dir ?? DEFAULT_DIR;\n const dir = path.resolve(cwd, dirRel);\n const entitiesDir = path.join(dir, \"entities\");\n const net = { url, key, ...(deps.fetch ? { fetch: deps.fetch } : {}) };\n const write = deps.write ?? defaultWrite;\n const clean = deps.clean ?? defaultClean;\n\n // Regenera a pasta weave/ a partir do server (overwrite cego). Usado pelo `gen`\n // e ao fim do `push` (re-sincroniza os $id recém-cunhados), salvo `--no-gen`.\n const regen = async (): Promise<void> => {\n const { files, entities, scopes } = await genProject(net);\n await clean(path.join(dir, \"entities\"));\n await clean(path.join(dir, \"scopes\"));\n for (const [rel, content] of Object.entries(files)) await write(path.join(dir, rel), content);\n log(`✓ generated ${entities.length} ${entities.length === 1 ? \"entity\" : \"entities\"}, ${scopes.length} ${scopes.length === 1 ? \"scope\" : \"scopes\"} → ${dirRel}/`);\n };\n\n // gen: server → pasta weave/ inteira (arquivos com $id, scopes resolvidos, barrels, client).\n if (args.command === \"gen\") {\n await regen();\n return 0;\n }\n\n // pull (legado): puxa os IRs remotos → escreve os arquivos de entidade (sem $id).\n if (args.command === \"pull\") {\n const { files, names } = await pullEntities(net);\n for (const [file, content] of Object.entries(files)) await write(path.join(entitiesDir, file), content);\n log(`✓ pulled ${names.length} ${names.length === 1 ? \"entity\" : \"entities\"} → ${dirRel}/entities`);\n return 0;\n }\n\n // push: tudo vai — entidades primeiro (cunham/fixam ids), depois scopes (resolvem\n // nome→id contra o server), e por fim o gen re-sincroniza os arquivos locais.\n const entities = await discoverEntities(entitiesDir, load);\n if (Object.keys(entities).length === 0) {\n log(`No entities found in ${dirRel}/entities.`);\n return 1;\n }\n\n const res = await pushEntities(entities, {\n ...net,\n confirm: args.confirm,\n fill: args.fill,\n renames: args.renames,\n });\n\n for (const n of res.applied) log(` 🟢 ${n} applied`);\n for (const r of res.review) {\n log(` ⚠ ${r.name} — needs review:`);\n for (const c of r.plan.changes) log(` ${riskIcon(c.risk)} ${c.op} ${c.path} (${c.risk})`);\n }\n // Mudanças bloqueadas no gate → para aqui; scopes/gen ficam pra quando aplicar.\n if (res.review.length > 0) {\n log(\"Run again with --confirm / --fill / --rename to apply the gated changes.\");\n return 1;\n }\n log(`✓ pushed ${res.applied.length} ${res.applied.length === 1 ? \"entity\" : \"entities\"}.`);\n\n // Scopes (só depois das entidades aplicadas — o push resolve nome→id no server).\n const scopes = await discoverScopes(path.join(dir, \"scopes\"), load);\n if (Object.keys(scopes).length > 0) {\n const { pushed } = await pushScopes(scopes, net);\n log(`✓ pushed ${pushed.length} ${pushed.length === 1 ? \"scope\" : \"scopes\"}.`);\n }\n\n // Re-sincroniza os arquivos locais (ids recém-cunhados), salvo --no-gen.\n if (!args.noGen) await regen();\n return 0;\n}\n\nexport async function main(): Promise<void> {\n process.exit(await runCli(process.argv.slice(2)));\n}\n\n// Executado direto (bin) → roda o main. `realpathSync` resolve o symlink do bin\n// (node_modules/.bin/weave → dist/cli.js); sem isso, rodar via o symlink não bate\n// com `import.meta.url` (caminho real) e o main nunca rodava.\nif (process.argv[1]) {\n try {\n const invoked = pathToFileURL(realpathSync(process.argv[1])).href;\n if (invoked === import.meta.url) void main();\n } catch {\n /* não foi possível resolver o caminho — não é uma invocação direta */\n }\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { Entity, ShapeRecord } from \"@mauroandre/weave-core\";\nimport type { ScopeDef } from \"./scope.js\";\n\n// Descoberta por pasta (file-based, igual o VeloJS acha rotas): cada arquivo é uma\n// entidade, exportada como `default`. Node-only (usa fs) — fora do barrel do SDK.\n\n/** Importa um módulo por caminho absoluto. Injetável (a CLI usa um loader de TS). */\nexport type ModuleLoader = (absPath: string) => Promise<{ default?: unknown }>;\n\nconst isEntity = (v: unknown): v is Entity<string, ShapeRecord> =>\n !!v && typeof v === \"object\" && \"name\" in v && \"columns\" in v;\n\n/**\n * Lê a pasta de entidades, importa o `default` de cada arquivo, e monta o objeto\n * `entities` chaveado pelo nome da entidade — o mesmo que o `pushEntities`/`createClient`\n * consomem. Ignora arquivos sem `export default defineEntity(...)`.\n */\nexport async function discoverEntities(\n entitiesDir: string,\n load: ModuleLoader = (p) => import(pathToFileURL(p).href),\n): Promise<Record<string, Entity<string, ShapeRecord>>> {\n const files = (await fs.readdir(entitiesDir))\n .filter((f) => /\\.(ts|tsx|mts|js|mjs)$/.test(f) && !f.endsWith(\".d.ts\"))\n .sort();\n\n const entities: Record<string, Entity<string, ShapeRecord>> = {};\n for (const f of files) {\n const mod = await load(path.resolve(entitiesDir, f));\n if (isEntity(mod.default)) entities[mod.default.name] = mod.default;\n }\n return entities;\n}\n\nconst isScope = (v: unknown): v is ScopeDef =>\n !!v && typeof v === \"object\" && \"name\" in v && \"entities\" in v && !(\"columns\" in v);\n\n/**\n * Lê a pasta de scopes (1 arquivo = 1 scope, `export default defineScope(...)`),\n * chaveando pelo nome do scope. Pasta ausente → `{}` (scopes são opcionais). O\n * barrel `index.ts` não tem default export, então é ignorado naturalmente.\n */\nexport async function discoverScopes(\n scopesDir: string,\n load: ModuleLoader = (p) => import(pathToFileURL(p).href),\n): Promise<Record<string, ScopeDef>> {\n let names: string[];\n try {\n names = await fs.readdir(scopesDir);\n } catch {\n return {}; // sem pasta de scopes\n }\n const files = names.filter((f) => /\\.(ts|tsx|mts|js|mjs)$/.test(f) && !f.endsWith(\".d.ts\")).sort();\n\n const scopes: Record<string, ScopeDef> = {};\n for (const f of files) {\n const mod = await load(path.resolve(scopesDir, f));\n if (isScope(mod.default)) scopes[mod.default.name] = mod.default;\n }\n return scopes;\n}\n"],"mappings":"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","names":["path","pathToFileURL","fs","path","entities","scopes","pathToFileURL"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mauroandre/weave-sdk",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Weave SDK — typed object client over the Weave HTTP API. The glue: entities-as-code in, objects out, HTTP/JSON invisible.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -43,5 +43,8 @@
43
43
  "typed-client",
44
44
  "sdk",
45
45
  "typescript"
46
- ]
46
+ ],
47
+ "dependencies": {
48
+ "jiti": "^2.7.0"
49
+ }
47
50
  }