@supacloud/compiler 0.22.0 → 0.23.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
@@ -197,10 +197,24 @@ function renderApplication(graph, options) {
197
197
  ""
198
198
  ].join(`
199
199
  `);
200
+ const commandGovernance = graph.modules.flatMap((module) => module.commands.map((command) => ({
201
+ module: module.name,
202
+ className: command.className,
203
+ name: command.name,
204
+ permission: command.permission ?? null,
205
+ rpc: command.rpc ?? null,
206
+ transaction: command.transaction ?? null,
207
+ audit: command.audit ?? null,
208
+ idempotency: command.idempotency ?? null
209
+ }))).sort((left, right) => `${left.module}:${left.name}`.localeCompare(`${right.module}:${right.name}`));
200
210
  const manifest = {
201
211
  version: 1,
202
212
  modules: graph.modules,
203
- externalTokens: graph.externalTokens
213
+ externalTokens: graph.externalTokens,
214
+ commandGovernance: {
215
+ defaults: { authorization: "required", audit: "required", idempotency: "required", transaction: "required" },
216
+ commands: commandGovernance
217
+ }
204
218
  };
205
219
  const clientCode = options.generateClient ? renderClient(graph, options) : undefined;
206
220
  const openApiCode = options.generateOpenApi ? renderOpenApi(graph, options) : undefined;
