@sequenceholdings/orm 0.1.3 → 2.0.0

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/cli.js CHANGED
@@ -1219,7 +1219,12 @@ async function loadNamespaceFromDir(dir, options = {}) {
1219
1219
  const jiti = createJiti(import.meta.url, {
1220
1220
  interopDefault: true,
1221
1221
  fsCache: false,
1222
- ...options.ormModulePath !== void 0 ? { alias: { "@sequenceholdings/orm": options.ormModulePath } } : {}
1222
+ ...options.ormModulePath !== void 0 ? {
1223
+ alias: {
1224
+ "@sequenceholdings/orm": options.ormModulePath,
1225
+ "@sequenceholdings/orm/authoring": options.ormModulePath
1226
+ }
1227
+ } : {}
1223
1228
  });
1224
1229
  const context = beginAuthoringContext();
1225
1230
  try {
@@ -1310,7 +1315,7 @@ var manifestOperationSchema = z.object({
1310
1315
  kind: z.enum(["query", "mutation"]),
1311
1316
  requires: manifestRequiresSchema
1312
1317
  });
1313
- z.object({
1318
+ var operationsManifestSchema = z.object({
1314
1319
  manifestVersion: z.literal(MANIFEST_VERSION),
1315
1320
  schemaHash: z.string().min(1),
1316
1321
  opsHash: z.string().regex(OP_HASH_RE),
@@ -1921,6 +1926,10 @@ var Parser = class {
1921
1926
  this.expect("rparen", "')'");
1922
1927
  return inner;
1923
1928
  }
1929
+ if (this.peekKeyword("true") || this.peekKeyword("false")) {
1930
+ const token = this.advance();
1931
+ return { kind: "literal", value: token.value === "true" };
1932
+ }
1924
1933
  if (this.peekKeyword("capability") || this.peekKeyword("role")) {
1925
1934
  const fn = this.peek().value;
1926
1935
  const node = this.parseBooleanCall(fn);
@@ -2104,6 +2113,8 @@ var PolicyCompiler = class {
2104
2113
  }
2105
2114
  compile(node, table, depth) {
2106
2115
  switch (node.kind) {
2116
+ case "literal":
2117
+ return { kind: "const", value: node.value };
2107
2118
  case "and":
2108
2119
  case "or":
2109
2120
  return { kind: node.kind, operands: node.operands.map((operand) => this.compile(operand, table, depth)) };
@@ -7295,6 +7306,8 @@ var USAGE = `usage:
7295
7306
  seq-studio orm apply [dir] -e <env> author the migration, register, apply, and refresh the generated outputs (the everyday command)
7296
7307
  seq-studio orm apply --dry-run -e <env> rehearse the migration on a copy of the environment's real data, then discard it (no real apply)
7297
7308
  seq-studio orm apply --no-create -e <env> apply only if the namespace is already registered (CI guard; never provisions a new namespace)
7309
+ seq-studio orm execute <operation> [dir] --variables-file <file> -e <env>
7310
+ execute one named persisted operation as the signed-in caller
7298
7311
  seq-studio orm diff [dir] write/verify the committed migration standalone (--check is the offline CI gate; --allow-destructive consents; --rebase records a v1 -> v2 conversion as a verified no-op)
7299
7312
  seq-studio orm migrate-from-yaml <dir> convert a v1 YAML namespace to the v2 TypeScript format (migrations/ preserved)
7300
7313
 
@@ -7318,6 +7331,10 @@ async function runCli(argv) {
7318
7331
  console.log(USAGE);
7319
7332
  return command ? 0 : 1;
7320
7333
  }
7334
+ if (rest.includes("--help") || rest.includes("-h")) {
7335
+ console.log(USAGE);
7336
+ return 0;
7337
+ }
7321
7338
  try {
7322
7339
  switch (command) {
7323
7340
  case "init":
@@ -7355,6 +7372,8 @@ async function runCli(argv) {
7355
7372
  const dir = positional(rest) ?? ".";
7356
7373
  return await detectProjectFormat(dir) === "v2" ? await applyV2Command(rest, dir) : await applyCommand(rest);
7357
7374
  }
7375
+ case "execute":
7376
+ return await executeV2Command(rest);
7358
7377
  default:
7359
7378
  console.error(`unknown command: ${command}`);
7360
7379
  console.log(USAGE);
@@ -7365,13 +7384,14 @@ async function runCli(argv) {
7365
7384
  return 1;
7366
7385
  }
7367
7386
  }
7387
+ var NON_DEFINITION_YAML_FILES = /* @__PURE__ */ new Set(["pnpm-lock.yaml", "pnpm-workspace.yaml"]);
7368
7388
  async function detectProjectFormat(dir) {
7369
7389
  const entries = await readdir(dir, { withFileTypes: true }).catch(() => {
7370
7390
  throw new OrmDefinitionError(`namespace directory not found: ${dir}`);
7371
7391
  });
7372
7392
  const hasConfig = entries.some((entry) => entry.isFile() && entry.name === NAMESPACE_CONFIG_FILE);
7373
7393
  const hasYaml = entries.some(
7374
- (entry) => entry.isFile() && DEFINITION_FILE_EXTENSIONS.some((extension) => entry.name.endsWith(extension))
7394
+ (entry) => entry.isFile() && !NON_DEFINITION_YAML_FILES.has(entry.name) && DEFINITION_FILE_EXTENSIONS.some((extension) => entry.name.endsWith(extension))
7375
7395
  );
7376
7396
  if (hasConfig && hasYaml) {
7377
7397
  throw new OrmDefinitionError(
@@ -7566,6 +7586,79 @@ async function runConsumerCodegen(dir) {
7566
7586
  console.log(`ran consumer graphql-codegen (${CODEGEN_CONFIG_FILE})`);
7567
7587
  return 0;
7568
7588
  }
7589
+ function isVariablesObject(value) {
7590
+ return value !== null && typeof value === "object" && !Array.isArray(value);
7591
+ }
7592
+ function parseExecuteArgs(rest) {
7593
+ const args = [...rest];
7594
+ const variablesIndex = args.indexOf("--variables-file");
7595
+ if (variablesIndex === -1) {
7596
+ throw new OrmDefinitionError("execute requires --variables-file <file>");
7597
+ }
7598
+ const variablesFile = args[variablesIndex + 1];
7599
+ if (!variablesFile) {
7600
+ throw new OrmDefinitionError("execute requires --variables-file <file>");
7601
+ }
7602
+ args.splice(variablesIndex, 2);
7603
+ const envIndex = args.indexOf("--env");
7604
+ if (envIndex !== -1) args.splice(envIndex, 2);
7605
+ if (args.some((arg) => arg.startsWith("-"))) {
7606
+ throw new OrmDefinitionError("execute accepts only <operation>, [dir], --variables-file, and --env");
7607
+ }
7608
+ const operation = args[0];
7609
+ if (!operation || args.length > 2) {
7610
+ throw new OrmDefinitionError("usage: seq-studio orm execute <operation> [dir] --variables-file <file> -e <env>");
7611
+ }
7612
+ return {
7613
+ operation,
7614
+ dir: args[1] ?? ".",
7615
+ variablesFile
7616
+ };
7617
+ }
7618
+ async function readExecuteVariables(variablesFile) {
7619
+ let parsed;
7620
+ try {
7621
+ parsed = JSON.parse(await readFile(resolve(variablesFile), "utf8"));
7622
+ } catch (error) {
7623
+ throw new OrmDefinitionError(
7624
+ `could not read JSON variables from ${variablesFile}: ${error instanceof Error ? error.message : String(error)}`
7625
+ );
7626
+ }
7627
+ if (!isVariablesObject(parsed)) {
7628
+ throw new OrmDefinitionError("--variables-file must contain a JSON object");
7629
+ }
7630
+ return parsed;
7631
+ }
7632
+ async function executeV2Command(rest) {
7633
+ const { dir, operation, variablesFile } = parseExecuteArgs(rest);
7634
+ if (await detectProjectFormat(dir) !== "v2") {
7635
+ throw new OrmDefinitionError("execute supports TypeScript ORM v2 namespaces only");
7636
+ }
7637
+ const loaded = await loadV2(dir);
7638
+ const manifestPath = join(dir, OPERATIONS_MANIFEST_FILE);
7639
+ let manifest;
7640
+ try {
7641
+ manifest = operationsManifestSchema.parse(JSON.parse(await readFile(manifestPath, "utf8")));
7642
+ } catch (error) {
7643
+ throw new OrmDefinitionError(
7644
+ `could not read ${OPERATIONS_MANIFEST_FILE}: ${error instanceof Error ? error.message : String(error)} \u2014 run \`seq-studio orm generate ${dir}\` first`
7645
+ );
7646
+ }
7647
+ const selected = manifest.operations[operation];
7648
+ if (!selected) {
7649
+ throw new OrmDefinitionError(
7650
+ `operation "${operation}" is not in ${OPERATIONS_MANIFEST_FILE}; run \`seq-studio orm generate ${dir}\` after editing GraphQL documents`
7651
+ );
7652
+ }
7653
+ const variables = await readExecuteVariables(variablesFile);
7654
+ const response = await apiRequestStrict(
7655
+ "POST",
7656
+ `/_data/v2/${loaded.canonical.namespace}`,
7657
+ { op: selected.hash, variables }
7658
+ );
7659
+ console.log(JSON.stringify(response, null, 2));
7660
+ return 0;
7661
+ }
7569
7662
  async function validateV2Command(dir) {
7570
7663
  const compiled = await compileV2Project(dir);
7571
7664
  printDiagnostics(compiled.ok ? compiled.project.diagnostics : compiled.diagnostics);