@elevasis/sdk 1.4.0 → 1.5.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.
Files changed (31) hide show
  1. package/dist/cli.cjs +100 -12
  2. package/dist/index.d.ts +1464 -749
  3. package/dist/index.js +74 -7
  4. package/dist/types/worker/adapters/crm.d.ts +20 -0
  5. package/dist/types/worker/adapters/index.d.ts +2 -0
  6. package/dist/types/worker/adapters/projects.d.ts +20 -0
  7. package/dist/worker/index.js +41 -1
  8. package/package.json +2 -2
  9. package/reference/_navigation.md +24 -0
  10. package/reference/deployment/provided-features.mdx +64 -25
  11. package/reference/framework/index.mdx +2 -2
  12. package/reference/framework/project-structure.mdx +10 -8
  13. package/reference/index.mdx +3 -3
  14. package/reference/packages/core/src/organization-model/README.md +19 -4
  15. package/reference/resources/patterns.mdx +54 -8
  16. package/reference/scaffold/core/organization-graph.mdx +262 -0
  17. package/reference/scaffold/core/organization-model.mdx +257 -0
  18. package/reference/scaffold/index.mdx +59 -0
  19. package/reference/scaffold/operations/workflow-recipes.md +419 -0
  20. package/reference/scaffold/recipes/add-a-feature.md +142 -0
  21. package/reference/scaffold/recipes/add-a-resource.md +163 -0
  22. package/reference/scaffold/recipes/gate-by-feature-or-admin.md +152 -0
  23. package/reference/scaffold/recipes/index.md +32 -0
  24. package/reference/scaffold/reference/contracts.md +1044 -0
  25. package/reference/scaffold/reference/feature-registry.md +30 -0
  26. package/reference/scaffold/reference/glossary.md +88 -0
  27. package/reference/scaffold/ui/composition-extensibility.mdx +216 -0
  28. package/reference/scaffold/ui/customization.md +239 -0
  29. package/reference/scaffold/ui/feature-flags-and-gating.md +265 -0
  30. package/reference/scaffold/ui/feature-shell.mdx +241 -0
  31. package/reference/scaffold/ui/recipes.md +418 -0
package/dist/cli.cjs CHANGED
@@ -43272,6 +43272,71 @@ var ResourceRegistry = class {
43272
43272
  validateRelationships(orgName, resources);
43273
43273
  }
43274
43274
  }