@@ -3953,7 +3967,7 @@ function validateGraph(graph, options = false) {
3953
3967
  if (typeof options === "object" && options.commandCapabilities) {
3954
3968
  const hostCaps = options.commandCapabilities;
3955
3969
  const rpcCaps = command.rpc && Object.hasOwn(hostCaps.rpc ?? {}, command.rpc) ? hostCaps.rpc?.[command.rpc] : undefined;
3956
- if (hostCaps.requirePersistentAdapters && (!rpcCaps?.boundary || rpcCaps.audit !== true || rpcCaps.idempotency !== true || hostCaps.permission !== true || !command.permission || !command.audit || command.idempotency !== "required" || rpcCaps.boundary === "database" && (rpcCaps.transaction !== true || command.transaction !== "required"))) {
3970
+ if (hostCaps.requirePersistentAdapters && (command.rpc !== undefined && (!rpcCaps?.boundary || rpcCaps.audit !== true || rpcCaps.idempotency !== true) || hostCaps.permission !== true || !command.permission || !command.audit || command.idempotency !== "required" || command.rpc !== undefined && rpcCaps?.boundary === "database" && (rpcCaps.transaction !== true || command.transaction !== "required") || command.rpc === undefined && (hostCaps.audit !== true || hostCaps.idempotency !== true || hostCaps.transaction !== true || command.transaction !== "required"))) {
3957
3971
  error("command-persistence-required", `Command ${command.name} requires an explicit persistent adapter, permission, audit and idempotency policy.`, module.file, module.line, "Register a named database/external adapter, enable permission checks and declare permission, audit and required idempotency on the command.");
3958
3972
  }
3959
3973
  if (rpcCaps?.boundary === "external" && (command.transaction === "required" || rpcCaps.transaction === true)) {
@@ -6923,10 +6937,20 @@ function validateRouteContracts(graph) {
6923
6937
  }
6924
6938
 
6925
6939
  // src/compile.ts
6940
+ function withDefaultGovernance(options) {
6941
+ return options.commandCapabilities === undefined ? { ...options, commandCapabilities: {
6942
+ requirePersistentAdapters: true,
6943
+ permission: true,
6944
+ audit: true,
6945
+ idempotency: true,
6946
+ transaction: true
6947
+ } } : options;
6948
+ }
6926
6949
  async function renderOptionalGraphql(options) {
6927
6950
  return options.graphql ? (await Promise.resolve().then(() => (init_graphql(), exports_graphql))).renderGraphql(options) : { diagnostics: [], files: {} };
6928
6951
  }
6929
6952
  async function compileProject(options) {
6953
+ options = withDefaultGovernance(options);
6930
6954
  const graph = await analyzeProject(options.rootDir, options.include, options.cache, options.changedPaths);
6931
6955
  const diagnostics = [
6932
6956
  ...graph.diagnostics ?? [],
@@ -6988,6 +7012,7 @@ async function compileProject(options) {
6988
7012
  return { diagnostics, graph, written, ...stats ? { stats } : {} };
6989
7013
  }
6990
7014
  async function checkProject(options) {
7015
+ options = withDefaultGovernance(options);
6991
7016
  const graph = await analyzeProject(options.rootDir, options.include, options.cache, options.changedPaths);
6992
7017
  const diagnostics = [
6993
7018
  ...graph.diagnostics ?? [],
@@ -11017,6 +11042,13 @@ var DEFAULT_SUPACLOUD_CONFIG = {
11017
11042
  generateOpenApi: true,
11018
11043
  generatePermissions: true,
11019
11044
  treeShakeUnusedProviders: true,
11045
+ commandCapabilities: {
11046
+ requirePersistentAdapters: true,
11047
+ permission: true,
11048
+ audit: true,
11049
+ idempotency: true,
11050
+ transaction: true
11051
+ },
11020
11052
  moduleBoundaryPreset: "modular-monolith"
11021
11053
  };
11022
11054
  function defineSupacloudConfig(config = {}) {
@@ -11100,7 +11132,7 @@ function resolveSupacloudConfig(config = {}, cwd = process.cwd()) {
11100
11132
  ...resolved.openApi === undefined ? {} : { openApi: resolved.openApi },
11101
11133
  generatePermissions: resolved.generatePermissions ?? DEFAULT_SUPACLOUD_CONFIG.generatePermissions,
11102
11134
  moduleBoundaryPreset: resolved.moduleBoundaryPreset ?? DEFAULT_SUPACLOUD_CONFIG.moduleBoundaryPreset,
11103
- commandCapabilities: resolved.commandCapabilities,
11135
+ commandCapabilities: resolved.commandCapabilities ?? DEFAULT_SUPACLOUD_CONFIG.commandCapabilities,
11104
11136
  ...resolved.moduleBoundaries ? { moduleBoundaries: resolved.moduleBoundaries } : {},
11105
11137
  ...resolved.typeSafety ? { typeSafety: resolved.typeSafety } : {},
11106
11138
  ...resolved.allowRouteCommandBindings === undefined ? {} : { allowRouteCommandBindings: resolved.allowRouteCommandBindings },
@@ -12173,9 +12205,9 @@ function compilerVersion() {
12173
12205
  }
12174
12206
  function migrationDependencies() {
12175
12207
  return {
12176
- "@supacloud/app": "0.14.0",
12208
+ "@supacloud/app": "0.15.0",
12177
12209
  "@supacloud/compiler": compilerVersion(),
12178
- "@supacloud/elysia": "0.17.0",
12210
+ "@supacloud/elysia": "0.18.0",
12179
12211
  elysia: "1.4.30",
12180
12212
  typescript: "7.0.2"
12181
12213
  };
package/dist/config.d.ts CHANGED
@@ -23,7 +23,7 @@ export interface SupaCloudConfig {
23
23
  commandCapabilities?: CommandExecutionCapabilities;
24
24
  treeShakeUnusedProviders?: boolean;
25
25
  }
26
- export declare const DEFAULT_SUPACLOUD_CONFIG: Required<Omit<SupaCloudConfig, "include" | "moduleBoundaryPreset" | "commandCapabilities" | "moduleBoundaries" | "typeSafety" | "delivery" | "allowRouteCommandBindings" | "disallowControllerDirectDb" | "detectOrphanModules" | "openApi">> & {
26
+ export declare const DEFAULT_SUPACLOUD_CONFIG: Required<Omit<SupaCloudConfig, "include" | "moduleBoundaryPreset" | "moduleBoundaries" | "typeSafety" | "delivery" | "allowRouteCommandBindings" | "disallowControllerDirectDb" | "detectOrphanModules" | "openApi">> & {
27
27
  include: string[];
28
28
  moduleBoundaryPreset: ModuleBoundaryPresetName;
29
29
  };
package/dist/index.js CHANGED
@@ -196,10 +196,24 @@ function renderApplication(graph, options) {
196
196
  ""
197
197
  ].join(`
198
198
  `);
199
+ const commandGovernance = graph.modules.flatMap((module) => module.commands.map((command) => ({
200
+ module: module.name,
201
+ className: command.className,
202
+ name: command.name,
203
+ permission: command.permission ?? null,
204
+ rpc: command.rpc ?? null,
205
+ transaction: command.transaction ?? null,
206
+ audit: command.audit ?? null,
207
+ idempotency: command.idempotency ?? null
208
+ }))).sort((left, right) => `${left.module}:${left.name}`.localeCompare(`${right.module}:${right.name}`));
199
209
  const manifest = {
200
210
  version: 1,
201
211
  modules: graph.modules,
202
- externalTokens: graph.externalTokens
212
+ externalTokens: graph.externalTokens,
213
+ commandGovernance: {
214
+ defaults: { authorization: "required", audit: "required", idempotency: "required", transaction: "required" },
215
+ commands: commandGovernance
216
+ }
203
217
  };
204
218
  const clientCode = options.generateClient ? renderClient(graph, options) : undefined;
205
219
  const openApiCode = options.generateOpenApi ? renderOpenApi(graph, options) : undefined;
@@ -3948,7 +3962,7 @@ function validateGraph(graph, options = false) {
3948
3962
  if (typeof options === "object" && options.commandCapabilities) {
3949
3963
  const hostCaps = options.commandCapabilities;
3950
3964
  const rpcCaps = command.rpc && Object.hasOwn(hostCaps.rpc ?? {}, command.rpc) ? hostCaps.rpc?.[command.rpc] : undefined;
3951
- if (hostCaps.requirePersistentAdapters && (!rpcCaps?.boundary || rpcCaps.audit !== true || rpcCaps.idempotency !== true || hostCaps.permission !== true || !command.permission || !command.audit || command.idempotency !== "required" || rpcCaps.boundary === "database" && (rpcCaps.transaction !== true || command.transaction !== "required"))) {
3965
+ if (hostCaps.requirePersistentAdapters && (command.rpc !== undefined && (!rpcCaps?.boundary || rpcCaps.audit !== true || rpcCaps.idempotency !== true) || hostCaps.permission !== true || !command.permission || !command.audit || command.idempotency !== "required" || command.rpc !== undefined && rpcCaps?.boundary === "database" && (rpcCaps.transaction !== true || command.transaction !== "required") || command.rpc === undefined && (hostCaps.audit !== true || hostCaps.idempotency !== true || hostCaps.transaction !== true || command.transaction !== "required"))) {
3952
3966
  error("command-persistence-required", `Command ${command.name} requires an explicit persistent adapter, permission, audit and idempotency policy.`, module.file, module.line, "Register a named database/external adapter, enable permission checks and declare permission, audit and required idempotency on the command.");
3953
3967
  }
3954
3968
  if (rpcCaps?.boundary === "external" && (command.transaction === "required" || rpcCaps.transaction === true)) {
@@ -6920,10 +6934,20 @@ function validateRouteContracts(graph) {
6920
6934
  }
6921
6935
 
6922
6936
  // src/compile.ts
6937
+ function withDefaultGovernance(options) {
6938
+ return options.commandCapabilities === undefined ? { ...options, commandCapabilities: {
6939
+ requirePersistentAdapters: true,
6940
+ permission: true,
6941
+ audit: true,
6942
+ idempotency: true,
6943
+ transaction: true
6944
+ } } : options;
6945
+ }
6923
6946
  async function renderOptionalGraphql(options) {
6924
6947
  return options.graphql ? (await Promise.resolve().then(() => (init_graphql(), exports_graphql))).renderGraphql(options) : { diagnostics: [], files: {} };
6925
6948
  }
6926
6949
  async function compileProject(options) {
6950
+ options = withDefaultGovernance(options);
6927
6951
  const graph = await analyzeProject(options.rootDir, options.include, options.cache, options.changedPaths);
6928
6952
  const diagnostics = [
6929
6953
  ...graph.diagnostics ?? [],
@@ -6985,6 +7009,7 @@ async function compileProject(options) {
6985
7009
  return { diagnostics, graph, written, ...stats ? { stats } : {} };
6986
7010
  }
6987
7011
  async function checkProject(options) {
7012
+ options = withDefaultGovernance(options);
6988
7013
  const graph = await analyzeProject(options.rootDir, options.include, options.cache, options.changedPaths);
6989
7014
  const diagnostics = [
6990
7015
  ...graph.diagnostics ?? [],
@@ -11750,9 +11775,9 @@ function compilerVersion() {
11750
11775
  }
11751
11776
  function migrationDependencies() {
11752
11777
  return {
11753
- "@supacloud/app": "0.14.0",
11778
+ "@supacloud/app": "0.15.0",
11754
11779
  "@supacloud/compiler": compilerVersion(),
11755
- "@supacloud/elysia": "0.17.0",
11780
+ "@supacloud/elysia": "0.18.0",
11756
11781
  elysia: "1.4.30",
11757
11782
  typescript: "7.0.2"
11758
11783
  };
@@ -12973,6 +12998,13 @@ var DEFAULT_SUPACLOUD_CONFIG = {
12973
12998
  generateOpenApi: true,
12974
12999
  generatePermissions: true,
12975
13000
  treeShakeUnusedProviders: true,
13001
+ commandCapabilities: {
13002
+ requirePersistentAdapters: true,
13003
+ permission: true,
13004
+ audit: true,
13005
+ idempotency: true,
13006
+ transaction: true
13007
+ },
12976
13008
  moduleBoundaryPreset: "modular-monolith"
12977
13009
  };
12978
13010
  function defineSupacloudConfig(config = {}) {
@@ -13056,7 +13088,7 @@ function resolveSupacloudConfig(config = {}, cwd = process.cwd()) {
13056
13088
  ...resolved.openApi === undefined ? {} : { openApi: resolved.openApi },
13057
13089
  generatePermissions: resolved.generatePermissions ?? DEFAULT_SUPACLOUD_CONFIG.generatePermissions,
13058
13090
  moduleBoundaryPreset: resolved.moduleBoundaryPreset ?? DEFAULT_SUPACLOUD_CONFIG.moduleBoundaryPreset,
13059
- commandCapabilities: resolved.commandCapabilities,
13091
+ commandCapabilities: resolved.commandCapabilities ?? DEFAULT_SUPACLOUD_CONFIG.commandCapabilities,
13060
13092
  ...resolved.moduleBoundaries ? { moduleBoundaries: resolved.moduleBoundaries } : {},
13061
13093
  ...resolved.typeSafety ? { typeSafety: resolved.typeSafety } : {},
13062
13094
  ...resolved.allowRouteCommandBindings === undefined ? {} : { allowRouteCommandBindings: resolved.allowRouteCommandBindings },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supacloud/compiler",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "description": "Static compiler for @supacloud/app metadata: builds the application graph from AST, validates it, and generates reflection-free factory code",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",