43275
+ /**
43276
+ * Get the remote resource IDs currently registered for an organization.
43277
+ * Used to validate redeployments against the post-swap state before any
43278
+ * live registry mutation occurs.
43279
+ */
43280
+ getRemoteResourceIds(orgName) {
43281
+ const prefix = `${orgName}/`;
43282
+ const remoteIds = /* @__PURE__ */ new Set();
43283
+ for (const key of this.remoteResources.keys()) {
43284
+ if (key.startsWith(prefix)) {
43285
+ remoteIds.add(key.slice(prefix.length));
43286
+ }
43287
+ }
43288
+ return remoteIds;
43289
+ }
43290
+ /**
43291
+ * Build the "static + surviving" baseline for registration validation.
43292
+ * On redeploy, this strips the currently remote-owned resources and
43293
+ * deployment-owned metadata so validation reflects the state after swap.
43294
+ */
43295
+ buildRegistrationBase(orgName) {
43296
+ const existingOrg = this.registry[orgName];
43297
+ if (!existingOrg) return void 0;
43298
+ const remoteIds = this.getRemoteResourceIds(orgName);
43299
+ if (remoteIds.size === 0) return existingOrg;
43300
+ const relationships = existingOrg.relationships ? Object.fromEntries(Object.entries(existingOrg.relationships).filter(([resourceId]) => !remoteIds.has(resourceId))) : void 0;
43301
+ return {
43302
+ ...existingOrg,
43303
+ version: existingOrg.version ?? "0.0.0",
43304
+ workflows: (existingOrg.workflows ?? []).filter((w) => !remoteIds.has(w.config.resourceId)),
43305
+ agents: (existingOrg.agents ?? []).filter((a) => !remoteIds.has(a.config.resourceId)),
43306
+ triggers: void 0,
43307
+ integrations: void 0,
43308
+ humanCheckpoints: void 0,
43309
+ externalResources: void 0,
43310
+ relationships: relationships && Object.keys(relationships).length > 0 ? relationships : void 0
43311
+ };
43312
+ }
43313
+ /**
43314
+ * Validate the registry state that would exist after registration succeeds.
43315
+ * This runs before any live mutation so invalid redeploys preserve the
43316
+ * currently active remote resources.
43317
+ */
43318
+ validateRegistrationCandidate(orgName, incoming) {
43319
+ const base = this.buildRegistrationBase(orgName);
43320
+ const candidate = base ? {
43321
+ ...base,
43322
+ version: incoming.version ?? base.version ?? "0.0.0",
43323
+ workflows: [...base.workflows ?? [], ...incoming.workflows ?? []],
43324
+ agents: [...base.agents ?? [], ...incoming.agents ?? []],
43325
+ triggers: incoming.triggers,
43326
+ integrations: incoming.integrations,
43327
+ humanCheckpoints: incoming.humanCheckpoints,
43328
+ externalResources: incoming.externalResources,
43329
+ relationships: incoming.relationships ? {
43330
+ ...base.relationships ?? {},
43331
+ ...incoming.relationships
43332
+ } : base.relationships
43333
+ } : {
43334
+ ...incoming,
43335
+ version: incoming.version ?? "0.0.0"
43336
+ };
43337
+ validateDeploymentSpec(orgName, candidate);
43338
+ validateRelationships(orgName, candidate);
43339
+ }
43275
43340
  /**
43276
43341
  * Get a resource definition by ID
43277
43342
  * Returns full definition (WorkflowDefinition or AgentDefinition)
@@ -43380,13 +43445,10 @@ var ResourceRegistry = class {
43380
43445
  );
43381
43446
  }
43382
43447
  }
43383
- if (this.isRemote(orgName)) {
43384
- this.unregisterOrganization(orgName);
43385
- }
43386
- const existingOrg = this.registry[orgName];
43387
- if (existingOrg) {
43388
- const staticWorkflowIds = new Set((existingOrg.workflows ?? []).map((w) => w.config.resourceId));
43389
- const staticAgentIds = new Set((existingOrg.agents ?? []).map((a) => a.config.resourceId));
43448
+ const validationBase = this.buildRegistrationBase(orgName);
43449
+ if (validationBase) {
43450
+ const staticWorkflowIds = new Set((validationBase.workflows ?? []).map((w) => w.config.resourceId));
43451
+ const staticAgentIds = new Set((validationBase.agents ?? []).map((a) => a.config.resourceId));
43390
43452
  for (const id of incomingIds) {
43391
43453
  if (staticWorkflowIds.has(id) || staticAgentIds.has(id)) {
43392
43454
  throw new Error(
@@ -43395,6 +43457,11 @@ var ResourceRegistry = class {
43395
43457
  }
43396
43458
  }
43397
43459
  }
43460
+ this.validateRegistrationCandidate(orgName, org);
43461
+ if (this.isRemote(orgName)) {
43462
+ this.unregisterOrganization(orgName);
43463
+ }
43464
+ const existingOrg = this.registry[orgName];
43398
43465
  if (existingOrg) {
43399
43466
  existingOrg.workflows = [...existingOrg.workflows ?? [], ...org.workflows ?? []];
43400
43467
  existingOrg.agents = [...existingOrg.agents ?? [], ...org.agents ?? []];
@@ -43795,8 +43862,21 @@ function resolveApiKey(prod) {
43795
43862
  }
43796
43863
  return process.env.ELEVASIS_PLATFORM_KEY ?? "";
43797
43864
  }
43865
+ function preParseEnvFlag(argv = process.argv) {
43866
+ const idx = argv.indexOf("--env");
43867
+ if (idx === -1 || idx + 1 >= argv.length) return void 0;
43868
+ const envPath2 = (0, import_path.resolve)(argv[idx + 1]);
43869
+ argv.splice(idx, 2);
43870
+ return envPath2;
43871
+ }
43798
43872
  function findEnvFile(startDir) {
43799
- const cwd = (0, import_path.resolve)(startDir ?? process.cwd());
43873
+ const raw = (0, import_path.resolve)(startDir ?? process.cwd());
43874
+ let cwd;
43875
+ try {
43876
+ cwd = (0, import_fs.realpathSync)(raw);
43877
+ } catch {
43878
+ cwd = raw;
43879
+ }
43800
43880
  let dir = cwd;
43801
43881
  while (true) {
43802
43882
  const candidate = (0, import_path.resolve)(dir, ".env");
@@ -43917,7 +43997,7 @@ function wrapAction(commandName, fn) {
43917
43997
  // package.json
43918
43998
  var package_default = {
43919
43999
  name: "@elevasis/sdk",
43920
- version: "1.4.0",
44000
+ version: "1.5.1",
43921
44001
  description: "SDK for building Elevasis organization resources",
43922
44002
  type: "module",
43923
44003
  bin: {
@@ -45776,13 +45856,18 @@ function registerProjectCommands(program3) {
45776
45856
  }
45777
45857
 
45778
45858
  // src/cli/index.ts
45779
- var envPath = findEnvFile();
45859
+ var explicitEnvPath = preParseEnvFlag();
45860
+ var envPath = explicitEnvPath ?? findEnvFile();
45780
45861
  if (envPath) {
45781
- (0, import_dotenv.config)({ path: envPath, override: true });
45862
+ const result = (0, import_dotenv.config)({ path: envPath, override: true });
45863
+ if (result.error) {
45864
+ console.error(source_default.yellow(`\u26A0 Found .env at ${envPath} but failed to load it: ${result.error.message}`));
45865
+ }
45782
45866
  } else if (!process.env.ELEVASIS_PLATFORM_KEY) {
45783
45867
  const cwd = process.cwd();
45784
45868
  console.error(source_default.yellow(`\u26A0 No .env file found (searched upward from ${cwd})`));
45785
- console.error(source_default.gray(" Set ELEVASIS_PLATFORM_KEY in a .env at your project root."));
45869
+ console.error(source_default.gray(" Set ELEVASIS_PLATFORM_KEY in a .env at your project root,"));
45870
+ console.error(source_default.gray(" or use --env <path> to specify the file location."));
45786
45871
  }
45787
45872
  var program2 = new Command();
45788
45873
  program2.name("elevasis-sdk").description(
@@ -45799,6 +45884,9 @@ Commands:
45799
45884
  elevasis-sdk deployments List deployments
45800
45885
  elevasis-sdk rename <id> --to <newId> [--prod] Rename resource across platform tables
45801
45886
 
45887
+ Global options:
45888
+ --env <path> Path to .env file (overrides automatic discovery)
45889
+
45802
45890
  Use "elevasis-sdk <command> --help" for more information about a command.`
45803
45891
  ).version(SDK_VERSION);
45804
45892
  registerCheckCommand(program2);